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
+
+