Thread through default settings into composer

This commit is contained in:
Eric Bailey
2025-02-05 14:58:53 -06:00
parent c4dde4aba5
commit 7a04e6473d
5 changed files with 94 additions and 52 deletions
@@ -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() {
<Inner preferences={preferences} />
) : (
<View style={[gutters, a.justify_center, a.align_center]}>
<Loader size='xl' />
<Loader size="xl" />
</View>
)}
</View>
@@ -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<string | undefined>(undefined)
const [postgate, setPostgate] = React.useState(() => {
return createPostgateRecord({
post: '',
embeddingRules: preferences.postInteractionSettings.postgateEmbeddingRules
embeddingRules:
preferences.postInteractionSettings.postgateEmbeddingRules,
})
})
const [allowUISettings, setAllowUISettings] = React.useState<ThreadgateAllowUISetting[]>(() => {
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 (
<>
<PostInteractionSettingsForm
isSaving={isSaving}
isSaving={isPending}
onSave={onSave}
postgate={postgate}
onChangePostgate={setPostgate}
threadgateAllowUISettings={allowUISettings}
onChangeThreadgateAllowUISettings={setAllowUISettings}
/>
{error && <Admonition type="error">{error}</Admonition>}
</>
)
}
@@ -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,
})
},
})
}
+4
View File
@@ -39,4 +39,8 @@ export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = {
activeProgressGuide: undefined,
nuxs: [],
},
postInteractionSettings: {
threadgateAllowRules: undefined,
postgateEmbeddingRules: [],
},
}
+16 -1
View File
@@ -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<UsePreferencesQueryResponse>(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,
)
+21 -4
View File
@@ -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,
}),
},
}
}