disable native dropdowns for now, remove ios-context-menu

This commit is contained in:
Hailey
2024-06-23 02:35:34 -07:00
parent 9054de701c
commit cd7f438f1a
6 changed files with 434 additions and 473 deletions
+1 -2
View File
@@ -171,7 +171,6 @@
"react-native-gesture-handler": "~2.16.2", "react-native-gesture-handler": "~2.16.2",
"react-native-get-random-values": "~1.11.0", "react-native-get-random-values": "~1.11.0",
"react-native-image-crop-picker": "0.40.3", "react-native-image-crop-picker": "0.40.3",
"react-native-ios-context-menu": "^1.15.3",
"react-native-keyboard-controller": "^1.12.1", "react-native-keyboard-controller": "^1.12.1",
"react-native-pager-view": "6.2.3", "react-native-pager-view": "6.2.3",
"react-native-picker-select": "^9.1.3", "react-native-picker-select": "^9.1.3",
@@ -196,7 +195,7 @@
"statsig-react-native-expo": "^4.6.1", "statsig-react-native-expo": "^4.6.1",
"tippy.js": "^6.3.7", "tippy.js": "^6.3.7",
"tlds": "^1.234.0", "tlds": "^1.234.0",
"zeego": "^1.6.2", "zeego": "^1.10.0",
"zod": "^3.20.2" "zod": "^3.20.2"
}, },
"devDependencies": { "devDependencies": {
+101 -116
View File
@@ -1,21 +1,10 @@
import React from 'react' import React from 'react'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native'
import {isInvalidHandle} from '#/lib/strings/handles'
import {EventStopper} from '#/view/com/util/EventStopper' import {EventStopper} from '#/view/com/util/EventStopper'
import {NativeDropdown} from '#/view/com/util/forms/NativeDropdown'
import {NavigationProp} from '#/lib/routes/types'
import {
usePreferencesQuery,
useUpsertMutedWordsMutation,
useRemoveMutedWordMutation,
} from '#/state/queries/preferences'
import {enforceLen} from '#/lib/strings/helpers'
import {web} from '#/alf'
import * as Dialog from '#/components/Dialog' import * as Dialog from '#/components/Dialog'
// @TODO Fabric
export function useTagMenuControl(): Dialog.DialogControlProps { export function useTagMenuControl(): Dialog.DialogControlProps {
return { return {
id: '', id: '',
@@ -30,11 +19,7 @@ export function useTagMenuControl(): Dialog.DialogControlProps {
} }
} }
export function TagMenu({ export function TagMenu({}: React.PropsWithChildren<{
children,
tag,
authorHandle,
}: React.PropsWithChildren<{
/** /**
* This should be the sanitized tag value from the facet itself, not the * This should be the sanitized tag value from the facet itself, not the
* "display" value with a leading `#`. * "display" value with a leading `#`.
@@ -42,108 +27,108 @@ export function TagMenu({
tag: string tag: string
authorHandle?: string authorHandle?: string
}>) { }>) {
const {_} = useLingui() // const {_} = useLingui()
const navigation = useNavigation<NavigationProp>() // const navigation = useNavigation<NavigationProp>()
const {data: preferences} = usePreferencesQuery() // const {data: preferences} = usePreferencesQuery()
const {mutateAsync: upsertMutedWord, variables: optimisticUpsert} = // const {mutateAsync: upsertMutedWord, variables: optimisticUpsert} =
useUpsertMutedWordsMutation() // useUpsertMutedWordsMutation()
const {mutateAsync: removeMutedWord, variables: optimisticRemove} = // const {mutateAsync: removeMutedWord, variables: optimisticRemove} =
useRemoveMutedWordMutation() // useRemoveMutedWordMutation()
const isMuted = Boolean( // const isMuted = Boolean(
(preferences?.moderationPrefs.mutedWords?.find( // (preferences?.moderationPrefs.mutedWords?.find(
m => m.value === tag && m.targets.includes('tag'), // m => m.value === tag && m.targets.includes('tag'),
) ?? // ) ??
optimisticUpsert?.find( // optimisticUpsert?.find(
m => m.value === tag && m.targets.includes('tag'), // m => m.value === tag && m.targets.includes('tag'),
)) && // )) &&
!(optimisticRemove?.value === tag), // !(optimisticRemove?.value === tag),
) // )
const truncatedTag = '#' + enforceLen(tag, 15, true, 'middle') // const truncatedTag = '#' + enforceLen(tag, 15, true, 'middle')
const dropdownItems = React.useMemo(() => { // const dropdownItems = React.useMemo(() => {
return [ // return [
{ // {
label: _(msg`See ${truncatedTag} posts`), // label: _(msg`See ${truncatedTag} posts`),
onPress() { // onPress() {
navigation.push('Hashtag', { // navigation.push('Hashtag', {
tag: encodeURIComponent(tag), // tag: encodeURIComponent(tag),
}) // })
}, // },
testID: 'tagMenuSearch', // testID: 'tagMenuSearch',
icon: { // icon: {
ios: { // ios: {
name: 'magnifyingglass', // name: 'magnifyingglass',
}, // },
android: '', // android: '',
web: 'magnifying-glass', // web: 'magnifying-glass',
}, // },
}, // },
authorHandle && // authorHandle &&
!isInvalidHandle(authorHandle) && { // !isInvalidHandle(authorHandle) && {
label: _(msg`See ${truncatedTag} posts by user`), // label: _(msg`See ${truncatedTag} posts by user`),
onPress() { // onPress() {
navigation.push('Hashtag', { // navigation.push('Hashtag', {
tag: encodeURIComponent(tag), // tag: encodeURIComponent(tag),
author: authorHandle, // author: authorHandle,
}) // })
}, // },
testID: 'tagMenuSearchByUser', // testID: 'tagMenuSearchByUser',
icon: { // icon: {
ios: { // ios: {
name: 'magnifyingglass', // name: 'magnifyingglass',
}, // },
android: '', // android: '',
web: ['far', 'user'], // web: ['far', 'user'],
}, // },
}, // },
preferences && { // preferences && {
label: 'separator', // label: 'separator',
}, // },
preferences && { // preferences && {
label: isMuted // label: isMuted
? _(msg`Unmute ${truncatedTag}`) // ? _(msg`Unmute ${truncatedTag}`)
: _(msg`Mute ${truncatedTag}`), // : _(msg`Mute ${truncatedTag}`),
onPress() { // onPress() {
if (isMuted) { // if (isMuted) {
removeMutedWord({value: tag, targets: ['tag']}) // removeMutedWord({value: tag, targets: ['tag']})
} else { // } else {
upsertMutedWord([{value: tag, targets: ['tag']}]) // upsertMutedWord([{value: tag, targets: ['tag']}])
} // }
}, // },
testID: 'tagMenuMute', // testID: 'tagMenuMute',
icon: { // icon: {
ios: { // ios: {
name: 'speaker.slash', // name: 'speaker.slash',
}, // },
android: 'ic_menu_sort_alphabetically', // android: 'ic_menu_sort_alphabetically',
web: isMuted ? 'eye' : ['far', 'eye-slash'], // web: isMuted ? 'eye' : ['far', 'eye-slash'],
}, // },
}, // },
].filter(Boolean) // ].filter(Boolean)
}, [ // }, [
_, // _,
authorHandle, // authorHandle,
isMuted, // isMuted,
navigation, // navigation,
preferences, // preferences,
tag, // tag,
truncatedTag, // truncatedTag,
upsertMutedWord, // upsertMutedWord,
removeMutedWord, // removeMutedWord,
]) // ])
return ( return (
<EventStopper> <EventStopper>
<NativeDropdown {/*<NativeDropdown*/}
accessibilityLabel={_(msg`Click here to open tag menu for ${tag}`)} {/* accessibilityLabel={_(msg`Click here to open tag menu for ${tag}`)}*/}
accessibilityHint="" {/* accessibilityHint=""*/}
// @ts-ignore {/* // @ts-ignore*/}
items={dropdownItems} {/* items={dropdownItems}*/}
triggerStyle={web({ {/* triggerStyle={web({*/}
textAlign: 'left', {/* textAlign: 'left',*/}
})}> {/* })}>*/}
{children} {/* {children}*/}
</NativeDropdown> {/*</NativeDropdown>*/}
</EventStopper> </EventStopper>
) )
} }
+49 -55
View File
@@ -3,24 +3,18 @@ import {View} from 'react-native'
import {AppBskyActorDefs, ModerationDecision} from '@atproto/api' import {AppBskyActorDefs, ModerationDecision} from '@atproto/api'
import {msg} from '@lingui/macro' import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native'
import {createHitslop} from '#/lib/constants' import {createHitslop} from '#/lib/constants'
import {NavigationProp} from '#/lib/routes/types'
import {useGate} from '#/lib/statsig/statsig' import {useGate} from '#/lib/statsig/statsig'
import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {useProfileShadow} from '#/state/cache/profile-shadow' import {useProfileShadow} from '#/state/cache/profile-shadow'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {
DropdownItem,
NativeDropdown,
} from '#/view/com/util/forms/NativeDropdown'
import * as Toast from '#/view/com/util/Toast'
import {atoms as a, select, useTheme} from '#/alf' import {atoms as a, select, useTheme} from '#/alf'
import {Button} from '#/components/Button' import {Button} from '#/components/Button'
import {useFollowMethods} from '#/components/hooks/useFollowMethods'
import {PlusSmall_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' import {PlusSmall_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
// @TODO Fabric
export function AviFollowButton({ export function AviFollowButton({
author, author,
moderation, moderation,
@@ -33,13 +27,13 @@ export function AviFollowButton({
const {_} = useLingui() const {_} = useLingui()
const t = useTheme() const t = useTheme()
const profile = useProfileShadow(author) const profile = useProfileShadow(author)
const {follow} = useFollowMethods({ // const {follow} = useFollowMethods({
profile: profile, // profile: profile,
logContext: 'AvatarButton', // logContext: 'AvatarButton',
}) // })
const gate = useGate() const gate = useGate()
const {currentAccount, hasSession} = useSession() const {currentAccount, hasSession} = useSession()
const navigation = useNavigation<NavigationProp>() // const navigation = useNavigation<NavigationProp>()
const name = sanitizeDisplayName( const name = sanitizeDisplayName(
profile.displayName || profile.handle, profile.displayName || profile.handle,
@@ -48,37 +42,37 @@ export function AviFollowButton({
const isFollowing = const isFollowing =
profile.viewer?.following || profile.did === currentAccount?.did profile.viewer?.following || profile.did === currentAccount?.did
function onPress() { // function onPress() {
follow() // follow()
Toast.show(_(msg`Following ${name}`)) // Toast.show(_(msg`Following ${name}`))
} // }
const items: DropdownItem[] = [ // const items: DropdownItem[] = [
{ // {
label: _(msg`View profile`), // label: _(msg`View profile`),
onPress: () => { // onPress: () => {
navigation.navigate('Profile', {name: profile.did}) // navigation.navigate('Profile', {name: profile.did})
}, // },
icon: { // icon: {
ios: { // ios: {
name: 'arrow.up.right.square', // name: 'arrow.up.right.square',
}, // },
android: '', // android: '',
web: ['far', 'arrow-up-right-from-square'], // web: ['far', 'arrow-up-right-from-square'],
}, // },
}, // },
{ // {
label: _(msg`Follow ${name}`), // label: _(msg`Follow ${name}`),
onPress: onPress, // onPress: onPress,
icon: { // icon: {
ios: { // ios: {
name: 'person.badge.plus', // name: 'person.badge.plus',
}, // },
android: '', // android: '',
web: ['far', 'user-plus'], // web: ['far', 'user-plus'],
}, // },
}, // },
] // ]
return hasSession && gate('show_avi_follow_button') ? ( return hasSession && gate('show_avi_follow_button') ? (
<View style={a.relative}> <View style={a.relative}>
@@ -103,18 +97,18 @@ export function AviFollowButton({
borderColor: t.atoms.bg.backgroundColor, borderColor: t.atoms.bg.backgroundColor,
}, },
]}> ]}>
<NativeDropdown items={items}> {/*<NativeDropdown items={items}>*/}
<Plus <Plus
size="sm" size="sm"
fill={ fill={
select(t.name, { select(t.name, {
light: t.atoms.bg_contrast_600, light: t.atoms.bg_contrast_600,
dim: t.atoms.bg_contrast_500, dim: t.atoms.bg_contrast_500,
dark: t.atoms.bg_contrast_600, dark: t.atoms.bg_contrast_600,
}).backgroundColor }).backgroundColor
} }
/> />
</NativeDropdown> {/*</NativeDropdown>*/}
</Button> </Button>
)} )}
</View> </View>
+37 -40
View File
@@ -1,50 +1,47 @@
import React from 'react' import React from 'react'
import {Pressable} from 'react-native' import {Pressable} from 'react-native'
import {
FontAwesomeIcon, import {SessionAccount} from '#/state/session'
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {s} from 'lib/styles' import {s} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'
import {DropdownItem, NativeDropdown} from './forms/NativeDropdown'
import * as Toast from '../../com/util/Toast'
import {useSessionApi, SessionAccount} from '#/state/session'
import {useLingui} from '@lingui/react'
import {msg} from '@lingui/macro'
export function AccountDropdownBtn({account}: {account: SessionAccount}) { // @TODO Fabric
const pal = usePalette('default') export function AccountDropdownBtn({
const {removeAccount} = useSessionApi() account: _account,
const {_} = useLingui() }: {
account: SessionAccount
}) {
// const pal = usePalette('default')
// const {removeAccount} = useSessionApi()
// const {_} = useLingui()
const items: DropdownItem[] = [ // const items: DropdownItem[] = [
{ // {
label: _(msg`Remove account`), // label: _(msg`Remove account`),
onPress: () => { // onPress: () => {
removeAccount(account) // removeAccount(account)
Toast.show(_(msg`Account removed from quick access`)) // Toast.show(_(msg`Account removed from quick access`))
}, // },
icon: { // icon: {
ios: { // ios: {
name: 'trash', // name: 'trash',
}, // },
android: 'ic_delete', // android: 'ic_delete',
web: ['far', 'trash-can'], // web: ['far', 'trash-can'],
}, // },
}, // },
] // ]
return ( return (
<Pressable accessibilityRole="button" style={s.pl10}> <Pressable accessibilityRole="button" style={s.pl10}>
<NativeDropdown {/*<NativeDropdown*/}
testID="accountSettingsDropdownBtn" {/* testID="accountSettingsDropdownBtn"*/}
items={items} {/* items={items}*/}
accessibilityLabel={_(msg`Account options`)} {/* accessibilityLabel={_(msg`Account options`)}*/}
accessibilityHint=""> {/* accessibilityHint="">*/}
<FontAwesomeIcon {/* <FontAwesomeIcon*/}
icon="ellipsis-h" {/* icon="ellipsis-h"*/}
style={pal.textLight as FontAwesomeIconStyle} {/* style={pal.textLight as FontAwesomeIconStyle}*/}
/> {/* />*/}
</NativeDropdown> {/*</NativeDropdown>*/}
</Pressable> </Pressable>
) )
} }
+237 -239
View File
@@ -11,7 +11,7 @@ import {useQueryClient} from '@tanstack/react-query'
import {useAnalytics} from '#/lib/analytics/analytics' import {useAnalytics} from '#/lib/analytics/analytics'
import {cleanError} from '#/lib/strings/errors' import {cleanError} from '#/lib/strings/errors'
import {logger} from '#/logger' import {logger} from '#/logger'
import {isNative, isWeb} from '#/platform/detection' import {isNative} from '#/platform/detection'
import {listenSoftReset} from '#/state/events' import {listenSoftReset} from '#/state/events'
import {useModalControls} from '#/state/modals' import {useModalControls} from '#/state/modals'
import { import {
@@ -41,9 +41,7 @@ import {ComposeIcon2} from 'lib/icons'
import {makeListLink, makeProfileLink} from 'lib/routes/links' import {makeListLink, makeProfileLink} from 'lib/routes/links'
import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types' import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
import {NavigationProp} from 'lib/routes/types' import {NavigationProp} from 'lib/routes/types'
import {shareUrl} from 'lib/sharing'
import {sanitizeHandle} from 'lib/strings/handles' import {sanitizeHandle} from 'lib/strings/handles'
import {toShareUrl} from 'lib/strings/url-helpers'
import {s} from 'lib/styles' import {s} from 'lib/styles'
import {ListMembers} from '#/view/com/lists/ListMembers' import {ListMembers} from '#/view/com/lists/ListMembers'
import {PagerWithHeader} from 'view/com/pager/PagerWithHeader' import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
@@ -52,7 +50,6 @@ import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader'
import {EmptyState} from 'view/com/util/EmptyState' import {EmptyState} from 'view/com/util/EmptyState'
import {FAB} from 'view/com/util/fab/FAB' import {FAB} from 'view/com/util/fab/FAB'
import {Button} from 'view/com/util/forms/Button' import {Button} from 'view/com/util/forms/Button'
import {DropdownItem, NativeDropdown} from 'view/com/util/forms/NativeDropdown'
import {TextLink} from 'view/com/util/Link' import {TextLink} from 'view/com/util/Link'
import {ListRef} from 'view/com/util/List' import {ListRef} from 'view/com/util/List'
import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn' import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
@@ -74,6 +71,8 @@ interface SectionRef {
scrollToTop: () => void scrollToTop: () => void
} }
// @TODO Fabric
type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileList'> type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileList'>
export function ProfileListScreen(props: Props) { export function ProfileListScreen(props: Props) {
const {_} = useLingui() const {_} = useLingui()
@@ -234,13 +233,13 @@ function ProfileListScreenLoaded({
} }
function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) { function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
const pal = usePalette('default') // const pal = usePalette('default')
const palInverted = usePalette('inverted') // const palInverted = usePalette('inverted')
const {_} = useLingui() const {_} = useLingui()
const navigation = useNavigation<NavigationProp>() const navigation = useNavigation<NavigationProp>()
const {currentAccount} = useSession() const {currentAccount} = useSession()
const reportDialogControl = useReportDialogControl() const reportDialogControl = useReportDialogControl()
const {openModal} = useModalControls() // const {openModal} = useModalControls()
const listMuteMutation = useListMuteMutation() const listMuteMutation = useListMuteMutation()
const listBlockMutation = useListBlockMutation() const listBlockMutation = useListBlockMutation()
const listDeleteMutation = useListDeleteMutation() const listDeleteMutation = useListDeleteMutation()
@@ -248,7 +247,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
const isModList = list.purpose === 'app.bsky.graph.defs#modlist' const isModList = list.purpose === 'app.bsky.graph.defs#modlist'
const isBlocking = !!list.viewer?.blocked const isBlocking = !!list.viewer?.blocked
const isMuting = !!list.viewer?.muted const isMuting = !!list.viewer?.muted
const isOwner = list.creator.did === currentAccount?.did // const isOwner = list.creator.did === currentAccount?.did
const {data: preferences} = usePreferencesQuery() const {data: preferences} = usePreferencesQuery()
const {track} = useAnalytics() const {track} = useAnalytics()
const playHaptic = useHaptics() const playHaptic = useHaptics()
@@ -312,17 +311,17 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
savedFeedConfig, savedFeedConfig,
]) ])
const onRemoveFromSavedFeeds = React.useCallback(async () => { // const onRemoveFromSavedFeeds = React.useCallback(async () => {
playHaptic() // playHaptic()
if (!savedFeedConfig) return // if (!savedFeedConfig) return
try { // try {
await removeSavedFeed(savedFeedConfig) // await removeSavedFeed(savedFeedConfig)
Toast.show(_(msg`Removed from your feeds`)) // Toast.show(_(msg`Removed from your feeds`))
} catch (e) { // } catch (e) {
Toast.show(_(msg`There was an issue contacting the server`)) // Toast.show(_(msg`There was an issue contacting the server`))
logger.error('Failed to remove pinned list', {message: e}) // logger.error('Failed to remove pinned list', {message: e})
} // }
}, [playHaptic, removeSavedFeed, _, savedFeedConfig]) // }, [playHaptic, removeSavedFeed, _, savedFeedConfig])
const onSubscribeMute = useCallback(async () => { const onSubscribeMute = useCallback(async () => {
try { try {
@@ -380,12 +379,12 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
} }
}, [list, listBlockMutation, track, _]) }, [list, listBlockMutation, track, _])
const onPressEdit = useCallback(() => { // const onPressEdit = useCallback(() => {
openModal({ // openModal({
name: 'create-or-edit-list', // name: 'create-or-edit-list',
list, // list,
}) // })
}, [openModal, list]) // }, [openModal, list])
const onPressDelete = useCallback(async () => { const onPressDelete = useCallback(async () => {
await listDeleteMutation.mutateAsync({uri: list.uri}) await listDeleteMutation.mutateAsync({uri: list.uri})
@@ -411,188 +410,188 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
savedFeedConfig, savedFeedConfig,
]) ])
const onPressReport = useCallback(() => { // const onPressReport = useCallback(() => {
reportDialogControl.open() // reportDialogControl.open()
}, [reportDialogControl]) // }, [reportDialogControl])
//
// const onPressShare = useCallback(() => {
// const url = toShareUrl(`/profile/${list.creator.did}/lists/${rkey}`)
// shareUrl(url)
// track('Lists:Share')
// }, [list, rkey, track])
const onPressShare = useCallback(() => { // const dropdownItems: DropdownItem[] = useMemo(() => {
const url = toShareUrl(`/profile/${list.creator.did}/lists/${rkey}`) // let items: DropdownItem[] = [
shareUrl(url) // {
track('Lists:Share') // testID: 'listHeaderDropdownShareBtn',
}, [list, rkey, track]) // label: isWeb ? _(msg`Copy link to list`) : _(msg`Share`),
// onPress: onPressShare,
// icon: {
// ios: {
// name: 'square.and.arrow.up',
// },
// android: '',
// web: 'share',
// },
// },
// ]
//
// if (savedFeedConfig) {
// items.push({
// testID: 'listHeaderDropdownRemoveFromFeedsBtn',
// label: _(msg`Remove from my feeds`),
// onPress: onRemoveFromSavedFeeds,
// icon: {
// ios: {
// name: 'trash',
// },
// android: '',
// web: ['far', 'trash-can'],
// },
// })
// }
//
// if (isOwner) {
// items.push({label: 'separator'})
// items.push({
// testID: 'listHeaderDropdownEditBtn',
// label: _(msg`Edit list details`),
// onPress: onPressEdit,
// icon: {
// ios: {
// name: 'pencil',
// },
// android: '',
// web: 'pen',
// },
// })
// items.push({
// testID: 'listHeaderDropdownDeleteBtn',
// label: _(msg`Delete List`),
// onPress: deleteListPromptControl.open,
// icon: {
// ios: {
// name: 'trash',
// },
// android: '',
// web: ['far', 'trash-can'],
// },
// })
// } else {
// items.push({label: 'separator'})
// items.push({
// testID: 'listHeaderDropdownReportBtn',
// label: _(msg`Report List`),
// onPress: onPressReport,
// icon: {
// ios: {
// name: 'exclamationmark.triangle',
// },
// android: '',
// web: 'circle-exclamation',
// },
// })
// }
// if (isModList && isPinned) {
// items.push({label: 'separator'})
// items.push({
// testID: 'listHeaderDropdownUnpinBtn',
// label: _(msg`Unpin moderation list`),
// onPress:
// isPending || !savedFeedConfig
// ? undefined
// : () => removeSavedFeed(savedFeedConfig),
// icon: {
// ios: {
// name: 'pin',
// },
// android: '',
// web: 'thumbtack',
// },
// })
// }
// if (isCurateList && (isBlocking || isMuting)) {
// items.push({label: 'separator'})
//
// if (isMuting) {
// items.push({
// testID: 'listHeaderDropdownMuteBtn',
// label: _(msg`Un-mute list`),
// onPress: onUnsubscribeMute,
// icon: {
// ios: {
// name: 'eye',
// },
// android: '',
// web: 'eye',
// },
// })
// }
//
// if (isBlocking) {
// items.push({
// testID: 'listHeaderDropdownBlockBtn',
// label: _(msg`Un-block list`),
// onPress: onUnsubscribeBlock,
// icon: {
// ios: {
// name: 'person.fill.xmark',
// },
// android: '',
// web: 'user-slash',
// },
// })
// }
// }
// return items
// }, [
// _,
// onPressShare,
// isOwner,
// isModList,
// isPinned,
// isCurateList,
// onPressEdit,
// deleteListPromptControl.open,
// onPressReport,
// isPending,
// isBlocking,
// isMuting,
// onUnsubscribeMute,
// onUnsubscribeBlock,
// removeSavedFeed,
// savedFeedConfig,
// onRemoveFromSavedFeeds,
// ])
const dropdownItems: DropdownItem[] = useMemo(() => { // const subscribeDropdownItems: DropdownItem[] = useMemo(() => {
let items: DropdownItem[] = [ // return [
{ // {
testID: 'listHeaderDropdownShareBtn', // testID: 'subscribeDropdownMuteBtn',
label: isWeb ? _(msg`Copy link to list`) : _(msg`Share`), // label: _(msg`Mute accounts`),
onPress: onPressShare, // onPress: subscribeMutePromptControl.open,
icon: { // icon: {
ios: { // ios: {
name: 'square.and.arrow.up', // name: 'speaker.slash',
}, // },
android: '', // android: '',
web: 'share', // web: 'user-slash',
}, // },
}, // },
] // {
// testID: 'subscribeDropdownBlockBtn',
if (savedFeedConfig) { // label: _(msg`Block accounts`),
items.push({ // onPress: subscribeBlockPromptControl.open,
testID: 'listHeaderDropdownRemoveFromFeedsBtn', // icon: {
label: _(msg`Remove from my feeds`), // ios: {
onPress: onRemoveFromSavedFeeds, // name: 'person.fill.xmark',
icon: { // },
ios: { // android: '',
name: 'trash', // web: 'ban',
}, // },
android: '', // },
web: ['far', 'trash-can'], // ]
}, // }, [_, subscribeMutePromptControl.open, subscribeBlockPromptControl.open])
})
}
if (isOwner) {
items.push({label: 'separator'})
items.push({
testID: 'listHeaderDropdownEditBtn',
label: _(msg`Edit list details`),
onPress: onPressEdit,
icon: {
ios: {
name: 'pencil',
},
android: '',
web: 'pen',
},
})
items.push({
testID: 'listHeaderDropdownDeleteBtn',
label: _(msg`Delete List`),
onPress: deleteListPromptControl.open,
icon: {
ios: {
name: 'trash',
},
android: '',
web: ['far', 'trash-can'],
},
})
} else {
items.push({label: 'separator'})
items.push({
testID: 'listHeaderDropdownReportBtn',
label: _(msg`Report List`),
onPress: onPressReport,
icon: {
ios: {
name: 'exclamationmark.triangle',
},
android: '',
web: 'circle-exclamation',
},
})
}
if (isModList && isPinned) {
items.push({label: 'separator'})
items.push({
testID: 'listHeaderDropdownUnpinBtn',
label: _(msg`Unpin moderation list`),
onPress:
isPending || !savedFeedConfig
? undefined
: () => removeSavedFeed(savedFeedConfig),
icon: {
ios: {
name: 'pin',
},
android: '',
web: 'thumbtack',
},
})
}
if (isCurateList && (isBlocking || isMuting)) {
items.push({label: 'separator'})
if (isMuting) {
items.push({
testID: 'listHeaderDropdownMuteBtn',
label: _(msg`Un-mute list`),
onPress: onUnsubscribeMute,
icon: {
ios: {
name: 'eye',
},
android: '',
web: 'eye',
},
})
}
if (isBlocking) {
items.push({
testID: 'listHeaderDropdownBlockBtn',
label: _(msg`Un-block list`),
onPress: onUnsubscribeBlock,
icon: {
ios: {
name: 'person.fill.xmark',
},
android: '',
web: 'user-slash',
},
})
}
}
return items
}, [
_,
onPressShare,
isOwner,
isModList,
isPinned,
isCurateList,
onPressEdit,
deleteListPromptControl.open,
onPressReport,
isPending,
isBlocking,
isMuting,
onUnsubscribeMute,
onUnsubscribeBlock,
removeSavedFeed,
savedFeedConfig,
onRemoveFromSavedFeeds,
])
const subscribeDropdownItems: DropdownItem[] = useMemo(() => {
return [
{
testID: 'subscribeDropdownMuteBtn',
label: _(msg`Mute accounts`),
onPress: subscribeMutePromptControl.open,
icon: {
ios: {
name: 'speaker.slash',
},
android: '',
web: 'user-slash',
},
},
{
testID: 'subscribeDropdownBlockBtn',
label: _(msg`Block accounts`),
onPress: subscribeBlockPromptControl.open,
icon: {
ios: {
name: 'person.fill.xmark',
},
android: '',
web: 'ban',
},
},
]
}, [_, subscribeMutePromptControl.open, subscribeBlockPromptControl.open])
return ( return (
<ProfileSubpageHeader <ProfileSubpageHeader
@@ -633,29 +632,28 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
label={_(msg`Unmute`)} label={_(msg`Unmute`)}
onPress={onUnsubscribeMute} onPress={onUnsubscribeMute}
/> />
) : ( ) : null
<NativeDropdown ) : // <NativeDropdown
testID="subscribeBtn" // testID="subscribeBtn"
items={subscribeDropdownItems} // items={subscribeDropdownItems}
accessibilityLabel={_(msg`Subscribe to this list`)} // accessibilityLabel={_(msg`Subscribe to this list`)}
accessibilityHint=""> // accessibilityHint="">
<View style={[palInverted.view, styles.btn]}> // <View style={[palInverted.view, styles.btn]}>
<Text style={palInverted.text}> // <Text style={palInverted.text}>
<Trans>Subscribe</Trans> // <Trans>Subscribe</Trans>
</Text> // </Text>
</View> // </View>
</NativeDropdown> // </NativeDropdown>
) null}
) : null} {/*<NativeDropdown*/}
<NativeDropdown {/* testID="headerDropdownBtn"*/}
testID="headerDropdownBtn" {/* items={dropdownItems}*/}
items={dropdownItems} {/* accessibilityLabel={_(msg`More options`)}*/}
accessibilityLabel={_(msg`More options`)} {/* accessibilityHint="">*/}
accessibilityHint=""> {/* <View style={[pal.viewLight, styles.btn]}>*/}
<View style={[pal.viewLight, styles.btn]}> {/* <FontAwesomeIcon icon="ellipsis" size={20} color={pal.colors.text} />*/}
<FontAwesomeIcon icon="ellipsis" size={20} color={pal.colors.text} /> {/* </View>*/}
</View> {/*</NativeDropdown>*/}
</NativeDropdown>
<Prompt.Basic <Prompt.Basic
control={deleteListPromptControl} control={deleteListPromptControl}
@@ -980,14 +978,14 @@ function ErrorScreen({error}: {error: string}) {
) )
} }
const styles = StyleSheet.create({ // const styles = StyleSheet.create({
btn: { // btn: {
flexDirection: 'row', // flexDirection: 'row',
alignItems: 'center', // alignItems: 'center',
gap: 6, // gap: 6,
paddingVertical: 7, // paddingVertical: 7,
paddingHorizontal: 14, // paddingHorizontal: 14,
borderRadius: 50, // borderRadius: 50,
marginLeft: 6, // marginLeft: 6,
}, // },
}) // })
+9 -21
View File
@@ -3118,11 +3118,6 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
"@dominicstop/ts-event-emitter@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@dominicstop/ts-event-emitter/-/ts-event-emitter-1.1.0.tgz#1f3d3fa878a1ccab686931280757954719cf88e4"
integrity sha512-CcxmJIvUb1vsFheuGGVSQf4KdPZC44XolpUT34+vlal+LyQoBUOn31pjFET5M9ctOxEpt8xa0M3/2M7uUiAoJw==
"@egjs/hammerjs@^2.0.17": "@egjs/hammerjs@^2.0.17":
version "2.0.17" version "2.0.17"
resolved "https://registry.yarnpkg.com/@egjs/hammerjs/-/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124" resolved "https://registry.yarnpkg.com/@egjs/hammerjs/-/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124"
@@ -18882,13 +18877,6 @@ react-native-image-crop-picker@0.40.3:
resolved "https://registry.yarnpkg.com/react-native-image-crop-picker/-/react-native-image-crop-picker-0.40.3.tgz#a6b135cd1218a33ad126c1a148ec5a1bd01737ff" resolved "https://registry.yarnpkg.com/react-native-image-crop-picker/-/react-native-image-crop-picker-0.40.3.tgz#a6b135cd1218a33ad126c1a148ec5a1bd01737ff"
integrity sha512-45PKcTnsnLS+E36YwoXutllQdRSOuOsMN0IRcAcwsFXOuAQIOtugXlAuGGL28JHKb/ATaSSPvqCSrdG65Jv3GA== integrity sha512-45PKcTnsnLS+E36YwoXutllQdRSOuOsMN0IRcAcwsFXOuAQIOtugXlAuGGL28JHKb/ATaSSPvqCSrdG65Jv3GA==
react-native-ios-context-menu@^1.15.3:
version "1.15.3"
resolved "https://registry.yarnpkg.com/react-native-ios-context-menu/-/react-native-ios-context-menu-1.15.3.tgz#c02e6a7af2df8c08d0b3e1c8f3395484b3c9c760"
integrity sha512-UNkVl7ocvSpNaEpvBvE1aHOfDy/DFdZ5I+ElfnTXFsRxrVZmxLtST0b1q2wSWGWDmd2Ig2AYd7GRbYtcY222Ag==
dependencies:
"@dominicstop/ts-event-emitter" "^1.1.0"
react-native-keyboard-controller@^1.12.1: react-native-keyboard-controller@^1.12.1:
version "1.12.1" version "1.12.1"
resolved "https://registry.yarnpkg.com/react-native-keyboard-controller/-/react-native-keyboard-controller-1.12.1.tgz#6de22ed4d060528a0dd25621eeaa7f71772ce35f" resolved "https://registry.yarnpkg.com/react-native-keyboard-controller/-/react-native-keyboard-controller-1.12.1.tgz#6de22ed4d060528a0dd25621eeaa7f71772ce35f"
@@ -19991,10 +19979,10 @@ setprototypeof@1.2.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
sf-symbols-typescript@^1.0.0: sf-symbols-typescript@^2.0.0:
version "1.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/sf-symbols-typescript/-/sf-symbols-typescript-1.0.0.tgz#94e9210bf27e7583f9749a0d07bd4f4937ea488f" resolved "https://registry.yarnpkg.com/sf-symbols-typescript/-/sf-symbols-typescript-2.0.0.tgz#52548c84d124914faed1868c55bb71bffac472f1"
integrity sha512-DkS7q3nN68dEMb4E18HFPDAvyrjDZK9YAQQF2QxeFu9gp2xRDXFMF8qLJ1EmQ/qeEGQmop4lmMM1WtYJTIcCMw== integrity sha512-Fc8Uhhl2plqXMw7GQ8q83t/zj1xhNCJvteDNJUDULaH/4a/Eqw5aW1UYEznyEIgkokw7QYXuQ9hOw8jhBLXL0A==
shallow-clone@^3.0.0: shallow-clone@^3.0.0:
version "3.0.1" version "3.0.1"
@@ -22520,14 +22508,14 @@ zeed-dom@0.10.9, zeed-dom@^0.9.19:
dependencies: dependencies:
css-what "^6.1.0" css-what "^6.1.0"
zeego@^1.6.2: zeego@^1.10.0:
version "1.7.0" version "1.10.0"
resolved "https://registry.yarnpkg.com/zeego/-/zeego-1.7.0.tgz#8034adb842199c4ccf21bcb19877800bff18606b" resolved "https://registry.yarnpkg.com/zeego/-/zeego-1.10.0.tgz#4f787e269f3d85b4eb2fdfe58e6765d7e0e8dcf2"
integrity sha512-dZP/iUMeYLfKFnWMn+gNBJkHrR5Cu1ySyCeSkBAJmG9wjCsXoBVMyO7kV6/Y7P0ZhD5c/oS+0/Z6duxeDIos0g== integrity sha512-HrPv7DfyAubkp/NOy+Uwcb1rcS3DtkZEtNQFiSDduBoZt2EDf89+1N+aweACj1UnmGOOu+kk56WYiV9sliMpng==
dependencies: dependencies:
"@radix-ui/react-context-menu" "^2.0.1" "@radix-ui/react-context-menu" "^2.0.1"
"@radix-ui/react-dropdown-menu" "^2.0.1" "@radix-ui/react-dropdown-menu" "^2.0.1"
sf-symbols-typescript "^1.0.0" sf-symbols-typescript "^2.0.0"
zod-validation-error@^2.1.0: zod-validation-error@^2.1.0:
version "2.1.0" version "2.1.0"