Finish migrating ProfileFeed, FeedSourceCard
This commit is contained in:
@@ -8,11 +8,10 @@ import {useLingui} from '@lingui/react'
|
|||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {FeedSourceInfo, useFeedSourceInfoQuery} from '#/state/queries/feed'
|
import {FeedSourceInfo, useFeedSourceInfoQuery} from '#/state/queries/feed'
|
||||||
import {
|
import {
|
||||||
usePinFeedMutation,
|
useAddSavedFeedMutation,
|
||||||
usePreferencesQuery,
|
usePreferencesQuery,
|
||||||
UsePreferencesQueryResponse,
|
UsePreferencesQueryResponse,
|
||||||
useRemoveFeedMutation,
|
useRemoveFeedMutation,
|
||||||
useSaveFeedMutation,
|
|
||||||
} from '#/state/queries/preferences'
|
} from '#/state/queries/preferences'
|
||||||
import {useNavigationDeduped} from 'lib/hooks/useNavigationDeduped'
|
import {useNavigationDeduped} from 'lib/hooks/useNavigationDeduped'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
@@ -90,11 +89,10 @@ export function FeedSourceCardLoaded({
|
|||||||
const removePromptControl = Prompt.usePromptControl()
|
const removePromptControl = Prompt.usePromptControl()
|
||||||
const navigation = useNavigationDeduped()
|
const navigation = useNavigationDeduped()
|
||||||
|
|
||||||
const {isPending: isSavePending, mutateAsync: saveFeed} =
|
const {isPending: isAddSavedFeedPending, mutateAsync: addSavedFeed} =
|
||||||
useSaveFeedMutation()
|
useAddSavedFeedMutation()
|
||||||
const {isPending: isRemovePending, mutateAsync: removeFeed} =
|
const {isPending: isRemovePending, mutateAsync: removeFeed} =
|
||||||
useRemoveFeedMutation()
|
useRemoveFeedMutation()
|
||||||
const {isPending: isPinPending, mutateAsync: pinFeed} = usePinFeedMutation()
|
|
||||||
|
|
||||||
const savedFeedConfig = preferences?.savedFeeds?.find(
|
const savedFeedConfig = preferences?.savedFeeds?.find(
|
||||||
f => f.value === feed?.uri,
|
f => f.value === feed?.uri,
|
||||||
@@ -105,17 +103,17 @@ export function FeedSourceCardLoaded({
|
|||||||
if (!feed) return
|
if (!feed) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (pinOnSave) {
|
await addSavedFeed({
|
||||||
await pinFeed({uri: feed.uri})
|
type: 'feed',
|
||||||
} else {
|
value: feed.uri,
|
||||||
await saveFeed({uri: feed.uri})
|
pinned: pinOnSave,
|
||||||
}
|
})
|
||||||
Toast.show(_(msg`Added to my feeds`))
|
Toast.show(_(msg`Added to my feeds`))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Toast.show(_(msg`There was an issue contacting your server`))
|
Toast.show(_(msg`There was an issue contacting your server`))
|
||||||
logger.error('Failed to save feed', {message: e})
|
logger.error('Failed to save feed', {message: e})
|
||||||
}
|
}
|
||||||
}, [_, feed, pinFeed, pinOnSave, saveFeed])
|
}, [_, feed, pinOnSave, addSavedFeed])
|
||||||
|
|
||||||
const onUnsave = React.useCallback(async () => {
|
const onUnsave = React.useCallback(async () => {
|
||||||
if (!savedFeedConfig) return
|
if (!savedFeedConfig) return
|
||||||
@@ -231,7 +229,7 @@ export function FeedSourceCardLoaded({
|
|||||||
<View style={[s.justifyCenter]}>
|
<View style={[s.justifyCenter]}>
|
||||||
<Pressable
|
<Pressable
|
||||||
testID={`feed-${feed.displayName}-toggleSave`}
|
testID={`feed-${feed.displayName}-toggleSave`}
|
||||||
disabled={isSavePending || isPinPending || isRemovePending}
|
disabled={isAddSavedFeedPending || isRemovePending}
|
||||||
accessibilityRole="button"
|
accessibilityRole="button"
|
||||||
accessibilityLabel={
|
accessibilityLabel={
|
||||||
isSaved
|
isSaved
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
|||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
import {HITSLOP_20} from '#/lib/constants'
|
import {HITSLOP_20} from '#/lib/constants'
|
||||||
import {useGate} from '#/lib/statsig/statsig'
|
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {isNative} from '#/platform/detection'
|
import {isNative} from '#/platform/detection'
|
||||||
import {listenSoftReset} from '#/state/events'
|
import {listenSoftReset} from '#/state/events'
|
||||||
@@ -16,13 +15,11 @@ import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like'
|
|||||||
import {FeedDescriptor} from '#/state/queries/post-feed'
|
import {FeedDescriptor} from '#/state/queries/post-feed'
|
||||||
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
|
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
|
||||||
import {
|
import {
|
||||||
usePinFeedMutation,
|
useAddSavedFeedMutation,
|
||||||
usePreferencesQuery,
|
usePreferencesQuery,
|
||||||
UsePreferencesQueryResponse,
|
UsePreferencesQueryResponse,
|
||||||
useRemoveFeedMutation,
|
useRemoveFeedMutation,
|
||||||
useSaveFeedMutation,
|
useUpdateSavedFeedMutation,
|
||||||
useSetPrimaryAlgorithmMutation,
|
|
||||||
useUnpinFeedMutation,
|
|
||||||
} from '#/state/queries/preferences'
|
} from '#/state/queries/preferences'
|
||||||
import {useResolveUriQuery} from '#/state/queries/resolve-uri'
|
import {useResolveUriQuery} from '#/state/queries/resolve-uri'
|
||||||
import {truncateAndInvalidate} from '#/state/queries/util'
|
import {truncateAndInvalidate} from '#/state/queries/util'
|
||||||
@@ -54,22 +51,18 @@ import {Text} from 'view/com/util/text/Text'
|
|||||||
import * as Toast from 'view/com/util/Toast'
|
import * as Toast from 'view/com/util/Toast'
|
||||||
import {CenteredView} from 'view/com/util/Views'
|
import {CenteredView} from 'view/com/util/Views'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {Button as NewButton, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button as NewButton, ButtonText} from '#/components/Button'
|
||||||
import {useDialogControl} from '#/components/Dialog'
|
|
||||||
import {ArrowOutOfBox_Stroke2_Corner0_Rounded as Share} from '#/components/icons/ArrowOutOfBox'
|
import {ArrowOutOfBox_Stroke2_Corner0_Rounded as Share} from '#/components/icons/ArrowOutOfBox'
|
||||||
import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
|
|
||||||
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
||||||
import {DotGrid_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/DotGrid'
|
import {DotGrid_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/DotGrid'
|
||||||
import {
|
import {
|
||||||
Heart2_Filled_Stroke2_Corner0_Rounded as HeartFilled,
|
Heart2_Filled_Stroke2_Corner0_Rounded as HeartFilled,
|
||||||
Heart2_Stroke2_Corner0_Rounded as HeartOutline,
|
Heart2_Stroke2_Corner0_Rounded as HeartOutline,
|
||||||
} from '#/components/icons/Heart2'
|
} from '#/components/icons/Heart2'
|
||||||
import {Home_Stroke2_Corner0_Rounded as Home} from '#/components/icons/Home'
|
|
||||||
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
|
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
|
||||||
import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
|
import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
|
||||||
import {InlineLinkText} from '#/components/Link'
|
import {InlineLinkText} from '#/components/Link'
|
||||||
import * as Menu from '#/components/Menu'
|
import * as Menu from '#/components/Menu'
|
||||||
import {PrimaryAlgoNoticeDialog} from '#/components/PrimaryAlgoNoticeDialog'
|
|
||||||
import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
|
import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
|
||||||
import {RichText} from '#/components/RichText'
|
import {RichText} from '#/components/RichText'
|
||||||
|
|
||||||
@@ -168,51 +161,21 @@ export function ProfileFeedScreenInner({
|
|||||||
const playHaptic = useHaptics()
|
const playHaptic = useHaptics()
|
||||||
const feedSectionRef = React.useRef<SectionRef>(null)
|
const feedSectionRef = React.useRef<SectionRef>(null)
|
||||||
const isScreenFocused = useIsFocused()
|
const isScreenFocused = useIsFocused()
|
||||||
const gate = useGate()
|
|
||||||
const primaryAlgoDialogControl = useDialogControl()
|
|
||||||
const primaryAlgo = preferences.primaryAlgorithm
|
|
||||||
|
|
||||||
const {
|
const {mutateAsync: addSavedFeed, isPending: isAddSavedFeedPending} =
|
||||||
mutateAsync: saveFeed,
|
useAddSavedFeedMutation()
|
||||||
variables: savedFeed,
|
const {mutateAsync: removeFeed, isPending: isRemovePending} =
|
||||||
reset: resetSaveFeed,
|
useRemoveFeedMutation()
|
||||||
isPending: isSavePending,
|
const {mutateAsync: updateFeed, isPending: isUpdateFeedPending} =
|
||||||
} = useSaveFeedMutation()
|
useUpdateSavedFeedMutation()
|
||||||
const {
|
|
||||||
mutateAsync: removeFeed,
|
|
||||||
variables: removedFeed,
|
|
||||||
reset: resetRemoveFeed,
|
|
||||||
isPending: isRemovePending,
|
|
||||||
} = useRemoveFeedMutation()
|
|
||||||
const {
|
|
||||||
mutateAsync: pinFeed,
|
|
||||||
variables: pinnedFeed,
|
|
||||||
reset: resetPinFeed,
|
|
||||||
isPending: isPinPending,
|
|
||||||
} = usePinFeedMutation()
|
|
||||||
const {
|
|
||||||
mutateAsync: unpinFeed,
|
|
||||||
variables: unpinnedFeed,
|
|
||||||
reset: resetUnpinFeed,
|
|
||||||
isPending: isUnpinPending,
|
|
||||||
} = useUnpinFeedMutation()
|
|
||||||
const {
|
|
||||||
mutateAsync: setPrimaryAlgo,
|
|
||||||
variables: primaryAlgoVariables,
|
|
||||||
isPending: isSetPrimaryAlgoPending,
|
|
||||||
} = useSetPrimaryAlgorithmMutation()
|
|
||||||
|
|
||||||
const isSaved =
|
const isPending =
|
||||||
!removedFeed &&
|
isAddSavedFeedPending || isRemovePending || isUpdateFeedPending
|
||||||
(!!savedFeed || preferences.feeds.saved.includes(feedInfo.uri))
|
const savedFeedConfig = preferences.savedFeeds.find(
|
||||||
const isPinned =
|
f => f.value === feedInfo.uri,
|
||||||
!unpinnedFeed &&
|
)
|
||||||
(!!pinnedFeed || preferences.feeds.pinned.includes(feedInfo.uri))
|
const isSaved = Boolean(savedFeedConfig)
|
||||||
const isPrimaryAlgo =
|
const isPinned = Boolean(savedFeedConfig?.pinned)
|
||||||
(primaryAlgo?.enabled &&
|
|
||||||
primaryAlgo?.uri &&
|
|
||||||
primaryAlgo.uri === feedInfo.uri) ||
|
|
||||||
(primaryAlgoVariables?.enabled && primaryAlgoVariables.uri === feedInfo.uri)
|
|
||||||
|
|
||||||
useSetTitle(feedInfo?.displayName)
|
useSetTitle(feedInfo?.displayName)
|
||||||
|
|
||||||
@@ -223,13 +186,18 @@ export function ProfileFeedScreenInner({
|
|||||||
try {
|
try {
|
||||||
playHaptic()
|
playHaptic()
|
||||||
|
|
||||||
if (isSaved) {
|
if (savedFeedConfig) {
|
||||||
await removeFeed({uri: feedInfo.uri})
|
// only allow removal of non-pinned feeds from this view
|
||||||
resetRemoveFeed()
|
if (!savedFeedConfig.pinned) {
|
||||||
Toast.show(_(msg`Removed from your feeds`))
|
await removeFeed(savedFeedConfig)
|
||||||
|
Toast.show(_(msg`Removed from your feeds`))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
await saveFeed({uri: feedInfo.uri})
|
await addSavedFeed({
|
||||||
resetSaveFeed()
|
type: 'feed',
|
||||||
|
value: feedInfo.uri,
|
||||||
|
pinned: false,
|
||||||
|
})
|
||||||
Toast.show(_(msg`Saved to your feeds`))
|
Toast.show(_(msg`Saved to your feeds`))
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -240,54 +208,36 @@ export function ProfileFeedScreenInner({
|
|||||||
)
|
)
|
||||||
logger.error('Failed up update feeds', {message: err})
|
logger.error('Failed up update feeds', {message: err})
|
||||||
}
|
}
|
||||||
}, [
|
}, [_, playHaptic, feedInfo, removeFeed, addSavedFeed, savedFeedConfig])
|
||||||
playHaptic,
|
|
||||||
isSaved,
|
|
||||||
removeFeed,
|
|
||||||
feedInfo,
|
|
||||||
resetRemoveFeed,
|
|
||||||
_,
|
|
||||||
saveFeed,
|
|
||||||
resetSaveFeed,
|
|
||||||
])
|
|
||||||
|
|
||||||
const onTogglePinned = React.useCallback(async () => {
|
const onTogglePinned = React.useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
playHaptic()
|
playHaptic()
|
||||||
|
|
||||||
if (isPinned) {
|
if (savedFeedConfig) {
|
||||||
await unpinFeed({uri: feedInfo.uri})
|
if (savedFeedConfig.pinned) {
|
||||||
resetUnpinFeed()
|
await updateFeed({
|
||||||
|
...savedFeedConfig,
|
||||||
|
pinned: false,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
await updateFeed({
|
||||||
|
...savedFeedConfig,
|
||||||
|
pinned: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
await pinFeed({uri: feedInfo.uri})
|
await addSavedFeed({
|
||||||
resetPinFeed()
|
type: 'feed',
|
||||||
|
value: feedInfo.uri,
|
||||||
|
pinned: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} 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 toggle pinned feed', {message: e})
|
logger.error('Failed to toggle pinned feed', {message: e})
|
||||||
}
|
}
|
||||||
}, [
|
}, [playHaptic, feedInfo, _, savedFeedConfig, updateFeed, addSavedFeed])
|
||||||
playHaptic,
|
|
||||||
isPinned,
|
|
||||||
unpinFeed,
|
|
||||||
feedInfo,
|
|
||||||
resetUnpinFeed,
|
|
||||||
pinFeed,
|
|
||||||
resetPinFeed,
|
|
||||||
_,
|
|
||||||
])
|
|
||||||
|
|
||||||
const onSetPrimaryAlgo = React.useCallback(async () => {
|
|
||||||
try {
|
|
||||||
playHaptic()
|
|
||||||
await setPrimaryAlgo({enabled: true, uri: feedInfo.uri})
|
|
||||||
} catch (e: any) {
|
|
||||||
Toast.show(_(msg`There was an issue contacting the server`))
|
|
||||||
logger.error('ProfileFeed: failed to set primary algo', {
|
|
||||||
message: e.message,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, [setPrimaryAlgo, feedInfo, _, playHaptic])
|
|
||||||
|
|
||||||
const onPressShare = React.useCallback(() => {
|
const onPressShare = React.useCallback(() => {
|
||||||
const url = toShareUrl(feedInfo.route.href)
|
const url = toShareUrl(feedInfo.route.href)
|
||||||
@@ -325,40 +275,18 @@ export function ProfileFeedScreenInner({
|
|||||||
avatarType="algo">
|
avatarType="algo">
|
||||||
<View style={[a.flex_row, a.align_center, a.gap_sm]}>
|
<View style={[a.flex_row, a.align_center, a.gap_sm]}>
|
||||||
{feedInfo && hasSession && (
|
{feedInfo && hasSession && (
|
||||||
<>
|
<NewButton
|
||||||
{gate('reduced_onboarding_and_home_algo') && isPrimaryAlgo ? (
|
testID={isPinned ? 'unpinBtn' : 'pinBtn'}
|
||||||
<NewButton
|
disabled={isPending}
|
||||||
variant="solid"
|
size="small"
|
||||||
color="secondary"
|
variant="solid"
|
||||||
size="small"
|
color={isPinned ? 'secondary' : 'primary'}
|
||||||
label={_(
|
label={isPinned ? _(msg`Unpin from home`) : _(msg`Pin to home`)}
|
||||||
msg`This feed is already set as your primary algorithm.`,
|
onPress={onTogglePinned}>
|
||||||
)}
|
<ButtonText>
|
||||||
onPress={() => {
|
{isPinned ? _(msg`Unpin`) : _(msg`Pin to Home`)}
|
||||||
primaryAlgoDialogControl.open()
|
</ButtonText>
|
||||||
}}>
|
</NewButton>
|
||||||
<ButtonIcon icon={Check} position="left" />
|
|
||||||
<ButtonText>
|
|
||||||
<Trans>Primary Algorithm</Trans>
|
|
||||||
</ButtonText>
|
|
||||||
</NewButton>
|
|
||||||
) : (
|
|
||||||
<NewButton
|
|
||||||
testID={isPinned ? 'unpinBtn' : 'pinBtn'}
|
|
||||||
disabled={isPinPending || isUnpinPending}
|
|
||||||
size="small"
|
|
||||||
variant="solid"
|
|
||||||
color={isPinned ? 'secondary' : 'primary'}
|
|
||||||
label={
|
|
||||||
isPinned ? _(msg`Unpin from home`) : _(msg`Pin to home`)
|
|
||||||
}
|
|
||||||
onPress={onTogglePinned}>
|
|
||||||
<ButtonText>
|
|
||||||
{isPinned ? _(msg`Unpin`) : _(msg`Pin to Home`)}
|
|
||||||
</ButtonText>
|
|
||||||
</NewButton>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
<Menu.Root>
|
<Menu.Root>
|
||||||
<Menu.Trigger label={_(msg`Open feed options menu`)}>
|
<Menu.Trigger label={_(msg`Open feed options menu`)}>
|
||||||
@@ -389,44 +317,27 @@ export function ProfileFeedScreenInner({
|
|||||||
|
|
||||||
<Menu.Outer>
|
<Menu.Outer>
|
||||||
<Menu.Group>
|
<Menu.Group>
|
||||||
{hasSession && (
|
{hasSession && !isPinned && (
|
||||||
<>
|
<>
|
||||||
{!isPrimaryAlgo && (
|
<Menu.Item
|
||||||
<>
|
disabled={isPending}
|
||||||
<Menu.Item
|
testID="feedHeaderDropdownToggleSavedBtn"
|
||||||
disabled={isSavePending || isRemovePending}
|
label={
|
||||||
testID="feedHeaderDropdownToggleSavedBtn"
|
isSaved
|
||||||
label={
|
? _(msg`Remove from my feeds`)
|
||||||
isSaved
|
: _(msg`Save to my feeds`)
|
||||||
? _(msg`Remove from my feeds`)
|
}
|
||||||
: _(msg`Save to my feeds`)
|
onPress={onToggleSaved}>
|
||||||
}
|
<Menu.ItemText>
|
||||||
onPress={onToggleSaved}>
|
{isSaved
|
||||||
<Menu.ItemText>
|
? _(msg`Remove from my feeds`)
|
||||||
{isSaved
|
: _(msg`Save to my feeds`)}
|
||||||
? _(msg`Remove from my feeds`)
|
</Menu.ItemText>
|
||||||
: _(msg`Save to my feeds`)}
|
<Menu.ItemIcon
|
||||||
</Menu.ItemText>
|
icon={isSaved ? Trash : Plus}
|
||||||
<Menu.ItemIcon
|
position="right"
|
||||||
icon={isSaved ? Trash : Plus}
|
/>
|
||||||
position="right"
|
</Menu.Item>
|
||||||
/>
|
|
||||||
</Menu.Item>
|
|
||||||
|
|
||||||
{gate('reduced_onboarding_and_home_algo') && (
|
|
||||||
<Menu.Item
|
|
||||||
disabled={isSetPrimaryAlgoPending}
|
|
||||||
testID="feedHeaderDropdownSetPrimaryAlgoBtn"
|
|
||||||
label={_(msg`Set as primary algorithm`)}
|
|
||||||
onPress={onSetPrimaryAlgo}>
|
|
||||||
<Menu.ItemText>
|
|
||||||
{_(msg`Set as primary algorithm`)}
|
|
||||||
</Menu.ItemText>
|
|
||||||
<Menu.ItemIcon icon={Home} position="right" />
|
|
||||||
</Menu.Item>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
testID="feedHeaderDropdownReportBtn"
|
testID="feedHeaderDropdownReportBtn"
|
||||||
@@ -455,8 +366,6 @@ export function ProfileFeedScreenInner({
|
|||||||
feedRkey={feedInfo.route.params.rkey}
|
feedRkey={feedInfo.route.params.rkey}
|
||||||
feedInfo={feedInfo}
|
feedInfo={feedInfo}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PrimaryAlgoNoticeDialog control={primaryAlgoDialogControl} />
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}, [
|
}, [
|
||||||
@@ -467,19 +376,11 @@ export function ProfileFeedScreenInner({
|
|||||||
onTogglePinned,
|
onTogglePinned,
|
||||||
onToggleSaved,
|
onToggleSaved,
|
||||||
currentAccount?.did,
|
currentAccount?.did,
|
||||||
isPinPending,
|
|
||||||
isRemovePending,
|
|
||||||
isSavePending,
|
|
||||||
isSaved,
|
isSaved,
|
||||||
isUnpinPending,
|
|
||||||
onPressReport,
|
onPressReport,
|
||||||
onPressShare,
|
onPressShare,
|
||||||
t,
|
t,
|
||||||
gate,
|
isPending,
|
||||||
isPrimaryAlgo,
|
|
||||||
primaryAlgoDialogControl,
|
|
||||||
onSetPrimaryAlgo,
|
|
||||||
isSetPrimaryAlgoPending,
|
|
||||||
])
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user