ALF confirmation dialogs (Dialogs Pt. 3) (#3143)
* Improve a11y on ios * Format * Remove android * Fix android * ALF confirmation dialog * Use ALF for Delete Post confirmation organize diff fix text minimize change copy alternative confirm prompt revert type changes add ButtonColor param * small adjustment to buttons in prompt * full width below gtmobile * update hide post dialog * space out dialogs * update dialogs for lists * add example * add to app passwords * Revert some changes * use sharedvalue for `importantForAccessibility` * add back `isOpen` * fix some more types * small adjustment to buttons in prompt * full width below gtmobile * update the rest of the prompts rm old confirm modal rm update prompt feed error prompt feed source card and profile block/unblock composer discard * Update src/view/screens/AppPasswords.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * lint * How about a default * Reverse reverse * Port over confirm dialogs * Add some comments * Remove unused file * complete merge * add testID where needed --------- Co-authored-by: Eric Bailey <git@esb.lol> Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
This commit is contained in:
parent
090b35e52e
commit
9f2f7f221c
19 changed files with 540 additions and 605 deletions
|
@ -29,6 +29,8 @@ import {
|
|||
} from '#/state/queries/app-passwords'
|
||||
import {ErrorScreen} from '../com/util/error/ErrorScreen'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import {useDialogControl} from '#/components/Dialog'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'AppPasswords'>
|
||||
export function AppPasswords({}: Props) {
|
||||
|
@ -212,23 +214,18 @@ function AppPassword({
|
|||
}) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const {openModal} = useModalControls()
|
||||
const control = useDialogControl()
|
||||
const {contentLanguages} = useLanguagePrefs()
|
||||
const deleteMutation = useAppPasswordDeleteMutation()
|
||||
|
||||
const onDelete = React.useCallback(async () => {
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: _(msg`Delete app password`),
|
||||
message: _(
|
||||
msg`Are you sure you want to delete the app password "${name}"?`,
|
||||
),
|
||||
async onPressConfirm() {
|
||||
await deleteMutation.mutateAsync({name})
|
||||
Toast.show(_(msg`App password deleted`))
|
||||
},
|
||||
})
|
||||
}, [deleteMutation, openModal, name, _])
|
||||
await deleteMutation.mutateAsync({name})
|
||||
Toast.show(_(msg`App password deleted`))
|
||||
}, [deleteMutation, name, _])
|
||||
|
||||
const onPress = React.useCallback(() => {
|
||||
control.open()
|
||||
}, [control])
|
||||
|
||||
const primaryLocale =
|
||||
contentLanguages.length > 0 ? contentLanguages[0] : 'en-US'
|
||||
|
@ -237,7 +234,7 @@ function AppPassword({
|
|||
<TouchableOpacity
|
||||
testID={testID}
|
||||
style={[styles.item, pal.border]}
|
||||
onPress={onDelete}
|
||||
onPress={onPress}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(msg`Delete app password`)}
|
||||
accessibilityHint="">
|
||||
|
@ -260,6 +257,17 @@ function AppPassword({
|
|||
</Text>
|
||||
</View>
|
||||
<FontAwesomeIcon icon={['far', 'trash-can']} style={styles.trashIcon} />
|
||||
|
||||
<Prompt.Basic
|
||||
control={control}
|
||||
title={_(msg`Delete app password?`)}
|
||||
description={_(
|
||||
msg`Are you sure you want to delete the app password "${name}"?`,
|
||||
)}
|
||||
onConfirm={onDelete}
|
||||
confirmButtonCta={_(msg`Delete`)}
|
||||
confirmButtonColor="negative"
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -61,6 +61,8 @@ import {logger} from '#/logger'
|
|||
import {useAnalytics} from '#/lib/analytics/analytics'
|
||||
import {listenSoftReset} from '#/state/events'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import {useDialogControl} from '#/components/Dialog'
|
||||
|
||||
const SECTION_TITLES_CURATE = ['Posts', 'About']
|
||||
const SECTION_TITLES_MOD = ['About']
|
||||
|
@ -234,7 +236,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
const {_} = useLingui()
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
const {currentAccount} = useSession()
|
||||
const {openModal, closeModal} = useModalControls()
|
||||
const {openModal} = useModalControls()
|
||||
const listMuteMutation = useListMuteMutation()
|
||||
const listBlockMutation = useListBlockMutation()
|
||||
const listDeleteMutation = useListDeleteMutation()
|
||||
|
@ -251,6 +253,10 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
const {mutate: setSavedFeeds} = useSetSaveFeedsMutation()
|
||||
const {track} = useAnalytics()
|
||||
|
||||
const deleteListPromptControl = useDialogControl()
|
||||
const subscribeMutePromptControl = useDialogControl()
|
||||
const subscribeBlockPromptControl = useDialogControl()
|
||||
|
||||
const isPinned = preferences?.feeds?.pinned?.includes(list.uri)
|
||||
const isSaved = preferences?.feeds?.saved?.includes(list.uri)
|
||||
|
||||
|
@ -269,32 +275,19 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
}
|
||||
}, [list.uri, isPinned, pinFeed, unpinFeed, _])
|
||||
|
||||
const onSubscribeMute = useCallback(() => {
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: _(msg`Mute these accounts?`),
|
||||
message: _(
|
||||
msg`Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them.`,
|
||||
),
|
||||
confirmBtnText: _(msg`Mute this List`),
|
||||
async onPressConfirm() {
|
||||
try {
|
||||
await listMuteMutation.mutateAsync({uri: list.uri, mute: true})
|
||||
Toast.show(_(msg`List muted`))
|
||||
track('Lists:Mute')
|
||||
} catch {
|
||||
Toast.show(
|
||||
_(
|
||||
msg`There was an issue. Please check your internet connection and try again.`,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onPressCancel() {
|
||||
closeModal()
|
||||
},
|
||||
})
|
||||
}, [openModal, closeModal, list, listMuteMutation, track, _])
|
||||
const onSubscribeMute = useCallback(async () => {
|
||||
try {
|
||||
await listMuteMutation.mutateAsync({uri: list.uri, mute: true})
|
||||
Toast.show(_(msg`List muted`))
|
||||
track('Lists:Mute')
|
||||
} catch {
|
||||
Toast.show(
|
||||
_(
|
||||
msg`There was an issue. Please check your internet connection and try again.`,
|
||||
),
|
||||
)
|
||||
}
|
||||
}, [list, listMuteMutation, track, _])
|
||||
|
||||
const onUnsubscribeMute = useCallback(async () => {
|
||||
try {
|
||||
|
@ -310,32 +303,19 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
}
|
||||
}, [list, listMuteMutation, track, _])
|
||||
|
||||
const onSubscribeBlock = useCallback(() => {
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: _(msg`Block these accounts?`),
|
||||
message: _(
|
||||
msg`Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you.`,
|
||||
),
|
||||
confirmBtnText: _(msg`Block this List`),
|
||||
async onPressConfirm() {
|
||||
try {
|
||||
await listBlockMutation.mutateAsync({uri: list.uri, block: true})
|
||||
Toast.show(_(msg`List blocked`))
|
||||
track('Lists:Block')
|
||||
} catch {
|
||||
Toast.show(
|
||||
_(
|
||||
msg`There was an issue. Please check your internet connection and try again.`,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onPressCancel() {
|
||||
closeModal()
|
||||
},
|
||||
})
|
||||
}, [openModal, closeModal, list, listBlockMutation, track, _])
|
||||
const onSubscribeBlock = useCallback(async () => {
|
||||
try {
|
||||
await listBlockMutation.mutateAsync({uri: list.uri, block: true})
|
||||
Toast.show(_(msg`List blocked`))
|
||||
track('Lists:Block')
|
||||
} catch {
|
||||
Toast.show(
|
||||
_(
|
||||
msg`There was an issue. Please check your internet connection and try again.`,
|
||||
),
|
||||
)
|
||||
}
|
||||
}, [list, listBlockMutation, track, _])
|
||||
|
||||
const onUnsubscribeBlock = useCallback(async () => {
|
||||
try {
|
||||
|
@ -358,34 +338,26 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
})
|
||||
}, [openModal, list])
|
||||
|
||||
const onPressDelete = useCallback(() => {
|
||||
openModal({
|
||||
name: 'confirm',
|
||||
title: _(msg`Delete List`),
|
||||
message: _(msg`Are you sure?`),
|
||||
async onPressConfirm() {
|
||||
await listDeleteMutation.mutateAsync({uri: list.uri})
|
||||
const onPressDelete = useCallback(async () => {
|
||||
await listDeleteMutation.mutateAsync({uri: list.uri})
|
||||
|
||||
if (isSaved || isPinned) {
|
||||
const {saved, pinned} = preferences!.feeds
|
||||
if (isSaved || isPinned) {
|
||||
const {saved, pinned} = preferences!.feeds
|
||||
|
||||
setSavedFeeds({
|
||||
saved: isSaved ? saved.filter(uri => uri !== list.uri) : saved,
|
||||
pinned: isPinned ? pinned.filter(uri => uri !== list.uri) : pinned,
|
||||
})
|
||||
}
|
||||
setSavedFeeds({
|
||||
saved: isSaved ? saved.filter(uri => uri !== list.uri) : saved,
|
||||
pinned: isPinned ? pinned.filter(uri => uri !== list.uri) : pinned,
|
||||
})
|
||||
}
|
||||
|
||||
Toast.show(_(msg`List deleted`))
|
||||
track('Lists:Delete')
|
||||
if (navigation.canGoBack()) {
|
||||
navigation.goBack()
|
||||
} else {
|
||||
navigation.navigate('Home')
|
||||
}
|
||||
},
|
||||
})
|
||||
Toast.show(_(msg`List deleted`))
|
||||
track('Lists:Delete')
|
||||
if (navigation.canGoBack()) {
|
||||
navigation.goBack()
|
||||
} else {
|
||||
navigation.navigate('Home')
|
||||
}
|
||||
}, [
|
||||
openModal,
|
||||
list,
|
||||
listDeleteMutation,
|
||||
navigation,
|
||||
|
@ -443,7 +415,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
items.push({
|
||||
testID: 'listHeaderDropdownDeleteBtn',
|
||||
label: _(msg`Delete List`),
|
||||
onPress: onPressDelete,
|
||||
onPress: deleteListPromptControl.open,
|
||||
icon: {
|
||||
ios: {
|
||||
name: 'trash',
|
||||
|
@ -489,7 +461,9 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
items.push({
|
||||
testID: 'listHeaderDropdownMuteBtn',
|
||||
label: isMuting ? _(msg`Un-mute list`) : _(msg`Mute list`),
|
||||
onPress: isMuting ? onUnsubscribeMute : onSubscribeMute,
|
||||
onPress: isMuting
|
||||
? onUnsubscribeMute
|
||||
: subscribeMutePromptControl.open,
|
||||
icon: {
|
||||
ios: {
|
||||
name: isMuting ? 'eye' : 'eye.slash',
|
||||
|
@ -504,7 +478,9 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
items.push({
|
||||
testID: 'listHeaderDropdownBlockBtn',
|
||||
label: isBlocking ? _(msg`Un-block list`) : _(msg`Block list`),
|
||||
onPress: isBlocking ? onUnsubscribeBlock : onSubscribeBlock,
|
||||
onPress: isBlocking
|
||||
? onUnsubscribeBlock
|
||||
: subscribeBlockPromptControl.open,
|
||||
icon: {
|
||||
ios: {
|
||||
name: 'person.fill.xmark',
|
||||
|
@ -517,24 +493,24 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
}
|
||||
return items
|
||||
}, [
|
||||
isOwner,
|
||||
onPressShare,
|
||||
onPressEdit,
|
||||
onPressDelete,
|
||||
onPressReport,
|
||||
_,
|
||||
onPressShare,
|
||||
isOwner,
|
||||
isModList,
|
||||
isPinned,
|
||||
unpinFeed,
|
||||
isPending,
|
||||
list.uri,
|
||||
isCurateList,
|
||||
isMuting,
|
||||
onPressEdit,
|
||||
deleteListPromptControl.open,
|
||||
onPressReport,
|
||||
isPending,
|
||||
unpinFeed,
|
||||
list.uri,
|
||||
isBlocking,
|
||||
isMuting,
|
||||
onUnsubscribeMute,
|
||||
onSubscribeMute,
|
||||
subscribeMutePromptControl.open,
|
||||
onUnsubscribeBlock,
|
||||
onSubscribeBlock,
|
||||
subscribeBlockPromptControl.open,
|
||||
])
|
||||
|
||||
const subscribeDropdownItems: DropdownItem[] = useMemo(() => {
|
||||
|
@ -542,7 +518,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
{
|
||||
testID: 'subscribeDropdownMuteBtn',
|
||||
label: _(msg`Mute accounts`),
|
||||
onPress: onSubscribeMute,
|
||||
onPress: subscribeMutePromptControl.open,
|
||||
icon: {
|
||||
ios: {
|
||||
name: 'speaker.slash',
|
||||
|
@ -554,7 +530,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
{
|
||||
testID: 'subscribeDropdownBlockBtn',
|
||||
label: _(msg`Block accounts`),
|
||||
onPress: onSubscribeBlock,
|
||||
onPress: subscribeBlockPromptControl.open,
|
||||
icon: {
|
||||
ios: {
|
||||
name: 'person.fill.xmark',
|
||||
|
@ -564,7 +540,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
},
|
||||
},
|
||||
]
|
||||
}, [onSubscribeMute, onSubscribeBlock, _])
|
||||
}, [_, subscribeMutePromptControl.open, subscribeBlockPromptControl.open])
|
||||
|
||||
return (
|
||||
<ProfileSubpageHeader
|
||||
|
@ -620,6 +596,38 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
|
|||
<FontAwesomeIcon icon="ellipsis" size={20} color={pal.colors.text} />
|
||||
</View>
|
||||
</NativeDropdown>
|
||||
|
||||
<Prompt.Basic
|
||||
control={deleteListPromptControl}
|
||||
title={_(msg`Delete this list?`)}
|
||||
description={_(
|
||||
msg`If you delete this list, you won't be able to recover it.`,
|
||||
)}
|
||||
onConfirm={onPressDelete}
|
||||
confirmButtonCta={_(msg`Delete`)}
|
||||
confirmButtonColor="negative"
|
||||
/>
|
||||
|
||||
<Prompt.Basic
|
||||
control={subscribeMutePromptControl}
|
||||
title={_(msg`Mute these accounts?`)}
|
||||
description={_(
|
||||
msg`Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them.`,
|
||||
)}
|
||||
onConfirm={onSubscribeMute}
|
||||
confirmButtonCta={_(msg`Mute list`)}
|
||||
/>
|
||||
|
||||
<Prompt.Basic
|
||||
control={subscribeBlockPromptControl}
|
||||
title={_(msg`Block these accounts?`)}
|
||||
description={_(
|
||||
msg`Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you.`,
|
||||
)}
|
||||
onConfirm={onSubscribeBlock}
|
||||
confirmButtonCta={_(msg`Block list`)}
|
||||
confirmButtonColor="negative"
|
||||
/>
|
||||
</ProfileSubpageHeader>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ export function Dialogs() {
|
|||
</Prompt.Description>
|
||||
<Prompt.Actions>
|
||||
<Prompt.Cancel>Cancel</Prompt.Cancel>
|
||||
<Prompt.Action>Confirm</Prompt.Action>
|
||||
<Prompt.Action onPress={() => {}}>Confirm</Prompt.Action>
|
||||
</Prompt.Actions>
|
||||
</Prompt.Outer>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue