mirror of
https://github.com/tooot-app/app
synced 2025-02-27 09:07:51 +01:00
Fixed #495
This commit is contained in:
parent
a3a0bf523f
commit
29fd36a581
@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { StyleSheet, View } from 'react-native'
|
import { View } from 'react-native'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
@ -7,14 +7,16 @@ export interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const MenuContainer: React.FC<Props> = ({ children }) => {
|
const MenuContainer: React.FC<Props> = ({ children }) => {
|
||||||
return <View style={styles.base}>{children}</View>
|
return (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
||||||
|
marginBottom: StyleConstants.Spacing.Global.PagePadding
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
base: {
|
|
||||||
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
|
||||||
marginBottom: StyleConstants.Spacing.Global.PagePadding
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
export default MenuContainer
|
export default MenuContainer
|
||||||
|
@ -5,7 +5,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
|||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import { ColorDefinitions } from '@utils/styles/themes'
|
import { ColorDefinitions } from '@utils/styles/themes'
|
||||||
import React, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
import { View } from 'react-native'
|
import { Text, View } from 'react-native'
|
||||||
import { Flow } from 'react-native-animated-spinkit'
|
import { Flow } from 'react-native-animated-spinkit'
|
||||||
import { State, Switch, TapGestureHandler } from 'react-native-gesture-handler'
|
import { State, Switch, TapGestureHandler } from 'react-native-gesture-handler'
|
||||||
|
|
||||||
@ -65,6 +65,7 @@ const MenuRow: React.FC<Props> = ({
|
|||||||
>
|
>
|
||||||
<TapGestureHandler
|
<TapGestureHandler
|
||||||
onHandlerStateChange={async ({ nativeEvent }) => {
|
onHandlerStateChange={async ({ nativeEvent }) => {
|
||||||
|
if (typeof iconBack !== 'string') return // Let icon back handles the gesture
|
||||||
if (nativeEvent.state === State.ACTIVE && !loading) {
|
if (nativeEvent.state === State.ACTIVE && !loading) {
|
||||||
if (screenReaderEnabled && switchOnValueChange) {
|
if (screenReaderEnabled && switchOnValueChange) {
|
||||||
switchOnValueChange()
|
switchOnValueChange()
|
||||||
@ -79,12 +80,13 @@ const MenuRow: React.FC<Props> = ({
|
|||||||
style={{
|
style={{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
paddingTop: StyleConstants.Spacing.S
|
justifyContent: 'space-between',
|
||||||
|
marginTop: StyleConstants.Spacing.S
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
flexGrow: 3,
|
flex: 3,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
}}
|
}}
|
||||||
|
@ -28,8 +28,9 @@ const TimelineHeaderAndroid: React.FC<Props> = ({ queryKey, rootQueryKey, status
|
|||||||
url: status.url || status.uri
|
url: status.url || status.uri
|
||||||
})
|
})
|
||||||
const mAccount = menuAccount({
|
const mAccount = menuAccount({
|
||||||
|
type: 'status',
|
||||||
openChange,
|
openChange,
|
||||||
id: status.account.id,
|
account: status.account,
|
||||||
queryKey
|
queryKey
|
||||||
})
|
})
|
||||||
const mStatus = menuStatus({ status, queryKey, rootQueryKey })
|
const mStatus = menuStatus({ status, queryKey, rootQueryKey })
|
||||||
|
@ -45,8 +45,9 @@ const TimelineHeaderDefault: React.FC<Props> = ({
|
|||||||
copiableContent
|
copiableContent
|
||||||
})
|
})
|
||||||
const mAccount = menuAccount({
|
const mAccount = menuAccount({
|
||||||
|
type: 'status',
|
||||||
openChange,
|
openChange,
|
||||||
id: status.account.id,
|
account: status.account,
|
||||||
queryKey
|
queryKey
|
||||||
})
|
})
|
||||||
const mStatus = menuStatus({ status, queryKey, rootQueryKey })
|
const mStatus = menuStatus({ status, queryKey, rootQueryKey })
|
||||||
|
@ -31,8 +31,9 @@ const TimelineHeaderNotification = ({ queryKey, notification }: Props) => {
|
|||||||
url: notification.status?.url || notification.status?.uri
|
url: notification.status?.url || notification.status?.uri
|
||||||
})
|
})
|
||||||
const mAccount = menuAccount({
|
const mAccount = menuAccount({
|
||||||
|
type: 'status',
|
||||||
openChange,
|
openChange,
|
||||||
id: notification.status?.account.id,
|
account: notification.status?.account,
|
||||||
queryKey
|
queryKey
|
||||||
})
|
})
|
||||||
const mStatus = menuStatus({ status: notification.status, queryKey })
|
const mStatus = menuStatus({ status: notification.status, queryKey })
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
import haptics from '@components/haptics'
|
import haptics from '@components/haptics'
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
|
import { useNavigation } from '@react-navigation/native'
|
||||||
|
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||||
|
import { TabSharedStackParamList } from '@utils/navigation/navigators'
|
||||||
import {
|
import {
|
||||||
QueryKeyRelationship,
|
QueryKeyRelationship,
|
||||||
useRelationshipMutation,
|
useRelationshipMutation,
|
||||||
@ -19,25 +22,29 @@ import { useQueryClient } from 'react-query'
|
|||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
|
|
||||||
const menuAccount = ({
|
const menuAccount = ({
|
||||||
|
type,
|
||||||
openChange,
|
openChange,
|
||||||
id,
|
account,
|
||||||
queryKey,
|
queryKey,
|
||||||
rootQueryKey
|
rootQueryKey
|
||||||
}: {
|
}: {
|
||||||
|
type: 'status' | 'account' // Where the action is coming from
|
||||||
openChange: boolean
|
openChange: boolean
|
||||||
id?: Mastodon.Account['id']
|
account?: Pick<Mastodon.Account, 'id' | 'username'>
|
||||||
queryKey?: QueryKeyTimeline
|
queryKey?: QueryKeyTimeline
|
||||||
rootQueryKey?: QueryKeyTimeline
|
rootQueryKey?: QueryKeyTimeline
|
||||||
}): ContextMenu[][] => {
|
}): ContextMenu[][] => {
|
||||||
if (!id) return []
|
if (!account) return []
|
||||||
|
|
||||||
|
const navigation =
|
||||||
|
useNavigation<NativeStackNavigationProp<TabSharedStackParamList, any, undefined>>()
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
const { t } = useTranslation('componentContextMenu')
|
const { t } = useTranslation('componentContextMenu')
|
||||||
|
|
||||||
const menus: ContextMenu[][] = [[]]
|
const menus: ContextMenu[][] = [[]]
|
||||||
|
|
||||||
const instanceAccount = useSelector(getInstanceAccount, (prev, next) => prev.id === next.id)
|
const instanceAccount = useSelector(getInstanceAccount, (prev, next) => prev.id === next.id)
|
||||||
const ownAccount = instanceAccount?.id === id
|
const ownAccount = instanceAccount?.id === account.id
|
||||||
|
|
||||||
const [enabled, setEnabled] = useState(openChange)
|
const [enabled, setEnabled] = useState(openChange)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -45,12 +52,12 @@ const menuAccount = ({
|
|||||||
setEnabled(true)
|
setEnabled(true)
|
||||||
}
|
}
|
||||||
}, [openChange, enabled])
|
}, [openChange, enabled])
|
||||||
const { data, isFetching } = useRelationshipQuery({ id, options: { enabled } })
|
const { data, isFetching } = useRelationshipQuery({ id: account.id, options: { enabled } })
|
||||||
|
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const timelineMutation = useTimelineMutation({
|
const timelineMutation = useTimelineMutation({
|
||||||
onSuccess: (_, params) => {
|
onSuccess: (_, params) => {
|
||||||
queryClient.refetchQueries(['Relationship', { id }])
|
queryClient.refetchQueries(['Relationship', { id: account.id }])
|
||||||
const theParams = params as MutationVarsTimelineUpdateAccountProperty
|
const theParams = params as MutationVarsTimelineUpdateAccountProperty
|
||||||
displayMessage({
|
displayMessage({
|
||||||
theme,
|
theme,
|
||||||
@ -90,7 +97,7 @@ const menuAccount = ({
|
|||||||
rootQueryKey && queryClient.invalidateQueries(rootQueryKey)
|
rootQueryKey && queryClient.invalidateQueries(rootQueryKey)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const queryKeyRelationship: QueryKeyRelationship = ['Relationship', { id }]
|
const queryKeyRelationship: QueryKeyRelationship = ['Relationship', { id: account.id }]
|
||||||
const relationshipMutation = useRelationshipMutation({
|
const relationshipMutation = useRelationshipMutation({
|
||||||
onSuccess: (res, { payload: { action } }) => {
|
onSuccess: (res, { payload: { action } }) => {
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
@ -118,14 +125,14 @@ const menuAccount = ({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!ownAccount && Platform.OS !== 'android') {
|
if (!ownAccount && Platform.OS !== 'android' && type !== 'account') {
|
||||||
menus[0].push({
|
menus[0].push({
|
||||||
key: 'account-following',
|
key: 'account-following',
|
||||||
item: {
|
item: {
|
||||||
onSelect: () =>
|
onSelect: () =>
|
||||||
data &&
|
data &&
|
||||||
relationshipMutation.mutate({
|
relationshipMutation.mutate({
|
||||||
id,
|
id: account.id,
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
payload: { action: 'follow', state: !data?.requested ? data.following : true }
|
payload: { action: 'follow', state: !data?.requested ? data.following : true }
|
||||||
}),
|
}),
|
||||||
@ -146,6 +153,17 @@ const menuAccount = ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (!ownAccount) {
|
if (!ownAccount) {
|
||||||
|
menus[0].push({
|
||||||
|
key: 'account-list',
|
||||||
|
item: {
|
||||||
|
onSelect: () => navigation.navigate('Tab-Shared-Account-In-Lists', { account }),
|
||||||
|
disabled: Platform.OS !== 'android' ? !data || isFetching : false,
|
||||||
|
destructive: false,
|
||||||
|
hidden: isFetching ? false : !data?.following
|
||||||
|
},
|
||||||
|
title: t('account.inLists'),
|
||||||
|
icon: 'checklist'
|
||||||
|
})
|
||||||
menus[0].push({
|
menus[0].push({
|
||||||
key: 'account-mute',
|
key: 'account-mute',
|
||||||
item: {
|
item: {
|
||||||
@ -153,7 +171,7 @@ const menuAccount = ({
|
|||||||
timelineMutation.mutate({
|
timelineMutation.mutate({
|
||||||
type: 'updateAccountProperty',
|
type: 'updateAccountProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
id,
|
id: account.id,
|
||||||
payload: { property: 'mute', currentValue: data?.muting }
|
payload: { property: 'mute', currentValue: data?.muting }
|
||||||
}),
|
}),
|
||||||
disabled: Platform.OS !== 'android' ? !data || isFetching : false,
|
disabled: Platform.OS !== 'android' ? !data || isFetching : false,
|
||||||
@ -176,7 +194,7 @@ const menuAccount = ({
|
|||||||
timelineMutation.mutate({
|
timelineMutation.mutate({
|
||||||
type: 'updateAccountProperty',
|
type: 'updateAccountProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
id,
|
id: account.id,
|
||||||
payload: { property: 'block', currentValue: data?.blocking }
|
payload: { property: 'block', currentValue: data?.blocking }
|
||||||
}),
|
}),
|
||||||
disabled: Platform.OS !== 'android' ? !data || isFetching : false,
|
disabled: Platform.OS !== 'android' ? !data || isFetching : false,
|
||||||
@ -195,13 +213,13 @@ const menuAccount = ({
|
|||||||
timelineMutation.mutate({
|
timelineMutation.mutate({
|
||||||
type: 'updateAccountProperty',
|
type: 'updateAccountProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
id,
|
id: account.id,
|
||||||
payload: { property: 'reports' }
|
payload: { property: 'reports' }
|
||||||
})
|
})
|
||||||
timelineMutation.mutate({
|
timelineMutation.mutate({
|
||||||
type: 'updateAccountProperty',
|
type: 'updateAccountProperty',
|
||||||
queryKey,
|
queryKey,
|
||||||
id,
|
id: account.id,
|
||||||
payload: { property: 'block', currentValue: false }
|
payload: { property: 'block', currentValue: false }
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"discard": "Discard",
|
"discard": "Discard",
|
||||||
"continue": "Continue",
|
"continue": "Continue",
|
||||||
"delete": "Delete"
|
"delete": "Delete",
|
||||||
|
"done": "Done"
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": "Custom emoji {{emoji}}"
|
"accessibilityLabel": "Custom emoji {{emoji}}"
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
"action_false": "Follow user",
|
"action_false": "Follow user",
|
||||||
"action_true": "Unfollow user"
|
"action_true": "Unfollow user"
|
||||||
},
|
},
|
||||||
|
"inLists": "Manage user of lists",
|
||||||
"mute": {
|
"mute": {
|
||||||
"action_false": "Mute user",
|
"action_false": "Mute user",
|
||||||
"action_true": "Unmute user"
|
"action_true": "Unmute user"
|
||||||
|
@ -320,6 +320,11 @@
|
|||||||
},
|
},
|
||||||
"suspended": "Account suspended by the moderators of your server"
|
"suspended": "Account suspended by the moderators of your server"
|
||||||
},
|
},
|
||||||
|
"accountInLists": {
|
||||||
|
"name": "Lists of @{{username}}",
|
||||||
|
"inLists": "In lists",
|
||||||
|
"notInLists": "Other lists"
|
||||||
|
},
|
||||||
"attachments": {
|
"attachments": {
|
||||||
"name": "<0 /><1>\"s media</1>"
|
"name": "<0 /><1>\"s media</1>"
|
||||||
},
|
},
|
||||||
|
@ -11,7 +11,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
|||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { StyleSheet, Text, View } from 'react-native'
|
import { Text, View } from 'react-native'
|
||||||
import { useSharedValue } from 'react-native-reanimated'
|
import { useSharedValue } from 'react-native-reanimated'
|
||||||
import { useIsFetching } from 'react-query'
|
import { useIsFetching } from 'react-query'
|
||||||
import * as DropdownMenu from 'zeego/dropdown-menu'
|
import * as DropdownMenu from 'zeego/dropdown-menu'
|
||||||
@ -30,21 +30,10 @@ const TabSharedAccount: React.FC<TabSharedStackScreenProps<'Tab-Shared-Account'>
|
|||||||
const { colors, mode } = useTheme()
|
const { colors, mode } = useTheme()
|
||||||
|
|
||||||
const mShare = menuShare({ type: 'account', url: account.url })
|
const mShare = menuShare({ type: 'account', url: account.url })
|
||||||
const mAccount = menuAccount({ openChange: true, id: account.id })
|
const mAccount = menuAccount({ type: 'account', openChange: true, account })
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
headerRight: () => {
|
headerRight: () => {
|
||||||
// const shareOnPress = contextMenuShare({
|
|
||||||
// actions,
|
|
||||||
// type: 'account',
|
|
||||||
// url: account.url
|
|
||||||
// })
|
|
||||||
// const accountOnPress = contextMenuAccount({
|
|
||||||
// actions,
|
|
||||||
// type: 'account',
|
|
||||||
// id: account.id
|
|
||||||
// })
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Root>
|
||||||
<DropdownMenu.Trigger>
|
<DropdownMenu.Trigger>
|
||||||
@ -107,7 +96,7 @@ const TabSharedAccount: React.FC<TabSharedStackScreenProps<'Tab-Shared-Account'>
|
|||||||
const ListHeaderComponent = useMemo(() => {
|
const ListHeaderComponent = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<View style={[styles.header, { borderBottomColor: colors.border }]}>
|
<View style={{ borderBottomWidth: 1, borderBottomColor: colors.border }}>
|
||||||
<AccountHeader account={data} />
|
<AccountHeader account={data} />
|
||||||
<AccountInformation account={data} />
|
<AccountInformation account={data} />
|
||||||
{!data?.suspended && fetchedTimeline.current ? (
|
{!data?.suspended && fetchedTimeline.current ? (
|
||||||
@ -129,7 +118,10 @@ const TabSharedAccount: React.FC<TabSharedStackScreenProps<'Tab-Shared-Account'>
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
style={styles.segmentsContainer}
|
style={{
|
||||||
|
marginTop: StyleConstants.Spacing.M,
|
||||||
|
marginHorizontal: StyleConstants.Spacing.Global.PagePadding
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
{data?.suspended ? (
|
{data?.suspended ? (
|
||||||
@ -178,14 +170,4 @@ const TabSharedAccount: React.FC<TabSharedStackScreenProps<'Tab-Shared-Account'>
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
header: {
|
|
||||||
borderBottomWidth: 1
|
|
||||||
},
|
|
||||||
segmentsContainer: {
|
|
||||||
marginTop: StyleConstants.Spacing.M,
|
|
||||||
marginHorizontal: StyleConstants.Spacing.Global.PagePadding
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
export default TabSharedAccount
|
export default TabSharedAccount
|
||||||
|
119
src/screens/Tabs/Shared/AccountInLists.tsx
Normal file
119
src/screens/Tabs/Shared/AccountInLists.tsx
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
import Button from '@components/Button'
|
||||||
|
import haptics from '@components/haptics'
|
||||||
|
import { HeaderRight } from '@components/Header'
|
||||||
|
import { MenuRow } from '@components/Menu'
|
||||||
|
import CustomText from '@components/Text'
|
||||||
|
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
|
||||||
|
import { useAccountInListsQuery } from '@utils/queryHooks/account'
|
||||||
|
import { useListAccountsMutation, useListsQuery } from '@utils/queryHooks/lists'
|
||||||
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
|
import React, { useEffect } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { SectionList, Text, View } from 'react-native'
|
||||||
|
|
||||||
|
const TabSharedAccountInLists: React.FC<
|
||||||
|
TabSharedStackScreenProps<'Tab-Shared-Account-In-Lists'>
|
||||||
|
> = ({
|
||||||
|
navigation,
|
||||||
|
route: {
|
||||||
|
params: { account }
|
||||||
|
}
|
||||||
|
}) => {
|
||||||
|
const { colors } = useTheme()
|
||||||
|
const { t } = useTranslation('screenTabs')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
navigation.setOptions({
|
||||||
|
presentation: 'modal',
|
||||||
|
title: t('shared.accountInLists.name', { username: account.username }),
|
||||||
|
headerLeft: () => null,
|
||||||
|
headerRight: () => {
|
||||||
|
return (
|
||||||
|
<HeaderRight
|
||||||
|
type='text'
|
||||||
|
content={t('common:buttons.done')}
|
||||||
|
onPress={() => navigation.pop(1)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const listsQuery = useListsQuery({})
|
||||||
|
const accountInListsQuery = useAccountInListsQuery({ id: account.id })
|
||||||
|
|
||||||
|
const sections = [
|
||||||
|
{ id: 'in', title: t('shared.accountInLists.inLists'), data: accountInListsQuery.data || [] },
|
||||||
|
{
|
||||||
|
id: 'out',
|
||||||
|
title: t('shared.accountInLists.notInLists'),
|
||||||
|
data:
|
||||||
|
listsQuery.data?.filter(
|
||||||
|
({ id }) => !accountInListsQuery.data?.filter(d => d.id === id).length
|
||||||
|
) || []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const listAccountsMutation = useListAccountsMutation({})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SectionList
|
||||||
|
style={{ padding: StyleConstants.Spacing.Global.PagePadding }}
|
||||||
|
sections={sections}
|
||||||
|
SectionSeparatorComponent={props => {
|
||||||
|
return props.leadingItem && props.trailingSection ? (
|
||||||
|
<View style={{ flex: 1, height: StyleConstants.Spacing.Global.PagePadding * 2 }} />
|
||||||
|
) : null
|
||||||
|
}}
|
||||||
|
renderSectionHeader={({ section: { title, data } }) =>
|
||||||
|
data.length ? (
|
||||||
|
<CustomText fontStyle='S' style={{ color: colors.secondary }} children={title} />
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
renderItem={({ index, item, section }) => (
|
||||||
|
<MenuRow
|
||||||
|
key={index}
|
||||||
|
iconFront='List'
|
||||||
|
content={
|
||||||
|
<Button
|
||||||
|
type='icon'
|
||||||
|
content={section.id === 'in' ? 'Minus' : 'Plus'}
|
||||||
|
round
|
||||||
|
disabled={accountInListsQuery.isFetching}
|
||||||
|
onPress={() => {
|
||||||
|
switch (section.id) {
|
||||||
|
case 'in':
|
||||||
|
listAccountsMutation
|
||||||
|
.mutateAsync({
|
||||||
|
type: 'delete',
|
||||||
|
payload: { id: item.id, accounts: [account.id] }
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
haptics('Light')
|
||||||
|
accountInListsQuery.refetch()
|
||||||
|
})
|
||||||
|
break
|
||||||
|
case 'out':
|
||||||
|
listAccountsMutation
|
||||||
|
.mutateAsync({
|
||||||
|
type: 'add',
|
||||||
|
payload: { id: item.id, accounts: [account.id] }
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
haptics('Light')
|
||||||
|
accountInListsQuery.refetch()
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
title={item.title}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
></SectionList>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TabSharedAccountInLists
|
@ -16,6 +16,7 @@ import { debounce } from 'lodash'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
import { Platform, TextInput, View } from 'react-native'
|
import { Platform, TextInput, View } from 'react-native'
|
||||||
|
import TabSharedAccountInLists from './AccountInLists'
|
||||||
|
|
||||||
const TabShared = ({ Stack }: { Stack: ReturnType<typeof createNativeStackNavigator> }) => {
|
const TabShared = ({ Stack }: { Stack: ReturnType<typeof createNativeStackNavigator> }) => {
|
||||||
const { colors, mode } = useTheme()
|
const { colors, mode } = useTheme()
|
||||||
@ -48,6 +49,12 @@ const TabShared = ({ Stack }: { Stack: ReturnType<typeof createNativeStackNaviga
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Stack.Screen
|
||||||
|
key='Tab-Shared-Account-In-Lists'
|
||||||
|
name='Tab-Shared-Account-In-Lists'
|
||||||
|
component={TabSharedAccountInLists}
|
||||||
|
/>
|
||||||
|
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
key='Tab-Shared-Attachments'
|
key='Tab-Shared-Attachments'
|
||||||
name='Tab-Shared-Attachments'
|
name='Tab-Shared-Attachments'
|
||||||
|
@ -92,6 +92,9 @@ export type TabSharedStackParamList = {
|
|||||||
'Tab-Shared-Account': {
|
'Tab-Shared-Account': {
|
||||||
account: Mastodon.Account | Mastodon.Mention
|
account: Mastodon.Account | Mastodon.Mention
|
||||||
}
|
}
|
||||||
|
'Tab-Shared-Account-In-Lists': {
|
||||||
|
account: Pick<Mastodon.Account, 'id' | 'username'>
|
||||||
|
}
|
||||||
'Tab-Shared-Attachments': { account: Mastodon.Account }
|
'Tab-Shared-Attachments': { account: Mastodon.Account }
|
||||||
'Tab-Shared-Hashtag': {
|
'Tab-Shared-Hashtag': {
|
||||||
hashtag: Mastodon.Tag['name']
|
hashtag: Mastodon.Tag['name']
|
||||||
|
@ -4,7 +4,7 @@ import { QueryFunctionContext, useQuery, UseQueryOptions } from 'react-query'
|
|||||||
|
|
||||||
export type QueryKeyAccount = ['Account', { id: Mastodon.Account['id'] }]
|
export type QueryKeyAccount = ['Account', { id: Mastodon.Account['id'] }]
|
||||||
|
|
||||||
const queryFunction = ({ queryKey }: QueryFunctionContext<QueryKeyAccount>) => {
|
const accountQueryFunction = ({ queryKey }: QueryFunctionContext<QueryKeyAccount>) => {
|
||||||
const { id } = queryKey[1]
|
const { id } = queryKey[1]
|
||||||
|
|
||||||
return apiInstance<Mastodon.Account>({
|
return apiInstance<Mastodon.Account>({
|
||||||
@ -20,7 +20,30 @@ const useAccountQuery = ({
|
|||||||
options?: UseQueryOptions<Mastodon.Account, AxiosError>
|
options?: UseQueryOptions<Mastodon.Account, AxiosError>
|
||||||
}) => {
|
}) => {
|
||||||
const queryKey: QueryKeyAccount = ['Account', { ...queryKeyParams }]
|
const queryKey: QueryKeyAccount = ['Account', { ...queryKeyParams }]
|
||||||
return useQuery(queryKey, queryFunction, options)
|
return useQuery(queryKey, accountQueryFunction, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
export { useAccountQuery }
|
/* ----- */
|
||||||
|
|
||||||
|
export type QueryKeyAccountInLists = ['AccountInLists', { id: Mastodon.Account['id'] }]
|
||||||
|
|
||||||
|
const accountInListsQueryFunction = ({ queryKey }: QueryFunctionContext<QueryKeyAccount>) => {
|
||||||
|
const { id } = queryKey[1]
|
||||||
|
|
||||||
|
return apiInstance<Mastodon.List[]>({
|
||||||
|
method: 'get',
|
||||||
|
url: `accounts/${id}/lists`
|
||||||
|
}).then(res => res.body)
|
||||||
|
}
|
||||||
|
|
||||||
|
const useAccountInListsQuery = ({
|
||||||
|
options,
|
||||||
|
...queryKeyParams
|
||||||
|
}: QueryKeyAccount[1] & {
|
||||||
|
options?: UseQueryOptions<Mastodon.List[], AxiosError>
|
||||||
|
}) => {
|
||||||
|
const queryKey: QueryKeyAccount = ['Account', { ...queryKeyParams }]
|
||||||
|
return useQuery(queryKey, accountInListsQueryFunction, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { useAccountQuery, useAccountInListsQuery }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user