From e2b24e820476375f0ae4c871a3748d8082ef4c21 Mon Sep 17 00:00:00 2001 From: Alex Risch Date: Tue, 28 May 2024 12:05:19 -0600 Subject: [PATCH] feat: Group Consent Work Added consent work for groups Updated AppConfig Cleaned up some push handling for now --- src/consts/AppConfig.ts | 2 +- src/hooks/useGroupConsent.ts | 60 ++++++++++++++++++++++++++ src/screens/ConversationListScreen.tsx | 37 +++++++++++++--- src/screens/GroupScreen.tsx | 54 +++-------------------- src/services/mmkvStorage.ts | 25 +++++++++++ src/services/pushNotifications.ts | 7 +-- src/utils/getAllListMessages.ts | 7 +++ 7 files changed, 132 insertions(+), 60 deletions(-) create mode 100644 src/hooks/useGroupConsent.ts diff --git a/src/consts/AppConfig.ts b/src/consts/AppConfig.ts index 27397ea..f4111fe 100644 --- a/src/consts/AppConfig.ts +++ b/src/consts/AppConfig.ts @@ -6,5 +6,5 @@ export const AppConfig = { XMTP_ENV: 'dev' as 'local' | 'dev' | 'production', MULTI_WALLET: false, PUSH_NOTIFICATIONS: Platform.OS === 'ios', - GROUP_CONSENT: false, + GROUP_CONSENT: Platform.OS === 'android', }; diff --git a/src/hooks/useGroupConsent.ts b/src/hooks/useGroupConsent.ts new file mode 100644 index 0000000..cc4d542 --- /dev/null +++ b/src/hooks/useGroupConsent.ts @@ -0,0 +1,60 @@ +import {useCallback, useEffect, useState} from 'react'; +import {AppConfig} from '../consts/AppConfig'; +import {mmkvStorage} from '../services/mmkvStorage'; +import {useClient} from './useClient'; +import {useGroup} from './useGroup'; + +type ConsentState = 'allowed' | 'denied' | 'unknown'; + +const getInitialConsent = (groupId?: string): ConsentState => { + if (!AppConfig.GROUP_CONSENT || !groupId) { + return 'allowed'; + } + return (mmkvStorage.getGroupConsent(groupId) as ConsentState) ?? 'unknown'; +}; + +export const useGroupConsent = (topic: string) => { + const {data: group} = useGroup(topic); + const {client} = useClient(); + const [consent, setConsent] = useState( + getInitialConsent(group?.id), + ); + + useEffect(() => { + if (!group) { + return; + } + if (!AppConfig.GROUP_CONSENT) { + setConsent('allowed'); + return; + } + group.consentState().then(currentConsent => { + setConsent(currentConsent); + mmkvStorage.saveGroupConsent(group.id, currentConsent); + }); + }, [group, topic]); + + const allow = useCallback(async () => { + if (!group?.id) { + return; + } + await client?.contacts.allowGroups([group.id]); + setConsent('allowed'); + mmkvStorage.saveGroupConsent(group.id, 'allowed'); + }, [client?.contacts, group?.id]); + + const deny = useCallback(async () => { + if (!group?.id) { + return; + } + await client?.contacts.denyGroups([group.id]); + setConsent('denied'); + mmkvStorage.saveGroupConsent(group.id, 'denied'); + }, [client?.contacts, group?.id]); + + return { + consent, + allow, + deny, + }; +}; diff --git a/src/screens/ConversationListScreen.tsx b/src/screens/ConversationListScreen.tsx index 7c609e8..fc2de07 100644 --- a/src/screens/ConversationListScreen.tsx +++ b/src/screens/ConversationListScreen.tsx @@ -10,6 +10,7 @@ import {Drawer} from '../components/common/Drawer'; import {Icon} from '../components/common/Icon'; import {Screen} from '../components/common/Screen'; import {Text} from '../components/common/Text'; +import {AppConfig} from '../consts/AppConfig'; import {SupportedContentTypes} from '../consts/ContentTypes'; import {TestIds} from '../consts/TestIds'; import {useClient} from '../hooks/useClient'; @@ -17,6 +18,7 @@ import {useTypedNavigation} from '../hooks/useTypedNavigation'; import {translate} from '../i18n'; import {ScreenNames} from '../navigation/ScreenNames'; import {useListQuery} from '../queries/useListQuery'; +import {mmkvStorage} from '../services/mmkvStorage'; import {colors} from '../theme/colors'; const EmptyBackground = require('../../assets/images/Bg_asset.svg').default; @@ -28,20 +30,35 @@ const useData = () => { const {data, isLoading, refetch, isRefetching, isError, error} = useListQuery(); - const {listItems, requests} = useMemo(() => { + const {listItems, requests, requestsCount} = useMemo(() => { const listMessages: Group[] = []; const requestsItems: Group[] = []; + let requestCount = 0; data?.forEach(item => { - // TODO: add a check for isRequest - listMessages.push(item); + if ( + !AppConfig.GROUP_CONSENT || + mmkvStorage.getGroupConsent(item.id) === 'allowed' + ) { + listMessages.push(item); + } else { + requestsItems.push(item); + if ((mmkvStorage.getGroupConsent(item.id) ?? 'unknown') === 'unknown') { + requestCount++; + } + } }); - return {listItems: listMessages, requests: requestsItems}; + return { + listItems: listMessages, + requests: requestsItems, + requestsCount: requestCount, + }; }, [data]); console.log('Connected as address:', client?.address); return { messageRequests: requests, + messageRequestsCount: requestsCount, messages: listItems, isLoading, refetch, @@ -58,8 +75,14 @@ export const ConversationListScreen = () => { const [showPickerModal, setShowPickerModal] = useState(false); const [showConsentDrawer, setShowConsentDrawer] = useState(false); const focused = useIsFocused(); - const {messages, messageRequests, isLoading, refetch, isRefetching} = - useData(); + const { + messages, + messageRequests, + messageRequestsCount, + isLoading, + refetch, + isRefetching, + } = useData(); const {navigate} = useTypedNavigation(); const showPicker = () => { @@ -98,7 +121,7 @@ export const ConversationListScreen = () => { setList('MESSAGE_REQUESTS')} /> } diff --git a/src/screens/GroupScreen.tsx b/src/screens/GroupScreen.tsx index b211cda..4f81585 100644 --- a/src/screens/GroupScreen.tsx +++ b/src/screens/GroupScreen.tsx @@ -1,7 +1,7 @@ import {useFocusEffect, useRoute} from '@react-navigation/native'; import {RemoteAttachmentContent} from '@xmtp/react-native-sdk'; import {Box, FlatList, HStack, VStack} from 'native-base'; -import React, {useCallback, useEffect, useMemo, useState} from 'react'; +import React, {useCallback, useMemo, useState} from 'react'; import {KeyboardAvoidingView, ListRenderItem, Platform} from 'react-native'; import {Asset} from 'react-native-image-picker'; import {ConversationInput} from '../components/ConversationInput'; @@ -16,10 +16,10 @@ import {GroupInfoModal} from '../components/modals/GroupInfoModal'; import {GroupContext, GroupContextValue} from '../context/GroupContext'; import {useClient} from '../hooks/useClient'; import {useGroup} from '../hooks/useGroup'; +import {useGroupConsent} from '../hooks/useGroupConsent'; import {useGroupMessages} from '../hooks/useGroupMessages'; import {translate} from '../i18n'; import {useGroupParticipantsQuery} from '../queries/useGroupParticipantsQuery'; -import {mmkvStorage} from '../services/mmkvStorage'; import {AWSHelper} from '../services/s3'; import {colors} from '../theme/colors'; @@ -43,21 +43,6 @@ const useData = (topic: string) => { }; }; -const getInitialConsentState = ( - addresses: string, - groupId: string, -): 'allowed' | 'denied' | 'unknown' => { - const cachedConsent = mmkvStorage.getConsent(addresses, groupId); - // if (cachedConsent === undefined) { - // return 'unknown'; - // } - // if (cachedConsent) { - // return 'allowed'; - // } - // return 'denied'; - return cachedConsent ? 'allowed' : 'allowed'; -}; - export const GroupScreen = () => { const {params} = useRoute(); const {topic} = params as {topic: string}; @@ -65,25 +50,12 @@ export const GroupScreen = () => { useData(topic); const [showGroupModal, setShowGroupModal] = useState(false); const [showAddModal, setShowAddModal] = useState(false); - const [consent, setConsent] = useState<'allowed' | 'denied' | 'unknown'>( - getInitialConsentState(myAddress ?? '', group?.topic ?? ''), - ); const [replyId, setReplyId] = useState(null); const [reactId, setReactId] = useState(null); + const {consent, allow, deny} = useGroupConsent(topic); const {ids, entities, reactionsEntities} = messages ?? {}; - useEffect(() => { - if (!group) { - return; - } - // TODO: Update with consent - setConsent('allowed'); - // group..then(currentConsent => { - // setConsent(currentConsent); - // }); - }, [group]); - useFocusEffect( useCallback(() => { refetch(); @@ -136,22 +108,6 @@ export const GroupScreen = () => { return ; }; - const onConsent = useCallback(() => { - if (addresses) { - client?.contacts.allow(addresses); - } - setConsent('allowed'); - mmkvStorage.saveConsent(myAddress ?? '', topic ?? '', true); - }, [addresses, client?.contacts, myAddress, topic]); - - const onBlock = useCallback(() => { - if (addresses) { - client?.contacts.deny(addresses); - } - setConsent('denied'); - mmkvStorage.saveConsent(myAddress ?? '', topic ?? '', false); - }, [addresses, client?.contacts, topic, myAddress]); - const setReply = useCallback( (id: string) => { setReplyId(id); @@ -211,14 +167,14 @@ export const GroupScreen = () => { /> ) : ( - -