diff --git a/android/app/build.gradle b/android/app/build.gradle index 610b8fc..16481f0 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -79,8 +79,8 @@ android { applicationId "com.micahlindley.offsides" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 15 - versionName "0.4.5" + versionCode 17 + versionName "0.4.7" } signingConfigs { debug { diff --git a/android/app/release/app-release.apk b/android/app/release/app-release.apk index 45e4955..1d11bb7 100644 Binary files a/android/app/release/app-release.apk and b/android/app/release/app-release.apk differ diff --git a/android/app/release/output-metadata.json b/android/app/release/output-metadata.json index c38e5d0..9ff8419 100644 --- a/android/app/release/output-metadata.json +++ b/android/app/release/output-metadata.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "attributes": [], - "versionCode": 15, - "versionName": "0.4.5", + "versionCode": 17, + "versionName": "0.4.7", "outputFile": "app-release.apk" } ], diff --git a/docs/latest.json b/docs/latest.json index ad82719..197d84b 100644 --- a/docs/latest.json +++ b/docs/latest.json @@ -1,3 +1,3 @@ { - "latestVersion": "0.4.5" + "latestVersion": "0.4.7" } diff --git a/package-lock.json b/package-lock.json index 150aca0..367ec9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,14 @@ { "name": "offsides", - "version": "0.4.5", + "version": "0.4.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "offsides", - "version": "0.4.5", + "version": "0.4.7", "dependencies": { + "@devvie/bottom-sheet": "^0.3.0", "@pchmn/expo-material3-theme": "^1.3.2", "@react-native-async-storage/async-storage": "^1.22.3", "@react-navigation/native": "^6.1.14", @@ -29,7 +30,7 @@ "reanimated-color-picker": "^3.0.3", "rn-emoji-keyboard": "^1.6.1", "semver": "^7.6.0", - "sidechat.js": "^2.2.1", + "sidechat.js": "^2.2.3", "timesago": "^1.0.1" }, "devDependencies": { @@ -2449,6 +2450,15 @@ "node": ">=0.10.0" } }, + "node_modules/@devvie/bottom-sheet": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@devvie/bottom-sheet/-/bottom-sheet-0.3.0.tgz", + "integrity": "sha512-Cchl99PwSh+O/keyKHqXLfe+EqWwDIkMjPw50f4tlMrpaNE0PV7egQC5cTPZK6GRgj27mB4ZqsIZbeacwZkw+w==", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/@egjs/hammerjs": { "version": "2.0.17", "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", @@ -2572,9 +2582,9 @@ } }, "node_modules/@expo/cli": { - "version": "0.17.7", - "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.17.7.tgz", - "integrity": "sha512-sOssVCFCVXSdZr2/KdqPeT2Qwxmty3rZeO9g5RbzZexHz93VUyONuqGwO1VlYKibn7FLYEGUovqU9Xi8zVB6JQ==", + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.17.8.tgz", + "integrity": "sha512-yfkoghCltbGPDbRI71Qu3puInjXx4wO82+uhW82qbWLvosfIN7ep5Gr0Lq54liJpvlUG6M0IXM1GiGqcCyP12w==", "dependencies": { "@babel/runtime": "^7.20.0", "@expo/code-signing-certificates": "0.0.5", @@ -8510,12 +8520,12 @@ } }, "node_modules/expo": { - "version": "50.0.12", - "resolved": "https://registry.npmjs.org/expo/-/expo-50.0.12.tgz", - "integrity": "sha512-GqngGj+BRjapzZ+/Ve3kFCHDdiGFPZ3FsIkd034aYKVExjxI298vOeGkfQsh/CpSpSpBvnt10XMYdgDn+RwyVQ==", + "version": "50.0.13", + "resolved": "https://registry.npmjs.org/expo/-/expo-50.0.13.tgz", + "integrity": "sha512-p0FYrhUJZe92YOwOXx6GZ/WaxF6YtsLXtWkql9pFIIocYBN6iQ3OMGsbQCRSu0ao8rlxsk7HgQDEWK4D+y9tAg==", "dependencies": { "@babel/runtime": "^7.20.0", - "@expo/cli": "0.17.7", + "@expo/cli": "0.17.8", "@expo/config": "8.5.4", "@expo/config-plugins": "7.8.4", "@expo/metro-config": "0.17.6", @@ -8526,7 +8536,7 @@ "expo-font": "~11.10.3", "expo-keep-awake": "~12.8.2", "expo-modules-autolinking": "1.10.3", - "expo-modules-core": "1.11.11", + "expo-modules-core": "1.11.12", "fbemitter": "^3.0.0", "whatwg-url-without-unicode": "8.0.0-3" }, @@ -8686,9 +8696,9 @@ } }, "node_modules/expo-modules-core": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.11.11.tgz", - "integrity": "sha512-c4SmfHfLV/HthYLJT16NJhUZ1lVV8XP4UImIabdvKQQ8MGiFnFytVX+Jf8rm2uGBDbzz6zgEbNITeio14mdUhg==", + "version": "1.11.12", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.11.12.tgz", + "integrity": "sha512-/e8g4kis0pFLer7C0PLyx98AfmztIM6gU9jLkYnB1pU9JAfQf904XEi3bmszO7uoteBQwSL6FLp1m3TePKhDaA==", "dependencies": { "invariant": "^2.2.4" } @@ -13380,9 +13390,9 @@ } }, "node_modules/postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "version": "8.4.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.36.tgz", + "integrity": "sha512-/n7eumA6ZjFHAsbX30yhHup/IMkOmlmvtEi7P+6RMYf+bGJSUHc3geH4a0NSZxAz/RJfiS9tooCTs9LAVYUZKw==", "funding": [ { "type": "opencollective", @@ -13400,7 +13410,7 @@ "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.1.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -14658,9 +14668,9 @@ } }, "node_modules/sidechat.js": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/sidechat.js/-/sidechat.js-2.2.1.tgz", - "integrity": "sha512-XoMR5VYaCmCCcoXfj4bg3UsntePmKL/I+gMTBzeamTtNdeIzfOXuWTTRrn0kEbUlyqbfZEBzTSvAZQx9A6tK0A==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/sidechat.js/-/sidechat.js-2.2.3.tgz", + "integrity": "sha512-9Q1NncBvhLbyiHHvd2fgcoiBiS5OIIY8b7tkcASKcpc49a15iW9mUBL4PmMeb4jXAdSCZm1cQxDmi7Sj6a6aRw==", "engines": { "node": ">=18.0.0" } @@ -14788,9 +14798,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.1.0.tgz", + "integrity": "sha512-9vC2SfsJzlej6MAaMPLu8HiBSHGdRAJ9hVFYN1ibZoNkeanmDmLUcIrj6G9DGL7XMJ54AKg/G75akXl1/izTOw==", "engines": { "node": ">=0.10.0" } diff --git a/package.json b/package.json index 681395c..1f52861 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "offsides", - "version": "0.4.5", + "version": "0.4.7", "private": true, "scripts": { "android": "react-native run-android", @@ -10,6 +10,7 @@ "test": "jest" }, "dependencies": { + "@devvie/bottom-sheet": "^0.3.0", "@pchmn/expo-material3-theme": "^1.3.2", "@react-native-async-storage/async-storage": "^1.22.3", "@react-navigation/native": "^6.1.14", @@ -31,7 +32,7 @@ "reanimated-color-picker": "^3.0.3", "rn-emoji-keyboard": "^1.6.1", "semver": "^7.6.0", - "sidechat.js": "^2.2.1", + "sidechat.js": "^2.2.3", "timesago": "^1.0.1" }, "devDependencies": { diff --git a/src/App.jsx b/src/App.jsx index 71df837..626eee6 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,7 +1,7 @@ import 'react-native-gesture-handler'; import React, { Context } from 'react'; import { OffsidesAppState } from './types/OffsidesTypes'; -import { StatusBar, useColorScheme } from 'react-native'; +import { InteractionManager, StatusBar, useColorScheme } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import AsyncStorage from '@react-native-async-storage/async-storage'; @@ -35,6 +35,11 @@ export default function App() { 'groupID', 'groupName', 'groupImage', + 'groupColor', + 'schoolGroupID', + 'schoolGroupName', + 'schoolGroupImage', + 'schoolGroupColor', ]).then(res => { let tempState = {}; // If user token is defined @@ -51,6 +56,22 @@ export default function App() { setAppState(tempState); }); }, []); + React.useEffect(() => { + InteractionManager.runAfterInteractions(() => { + if (!appState.groupName || !appState.groupID) return; + AsyncStorage.multiSet([ + ['groupID', String(appState.groupID)], + ['groupName', String(appState.groupName)], + ['groupColor', String(appState.groupColor)], + ['groupImage', String(appState.groupImage)], + ]); + }); + }, [ + appState.groupName, + appState.groupID, + appState.groupColor, + appState.groupImage, + ]); return ( diff --git a/src/components/Group.jsx b/src/components/Group.jsx index a881e76..4a677ba 100644 --- a/src/components/Group.jsx +++ b/src/components/Group.jsx @@ -1,18 +1,29 @@ import React from 'react'; import { View, Image } from 'react-native'; -import { Card, Text, Avatar, Icon, TouchableRipple } from 'react-native-paper'; +import { + Card, + Text, + Avatar, + Icon, + TouchableRipple, + IconButton, + useTheme, +} from 'react-native-paper'; function Group({ group, cardMode = 'contained', - onPress, + onPress = () => {}, exploreMode = false, + removeMode = false, + onRemove = () => {}, }) { + const { colors } = useTheme(); return ( + style={{ borderRadius: 10 }}> @@ -46,23 +57,42 @@ function Group({ {group.name} - {group.membership_type == 'member' && ( - - )} - - {group.group_visibility == 'public_to_all' && ( - - )} - {group.group_visibility == 'private' && ( - - )} - {group.group_visibility == 'public_to_schools' && ( - + {removeMode ? ( + onRemove(group.id)} + iconColor={colors.error} + /> + ) : ( + <> + {group.membership_type == 'member' && ( + + )} + + {group.group_visibility == 'public_to_all' && ( + + )} + {group.group_visibility == 'private' && ( + + )} + {group.group_visibility == 'public_to_schools' && ( + + )} + )} {exploreMode && ( {group.description} + {group.member_count && ( + + {group.description && ` | `} + {group.member_count.toLocaleString()} members + + )} )} diff --git a/src/components/GroupAvatar.jsx b/src/components/GroupAvatar.jsx new file mode 100644 index 0000000..fb08e36 --- /dev/null +++ b/src/components/GroupAvatar.jsx @@ -0,0 +1,62 @@ +import React from 'react'; +import { Image } from 'react-native'; +import { TouchableRipple, Avatar, useTheme } from 'react-native-paper'; + +function GroupAvatar({ + groupName, + groupImage, + groupColor, + onPress = () => {}, + onLongPress = () => {}, + borderRadius = 12, + style = {}, +}) { + const { colors } = useTheme(); + const ComponentOption = React.useCallback(() => { + if (groupName == 'Home') { + return ( + + ); + } else if (groupImage) { + return ( + + ); + } else { + return ( + + ); + } + }, [groupName]); + return ( + + + + ); +} + +export default GroupAvatar; diff --git a/src/components/GroupPicker.jsx b/src/components/GroupPicker.jsx index f8a74ff..43d53e1 100644 --- a/src/components/GroupPicker.jsx +++ b/src/components/GroupPicker.jsx @@ -1,28 +1,29 @@ import * as React from 'react'; -import { ScrollView } from 'react-native'; +import { ScrollView, View } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import { - Dialog, - Portal, + ActivityIndicator, Button, - ProgressBar, + Card, + IconButton, + Text, useTheme, } from 'react-native-paper'; import { AppContext } from '../App'; import Group from './Group'; -function GroupPicker({ visible, hide }) { +function GroupPicker({ sheetRef }) { const nav = useNavigation(); const { colors } = useTheme(); const { appState, setAppState } = React.useContext(AppContext); const API = appState.API; const [groups, setGroups] = React.useState(false); - const [loading, setLoading] = React.useState(true); + const [removeMode, setRemoveMode] = React.useState(false); React.useEffect(() => { - if (API && visible) { + if (API) { loadGroups(); } - }, [visible, API]); + }, [API]); const loadGroups = async () => { const user = await API.getCurrentUser(); Promise.all( @@ -35,7 +36,6 @@ function GroupPicker({ visible, hide }) { else return false; }); setGroups(data); - setLoading(false); }); }; const selectGroup = group => { @@ -44,53 +44,79 @@ function GroupPicker({ visible, hide }) { groupID: group.id, groupName: group.name, groupImage: group?.icon_url || '', + groupColor: group.color, }); - hide(); + sheetRef?.current?.close(); + setRemoveMode(false); }; const explore = () => { nav.navigate('ExploreGroups'); - hide(); + sheetRef?.current?.close(); + setRemoveMode(false); }; return ( - - - Switch groups - - - {groups && ( - - {groups.map(group => ( - selectGroup(group)} - /> - ))} - - )} - - - - - - - + + {groups ? ( + + + + Your groups + + setRemoveMode(!removeMode)} + /> + + + + + + + In future releases of Offsides, this modal will only appear when + you long press the group's icon. + + + + {groups.map(group => ( + selectGroup(group)} + removeMode={removeMode} + onRemove={() => alert('This feature is coming soon!')} + /> + ))} + + ) : ( + + )} + ); } diff --git a/src/components/Post.jsx b/src/components/Post.jsx index 3c4a659..fe4ecda 100644 --- a/src/components/Post.jsx +++ b/src/components/Post.jsx @@ -4,6 +4,7 @@ import { Avatar, Card, IconButton, Text, useTheme } from 'react-native-paper'; import timesago from 'timesago'; import { AppContext } from '../App'; import AutoImage from './AutoImage'; +import GroupAvatar from './GroupAvatar'; const BORDER_RADIUS = 12; @@ -54,10 +55,10 @@ function Post({ post, nav, commentView = false }) { }} /> ) : ( - )} diff --git a/src/screens/ExploreGroupsScreen.jsx b/src/screens/ExploreGroupsScreen.jsx index f3028b6..78ecfd8 100644 --- a/src/screens/ExploreGroupsScreen.jsx +++ b/src/screens/ExploreGroupsScreen.jsx @@ -1,9 +1,14 @@ import React from 'react'; import { View, StatusBar, FlatList } from 'react-native'; -import { Appbar, useTheme, Card, ProgressBar } from 'react-native-paper'; +import { + Appbar, + useTheme, + Card, + ProgressBar, + Searchbar, +} from 'react-native-paper'; import { AppContext } from '../App'; import Group from '../components/Group'; -import useUniqueList from '../hooks/useUniqueList'; const BORDER_RADIUS = 15; @@ -12,6 +17,7 @@ function ExploreGroupsScreen({ navigation }) { const API = appState.API; const [groups, setGroups] = React.useState(false); const [loading, setLoading] = React.useState(true); + const [searchQuery, setSearchQuery] = React.useState(''); const { colors } = useTheme(); React.useEffect(() => { loadGroups(); @@ -39,11 +45,38 @@ function ExploreGroupsScreen({ navigation }) { ...appState, groupID: group.id, groupName: group.name, - groupImage: group?.icon_url || '', + groupImage: group.icon_url || '', + groupColor: group.color, }); navigation.navigate('Home'); }; + const groupsSearched = React.useMemo(() => { + if (groups) { + return groups.filter(item => { + if ( + item.name.toLowerCase().includes(searchQuery.toLowerCase()) || + searchQuery.toLowerCase().includes(item.name.toLowerCase()) || + searchQuery.toLowerCase() == item.name.toLowerCase() + ) { + return true; + } else if (item.description) { + if ( + item.description.toLowerCase().includes(searchQuery.toLowerCase()) + ) { + return true; + } else { + return false; + } + } else { + return false; + } + }); + } else { + return []; + } + }, [groups, searchQuery]); + return ( @@ -53,15 +86,31 @@ function ExploreGroupsScreen({ navigation }) { {groups && ( - g.id} - renderItem={renderGroup} - /> + + + g.id} + renderItem={renderGroup} + /> + )} ); diff --git a/src/screens/HomeScreen.jsx b/src/screens/HomeScreen.jsx index 0d930f5..4fead61 100644 --- a/src/screens/HomeScreen.jsx +++ b/src/screens/HomeScreen.jsx @@ -10,6 +10,7 @@ import { Image, StatusBar, InteractionManager, + useColorScheme, } from 'react-native'; import { Appbar, @@ -20,16 +21,22 @@ import { ProgressBar, TouchableRipple, FAB, + ThemeProvider, } from 'react-native-paper'; import { AppContext } from '../App'; import { useFocusEffect } from '@react-navigation/native'; import Post from '../components/Post'; import GroupPicker from '../components/GroupPicker'; import useUniqueList from '../hooks/useUniqueList'; +import GroupAvatar from '../components/GroupAvatar'; +import { createMaterial3Theme } from '@pchmn/expo-material3-theme'; +import BottomSheet, { BottomSheetMethods } from '@devvie/bottom-sheet'; const BORDER_RADIUS = 12; function HomeScreen({ navigation }) { + const sheetRef = React.useRef(null); + const [customTheme, setCustomTheme] = React.useState(false); const { appState } = React.useContext(AppContext); const API = appState.API; const [postCategory, setPostCategory] = React.useState('hot'); @@ -37,15 +44,16 @@ function HomeScreen({ navigation }) { const [cursor, setCursor] = React.useState( /** @type {SidechatCursorString} */ (null), ); - const { colors } = useTheme(); + const theme = useTheme(); + const colorScheme = useColorScheme(); + const colors = theme.colors; const [filterOpen, setFilterOpen] = React.useState(false); const [loadingPosts, setLoadingPosts] = React.useState(false); - const [renderedPostIds, setRenderedPostIds] = React.useState(new Set()); const [currentGroupId, setCurrentGroupId] = React.useState(appState.groupID); + const [sheetIsOpen, setSheetIsOpen] = React.useState(false); const [posts, setPosts] = React.useState( /** @type {SidechatPostOrComment[]} */ ([]), ); - const [groupPickerShown, setGroupPickerShown] = React.useState(false); useFocusEffect(() => { if (appState.groupID != currentGroupId) { setCurrentGroupId(appState.groupID); @@ -54,6 +62,10 @@ function HomeScreen({ navigation }) { React.useEffect(() => { if (!loadingPosts) { InteractionManager.runAfterInteractions(() => { + if (appState.groupColor) { + const t = createMaterial3Theme(appState.groupColor); + setCustomTheme(colorScheme == 'dark' ? t.dark : t.light); + } if (appState.groupID && appState.userToken) { setCurrentGroupId(currentGroupId); setLoadingPosts(true); @@ -66,7 +78,6 @@ function HomeScreen({ navigation }) { }, [postCategory, currentGroupId]); const uniquePosts = useUniqueList(posts); const renderItem = React.useCallback(each => { - // Check if the post has already been rendered return ; }); const fetchPosts = refresh => { @@ -92,46 +103,28 @@ function HomeScreen({ navigation }) { } }; return ( - <> - - setGroupPickerShown(false)} + + {appState.groupName && ( - setGroupPickerShown(true)} - style={{ borderRadius: BORDER_RADIUS, marginRight: 15 }} - borderless={true}> - {appState.groupImage ? ( - - ) : ( - - )} - + sheetRef.current?.open()} + onLongPress={() => sheetRef.current?.open()} + borderRadius={BORDER_RADIUS} + style={{ marginRight: 15 }} + /> {appState.groupName.length > 2 ? ( { setPostCategory('hot'); @@ -201,7 +198,13 @@ function HomeScreen({ navigation }) { onPress={() => navigation.push('MyProfile')}> )} - + - + setSheetIsOpen(false)} + onOpen={() => setSheetIsOpen(true)}> + {sheetIsOpen && } + + ); } diff --git a/src/screens/LoginScreen.jsx b/src/screens/LoginScreen.jsx index 139ae28..f2b5c89 100644 --- a/src/screens/LoginScreen.jsx +++ b/src/screens/LoginScreen.jsx @@ -76,6 +76,22 @@ function LoginScreen({}) { 'groupImage', res.logged_in_user.group.icon_url || '', ); + await AsyncStorage.setItem( + 'schoolGroupID', + res.logged_in_user.group.id, + ); + await AsyncStorage.setItem( + 'schoolGroupName', + res.logged_in_user.group.name, + ); + await AsyncStorage.setItem( + 'schoolGroupColor', + res.logged_in_user.group.color, + ); + await AsyncStorage.setItem( + 'schoolGroupImage', + res.logged_in_user.group.icon_url || '', + ); RNRestart.restart(); } else { if (res.registration_id) { @@ -155,12 +171,19 @@ function LoginScreen({}) { await AsyncStorage.setItem('userID', res.user.id); if (res.group) { await AsyncStorage.setItem('groupID', res.group.id); + await AsyncStorage.setItem('schoolGroupID', res.group.id); await AsyncStorage.setItem('groupName', res.group.name); + await AsyncStorage.setItem('schoolGroupName', res.group.name); await AsyncStorage.setItem('groupColor', res.group.color); + await AsyncStorage.setItem('schoolGroupColor', res.group.color); await AsyncStorage.setItem( 'groupImage', res.group.icon_url || '', ); + await AsyncStorage.setItem( + 'schoolGroupImage', + res.group.icon_url || '', + ); RNRestart.restart(); } else { throw new Error('Try clicking the link in your email again.'); diff --git a/src/types/OffsidesTypes.js b/src/types/OffsidesTypes.js index 52c2d4c..e41df49 100644 --- a/src/types/OffsidesTypes.js +++ b/src/types/OffsidesTypes.js @@ -9,6 +9,12 @@ import { SidechatAPIClient } from 'sidechat.js'; * @prop {String} userID - the logged-in user's alphanumeric ID * @prop {String} groupID - the currently selected group ID * @prop {String} groupName - the currently selected group name + * @prop {String} groupImage - the currently selected group image URL + * @prop {String} groupColor - the currently selected group theme color + * @prop {String} schoolGroupID - the user's school group ID + * @prop {String} schoolGroupName - the user's school group name + * @prop {String} schoolGroupImage - the user's school group image URL + * @prop {String} schoolGroupColor - the user's school group theme color */ export default {}; diff --git a/src/utils/organizeGroups.js b/src/utils/organizeGroups.js new file mode 100644 index 0000000..e69de29 diff --git a/yarn.lock b/yarn.lock index b96548a..6640be7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1224,6 +1224,11 @@ deepmerge "^3.2.0" hoist-non-react-statics "^3.3.0" +"@devvie/bottom-sheet@^0.3.0": + version "0.3.0" + resolved "https://registry.npmjs.org/@devvie/bottom-sheet/-/bottom-sheet-0.3.0.tgz" + integrity sha512-Cchl99PwSh+O/keyKHqXLfe+EqWwDIkMjPw50f4tlMrpaNE0PV7egQC5cTPZK6GRgj27mB4ZqsIZbeacwZkw+w== + "@egjs/hammerjs@^2.0.17": version "2.0.17" resolved "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz" @@ -1273,10 +1278,10 @@ mv "~2" safe-json-stringify "~1" -"@expo/cli@0.17.7": - version "0.17.7" - resolved "https://registry.npmjs.org/@expo/cli/-/cli-0.17.7.tgz" - integrity sha512-sOssVCFCVXSdZr2/KdqPeT2Qwxmty3rZeO9g5RbzZexHz93VUyONuqGwO1VlYKibn7FLYEGUovqU9Xi8zVB6JQ== +"@expo/cli@0.17.8": + version "0.17.8" + resolved "https://registry.npmjs.org/@expo/cli/-/cli-0.17.8.tgz" + integrity sha512-yfkoghCltbGPDbRI71Qu3puInjXx4wO82+uhW82qbWLvosfIN7ep5Gr0Lq54liJpvlUG6M0IXM1GiGqcCyP12w== dependencies: "@babel/runtime" "^7.20.0" "@expo/code-signing-certificates" "0.0.5" @@ -4479,20 +4484,20 @@ expo-modules-autolinking@>=0.8.1, expo-modules-autolinking@1.10.3: find-up "^5.0.0" fs-extra "^9.1.0" -expo-modules-core@^1.11.9, expo-modules-core@1.11.11: - version "1.11.11" - resolved "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.11.11.tgz" - integrity sha512-c4SmfHfLV/HthYLJT16NJhUZ1lVV8XP4UImIabdvKQQ8MGiFnFytVX+Jf8rm2uGBDbzz6zgEbNITeio14mdUhg== +expo-modules-core@^1.11.9, expo-modules-core@1.11.12: + version "1.11.12" + resolved "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.11.12.tgz" + integrity sha512-/e8g4kis0pFLer7C0PLyx98AfmztIM6gU9jLkYnB1pU9JAfQf904XEi3bmszO7uoteBQwSL6FLp1m3TePKhDaA== dependencies: invariant "^2.2.4" expo@*, expo@^50.0.8, expo@>=44.0.0: - version "50.0.12" - resolved "https://registry.npmjs.org/expo/-/expo-50.0.12.tgz" - integrity sha512-GqngGj+BRjapzZ+/Ve3kFCHDdiGFPZ3FsIkd034aYKVExjxI298vOeGkfQsh/CpSpSpBvnt10XMYdgDn+RwyVQ== + version "50.0.13" + resolved "https://registry.npmjs.org/expo/-/expo-50.0.13.tgz" + integrity sha512-p0FYrhUJZe92YOwOXx6GZ/WaxF6YtsLXtWkql9pFIIocYBN6iQ3OMGsbQCRSu0ao8rlxsk7HgQDEWK4D+y9tAg== dependencies: "@babel/runtime" "^7.20.0" - "@expo/cli" "0.17.7" + "@expo/cli" "0.17.8" "@expo/config" "8.5.4" "@expo/config-plugins" "7.8.4" "@expo/metro-config" "0.17.6" @@ -4503,7 +4508,7 @@ expo@*, expo@^50.0.8, expo@>=44.0.0: expo-font "~11.10.3" expo-keep-awake "~12.8.2" expo-modules-autolinking "1.10.3" - expo-modules-core "1.11.11" + expo-modules-core "1.11.12" fbemitter "^3.0.0" whatwg-url-without-unicode "8.0.0-3" @@ -7275,13 +7280,13 @@ possible-typed-array-names@^1.0.0: integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== postcss@~8.4.32: - version "8.4.35" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz" - integrity sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA== + version "8.4.36" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.36.tgz" + integrity sha512-/n7eumA6ZjFHAsbX30yhHup/IMkOmlmvtEi7P+6RMYf+bGJSUHc3geH4a0NSZxAz/RJfiS9tooCTs9LAVYUZKw== dependencies: nanoid "^3.3.7" picocolors "^1.0.0" - source-map-js "^1.0.2" + source-map-js "^1.1.0" prelude-ls@^1.2.1: version "1.2.1" @@ -8113,10 +8118,10 @@ side-channel@^1.0.4: get-intrinsic "^1.2.4" object-inspect "^1.13.1" -sidechat.js@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/sidechat.js/-/sidechat.js-2.2.1.tgz" - integrity sha512-XoMR5VYaCmCCcoXfj4bg3UsntePmKL/I+gMTBzeamTtNdeIzfOXuWTTRrn0kEbUlyqbfZEBzTSvAZQx9A6tK0A== +sidechat.js@^2.2.3: + version "2.2.3" + resolved "https://registry.npmjs.org/sidechat.js/-/sidechat.js-2.2.3.tgz" + integrity sha512-9Q1NncBvhLbyiHHvd2fgcoiBiS5OIIY8b7tkcASKcpc49a15iW9mUBL4PmMeb4jXAdSCZm1cQxDmi7Sj6a6aRw== signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" @@ -8163,10 +8168,10 @@ slugify@^1.3.4, slugify@^1.6.6: resolved "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz" integrity sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw== -source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +source-map-js@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.1.0.tgz" + integrity sha512-9vC2SfsJzlej6MAaMPLu8HiBSHGdRAJ9hVFYN1ibZoNkeanmDmLUcIrj6G9DGL7XMJ54AKg/G75akXl1/izTOw== source-map-support@^0.5.16, source-map-support@~0.5.20, source-map-support@~0.5.21: version "0.5.21"