diff options
author | Eric Bailey <git@esb.lol> | 2025-02-06 11:51:40 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-06 11:51:40 -0600 |
commit | 9cd4f92027774029234e38980fac3a12f136166f (patch) | |
tree | 52805dd7ba11a128bc0cf582c984d89d9a7c390d /src/screens/ModerationInteractionSettings/index.tsx | |
parent | 1db2668a96208046ffe316114f65d432e57db994 (diff) | |
download | voidsky-9cd4f92027774029234e38980fac3a12f136166f.tar.zst |
[APP-1013] Configure and apply default post interaction settings from user preferences (#7664)
* Add interaction settings screen * Move header out of interaction settings form * WIP hook it up * Thread through default settings into composer * Update copy pasta * Handle edited state * Copy feedback * Sentence case Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update copy * Bump SDK * Fix new type error * Less in your face * Remove new dep * Add slot * Copy edit --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
Diffstat (limited to 'src/screens/ModerationInteractionSettings/index.tsx')
-rw-r--r-- | src/screens/ModerationInteractionSettings/index.tsx | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/screens/ModerationInteractionSettings/index.tsx b/src/screens/ModerationInteractionSettings/index.tsx new file mode 100644 index 000000000..99b29d950 --- /dev/null +++ b/src/screens/ModerationInteractionSettings/index.tsx @@ -0,0 +1,127 @@ +import React from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import deepEqual from 'lodash.isequal' + +import {logger} from '#/logger' +import {usePostInteractionSettingsMutation} from '#/state/queries/post-interaction-settings' +import {createPostgateRecord} from '#/state/queries/postgate/util' +import { + usePreferencesQuery, + UsePreferencesQueryResponse, +} from '#/state/queries/preferences' +import { + threadgateAllowUISettingToAllowRecordValue, + threadgateRecordToAllowUISetting, +} from '#/state/queries/threadgate' +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() { + const gutters = useGutters(['base']) + const {data: preferences} = usePreferencesQuery() + return ( + <Layout.Screen testID="ModerationInteractionSettingsScreen"> + <Layout.Header.Outer> + <Layout.Header.BackButton /> + <Layout.Header.Content> + <Layout.Header.TitleText> + <Trans>Post Interaction Settings</Trans> + </Layout.Header.TitleText> + </Layout.Header.Content> + <Layout.Header.Slot /> + </Layout.Header.Outer> + <Layout.Content> + <View style={[gutters, a.gap_xl]}> + <Admonition type="tip"> + <Trans> + The following settings will be used as your defaults when creating + new posts. You can edit these for a specific post from the + composer. + </Trans> + </Admonition> + {preferences ? ( + <Inner preferences={preferences} /> + ) : ( + <View style={[gutters, a.justify_center, a.align_center]}> + <Loader size="xl" /> + </View> + )} + </View> + </Layout.Content> + </Layout.Screen> + ) +} + +function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) { + const {_} = useLingui() + const {mutateAsync: setPostInteractionSettings, isPending} = + usePostInteractionSettingsMutation() + const [error, setError] = React.useState<string | undefined>(undefined) + + const allowUI = React.useMemo(() => { + return threadgateRecordToAllowUISetting({ + $type: 'app.bsky.feed.threadgate', + post: '', + createdAt: new Date().toString(), + allow: preferences.postInteractionSettings.threadgateAllowRules, + }) + }, [preferences.postInteractionSettings.threadgateAllowRules]) + const postgate = React.useMemo(() => { + return createPostgateRecord({ + post: '', + embeddingRules: + preferences.postInteractionSettings.postgateEmbeddingRules, + }) + }, [preferences.postInteractionSettings.postgateEmbeddingRules]) + + const [maybeEditedAllowUI, setAllowUI] = React.useState(allowUI) + const [maybeEditedPostgate, setEditedPostgate] = React.useState(postgate) + + const wasEdited = React.useMemo(() => { + return ( + !deepEqual(allowUI, maybeEditedAllowUI) || + !deepEqual(postgate.embeddingRules, maybeEditedPostgate.embeddingRules) + ) + }, [postgate, allowUI, maybeEditedAllowUI, maybeEditedPostgate]) + + const onSave = React.useCallback(async () => { + setError('') + + try { + await setPostInteractionSettings({ + threadgateAllowRules: + threadgateAllowUISettingToAllowRecordValue(maybeEditedAllowUI), + postgateEmbeddingRules: maybeEditedPostgate.embeddingRules ?? [], + }) + Toast.show(_(msg`Settings saved`)) + } catch (e: any) { + logger.error(`Failed to save post interaction settings`, { + context: 'ModerationInteractionSettingsScreen', + safeMessage: e.message, + }) + setError(_(msg`Failed to save settings. Please try again.`)) + } + }, [_, maybeEditedPostgate, maybeEditedAllowUI, setPostInteractionSettings]) + + return ( + <> + <PostInteractionSettingsForm + canSave={wasEdited} + isSaving={isPending} + onSave={onSave} + postgate={maybeEditedPostgate} + onChangePostgate={setEditedPostgate} + threadgateAllowUISettings={maybeEditedAllowUI} + onChangeThreadgateAllowUISettings={setAllowUI} + /> + + {error && <Admonition type="error">{error}</Admonition>} + </> + ) +} |