134 lines
4.6 KiB
TypeScript
134 lines
4.6 KiB
TypeScript
import {useCallback, useMemo, useState} from 'react'
|
|
import {View} from 'react-native'
|
|
import {type AtUriString, toDatetimeString} from '@atproto/syntax'
|
|
import {msg} from '@lingui/core/macro'
|
|
import {useLingui} from '@lingui/react'
|
|
import {Trans} from '@lingui/react/macro'
|
|
import deepEqual from 'fast-deep-equal'
|
|
|
|
import {logger} from '#/logger'
|
|
import {usePostInteractionSettingsMutation} from '#/state/queries/post-interaction-settings'
|
|
import {createPostgateRecord} from '#/state/queries/postgate/util'
|
|
import {
|
|
usePreferencesQuery,
|
|
type UsePreferencesQueryResponse,
|
|
} from '#/state/queries/preferences'
|
|
import {
|
|
threadgateAllowUISettingToAllowRecordValue,
|
|
threadgateRecordToAllowUISetting,
|
|
} from '#/state/queries/threadgate'
|
|
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'
|
|
import * as Toast from '#/components/Toast'
|
|
|
|
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] = useState<string | undefined>(undefined)
|
|
|
|
const allowUI = useMemo(() => {
|
|
return threadgateRecordToAllowUISetting({
|
|
$type: 'app.bsky.feed.threadgate',
|
|
post: '' as AtUriString,
|
|
createdAt: toDatetimeString(new Date()),
|
|
/*
|
|
* Preferences are still typed against the legacy client, so the stored
|
|
* rules arrive unbranded. Wave B migrates `getPreferences`.
|
|
*/
|
|
allow: preferences.postInteractionSettings.threadgateAllowRules,
|
|
})
|
|
}, [preferences.postInteractionSettings.threadgateAllowRules])
|
|
const postgate = useMemo(() => {
|
|
return createPostgateRecord({
|
|
post: '',
|
|
embeddingRules:
|
|
preferences.postInteractionSettings.postgateEmbeddingRules,
|
|
})
|
|
}, [preferences.postInteractionSettings.postgateEmbeddingRules])
|
|
|
|
const [maybeEditedAllowUI, setAllowUI] = useState(allowUI)
|
|
const [maybeEditedPostgate, setEditedPostgate] = useState(postgate)
|
|
|
|
const wasEdited = useMemo(() => {
|
|
return (
|
|
!deepEqual(allowUI, maybeEditedAllowUI) ||
|
|
!deepEqual(postgate.embeddingRules, maybeEditedPostgate.embeddingRules)
|
|
)
|
|
}, [postgate, allowUI, maybeEditedAllowUI, maybeEditedPostgate])
|
|
|
|
const onSave = useCallback(async () => {
|
|
setError('')
|
|
|
|
try {
|
|
await setPostInteractionSettings({
|
|
threadgateAllowRules:
|
|
threadgateAllowUISettingToAllowRecordValue(maybeEditedAllowUI),
|
|
postgateEmbeddingRules: maybeEditedPostgate.embeddingRules ?? [],
|
|
})
|
|
Toast.show(_(msg({message: 'Settings saved', context: 'toast'})))
|
|
} catch (e: any) {
|
|
logger.error(`Failed to save post interaction settings`, {
|
|
source: '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>}
|
|
</>
|
|
)
|
|
}
|