Add Renew menu for expired mute words (#9883)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import {logger} from '#/logger'
|
|||||||
import {
|
import {
|
||||||
usePreferencesQuery,
|
usePreferencesQuery,
|
||||||
useRemoveMutedWordMutation,
|
useRemoveMutedWordMutation,
|
||||||
|
useUpdateMutedWordMutation,
|
||||||
useUpsertMutedWordsMutation,
|
useUpsertMutedWordsMutation,
|
||||||
} from '#/state/queries/preferences'
|
} from '#/state/queries/preferences'
|
||||||
import {
|
import {
|
||||||
@@ -29,6 +30,7 @@ import {PageText_Stroke2_Corner0_Rounded as PageText} from '#/components/icons/P
|
|||||||
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
|
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
|
||||||
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
|
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
|
||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
|
import * as Menu from '#/components/Menu'
|
||||||
import * as Prompt from '#/components/Prompt'
|
import * as Prompt from '#/components/Prompt'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {IS_NATIVE} from '#/env'
|
import {IS_NATIVE} from '#/env'
|
||||||
@@ -421,6 +423,7 @@ function MutedWordRow({
|
|||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const {isPending, mutateAsync: removeMutedWord} = useRemoveMutedWordMutation()
|
const {isPending, mutateAsync: removeMutedWord} = useRemoveMutedWordMutation()
|
||||||
|
const {mutateAsync: updateMutedWord} = useUpdateMutedWordMutation()
|
||||||
const control = Prompt.usePromptControl()
|
const control = Prompt.usePromptControl()
|
||||||
const expiryDate = word.expiresAt ? new Date(word.expiresAt) : undefined
|
const expiryDate = word.expiresAt ? new Date(word.expiresAt) : undefined
|
||||||
const isExpired = expiryDate && expiryDate < new Date()
|
const isExpired = expiryDate && expiryDate < new Date()
|
||||||
@@ -431,6 +434,15 @@ function MutedWordRow({
|
|||||||
removeMutedWord(word)
|
removeMutedWord(word)
|
||||||
}, [removeMutedWord, word, control])
|
}, [removeMutedWord, word, control])
|
||||||
|
|
||||||
|
const renew = (days?: number) => {
|
||||||
|
updateMutedWord({
|
||||||
|
...word,
|
||||||
|
expiresAt: days
|
||||||
|
? new Date(Date.now() + days * ONE_DAY).toISOString()
|
||||||
|
: undefined,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Prompt.Basic
|
<Prompt.Basic
|
||||||
@@ -493,35 +505,104 @@ function MutedWordRow({
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
{(expiryDate || word.actorTarget === 'exclude-following') && (
|
{(expiryDate || word.actorTarget === 'exclude-following') && (
|
||||||
<View style={[a.flex_1, a.flex_row, a.align_center, a.gap_sm]}>
|
<View style={[a.flex_1, a.flex_row, a.align_center, a.flex_wrap]}>
|
||||||
<Text
|
{expiryDate &&
|
||||||
style={[
|
(isExpired ? (
|
||||||
a.flex_1,
|
|
||||||
a.text_xs,
|
|
||||||
a.leading_snug,
|
|
||||||
t.atoms.text_contrast_medium,
|
|
||||||
]}>
|
|
||||||
{expiryDate && (
|
|
||||||
<>
|
<>
|
||||||
{isExpired ? (
|
<Text
|
||||||
|
style={[
|
||||||
|
a.text_xs,
|
||||||
|
a.leading_snug,
|
||||||
|
t.atoms.text_contrast_medium,
|
||||||
|
]}>
|
||||||
<Trans>Expired</Trans>
|
<Trans>Expired</Trans>
|
||||||
) : (
|
</Text>
|
||||||
<Trans>
|
<Text
|
||||||
Expires{' '}
|
style={[
|
||||||
{formatDistance(expiryDate, new Date(), {
|
a.text_xs,
|
||||||
addSuffix: true,
|
a.leading_snug,
|
||||||
})}
|
t.atoms.text_contrast_medium,
|
||||||
</Trans>
|
]}>
|
||||||
)}
|
{' · '}
|
||||||
|
</Text>
|
||||||
|
<Menu.Root>
|
||||||
|
<Menu.Trigger label={_(msg`Renew mute word`)}>
|
||||||
|
{({props}) => (
|
||||||
|
<Text
|
||||||
|
{...props}
|
||||||
|
style={[
|
||||||
|
a.text_xs,
|
||||||
|
a.leading_snug,
|
||||||
|
a.font_semi_bold,
|
||||||
|
{color: t.palette.primary_500},
|
||||||
|
]}>
|
||||||
|
<Trans>Renew</Trans>
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</Menu.Trigger>
|
||||||
|
<Menu.Outer>
|
||||||
|
<Menu.LabelText>
|
||||||
|
<Trans>Renew duration</Trans>
|
||||||
|
</Menu.LabelText>
|
||||||
|
<Menu.Group>
|
||||||
|
<Menu.Item
|
||||||
|
label={_(msg`24 hours`)}
|
||||||
|
onPress={() => renew(1)}>
|
||||||
|
<Menu.ItemText>
|
||||||
|
<Trans>24 hours</Trans>
|
||||||
|
</Menu.ItemText>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item
|
||||||
|
label={_(msg`7 days`)}
|
||||||
|
onPress={() => renew(7)}>
|
||||||
|
<Menu.ItemText>
|
||||||
|
<Trans>7 days</Trans>
|
||||||
|
</Menu.ItemText>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item
|
||||||
|
label={_(msg`30 days`)}
|
||||||
|
onPress={() => renew(30)}>
|
||||||
|
<Menu.ItemText>
|
||||||
|
<Trans>30 days</Trans>
|
||||||
|
</Menu.ItemText>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item
|
||||||
|
label={_(msg`Forever`)}
|
||||||
|
onPress={() => renew()}>
|
||||||
|
<Menu.ItemText>
|
||||||
|
<Trans>Forever</Trans>
|
||||||
|
</Menu.ItemText>
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu.Group>
|
||||||
|
</Menu.Outer>
|
||||||
|
</Menu.Root>
|
||||||
</>
|
</>
|
||||||
)}
|
) : (
|
||||||
{word.actorTarget === 'exclude-following' && (
|
<Text
|
||||||
<>
|
style={[
|
||||||
{' • '}
|
a.text_xs,
|
||||||
<Trans>Excludes users you follow</Trans>
|
a.leading_snug,
|
||||||
</>
|
t.atoms.text_contrast_medium,
|
||||||
)}
|
]}>
|
||||||
</Text>
|
<Trans>
|
||||||
|
Expires{' '}
|
||||||
|
{formatDistance(expiryDate, new Date(), {
|
||||||
|
addSuffix: true,
|
||||||
|
})}
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
))}
|
||||||
|
{word.actorTarget === 'exclude-following' && (
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
a.text_xs,
|
||||||
|
a.leading_snug,
|
||||||
|
t.atoms.text_contrast_medium,
|
||||||
|
]}>
|
||||||
|
{expiryDate ? ' · ' : ''}
|
||||||
|
<Trans>Excludes users you follow</Trans>
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
Reference in New Issue
Block a user