From 7a04e6473da6c060d9d1c7a694683e512ddf801b Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 5 Feb 2025 14:58:53 -0600 Subject: [PATCH] Thread through default settings into composer --- .../ModerationInteractionSettings/index.tsx | 80 ++++++++----------- .../queries/post-interaction-settings.ts | 20 +++++ src/state/queries/preferences/const.ts | 4 + src/view/com/composer/Composer.tsx | 17 +++- src/view/com/composer/state/composer.ts | 25 +++++- 5 files changed, 94 insertions(+), 52 deletions(-) create mode 100644 src/state/queries/post-interaction-settings.ts diff --git a/src/screens/ModerationInteractionSettings/index.tsx b/src/screens/ModerationInteractionSettings/index.tsx index 6c7c85caf2..4b7e3c984a 100644 --- a/src/screens/ModerationInteractionSettings/index.tsx +++ b/src/screens/ModerationInteractionSettings/index.tsx @@ -2,34 +2,24 @@ import React from 'react' import {View} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {AppBskyFeedDefs, AppBskyFeedPostgate, AtUri} from '@atproto/api' import {logger} from '#/logger' -import {useAgent, useSession} from '#/state/session' -import {atoms as a, useGutters} from '#/alf' -import {PostInteractionSettingsForm} from '#/components/dialogs/PostInteractionSettingsDialog' -import * as Layout from '#/components/Layout' -import {Admonition} from '#/components/Admonition' +import {usePostInteractionSettingsMutation} from '#/state/queries/post-interaction-settings' +import {createPostgateRecord} from '#/state/queries/postgate/util' import { - createPostgateQueryKey, - getPostgateRecord, - usePostgateQuery, - useWritePostgateMutation, -} from '#/state/queries/postgate' + usePreferencesQuery, + UsePreferencesQueryResponse, +} from '#/state/queries/preferences' import { - createPostgateRecord, - embeddingRules, -} from '#/state/queries/postgate/util' -import { - createThreadgateViewQueryKey, - getThreadgateView, ThreadgateAllowUISetting, - threadgateViewToAllowUISetting, - useSetThreadgateAllowMutation, - useThreadgateViewQuery, + threadgateAllowUISettingToAllowRecordValue, threadgateRecordToAllowUISetting, } from '#/state/queries/threadgate' -import {usePreferencesQuery, UsePreferencesQueryResponse} from '#/state/queries/preferences' +import * as Toast from '#/view/com/util/Toast' +import {atoms as a, useGutters} from '#/alf' +import {Admonition} from '#/components/Admonition' +import {PostInteractionSettingsForm} from '#/components/dialogs/PostInteractionSettingsDialog' +import * as Layout from '#/components/Layout' import {Loader} from '#/components/Loader' export function Screen() { @@ -58,7 +48,7 @@ export function Screen() { ) : ( - + )} @@ -69,63 +59,59 @@ export function Screen() { function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) { const {_} = useLingui() - const {currentAccount} = useSession() - const [isSaving, setIsSaving] = React.useState(false) - console.log(preferences) + const {mutateAsync: setPostInteractionSettings, isPending} = + usePostInteractionSettingsMutation() + const [error, setError] = React.useState(undefined) const [postgate, setPostgate] = React.useState(() => { return createPostgateRecord({ post: '', - embeddingRules: preferences.postInteractionSettings.postgateEmbeddingRules + embeddingRules: + preferences.postInteractionSettings.postgateEmbeddingRules, }) }) - const [allowUISettings, setAllowUISettings] = React.useState(() => { + const [allowUISettings, setAllowUISettings] = React.useState< + ThreadgateAllowUISetting[] + >(() => { return threadgateRecordToAllowUISetting({ $type: 'app.bsky.feed.threadgate', post: '', createdAt: new Date().toString(), - allow: preferences.postInteractionSettings.threadgateAllowRules + allow: preferences.postInteractionSettings.threadgateAllowRules, }) }) const onSave = React.useCallback(async () => { - setIsSaving(true) + setError('') try { - const requests = [] - - if (postgate) { - // TODO - } - - if (allowUISettings) { - // TODO - } + await setPostInteractionSettings({ + threadgateAllowRules: + threadgateAllowUISettingToAllowRecordValue(allowUISettings), + postgateEmbeddingRules: postgate.embeddingRules ?? [], + }) + Toast.show(_(msg`Settings saved`)) } catch (e: any) { logger.error(`Failed to save post interaction settings`, { context: 'PostInteractionSettingsDialogControlledInner', safeMessage: e.message, }) - } finally { - setIsSaving(false) + setError(_(msg`Failed to save settings. Please try again.`)) } - }, [ - _, - postgate, - allowUISettings, - setIsSaving, - ]) + }, [_, postgate, allowUISettings, setPostInteractionSettings]) return ( <> + + {error && {error}} ) } diff --git a/src/state/queries/post-interaction-settings.ts b/src/state/queries/post-interaction-settings.ts new file mode 100644 index 0000000000..a256f29561 --- /dev/null +++ b/src/state/queries/post-interaction-settings.ts @@ -0,0 +1,20 @@ +import {AppBskyActorDefs} from '@atproto/api' +import {useMutation, useQueryClient} from '@tanstack/react-query' + +import {preferencesQueryKey} from '#/state/queries/preferences' +import {useAgent} from '#/state/session' + +export function usePostInteractionSettingsMutation() { + const qc = useQueryClient() + const agent = useAgent() + return useMutation({ + async mutationFn(props: AppBskyActorDefs.PostInteractionSettingsPref) { + await agent.setPostInteractionSettings(props) + }, + async onSuccess() { + await qc.invalidateQueries({ + queryKey: preferencesQueryKey, + }) + }, + }) +} diff --git a/src/state/queries/preferences/const.ts b/src/state/queries/preferences/const.ts index 549f7ce291..3c1fead5e8 100644 --- a/src/state/queries/preferences/const.ts +++ b/src/state/queries/preferences/const.ts @@ -39,4 +39,8 @@ export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = { activeProgressGuide: undefined, nuxs: [], }, + postInteractionSettings: { + threadgateAllowRules: undefined, + postgateEmbeddingRules: [], + }, } diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 0e9b52ce0c..6be418fad2 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -83,6 +83,10 @@ import { useLanguagePrefs, useLanguagePrefsApi, } from '#/state/preferences/languages' +import { + preferencesQueryKey, + UsePreferencesQueryResponse, +} from '#/state/queries/preferences' import {useProfileQuery} from '#/state/queries/profile' import {Gif} from '#/state/queries/tenor' import {useAgent, useSession} from '#/state/session' @@ -169,6 +173,11 @@ export const ComposePost = ({ const discardPromptControl = Prompt.usePromptControl() const {closeAllDialogs} = useDialogStateControlContext() const {closeAllModals} = useModalControls() + const initInteractionSettings = useMemo(() => { + const prefs = + queryClient.getQueryData(preferencesQueryKey) + return prefs?.postInteractionSettings + }, [queryClient]) const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true}) const [isPublishing, setIsPublishing] = useState(false) @@ -177,7 +186,13 @@ export const ComposePost = ({ const [composerState, composerDispatch] = useReducer( composerReducer, - {initImageUris, initQuoteUri: initQuote?.uri, initText, initMention}, + { + initImageUris, + initQuoteUri: initQuote?.uri, + initText, + initMention, + initInteractionSettings, + }, createComposerState, ) diff --git a/src/view/com/composer/state/composer.ts b/src/view/com/composer/state/composer.ts index 6d4f10297f..f5a55f175c 100644 --- a/src/view/com/composer/state/composer.ts +++ b/src/view/com/composer/state/composer.ts @@ -1,5 +1,10 @@ import {ImagePickerAsset} from 'expo-image-picker' -import {AppBskyFeedPostgate, AppBskyRichtextFacet, RichText} from '@atproto/api' +import { + AppBskyFeedPostgate, + AppBskyRichtextFacet, + BskyPreferences, + RichText, +} from '@atproto/api' import {nanoid} from 'nanoid/non-secure' import {SelfLabel} from '#/lib/moderation' @@ -13,7 +18,7 @@ import { import {ComposerImage, createInitialImages} from '#/state/gallery' import {createPostgateRecord} from '#/state/queries/postgate/util' import {Gif} from '#/state/queries/tenor' -import {threadgateViewToAllowUISetting} from '#/state/queries/threadgate' +import {threadgateRecordToAllowUISetting} from '#/state/queries/threadgate' import {ThreadgateAllowUISetting} from '#/state/queries/threadgate' import {ComposerOpts} from '#/state/shell/composer' import { @@ -477,11 +482,15 @@ export function createComposerState({ initMention, initImageUris, initQuoteUri, + initInteractionSettings, }: { initText: string | undefined initMention: string | undefined initImageUris: ComposerOpts['imageUris'] initQuoteUri: string | undefined + initInteractionSettings: + | BskyPreferences['postInteractionSettings'] + | undefined }): ComposerState { let media: ImagesMedia | undefined if (initImageUris?.length) { @@ -591,8 +600,16 @@ export function createComposerState({ }, }, ], - postgate: createPostgateRecord({post: ''}), - threadgate: threadgateViewToAllowUISetting(undefined), + postgate: createPostgateRecord({ + post: '', + embeddingRules: initInteractionSettings?.postgateEmbeddingRules || [], + }), + threadgate: threadgateRecordToAllowUISetting({ + $type: 'app.bsky.feed.threadgate', + post: '', + createdAt: new Date().toString(), + allow: initInteractionSettings?.threadgateAllowRules, + }), }, } }