mirror of
https://github.com/tooot-app/app
synced 2025-02-04 04:17:36 +01:00
Fixed #49
This commit is contained in:
parent
7e1916989d
commit
e6adbf6986
@ -1,3 +1,5 @@
|
||||
# [tooot](https://tooot.app/) app for Mastodon
|
||||
|
||||
[![GPL-3.0](https://img.shields.io/github/license/tooot-app/push?style=flat-square)](LICENSE) ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/tooot-app/app/build?style=flat-square) ![GitHub issues](https://img.shields.io/github/issues/tooot-app/app?style=flat-square) ![GitHub package.json version](https://img.shields.io/github/package-json/v/tooot-app/app?style=flat-square) ![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/tooot-app/app?style=flat-square)
|
||||
[![GPL-3.0](https://img.shields.io/github/license/tooot-app/push?style=flat-square)](LICENSE) ![GitHub issues](https://img.shields.io/github/issues/tooot-app/app?style=flat-square) ![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/tooot-app/app?include_prereleases&style=flat-square) ![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/tooot-app/app?style=flat-square)
|
||||
|
||||
![GitHub Workflow Status](https://img.shields.io/github/workflow/status/tooot-app/app/build?style=flat-square) ![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/tooot-app/app/build/candidate?label=build%20candidate&style=flat-square) ![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/tooot-app/app/build/release?label=build%20release&style=flat-square)
|
||||
|
17
src/@types/react-navigation.d.ts
vendored
17
src/@types/react-navigation.d.ts
vendored
@ -84,15 +84,24 @@ declare namespace Nav {
|
||||
'Tab-Shared-Hashtag': {
|
||||
hashtag: Mastodon.Tag['name']
|
||||
}
|
||||
'Tab-Shared-Relationships': {
|
||||
account: Mastodon.Account
|
||||
initialType: 'following' | 'followers'
|
||||
}
|
||||
'Tab-Shared-Search': { text: string | undefined }
|
||||
'Tab-Shared-Toot': {
|
||||
toot: Mastodon.Status
|
||||
rootQueryKey: any
|
||||
}
|
||||
'Tab-Shared-Users':
|
||||
| {
|
||||
reference: 'accounts'
|
||||
id: Mastodon.Account['id']
|
||||
type: 'following' | 'followers'
|
||||
count: number
|
||||
}
|
||||
| {
|
||||
reference: 'statuses'
|
||||
id: Mastodon.Status['id']
|
||||
type: 'reblogged_by' | 'favourited_by'
|
||||
count: number
|
||||
}
|
||||
}
|
||||
|
||||
type TabLocalStackParamList = {
|
||||
|
@ -17,6 +17,7 @@ import { uniqBy } from 'lodash'
|
||||
import React, { useCallback } from 'react'
|
||||
import { Pressable, StyleSheet, View } from 'react-native'
|
||||
import { useSelector } from 'react-redux'
|
||||
import TimelineActionsUsers from './Shared/ActionsUsers'
|
||||
import TimelineFullConversation from './Shared/FullConversation'
|
||||
|
||||
export interface Props {
|
||||
@ -128,6 +129,8 @@ const TimelineDefault: React.FC<Props> = ({
|
||||
<TimelineFullConversation queryKey={queryKey} status={actualStatus} />
|
||||
</View>
|
||||
|
||||
<TimelineActionsUsers status={actualStatus} highlighted={highlighted} />
|
||||
|
||||
{queryKey && !disableDetails && (
|
||||
<View
|
||||
style={{
|
||||
|
@ -300,7 +300,8 @@ const styles = StyleSheet.create({
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
minHeight: StyleConstants.Font.Size.L + StyleConstants.Spacing.S * 4
|
||||
minHeight: StyleConstants.Font.Size.L + StyleConstants.Spacing.S * 4,
|
||||
marginHorizontal: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
|
90
src/components/Timeline/Shared/ActionsUsers.tsx
Normal file
90
src/components/Timeline/Shared/ActionsUsers.tsx
Normal file
@ -0,0 +1,90 @@
|
||||
import analytics from '@components/analytics'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
status: Mastodon.Status
|
||||
highlighted: boolean
|
||||
}
|
||||
|
||||
const TimelineActionsUsers = React.memo(
|
||||
({ status, highlighted }: Props) => {
|
||||
if (!highlighted) {
|
||||
return null
|
||||
}
|
||||
|
||||
const { t } = useTranslation('componentTimeline')
|
||||
const { theme } = useTheme()
|
||||
const navigation = useNavigation<
|
||||
StackNavigationProp<Nav.TabLocalStackParamList>
|
||||
>()
|
||||
|
||||
return (
|
||||
<View style={styles.base}>
|
||||
{status.reblogs_count > 0 ? (
|
||||
<Text
|
||||
style={[styles.text, { color: theme.secondary }]}
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_actionsusers_press_boosted', {
|
||||
count: status.reblogs_count
|
||||
})
|
||||
navigation.push('Tab-Shared-Users', {
|
||||
reference: 'statuses',
|
||||
id: status.id,
|
||||
type: 'reblogged_by',
|
||||
count: status.reblogs_count
|
||||
})
|
||||
}}
|
||||
>
|
||||
{t('shared.actionsUsers.reblogged_by', {
|
||||
count: status.reblogs_count
|
||||
})}
|
||||
</Text>
|
||||
) : null}
|
||||
{status.favourites_count > 0 ? (
|
||||
<Text
|
||||
style={[styles.text, { color: theme.secondary }]}
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_actionsusers_press_boosted', {
|
||||
count: status.favourites_count
|
||||
})
|
||||
navigation.push('Tab-Shared-Users', {
|
||||
reference: 'statuses',
|
||||
id: status.id,
|
||||
type: 'favourited_by',
|
||||
count: status.favourites_count
|
||||
})
|
||||
}}
|
||||
>
|
||||
{t('shared.actionsUsers.favourited_by', {
|
||||
count: status.favourites_count
|
||||
})}
|
||||
</Text>
|
||||
) : null}
|
||||
</View>
|
||||
)
|
||||
},
|
||||
(prev, next) =>
|
||||
prev.status.reblogs_count === next.status.reblogs_count &&
|
||||
prev.status.favourites_count === next.status.favourites_count
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
flexDirection: 'row'
|
||||
},
|
||||
pressable: { margin: StyleConstants.Spacing.M },
|
||||
text: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
padding: StyleConstants.Spacing.S * 1.5,
|
||||
paddingLeft: 0,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
export default TimelineActionsUsers
|
@ -22,9 +22,9 @@ export default {
|
||||
sharedAnnouncements: require('./screens/sharedAnnouncements').default,
|
||||
sharedAttachments: require('./screens/sharedAttachments').default,
|
||||
sharedCompose: require('./screens/sharedCompose').default,
|
||||
sharedRelationships: require('./screens/sharedRelationships').default,
|
||||
sharedSearch: require('./screens/sharedSearch').default,
|
||||
sharedToot: require('./screens/sharedToot').default,
|
||||
sharedUsers: require('./screens/sharedUsers').default,
|
||||
|
||||
componentInstance: require('./components/instance').default,
|
||||
componentParse: require('./components/parse').default,
|
||||
|
@ -39,6 +39,10 @@ export default {
|
||||
function: 'Bookmark toot'
|
||||
}
|
||||
},
|
||||
actionsUsers: {
|
||||
reblogged_by: '$t(sharedUsers:heading.statuses.reblogged_by)',
|
||||
favourited_by: '$t(sharedUsers:heading.statuses.favourited_by)'
|
||||
},
|
||||
attachment: {
|
||||
sensitive: {
|
||||
button: 'Show sensitive media'
|
||||
|
@ -4,8 +4,8 @@ export default {
|
||||
created_at: 'Registered: {{date}}',
|
||||
summary: {
|
||||
statuses_count: '{{count}} toots',
|
||||
following_count: 'Following {{count}}',
|
||||
followers_count: '{{count}} followers'
|
||||
following_count: '$t(sharedUsers:heading.accounts.following)',
|
||||
followers_count: '$t(sharedUsers:heading.accounts.followers)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
export default {
|
||||
heading: {
|
||||
segments: {
|
||||
left: 'Following',
|
||||
right: 'Followers'
|
||||
}
|
||||
}
|
||||
}
|
12
src/i18n/en/screens/sharedUsers.ts
Normal file
12
src/i18n/en/screens/sharedUsers.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export default {
|
||||
heading: {
|
||||
accounts: {
|
||||
following: 'Following {{count}}',
|
||||
followers: '{{count}} followers'
|
||||
},
|
||||
statuses: {
|
||||
reblogged_by: '{{count}} boosted',
|
||||
favourited_by: '{{count}} favourited'
|
||||
}
|
||||
}
|
||||
}
|
@ -22,9 +22,9 @@ export default {
|
||||
sharedAnnouncements: require('./screens/sharedAnnouncements').default,
|
||||
sharedAttachments: require('./screens/sharedAttachments').default,
|
||||
sharedCompose: require('./screens/sharedCompose').default,
|
||||
sharedRelationships: require('./screens/sharedRelationships').default,
|
||||
sharedSearch: require('./screens/sharedSearch').default,
|
||||
sharedToot: require('./screens/sharedToot').default,
|
||||
sharedUsers: require('./screens/sharedUsers').default,
|
||||
|
||||
componentInstance: require('./components/instance').default,
|
||||
componentParse: require('./components/parse').default,
|
||||
|
@ -39,6 +39,10 @@ export default {
|
||||
function: '收藏嘟文'
|
||||
}
|
||||
},
|
||||
actionsUsers: {
|
||||
reblogged_by: '$t(sharedUsers:heading.statuses.reblogged_by)',
|
||||
favourited_by: '$t(sharedUsers:heading.statuses.favourited_by)'
|
||||
},
|
||||
attachment: {
|
||||
sensitive: {
|
||||
button: '显示敏感内容'
|
||||
|
@ -4,8 +4,8 @@ export default {
|
||||
created_at: '注册时间:{{date}}',
|
||||
summary: {
|
||||
statuses_count: '{{count}} 条嘟文',
|
||||
following_count: '关注 {{count}} 人',
|
||||
followers_count: '被 {{count}} 人关注'
|
||||
following_count: '$t(sharedUsers:heading.accounts.following)',
|
||||
followers_count: '$t(sharedUsers:heading.accounts.followers)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
export default {
|
||||
heading: {
|
||||
segments: {
|
||||
left: '关注中',
|
||||
right: '关注者'
|
||||
}
|
||||
}
|
||||
}
|
12
src/i18n/zh-Hans/screens/sharedUsers.ts
Normal file
12
src/i18n/zh-Hans/screens/sharedUsers.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export default {
|
||||
heading: {
|
||||
accounts: {
|
||||
following: '关注 {{count}} 人',
|
||||
followers: '被 {{count}} 人关注'
|
||||
},
|
||||
statuses: {
|
||||
reblogged_by: '{{count}} 人转嘟',
|
||||
favourited_by: '{{count}} 人收藏'
|
||||
}
|
||||
}
|
||||
}
|
@ -48,15 +48,17 @@ const AccountInformationStats: React.FC<Props> = ({ account, myInfo }) => {
|
||||
<Text
|
||||
style={[styles.stat, { color: theme.primary, textAlign: 'right' }]}
|
||||
children={t('content.summary.following_count', {
|
||||
count: account.following_count || 0
|
||||
count: account.following_count
|
||||
})}
|
||||
onPress={() => {
|
||||
analytics('account_stats_following_press', {
|
||||
count: account.following_count
|
||||
})
|
||||
navigation.push('Tab-Shared-Relationships', {
|
||||
account,
|
||||
initialType: 'following'
|
||||
navigation.push('Tab-Shared-Users', {
|
||||
reference: 'accounts',
|
||||
id: account.id,
|
||||
type: 'following',
|
||||
count: account.following_count
|
||||
})
|
||||
}}
|
||||
/>
|
||||
@ -73,15 +75,17 @@ const AccountInformationStats: React.FC<Props> = ({ account, myInfo }) => {
|
||||
<Text
|
||||
style={[styles.stat, { color: theme.primary, textAlign: 'center' }]}
|
||||
children={t('content.summary.followers_count', {
|
||||
count: account.followers_count || 0
|
||||
count: account.followers_count
|
||||
})}
|
||||
onPress={() => {
|
||||
analytics('account_stats_followers_press', {
|
||||
count: account.followers_count
|
||||
})
|
||||
navigation.push('Tab-Shared-Relationships', {
|
||||
account,
|
||||
initialType: 'followers'
|
||||
navigation.push('Tab-Shared-Users', {
|
||||
reference: 'accounts',
|
||||
id: account.id,
|
||||
type: 'followers',
|
||||
count: account.followers_count
|
||||
})
|
||||
}}
|
||||
/>
|
||||
|
@ -1,79 +0,0 @@
|
||||
import SegmentedControl from '@react-native-community/segmented-control'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Dimensions, StyleSheet, View } from 'react-native'
|
||||
import { TabView } from 'react-native-tab-view'
|
||||
import RelationshipsList from './Relationships/List'
|
||||
import { SharedRelationshipsProp } from './sharedScreens'
|
||||
|
||||
const TabSharedRelationships = React.memo(
|
||||
({
|
||||
route: {
|
||||
params: { account, initialType }
|
||||
}
|
||||
}: SharedRelationshipsProp) => {
|
||||
const { t } = useTranslation('sharedRelationships')
|
||||
const { mode } = useTheme()
|
||||
const navigation = useNavigation()
|
||||
|
||||
const [segment, setSegment] = useState(initialType === 'following' ? 0 : 1)
|
||||
useEffect(() => {
|
||||
const updateHeaderRight = () =>
|
||||
navigation.setOptions({
|
||||
headerCenter: () => (
|
||||
<View style={styles.segmentsContainer}>
|
||||
<SegmentedControl
|
||||
appearance={mode}
|
||||
values={[
|
||||
t('heading.segments.left'),
|
||||
t('heading.segments.right')
|
||||
]}
|
||||
selectedIndex={segment}
|
||||
onChange={({ nativeEvent }) =>
|
||||
setSegment(nativeEvent.selectedSegmentIndex)
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
})
|
||||
return updateHeaderRight()
|
||||
}, [segment, mode])
|
||||
|
||||
const routes: {
|
||||
key: SharedRelationshipsProp['route']['params']['initialType']
|
||||
}[] = [{ key: 'following' }, { key: 'followers' }]
|
||||
|
||||
const renderScene = ({
|
||||
route
|
||||
}: {
|
||||
route: {
|
||||
key: SharedRelationshipsProp['route']['params']['initialType']
|
||||
}
|
||||
}) => {
|
||||
return <RelationshipsList id={account.id} type={route.key} />
|
||||
}
|
||||
|
||||
return (
|
||||
<TabView
|
||||
lazy
|
||||
swipeEnabled
|
||||
renderScene={renderScene}
|
||||
renderTabBar={() => null}
|
||||
onIndexChange={index => setSegment(index)}
|
||||
navigationState={{ index: segment, routes }}
|
||||
initialLayout={{ width: Dimensions.get('screen').width }}
|
||||
/>
|
||||
)
|
||||
},
|
||||
() => true
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
segmentsContainer: {
|
||||
flexBasis: '60%'
|
||||
}
|
||||
})
|
||||
|
||||
export default TabSharedRelationships
|
@ -1,84 +0,0 @@
|
||||
import ComponentAccount from '@components/Account'
|
||||
import ComponentSeparator from '@components/Separator'
|
||||
import { useScrollToTop } from '@react-navigation/native'
|
||||
import {
|
||||
QueryKeyRelationships,
|
||||
useRelationshipsQuery
|
||||
} from '@utils/queryHooks/relationships'
|
||||
import React, { useCallback, useMemo, useRef } from 'react'
|
||||
import { RefreshControl, StyleSheet } from 'react-native'
|
||||
import { FlatList } from 'react-native-gesture-handler'
|
||||
|
||||
export interface Props {
|
||||
id: Mastodon.Account['id']
|
||||
type: 'following' | 'followers'
|
||||
}
|
||||
|
||||
const RelationshipsList: React.FC<Props> = ({ id, type }) => {
|
||||
const queryKey: QueryKeyRelationships = ['Relationships', { type, id }]
|
||||
const {
|
||||
data,
|
||||
isFetching,
|
||||
refetch,
|
||||
fetchNextPage,
|
||||
isFetchingNextPage
|
||||
} = useRelationshipsQuery({
|
||||
...queryKey[1],
|
||||
options: {
|
||||
getPreviousPageParam: firstPage =>
|
||||
firstPage.links?.prev && { since_id: firstPage.links.next },
|
||||
getNextPageParam: lastPage =>
|
||||
lastPage.links?.next && { max_id: lastPage.links.next }
|
||||
}
|
||||
})
|
||||
const flattenData = data?.pages ? data.pages.flatMap(d => [...d.body]) : []
|
||||
|
||||
const flRef = useRef<FlatList<Mastodon.Account>>(null)
|
||||
|
||||
const keyExtractor = useCallback(({ id }) => id, [])
|
||||
const renderItem = useCallback(
|
||||
({ item }) => <ComponentAccount account={item} origin='relationship' />,
|
||||
[]
|
||||
)
|
||||
const onEndReached = useCallback(
|
||||
() => !isFetchingNextPage && fetchNextPage(),
|
||||
[isFetchingNextPage]
|
||||
)
|
||||
const refreshControl = useMemo(
|
||||
() => (
|
||||
<RefreshControl refreshing={isFetching} onRefresh={() => refetch()} />
|
||||
),
|
||||
[isFetching]
|
||||
)
|
||||
|
||||
useScrollToTop(flRef)
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
ref={flRef}
|
||||
windowSize={11}
|
||||
data={flattenData}
|
||||
initialNumToRender={5}
|
||||
maxToRenderPerBatch={5}
|
||||
style={styles.flatList}
|
||||
renderItem={renderItem}
|
||||
onEndReached={onEndReached}
|
||||
keyExtractor={keyExtractor}
|
||||
onEndReachedThreshold={0.75}
|
||||
refreshControl={refreshControl}
|
||||
ItemSeparatorComponent={ComponentSeparator}
|
||||
maintainVisibleContentPosition={{
|
||||
minIndexForVisible: 0,
|
||||
autoscrollToTopThreshold: 2
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
flatList: {
|
||||
minHeight: '100%'
|
||||
}
|
||||
})
|
||||
|
||||
export default RelationshipsList
|
66
src/screens/Tabs/Shared/Users.tsx
Normal file
66
src/screens/Tabs/Shared/Users.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
import ComponentAccount from '@components/Account'
|
||||
import ComponentSeparator from '@components/Separator'
|
||||
import { QueryKeyUsers, useUsersQuery } from '@utils/queryHooks/users'
|
||||
import React, { useCallback } from 'react'
|
||||
import { StyleSheet } from 'react-native'
|
||||
import { FlatList } from 'react-native-gesture-handler'
|
||||
import { SharedUsersProp } from './sharedScreens'
|
||||
|
||||
const TabSharedUsers = React.memo(
|
||||
({ route: { params } }: SharedUsersProp) => {
|
||||
const queryKey: QueryKeyUsers = ['Users', params]
|
||||
const {
|
||||
data,
|
||||
hasNextPage,
|
||||
fetchNextPage,
|
||||
isFetchingNextPage
|
||||
} = useUsersQuery({
|
||||
...queryKey[1],
|
||||
options: {
|
||||
getPreviousPageParam: firstPage =>
|
||||
firstPage.links?.prev && { since_id: firstPage.links.next },
|
||||
getNextPageParam: lastPage =>
|
||||
lastPage.links?.next && { max_id: lastPage.links.next }
|
||||
}
|
||||
})
|
||||
const flattenData = data?.pages
|
||||
? data.pages.flatMap(page => [...page.body])
|
||||
: []
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ item }) => <ComponentAccount account={item} origin='relationship' />,
|
||||
[]
|
||||
)
|
||||
const onEndReached = useCallback(
|
||||
() => hasNextPage && !isFetchingNextPage && fetchNextPage(),
|
||||
[hasNextPage, isFetchingNextPage]
|
||||
)
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
windowSize={11}
|
||||
data={flattenData}
|
||||
initialNumToRender={5}
|
||||
maxToRenderPerBatch={5}
|
||||
style={styles.flatList}
|
||||
renderItem={renderItem}
|
||||
onEndReached={onEndReached}
|
||||
onEndReachedThreshold={0.75}
|
||||
ItemSeparatorComponent={ComponentSeparator}
|
||||
maintainVisibleContentPosition={{
|
||||
minIndexForVisible: 0,
|
||||
autoscrollToTopThreshold: 2
|
||||
}}
|
||||
/>
|
||||
)
|
||||
},
|
||||
() => true
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
flatList: {
|
||||
minHeight: '100%'
|
||||
}
|
||||
})
|
||||
|
||||
export default TabSharedUsers
|
@ -5,9 +5,9 @@ import { StackScreenProps } from '@react-navigation/stack'
|
||||
import TabSharedAccount from '@screens/Tabs/Shared/Account'
|
||||
import TabSharedAttachments from '@screens/Tabs/Shared/Attachments'
|
||||
import TabSharedHashtag from '@screens/Tabs/Shared/Hashtag'
|
||||
import TabSharedRelationships from '@screens/Tabs/Shared/Relationships'
|
||||
import TabSharedSearch from '@screens/Tabs/Shared/Search'
|
||||
import TabSharedToot from '@screens/Tabs/Shared/Toot'
|
||||
import TabSharedUsers from '@screens/Tabs/Shared/Users'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { debounce } from 'lodash'
|
||||
@ -41,11 +41,6 @@ export type SharedHashtagProp = StackScreenProps<
|
||||
'Tab-Shared-Hashtag'
|
||||
>
|
||||
|
||||
export type SharedRelationshipsProp = StackScreenProps<
|
||||
BaseScreens,
|
||||
'Tab-Shared-Relationships'
|
||||
>
|
||||
|
||||
export type SharedSearchProp = StackScreenProps<
|
||||
BaseScreens,
|
||||
'Tab-Shared-Search'
|
||||
@ -53,6 +48,8 @@ export type SharedSearchProp = StackScreenProps<
|
||||
|
||||
export type SharedTootProp = StackScreenProps<BaseScreens, 'Tab-Shared-Toot'>
|
||||
|
||||
export type SharedUsersProp = StackScreenProps<BaseScreens, 'Tab-Shared-Users'>
|
||||
|
||||
const sharedScreens = (
|
||||
Stack: TypedNavigator<
|
||||
BaseScreens,
|
||||
@ -133,14 +130,6 @@ const sharedScreens = (
|
||||
headerLeft: () => <HeaderLeft onPress={() => navigation.goBack()} />
|
||||
})}
|
||||
/>,
|
||||
<Stack.Screen
|
||||
key='Tab-Shared-Relationships'
|
||||
name='Tab-Shared-Relationships'
|
||||
component={TabSharedRelationships}
|
||||
options={({ navigation }: SharedRelationshipsProp) => ({
|
||||
headerLeft: () => <HeaderLeft onPress={() => navigation.goBack()} />
|
||||
})}
|
||||
/>,
|
||||
<Stack.Screen
|
||||
key='Tab-Shared-Search'
|
||||
name='Tab-Shared-Search'
|
||||
@ -210,6 +199,20 @@ const sharedScreens = (
|
||||
}),
|
||||
headerLeft: () => <HeaderLeft onPress={() => navigation.goBack()} />
|
||||
})}
|
||||
/>,
|
||||
<Stack.Screen
|
||||
key='Tab-Shared-Users'
|
||||
name='Tab-Shared-Users'
|
||||
component={TabSharedUsers}
|
||||
options={({
|
||||
navigation,
|
||||
route: {
|
||||
params: { reference, type, count }
|
||||
}
|
||||
}: SharedUsersProp) => ({
|
||||
headerLeft: () => <HeaderLeft onPress={() => navigation.goBack()} />,
|
||||
headerTitle: t(`sharedUsers:heading.${reference}.${type}`, { count })
|
||||
})}
|
||||
/>
|
||||
]
|
||||
}
|
||||
|
@ -2,46 +2,46 @@ import apiInstance from '@api/instance'
|
||||
import { AxiosError } from 'axios'
|
||||
import { useInfiniteQuery, UseInfiniteQueryOptions } from 'react-query'
|
||||
|
||||
export type QueryKeyRelationships = [
|
||||
'Relationships',
|
||||
{ type: 'following' | 'followers'; id: Mastodon.Account['id'] }
|
||||
export type QueryKeyUsers = [
|
||||
'Users',
|
||||
Nav.TabSharedStackParamList['Tab-Shared-Users']
|
||||
]
|
||||
|
||||
const queryFunction = ({
|
||||
queryKey,
|
||||
pageParam
|
||||
}: {
|
||||
queryKey: QueryKeyRelationships
|
||||
queryKey: QueryKeyUsers
|
||||
pageParam?: { [key: string]: string }
|
||||
}) => {
|
||||
const { type, id } = queryKey[1]
|
||||
const { reference, id, type } = queryKey[1]
|
||||
let params: { [key: string]: string } = { ...pageParam }
|
||||
|
||||
return apiInstance<Mastodon.Account[]>({
|
||||
method: 'get',
|
||||
url: `accounts/${id}/${type}`,
|
||||
url: `${reference}/${id}/${type}`,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
const useRelationshipsQuery = <TData = Mastodon.Account[]>({
|
||||
const useUsersQuery = ({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKeyRelationships[1] & {
|
||||
}: QueryKeyUsers[1] & {
|
||||
options?: UseInfiniteQueryOptions<
|
||||
{
|
||||
body: Mastodon.Account[]
|
||||
links?: { prev?: string; next?: string }
|
||||
},
|
||||
AxiosError,
|
||||
TData
|
||||
{
|
||||
body: Mastodon.Account[]
|
||||
links?: { prev?: string; next?: string }
|
||||
}
|
||||
>
|
||||
}) => {
|
||||
const queryKey: QueryKeyRelationships = [
|
||||
'Relationships',
|
||||
{ ...queryKeyParams }
|
||||
]
|
||||
const queryKey: QueryKeyUsers = ['Users', { ...queryKeyParams }]
|
||||
return useInfiniteQuery(queryKey, queryFunction, options)
|
||||
}
|
||||
|
||||
export { useRelationshipsQuery }
|
||||
export { useUsersQuery }
|
Loading…
x
Reference in New Issue
Block a user