diff --git a/src/components/dms/MessagesNUX.tsx b/src/components/dms/MessagesNUX.tsx new file mode 100644 index 00000000..81d1cfff --- /dev/null +++ b/src/components/dms/MessagesNUX.tsx @@ -0,0 +1,172 @@ +import React, {useCallback, useEffect} from 'react' +import {View} from 'react-native' +import {ChatBskyActorDeclaration} from '@atproto/api' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {useUpdateActorDeclaration} from '#/state/queries/messages/actor-declaration' +import {useProfileQuery} from '#/state/queries/profile' +import {useSession} from '#/state/session' +import * as Toast from '#/view/com/util/Toast' +import {atoms as a, useTheme, web} from '#/alf' +import {Button, ButtonText} from '#/components/Button' +import * as Dialog from '#/components/Dialog' +import * as Toggle from '#/components/forms/Toggle' +import {Message_Stroke2_Corner0_Rounded} from '#/components/icons/Message' +import {Text} from '#/components/Typography' + +export function MessagesNUX() { + const control = Dialog.useDialogControl() + + const {currentAccount} = useSession() + const {data: profile} = useProfileQuery({ + did: currentAccount!.did, + }) + + useEffect(() => { + if (profile && typeof profile.associated?.chat === 'undefined') { + const timeout = setTimeout(() => { + control.open() + }, 1000) + + return () => { + clearTimeout(timeout) + } + } + }, [profile, control]) + + if (!profile) return null + + return ( + + + + + ) +} + +function DialogInner({ + chatDeclation, +}: { + chatDeclation?: ChatBskyActorDeclaration.Record +}) { + const control = Dialog.useDialogContext() + const {_} = useLingui() + const t = useTheme() + const {mutate: updateDeclaration} = useUpdateActorDeclaration({ + onError: () => { + Toast.show(_(msg`Failed to update settings`)) + }, + }) + + const onSelectItem = useCallback( + (keys: string[]) => { + const key = keys[0] + if (!key) return + updateDeclaration(key as 'all' | 'none' | 'following') + }, + [updateDeclaration], + ) + + useEffect(() => { + if (!chatDeclation) { + updateDeclaration('following') + } + }, [chatDeclation, updateDeclaration]) + + return ( + + + + + + Direct messages are here! + + + Privately chat with other users. + + + + + + Who can message you? + + + You can change this at any time. + + + + + + + + Everyone + + + + + + Users I follow + + + + + + No one + + + + + + + + + + + + ) +} diff --git a/src/screens/Messages/List/index.tsx b/src/screens/Messages/List/index.tsx index 060dac63..e36d1edf 100644 --- a/src/screens/Messages/List/index.tsx +++ b/src/screens/Messages/List/index.tsx @@ -17,6 +17,7 @@ import {CenteredView} from '#/view/com/util/Views' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {DialogControlProps, useDialogControl} from '#/components/Dialog' +import {MessagesNUX} from '#/components/dms/MessagesNUX' import {NewChat} from '#/components/dms/NewChat' import {useRefreshOnFocus} from '#/components/hooks/useRefreshOnFocus' import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' @@ -131,6 +132,7 @@ export function MessagesScreen({navigation, route}: Props) { if (conversations.length < 1) { return ( + {gtMobile ? ( + {!gtMobile && ( + }) const {preferences, setPref} = useBackgroundNotificationPreferences() const {mutate: updateDeclaration} = useUpdateActorDeclaration({ diff --git a/src/state/queries/messages/actor-declaration.ts b/src/state/queries/messages/actor-declaration.ts index c8cc4acb..0886af38 100644 --- a/src/state/queries/messages/actor-declaration.ts +++ b/src/state/queries/messages/actor-declaration.ts @@ -21,9 +21,9 @@ export function useUpdateActorDeclaration({ if (!currentAccount) throw new Error('Not logged in') // TODO(sam): remove validate: false once PDSes have the new lexicon const result = await getAgent().api.com.atproto.repo.putRecord({ + repo: currentAccount.did, collection: 'chat.bsky.actor.declaration', rkey: 'self', - repo: currentAccount.did, validate: false, record: { $type: 'chat.bsky.actor.declaration', @@ -62,3 +62,23 @@ export function useUpdateActorDeclaration({ }, }) } + +// for use in the settings screen for testing +export function useDeleteActorDeclaration() { + const {currentAccount} = useSession() + const {getAgent} = useAgent() + + return useMutation({ + mutationFn: async () => { + if (!currentAccount) throw new Error('Not logged in') + // TODO(sam): remove validate: false once PDSes have the new lexicon + const result = await getAgent().api.com.atproto.repo.deleteRecord({ + repo: currentAccount.did, + collection: 'chat.bsky.actor.declaration', + rkey: 'self', + validate: false, + }) + return result + }, + }) +} diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index c3864e5a..b3b937c6 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -26,6 +26,7 @@ import { useInAppBrowser, useSetInAppBrowser, } from '#/state/preferences/in-app-browser' +import {useDeleteActorDeclaration} from '#/state/queries/messages/actor-declaration' import {useClearPreferencesMutation} from '#/state/queries/preferences' import {RQKEY as RQKEY_PROFILE} from '#/state/queries/profile' import {useProfileQuery} from '#/state/queries/profile' @@ -305,6 +306,8 @@ export function SettingsScreen({}: Props) { Toast.show(_(msg`Legacy storage cleared, you need to restart the app now.`)) }, [_]) + const {mutate: onPressDeleteChatDeclaration} = useDeleteActorDeclaration() + return ( @@ -826,6 +829,16 @@ export function SettingsScreen({}: Props) { Reset preferences state + onPressDeleteChatDeclaration()} + accessibilityRole="button" + accessibilityLabel={_(msg`Delete chat declaration record`)} + accessibilityHint={_(msg`Deletes the chat declaration record`)}> + + Delete chat declaration record + +