Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
S
se390-1-fe
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
10
Issues
10
List
Boards
Labels
Service Desk
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Milan John Paul Digiuseppe
se390-1-fe
Commits
b9c583d2
Commit
b9c583d2
authored
Aug 17, 2020
by
will brown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Groups to Store + hard-coded sample Groups to test UI
parent
be87ea86
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
354 additions
and
3 deletions
+354
-3
.eslintrc.json
.eslintrc.json
+1
-0
src/SampleGroups.ts
src/SampleGroups.ts
+67
-0
src/navigation/HomeNavigator.tsx
src/navigation/HomeNavigator.tsx
+6
-1
src/screens/GroupScreen.tsx
src/screens/GroupScreen.tsx
+146
-0
src/screens/MainDrawer.tsx
src/screens/MainDrawer.tsx
+40
-2
src/store/RootReducer.ts
src/store/RootReducer.ts
+2
-0
src/store/groups/GroupActions.ts
src/store/groups/GroupActions.ts
+2
-0
src/store/groups/GroupSelectors.ts
src/store/groups/GroupSelectors.ts
+30
-0
src/store/groups/GroupSlice.ts
src/store/groups/GroupSlice.ts
+35
-0
src/store/groups/GroupState.ts
src/store/groups/GroupState.ts
+25
-0
No files found.
.eslintrc.json
View file @
b9c583d2
...
...
@@ -23,6 +23,7 @@
},
"plugins"
:
[
"react"
,
"@typescript-eslint"
,
"prettier"
],
"rules"
:
{
"linebreak-style"
:
"off"
,
"func-names"
:
"off"
,
"max-len"
:
"error"
,
"no-console"
:
"off"
,
...
...
src/SampleGroups.ts
0 → 100644
View file @
b9c583d2
import
{
Group
}
from
'
./store/groups/GroupState
'
;
export
const
sampleGroups
:
Group
[]
=
[
{
groupId
:
'
0
'
,
groupName
:
'
School Squad
'
,
memberList
:
[
{
userId
:
'
will.brown
'
,
permissions
:
{
admin
:
true
},
},
{
userId
:
'
jayson
'
,
permissions
:
{
admin
:
false
},
},
{
userId
:
'
krisztian
'
,
permissions
:
{
admin
:
false
},
},
],
cacheIdList
:
[
'
1
'
,
'
2
'
,
],
},
{
groupId
:
'
1
'
,
groupName
:
'
Cool Club
'
,
memberList
:
[
{
userId
:
'
will.brown
'
,
permissions
:
{
admin
:
true
},
},
{
userId
:
'
krisztian
'
,
permissions
:
{
admin
:
false
},
},
{
userId
:
'
jason
'
,
permissions
:
{
admin
:
false
},
},
{
userId
:
'
milan.digiuseppe
'
,
permissions
:
{
admin
:
false
},
},
{
userId
:
'
roxy.the.dog
'
,
permissions
:
{
admin
:
false
},
},
{
userId
:
'
clifford.the.big.dog
'
,
permissions
:
{
admin
:
false
},
},
{
userId
:
'
dogmeat
'
,
permissions
:
{
admin
:
false
},
},
{
userId
:
'
epic.gamer.cool.dude
'
,
permissions
:
{
admin
:
false
},
},
],
cacheIdList
:
[
'
3
'
,
],
},
];
src/navigation/HomeNavigator.tsx
View file @
b9c583d2
...
...
@@ -8,6 +8,7 @@ import SavedListScreen from '../screens/SavedListScreen';
import
CacheDetailScreen
,
{
NavParams
}
from
'
../screens/CacheDetailScreen
'
;
import
RevisitCacheScreen
from
'
../screens/RevisitCacheScreen
'
;
import
DevScreen
from
'
../screens/DevScreen
'
;
import
GroupScreen
from
'
../screens/GroupScreen
'
;
const
Stack
=
createStackNavigator
();
const
HomeNavigator
=
()
=>
(
...
...
@@ -23,7 +24,7 @@ const HomeNavigator = () => (
<
Stack
.
Screen
name
=
{
'
Discover
'
}
component
=
{
DiscoverScreen
}
options
=
{
{
headerShown
:
false
}
}
options
=
{
{
headerShown
:
false
}
}
/>
<
Stack
.
Screen
...
...
@@ -52,6 +53,10 @@ const HomeNavigator = () => (
name
=
{
'
Dev
'
}
component
=
{
DevScreen
}
/>
<
Stack
.
Screen
name
=
{
'
Group
'
}
component
=
{
GroupScreen
}
/>
</
Stack
.
Navigator
>
);
...
...
src/screens/GroupScreen.tsx
0 → 100644
View file @
b9c583d2
import
React
from
'
react
'
;
import
{
useSelector
}
from
'
react-redux
'
;
import
{
useRoute
,
useNavigation
}
from
'
@react-navigation/native
'
;
import
{
View
,
StyleSheet
,
FlatList
,
Text
,
}
from
'
react-native
'
;
import
{
Avatar
,
ListItem
,
Icon
,
}
from
'
react-native-elements
'
;
import
CacheListItem
from
'
../components/CacheListItem
'
;
import
{
Cache
}
from
'
../store/caches/CachesState
'
;
import
GeoText
from
'
../components/GeoText
'
;
import
theme
from
'
../theme
'
;
import
{
getUserName
,
getUserImageUrl
,
}
from
'
../store/auth/AuthSelectors
'
;
import
{
getGroupMemgers
,
getGroupCaches
,
getGroup
}
from
'
../store/groups/GroupSelectors
'
;
import
{
Membership
}
from
'
../store/groups/GroupState
'
;
const
styles
=
StyleSheet
.
create
({
avatar
:
{
backgroundColor
:
theme
.
colors
.
mediumgray
,
marginTop
:
theme
.
spacing
.
medium
,
},
});
const
renderMember
=
(
item
:
{
item
:
Membership
})
=>
{
const
member
=
item
.
item
;
return
(
<
ListItem
key
=
{
member
.
userId
}
title
=
{
member
.
userId
}
style
=
{
{
marginTop
:
theme
.
spacing
.
small
,
marginLeft
:
theme
.
spacing
.
medium
,
marginRight
:
theme
.
spacing
.
medium
,
}
}
titleStyle
=
{
{
color
:
member
.
permissions
.
admin
?
theme
.
colors
.
green
:
theme
.
colors
.
black
,
}
}
containerStyle
=
{
{
backgroundColor
:
member
.
permissions
.
admin
?
theme
.
colors
.
lightgray
:
theme
.
colors
.
white
,
}
}
/>
);
};
const
renderCache
=
(
item
:
{
item
:
Cache
})
=>
{
const
{
id
,
found
,
name
,
message
,
isUserCreated
,
type
,
game
,
foundReverseGeocode
,
imageUri
,
}
=
item
.
item
;
return
(
<
CacheListItem
id
=
{
id
}
found
=
{
found
}
name
=
{
isUserCreated
?
'
me
'
:
name
}
message
=
{
message
}
cacheType
=
{
type
}
yourMove
=
{
game
&&
game
.
yourMove
}
foundReverseGeocode
=
{
foundReverseGeocode
}
imageUri
=
{
imageUri
}
/>
);
};
const
GroupScreen
=
()
=>
{
const
{
params
}
=
useRoute
();
const
userName
=
useSelector
(
getUserName
);
const
userImageUrl
=
useSelector
(
getUserImageUrl
);
const
{
groupId
}
=
params
;
const
group
=
useSelector
(
getGroup
(
groupId
));
const
memberList
=
useSelector
(
getGroupMemgers
(
groupId
));
const
cacheList
=
useSelector
(
getGroupCaches
(
groupId
));
return
(
<
View
style
=
{
{
flex
:
1
,
justifyContent
:
'
space-between
'
}
}
>
<
View
style
=
{
{
alignItems
:
'
center
'
}
}
>
<
GeoText
text
=
{
group
.
groupName
!
}
variant
=
{
'
header
'
}
style
=
{
{
marginTop
:
theme
.
spacing
.
small
}
}
/>
</
View
>
<
View
style
=
{
{
flex
:
1
,
justifyContent
:
'
space-between
'
}
}
>
<
ListItem
// todo: make geotext
key
=
{
'
cachesheader
'
}
title
=
{
'
Caches
'
}
style
=
{
{
marginTop
:
theme
.
spacing
.
small
,
marginLeft
:
theme
.
spacing
.
small
,
marginRight
:
theme
.
spacing
.
small
,
}
}
containerStyle
=
{
{
backgroundColor
:
theme
.
colors
.
white
,
}
}
/>
<
FlatList
data
=
{
Object
.
values
(
cacheList
)
}
renderItem
=
{
renderCache
}
keyExtractor
=
{
(
cache
:
Cache
)
=>
cache
.
id
}
/>
</
View
>
<
View
style
=
{
{
flex
:
1
,
justifyContent
:
'
space-between
'
}
}
>
<
ListItem
// todo: make geotext
key
=
{
'
membersheader
'
}
title
=
{
'
Members
'
}
style
=
{
{
marginTop
:
theme
.
spacing
.
small
,
}
}
containerStyle
=
{
{
backgroundColor
:
theme
.
colors
.
white
,
}
}
/>
<
FlatList
data
=
{
Object
.
values
(
memberList
)
}
renderItem
=
{
renderMember
}
keyExtractor
=
{
(
member
:
Membership
)
=>
member
.
userId
}
/>
</
View
>
</
View
>
);
};
export
default
GroupScreen
;
src/screens/MainDrawer.tsx
View file @
b9c583d2
import
React
,
{
useCallback
,
useMemo
}
from
'
react
'
;
import
{
View
,
StyleSheet
}
from
'
react-native
'
;
import
{
Avatar
,
ListItem
,
Icon
}
from
'
react-native-elements
'
;
import
{
View
,
StyleSheet
,
Group
}
from
'
react-native
'
;
import
{
Avatar
,
ListItem
,
Icon
,
}
from
'
react-native-elements
'
;
import
{
useSelector
,
useDispatch
}
from
'
react-redux
'
;
import
{
useNavigation
}
from
'
@react-navigation/native
'
;
import
{
getUserImageUrl
,
getUserName
}
from
'
../store/auth/AuthSelectors
'
;
import
{
getGroups
}
from
'
../store/groups/GroupSelectors
'
;
import
theme
from
'
../theme
'
;
import
GeoText
from
'
../components/GeoText
'
;
import
GeoButton
from
'
../components/GeoButton
'
;
...
...
@@ -40,6 +43,7 @@ const MainDrawer: React.FC<Props> = ({ onClose }) => {
const
{
navigate
}
=
useNavigation
();
const
userImageUrl
=
useSelector
(
getUserImageUrl
);
const
userName
=
useSelector
(
getUserName
);
const
groups
=
useSelector
(
getGroups
);
const
onSettingsPress
=
useCallback
(()
=>
{
onClose
();
...
...
@@ -55,6 +59,11 @@ const MainDrawer: React.FC<Props> = ({ onClose }) => {
dispatch
(
signOutAsync
());
},
[
dispatch
,
onClose
]);
const
onGroupSettings
=
useCallback
(()
=>
{
// onClose();
navigate
(
'
Group
'
,
{});
},
[
onClose
,
navigate
]);
const
items
:
ActionItem
[]
=
useMemo
(()
=>
([
{
icon
:
'
user-edit
'
,
...
...
@@ -73,6 +82,7 @@ const MainDrawer: React.FC<Props> = ({ onClose }) => {
},
]),
[
onSettingsPress
,
onDevPress
]);
return
(
<
View
style
=
{
styles
.
drawer
}
>
<
View
style
=
{
styles
.
header
}
>
...
...
@@ -104,6 +114,34 @@ const MainDrawer: React.FC<Props> = ({ onClose }) => {
onPress
=
{
item
.
onPress
}
/>
))
}
<
View
>
<
ListItem
key
=
{
'
groupheader
'
}
title
=
{
'
Groups
'
}
style
=
{
{
marginTop
:
theme
.
spacing
.
small
,
}
}
containerStyle
=
{
{
backgroundColor
:
theme
.
colors
.
white
,
}
}
/>
{
groups
.
map
((
group
)
=>
(
<
ListItem
key
=
{
group
.
groupId
}
title
=
{
group
.
groupName
}
style
=
{
{
marginTop
:
theme
.
spacing
.
small
,
marginLeft
:
theme
.
spacing
.
medium
,
}
}
containerStyle
=
{
{
backgroundColor
:
theme
.
colors
.
white
,
}
}
onPress
=
{
()
=>
navigate
(
'
Group
'
,
{
groupId
:
group
.
groupId
})
}
/>
))
}
</
View
>
<
View
style
=
{
styles
.
logout
}
>
<
GeoButton
title
=
{
'
Log out
'
}
onPress
=
{
onSignout
}
type
=
{
'
clear
'
}
/>
</
View
>
...
...
src/store/RootReducer.ts
View file @
b9c583d2
...
...
@@ -3,12 +3,14 @@ import authSlice from './auth/AuthSlice';
import
cachesSlice
from
'
./caches/CachesSlice
'
;
import
locationSlice
from
'
./location/LocationSlice
'
;
import
pendingCacheSlice
from
'
./pendingNewCache/PendingCacheSlice
'
;
import
groupsSlice
from
'
./groups/GroupSlice
'
;
const
rootReducer
=
combineReducers
({
auth
:
authSlice
.
reducer
,
caches
:
cachesSlice
.
reducer
,
location
:
locationSlice
.
reducer
,
pendingCache
:
pendingCacheSlice
.
reducer
,
groups
:
groupsSlice
.
reducer
,
});
export
type
RootState
=
ReturnType
<
typeof
rootReducer
>
;
...
...
src/store/groups/GroupActions.ts
0 → 100644
View file @
b9c583d2
import
{
Dispatch
}
from
'
@reduxjs/toolkit
'
;
import
{
LatLng
}
from
'
react-native-maps
'
;
src/store/groups/GroupSelectors.ts
0 → 100644
View file @
b9c583d2
import
{
createSelector
}
from
'
@reduxjs/toolkit
'
;
import
{
State
}
from
'
react-native-gesture-handler
'
;
import
{
getDiscoveredCaches
}
from
'
../caches/CachesSelectors
'
;
import
{
RootState
}
from
'
../RootReducer
'
;
export
const
getGroups
=
(
state
:
RootState
)
=>
Object
.
values
(
state
.
groups
.
groups
);
export
const
getGroup
=
(
id
:
string
)
=>
createSelector
(
[
getGroups
],
(
groups
)
=>
groups
[
id
],
);
export
const
getGroupMemgers
=
(
id
:
string
)
=>
createSelector
(
[
getGroups
],
(
groups
)
=>
groups
[
id
].
memberList
,
);
export
const
getGroupCaches
=
(
id
:
string
)
=>
createSelector
(
[
getGroups
,
(
state
)
=>
state
.
caches
.
saved
,
],
(
groups
,
caches
)
=>
{
const
result
:
Cache
[]
=
[];
for
(
const
c
in
Object
.
values
(
groups
[
id
].
cacheIdList
))
{
result
.
push
(
caches
[
c
]);
}
return
result
;
},
);
src/store/groups/GroupSlice.ts
0 → 100644
View file @
b9c583d2
import
{
createSlice
}
from
'
@reduxjs/toolkit
'
;
import
{
sampleCaches
}
from
'
../../SampleCaches
'
;
import
{
CachesState
}
from
'
./CachesState
'
;
import
{
sampleGroups
}
from
'
../../SampleGroups
'
;
import
{
GroupState
}
from
'
./GroupState
'
;
const
groupsSlice
=
createSlice
({
name
:
'
groups
'
,
initialState
:
{
groups
:
{
[
sampleGroups
[
0
].
groupId
]:
sampleGroups
[
0
],
[
sampleGroups
[
1
].
groupId
]:
sampleGroups
[
1
],
},
}
as
GroupState
,
reducers
:
{
/*
addSaved(state, action) {
const cache = action.payload;
state.saved[cache.id] = cache;
},
removeSaved(state, action) {
delete state.saved[action.payload];
},
addDiscovered(state, action) {
const cache = action.payload;
state.discovered[cache.id] = cache;
},
removeDiscovered(state, action) {
delete state.discovered[action.payload];
},
*/
},
});
export
default
groupsSlice
;
src/store/groups/GroupState.ts
0 → 100644
View file @
b9c583d2
import
{
User
}
from
'
firebase
'
;
import
{
UserInterfaceIdiom
}
from
'
expo-constants
'
;
export
interface
GroupPermissions
{
admin
:
boolean
;
}
export
interface
Membership
{
userId
:
string
;
// correct type ??
permissions
:
GroupPermissions
;
}
export
interface
Group
{
groupId
:
string
;
groupName
:
string
;
memberList
:
Membership
[];
cacheIdList
:
string
[];
// just reference caches.. don't need to duplicate info
}
export
interface
GroupState
{
groups
:
{
[
id
:
string
]:
Group
;
};
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment