mirror of
https://github.com/tooot-app/app
synced 2024-12-21 15:14:32 +01:00
parent
fb9b7486d0
commit
50332773c3
@ -1,5 +1,6 @@
|
|||||||
Enjoy toooting! This version includes following improvements and fixes:
|
Enjoy toooting! This version includes following improvements and fixes:
|
||||||
- Auto fetch remote content in conversations!
|
- Auto fetch remote content in conversations!
|
||||||
|
- Remember last read position in timeline!
|
||||||
- Allowing adding more context of reports
|
- Allowing adding more context of reports
|
||||||
- Option to disable autoplay gif
|
- Option to disable autoplay gif
|
||||||
- Hide boosts from users
|
- Hide boosts from users
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
toooting愉快!此版本包括以下改进和修复:
|
toooting愉快!此版本包括以下改进和修复:
|
||||||
- 主动获取对话的远程内容
|
- 主动获取对话的远程内容
|
||||||
|
- 自动加载上次我的关注的阅读位置
|
||||||
- 可添加举报细节
|
- 可添加举报细节
|
||||||
- 新增暂停自动播放gif动画选项
|
- 新增暂停自动播放gif动画选项
|
||||||
- 隐藏用户的转嘟
|
- 隐藏用户的转嘟
|
||||||
|
@ -7,18 +7,19 @@ import {
|
|||||||
QueryKeyTimeline,
|
QueryKeyTimeline,
|
||||||
useTimelineQuery
|
useTimelineQuery
|
||||||
} from '@utils/queryHooks/timeline'
|
} from '@utils/queryHooks/timeline'
|
||||||
|
import { setAccountStorage } from '@utils/storage/actions'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { RefObject, useEffect, useRef, useState } from 'react'
|
import React, { RefObject, useRef, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { FlatList, Platform, Text, View } from 'react-native'
|
import { FlatList, Platform, Text, View } from 'react-native'
|
||||||
import { Circle } from 'react-native-animated-spinkit'
|
|
||||||
import Animated, {
|
import Animated, {
|
||||||
Extrapolate,
|
Extrapolate,
|
||||||
interpolate,
|
interpolate,
|
||||||
runOnJS,
|
runOnJS,
|
||||||
useAnimatedReaction,
|
useAnimatedReaction,
|
||||||
useAnimatedStyle,
|
useAnimatedStyle,
|
||||||
|
useDerivedValue,
|
||||||
useSharedValue,
|
useSharedValue,
|
||||||
withTiming
|
withTiming
|
||||||
} from 'react-native-reanimated'
|
} from 'react-native-reanimated'
|
||||||
@ -26,9 +27,11 @@ import Animated, {
|
|||||||
export interface Props {
|
export interface Props {
|
||||||
flRef: RefObject<FlatList<any>>
|
flRef: RefObject<FlatList<any>>
|
||||||
queryKey: QueryKeyTimeline
|
queryKey: QueryKeyTimeline
|
||||||
|
fetchingActive: React.MutableRefObject<boolean>
|
||||||
scrollY: Animated.SharedValue<number>
|
scrollY: Animated.SharedValue<number>
|
||||||
fetchingType: Animated.SharedValue<0 | 1 | 2>
|
fetchingType: Animated.SharedValue<0 | 1 | 2>
|
||||||
disableRefresh?: boolean
|
disableRefresh?: boolean
|
||||||
|
readMarker?: 'read_marker_following'
|
||||||
}
|
}
|
||||||
|
|
||||||
const CONTAINER_HEIGHT = StyleConstants.Spacing.M * 2.5
|
const CONTAINER_HEIGHT = StyleConstants.Spacing.M * 2.5
|
||||||
@ -38,9 +41,11 @@ export const SEPARATION_Y_2 = -(CONTAINER_HEIGHT * 1.5 + StyleConstants.Font.Siz
|
|||||||
const TimelineRefresh: React.FC<Props> = ({
|
const TimelineRefresh: React.FC<Props> = ({
|
||||||
flRef,
|
flRef,
|
||||||
queryKey,
|
queryKey,
|
||||||
|
fetchingActive,
|
||||||
scrollY,
|
scrollY,
|
||||||
fetchingType,
|
fetchingType,
|
||||||
disableRefresh = false
|
disableRefresh = false,
|
||||||
|
readMarker
|
||||||
}) => {
|
}) => {
|
||||||
if (Platform.OS !== 'ios') {
|
if (Platform.OS !== 'ios') {
|
||||||
return null
|
return null
|
||||||
@ -55,7 +60,15 @@ const TimelineRefresh: React.FC<Props> = ({
|
|||||||
const prevStatusId = useRef<Mastodon.Status['id']>()
|
const prevStatusId = useRef<Mastodon.Status['id']>()
|
||||||
|
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const { refetch, isFetching } = useTimelineQuery({ ...queryKey[1] })
|
const { refetch, isRefetching } = useTimelineQuery({ ...queryKey[1] })
|
||||||
|
|
||||||
|
useDerivedValue(() => {
|
||||||
|
if (prevActive.current || isRefetching) {
|
||||||
|
fetchingActive.current = true
|
||||||
|
} else {
|
||||||
|
fetchingActive.current = false
|
||||||
|
}
|
||||||
|
}, [prevActive.current, isRefetching])
|
||||||
|
|
||||||
const { t } = useTranslation('componentTimeline')
|
const { t } = useTranslation('componentTimeline')
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
@ -83,7 +96,7 @@ const TimelineRefresh: React.FC<Props> = ({
|
|||||||
const arrowStage = useSharedValue(0)
|
const arrowStage = useSharedValue(0)
|
||||||
useAnimatedReaction(
|
useAnimatedReaction(
|
||||||
() => {
|
() => {
|
||||||
if (isFetching) {
|
if (fetchingActive.current) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
switch (arrowStage.value) {
|
switch (arrowStage.value) {
|
||||||
@ -116,7 +129,7 @@ const TimelineRefresh: React.FC<Props> = ({
|
|||||||
runOnJS(haptics)('Light')
|
runOnJS(haptics)('Light')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[isFetching]
|
[fetchingActive.current]
|
||||||
)
|
)
|
||||||
|
|
||||||
const fetchAndScrolled = useSharedValue(false)
|
const fetchAndScrolled = useSharedValue(false)
|
||||||
@ -201,11 +214,13 @@ const TimelineRefresh: React.FC<Props> = ({
|
|||||||
}
|
}
|
||||||
prevActive.current = false
|
prevActive.current = false
|
||||||
})
|
})
|
||||||
.catch(err => console.warn(err))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const runFetchLatest = async () => {
|
const runFetchLatest = async () => {
|
||||||
queryClient.invalidateQueries(queryKey)
|
queryClient.invalidateQueries(queryKey)
|
||||||
|
if (readMarker) {
|
||||||
|
setAccountStorage([{ key: readMarker, value: undefined }])
|
||||||
|
}
|
||||||
await refetch()
|
await refetch()
|
||||||
setTimeout(() => flRef.current?.scrollToOffset({ offset: 0 }), 50)
|
setTimeout(() => flRef.current?.scrollToOffset({ offset: 0 }), 50)
|
||||||
}
|
}
|
||||||
@ -239,61 +254,53 @@ const TimelineRefresh: React.FC<Props> = ({
|
|||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{prevActive.current || isFetching ? (
|
<View style={{ flex: 1, flexDirection: 'row', height: CONTAINER_HEIGHT }}>
|
||||||
<View style={{ height: CONTAINER_HEIGHT, justifyContent: 'center' }}>
|
<Text
|
||||||
<Circle size={StyleConstants.Font.Size.L} color={colors.secondary} />
|
style={{
|
||||||
</View>
|
fontSize: StyleConstants.Font.Size.S,
|
||||||
) : (
|
lineHeight: CONTAINER_HEIGHT,
|
||||||
<>
|
color: colors.primaryDefault
|
||||||
<View style={{ flex: 1, flexDirection: 'row', height: CONTAINER_HEIGHT }}>
|
}}
|
||||||
<Text
|
onLayout={({ nativeEvent }) => {
|
||||||
style={{
|
if (nativeEvent.layout.x + nativeEvent.layout.width > textRight) {
|
||||||
fontSize: StyleConstants.Font.Size.S,
|
setTextRight(nativeEvent.layout.x + nativeEvent.layout.width)
|
||||||
lineHeight: CONTAINER_HEIGHT,
|
}
|
||||||
color: colors.primaryDefault
|
}}
|
||||||
}}
|
children={t('refresh.fetchPreviousPage')}
|
||||||
onLayout={({ nativeEvent }) => {
|
/>
|
||||||
if (nativeEvent.layout.x + nativeEvent.layout.width > textRight) {
|
<Animated.View
|
||||||
setTextRight(nativeEvent.layout.x + nativeEvent.layout.width)
|
style={[
|
||||||
}
|
{
|
||||||
}}
|
position: 'absolute',
|
||||||
children={t('refresh.fetchPreviousPage')}
|
left: textRight + StyleConstants.Spacing.S
|
||||||
|
},
|
||||||
|
arrowY,
|
||||||
|
arrowTop
|
||||||
|
]}
|
||||||
|
children={
|
||||||
|
<Icon
|
||||||
|
name='ArrowLeft'
|
||||||
|
size={StyleConstants.Font.Size.M}
|
||||||
|
color={colors.primaryDefault}
|
||||||
/>
|
/>
|
||||||
<Animated.View
|
}
|
||||||
style={[
|
/>
|
||||||
{
|
</View>
|
||||||
position: 'absolute',
|
<View style={{ height: CONTAINER_HEIGHT, justifyContent: 'center' }}>
|
||||||
left: textRight + StyleConstants.Spacing.S
|
<Text
|
||||||
},
|
style={{
|
||||||
arrowY,
|
fontSize: StyleConstants.Font.Size.S,
|
||||||
arrowTop
|
lineHeight: CONTAINER_HEIGHT,
|
||||||
]}
|
color: colors.primaryDefault
|
||||||
children={
|
}}
|
||||||
<Icon
|
onLayout={({ nativeEvent }) => {
|
||||||
name='ArrowLeft'
|
if (nativeEvent.layout.x + nativeEvent.layout.width > textRight) {
|
||||||
size={StyleConstants.Font.Size.M}
|
setTextRight(nativeEvent.layout.x + nativeEvent.layout.width)
|
||||||
color={colors.primaryDefault}
|
}
|
||||||
/>
|
}}
|
||||||
}
|
children={t('refresh.refetch')}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={{ height: CONTAINER_HEIGHT, justifyContent: 'center' }}>
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
fontSize: StyleConstants.Font.Size.S,
|
|
||||||
lineHeight: CONTAINER_HEIGHT,
|
|
||||||
color: colors.primaryDefault
|
|
||||||
}}
|
|
||||||
onLayout={({ nativeEvent }) => {
|
|
||||||
if (nativeEvent.layout.x + nativeEvent.layout.width > textRight) {
|
|
||||||
setTextRight(nativeEvent.layout.x + nativeEvent.layout.width)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
children={t('refresh.refetch')}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
import ComponentSeparator from '@components/Separator'
|
import ComponentSeparator from '@components/Separator'
|
||||||
|
import TimelineDefault from '@components/Timeline/Default'
|
||||||
import { useScrollToTop } from '@react-navigation/native'
|
import { useScrollToTop } from '@react-navigation/native'
|
||||||
import { UseInfiniteQueryOptions } from '@tanstack/react-query'
|
import { UseInfiniteQueryOptions } from '@tanstack/react-query'
|
||||||
import { QueryKeyTimeline, useTimelineQuery } from '@utils/queryHooks/timeline'
|
import { QueryKeyTimeline, useTimelineQuery } from '@utils/queryHooks/timeline'
|
||||||
import { flattenPages } from '@utils/queryHooks/utils'
|
import { flattenPages } from '@utils/queryHooks/utils'
|
||||||
import { useGlobalStorageListener } from '@utils/storage/actions'
|
import {
|
||||||
|
getAccountStorage,
|
||||||
|
setAccountStorage,
|
||||||
|
useGlobalStorageListener
|
||||||
|
} from '@utils/storage/actions'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { RefObject, useRef } from 'react'
|
import React, { RefObject, useRef } from 'react'
|
||||||
@ -13,7 +18,7 @@ import TimelineEmpty from './Empty'
|
|||||||
import TimelineFooter from './Footer'
|
import TimelineFooter from './Footer'
|
||||||
import TimelineRefresh, { SEPARATION_Y_1, SEPARATION_Y_2 } from './Refresh'
|
import TimelineRefresh, { SEPARATION_Y_1, SEPARATION_Y_2 } from './Refresh'
|
||||||
|
|
||||||
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList)
|
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList<any>)
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
flRef?: RefObject<FlatList<any>>
|
flRef?: RefObject<FlatList<any>>
|
||||||
@ -24,7 +29,8 @@ export interface Props {
|
|||||||
>
|
>
|
||||||
disableRefresh?: boolean
|
disableRefresh?: boolean
|
||||||
disableInfinity?: boolean
|
disableInfinity?: boolean
|
||||||
customProps: Partial<FlatListProps<any>> & Pick<FlatListProps<any>, 'renderItem'>
|
readMarker?: 'read_marker_following'
|
||||||
|
customProps?: Partial<FlatListProps<any>>
|
||||||
}
|
}
|
||||||
|
|
||||||
const Timeline: React.FC<Props> = ({
|
const Timeline: React.FC<Props> = ({
|
||||||
@ -33,6 +39,7 @@ const Timeline: React.FC<Props> = ({
|
|||||||
queryOptions,
|
queryOptions,
|
||||||
disableRefresh = false,
|
disableRefresh = false,
|
||||||
disableInfinity = false,
|
disableInfinity = false,
|
||||||
|
readMarker = undefined,
|
||||||
customProps
|
customProps
|
||||||
}) => {
|
}) => {
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
@ -56,6 +63,7 @@ const Timeline: React.FC<Props> = ({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const flRef = useRef<FlatList>(null)
|
const flRef = useRef<FlatList>(null)
|
||||||
|
const fetchingActive = useRef<boolean>(false)
|
||||||
|
|
||||||
const scrollY = useSharedValue(0)
|
const scrollY = useSharedValue(0)
|
||||||
const fetchingType = useSharedValue<0 | 1 | 2>(0)
|
const fetchingType = useSharedValue<0 | 1 | 2>(0)
|
||||||
@ -78,6 +86,32 @@ const Timeline: React.FC<Props> = ({
|
|||||||
[isFetching]
|
[isFetching]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const viewabilityConfigCallbackPairs = useRef<
|
||||||
|
Pick<FlatListProps<any>, 'viewabilityConfigCallbackPairs'>['viewabilityConfigCallbackPairs']
|
||||||
|
>(
|
||||||
|
readMarker
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
viewabilityConfig: {
|
||||||
|
minimumViewTime: 300,
|
||||||
|
itemVisiblePercentThreshold: 80,
|
||||||
|
waitForInteraction: true
|
||||||
|
},
|
||||||
|
onViewableItemsChanged: ({ viewableItems }) => {
|
||||||
|
const marker = readMarker ? getAccountStorage.string(readMarker) : undefined
|
||||||
|
|
||||||
|
const firstItemId = viewableItems.filter(item => item.isViewable)[0]?.item.id
|
||||||
|
if (!fetchingActive.current && firstItemId && firstItemId > (marker || '0')) {
|
||||||
|
setAccountStorage([{ key: readMarker, value: firstItemId }])
|
||||||
|
} else {
|
||||||
|
// setAccountStorage([{ key: readMarker, value: '109519141378761752' }])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
: undefined
|
||||||
|
)
|
||||||
|
|
||||||
const androidRefreshControl = Platform.select({
|
const androidRefreshControl = Platform.select({
|
||||||
android: {
|
android: {
|
||||||
refreshControl: (
|
refreshControl: (
|
||||||
@ -102,9 +136,11 @@ const Timeline: React.FC<Props> = ({
|
|||||||
<TimelineRefresh
|
<TimelineRefresh
|
||||||
flRef={flRef}
|
flRef={flRef}
|
||||||
queryKey={queryKey}
|
queryKey={queryKey}
|
||||||
|
fetchingActive={fetchingActive}
|
||||||
scrollY={scrollY}
|
scrollY={scrollY}
|
||||||
fetchingType={fetchingType}
|
fetchingType={fetchingType}
|
||||||
disableRefresh={disableRefresh}
|
disableRefresh={disableRefresh}
|
||||||
|
readMarker={readMarker}
|
||||||
/>
|
/>
|
||||||
<AnimatedFlatList
|
<AnimatedFlatList
|
||||||
ref={customFLRef || flRef}
|
ref={customFLRef || flRef}
|
||||||
@ -112,6 +148,9 @@ const Timeline: React.FC<Props> = ({
|
|||||||
onScroll={onScroll}
|
onScroll={onScroll}
|
||||||
windowSize={7}
|
windowSize={7}
|
||||||
data={flattenPages(data)}
|
data={flattenPages(data)}
|
||||||
|
{...(customProps?.renderItem
|
||||||
|
? { renderItem: customProps.renderItem }
|
||||||
|
: { renderItem: ({ item }) => <TimelineDefault item={item} queryKey={queryKey} /> })}
|
||||||
initialNumToRender={6}
|
initialNumToRender={6}
|
||||||
maxToRenderPerBatch={3}
|
maxToRenderPerBatch={3}
|
||||||
onEndReached={() => !disableInfinity && !isFetchingNextPage && fetchNextPage()}
|
onEndReached={() => !disableInfinity && !isFetchingNextPage && fetchNextPage()}
|
||||||
@ -129,6 +168,7 @@ const Timeline: React.FC<Props> = ({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
viewabilityConfigCallbackPairs={viewabilityConfigCallbackPairs.current}
|
||||||
{...(!isLoading && {
|
{...(!isLoading && {
|
||||||
maintainVisibleContentPosition: {
|
maintainVisibleContentPosition: {
|
||||||
minIndexForVisible: 0
|
minIndexForVisible: 0
|
||||||
|
@ -2,7 +2,6 @@ import { HeaderRight } from '@components/Header'
|
|||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import Timeline from '@components/Timeline'
|
import Timeline from '@components/Timeline'
|
||||||
import TimelineDefault from '@components/Timeline/Default'
|
|
||||||
import { NativeStackScreenProps } from '@react-navigation/native-stack'
|
import { NativeStackScreenProps } from '@react-navigation/native-stack'
|
||||||
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||||
import { useListsQuery } from '@utils/queryHooks/lists'
|
import { useListsQuery } from '@utils/queryHooks/lists'
|
||||||
@ -178,14 +177,7 @@ const Root: React.FC<NativeStackScreenProps<TabLocalStackParamList, 'Tab-Local-R
|
|||||||
navigation.setParams({ queryKey: queryKey })
|
navigation.setParams({ queryKey: queryKey })
|
||||||
}, [mode, queryKey[1], pageLocal, lists])
|
}, [mode, queryKey[1], pageLocal, lists])
|
||||||
|
|
||||||
return (
|
return <Timeline queryKey={queryKey} readMarker='read_marker_following' />
|
||||||
<Timeline
|
|
||||||
queryKey={queryKey}
|
|
||||||
customProps={{
|
|
||||||
renderItem: ({ item }) => <TimelineDefault item={item} queryKey={queryKey} />
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Root
|
export default Root
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import Timeline from '@components/Timeline'
|
import Timeline from '@components/Timeline'
|
||||||
import TimelineDefault from '@components/Timeline/Default'
|
|
||||||
import { NativeStackScreenProps } from '@react-navigation/native-stack'
|
import { NativeStackScreenProps } from '@react-navigation/native-stack'
|
||||||
import { TabMeStackParamList } from '@utils/navigation/navigators'
|
import { TabMeStackParamList } from '@utils/navigation/navigators'
|
||||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||||
@ -13,14 +12,7 @@ const TabMeBookmarks: React.FC<NativeStackScreenProps<TabMeStackParamList, 'Tab-
|
|||||||
navigation.setParams({ queryKey: queryKey })
|
navigation.setParams({ queryKey: queryKey })
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return <Timeline queryKey={queryKey} />
|
||||||
<Timeline
|
|
||||||
queryKey={queryKey}
|
|
||||||
customProps={{
|
|
||||||
renderItem: ({ item }) => <TimelineDefault item={item} queryKey={queryKey} />
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TabMeBookmarks
|
export default TabMeBookmarks
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import Timeline from '@components/Timeline'
|
import Timeline from '@components/Timeline'
|
||||||
import TimelineDefault from '@components/Timeline/Default'
|
|
||||||
import { NativeStackScreenProps } from '@react-navigation/native-stack'
|
import { NativeStackScreenProps } from '@react-navigation/native-stack'
|
||||||
import { TabMeStackParamList } from '@utils/navigation/navigators'
|
import { TabMeStackParamList } from '@utils/navigation/navigators'
|
||||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||||
@ -13,14 +12,7 @@ const TabMeFavourites: React.FC<
|
|||||||
navigation.setParams({ queryKey: queryKey })
|
navigation.setParams({ queryKey: queryKey })
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return <Timeline queryKey={queryKey} />
|
||||||
<Timeline
|
|
||||||
queryKey={queryKey}
|
|
||||||
customProps={{
|
|
||||||
renderItem: ({ item }) => <TimelineDefault item={item} queryKey={queryKey} />
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TabMeFavourites
|
export default TabMeFavourites
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import Timeline from '@components/Timeline'
|
import Timeline from '@components/Timeline'
|
||||||
import TimelineDefault from '@components/Timeline/Default'
|
|
||||||
import { NativeStackScreenProps } from '@react-navigation/native-stack'
|
import { NativeStackScreenProps } from '@react-navigation/native-stack'
|
||||||
import { useQueryClient } from '@tanstack/react-query'
|
import { useQueryClient } from '@tanstack/react-query'
|
||||||
import { TabMeStackParamList } from '@utils/navigation/navigators'
|
import { TabMeStackParamList } from '@utils/navigation/navigators'
|
||||||
@ -74,14 +73,7 @@ const TabMeList: React.FC<NativeStackScreenProps<TabMeStackParamList, 'Tab-Me-Li
|
|||||||
navigation.setParams({ queryKey })
|
navigation.setParams({ queryKey })
|
||||||
}, [list])
|
}, [list])
|
||||||
|
|
||||||
return (
|
return <Timeline queryKey={queryKey} />
|
||||||
<Timeline
|
|
||||||
queryKey={queryKey}
|
|
||||||
customProps={{
|
|
||||||
renderItem: ({ item }) => <TimelineDefault item={item} queryKey={queryKey} />
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TabMeList
|
export default TabMeList
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { HeaderRight } from '@components/Header'
|
import { HeaderRight } from '@components/Header'
|
||||||
import Timeline from '@components/Timeline'
|
import Timeline from '@components/Timeline'
|
||||||
import TimelineDefault from '@components/Timeline/Default'
|
|
||||||
import SegmentedControl from '@react-native-community/segmented-control'
|
import SegmentedControl from '@react-native-community/segmented-control'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
import { NativeStackNavigationProp, NativeStackScreenProps } from '@react-navigation/native-stack'
|
import { NativeStackNavigationProp, NativeStackScreenProps } from '@react-navigation/native-stack'
|
||||||
@ -21,15 +20,7 @@ const Route = ({ route: { key: page } }: { route: any }) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
navigation.setParams({ queryKey })
|
navigation.setParams({ queryKey })
|
||||||
}, [])
|
}, [])
|
||||||
return (
|
return <Timeline queryKey={queryKey} disableRefresh={page === 'Trending'} />
|
||||||
<Timeline
|
|
||||||
queryKey={queryKey}
|
|
||||||
disableRefresh={page === 'Trending'}
|
|
||||||
customProps={{
|
|
||||||
renderItem: ({ item }: any) => <TimelineDefault item={item} queryKey={queryKey} />
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderScene = SceneMap({
|
const renderScene = SceneMap({
|
||||||
|
@ -2,7 +2,6 @@ import { HeaderLeft } from '@components/Header'
|
|||||||
import { ParseEmojis } from '@components/Parse'
|
import { ParseEmojis } from '@components/Parse'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import Timeline from '@components/Timeline'
|
import Timeline from '@components/Timeline'
|
||||||
import TimelineDefault from '@components/Timeline/Default'
|
|
||||||
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
|
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
|
||||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
@ -49,14 +48,7 @@ const TabSharedAttachments: React.FC<TabSharedStackScreenProps<'Tab-Shared-Attac
|
|||||||
{ page: 'Account', id: account.id, exclude_reblogs: true, only_media: true }
|
{ page: 'Account', id: account.id, exclude_reblogs: true, only_media: true }
|
||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return <Timeline queryKey={queryKey} />
|
||||||
<Timeline
|
|
||||||
queryKey={queryKey}
|
|
||||||
customProps={{
|
|
||||||
renderItem: ({ item }) => <TimelineDefault item={item} queryKey={queryKey} />
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TabSharedAttachments
|
export default TabSharedAttachments
|
||||||
|
@ -2,7 +2,6 @@ import haptics from '@components/haptics'
|
|||||||
import { HeaderLeft, HeaderRight } from '@components/Header'
|
import { HeaderLeft, HeaderRight } from '@components/Header'
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import Timeline from '@components/Timeline'
|
import Timeline from '@components/Timeline'
|
||||||
import TimelineDefault from '@components/Timeline/Default'
|
|
||||||
import { useQueryClient } from '@tanstack/react-query'
|
import { useQueryClient } from '@tanstack/react-query'
|
||||||
import { featureCheck } from '@utils/helpers/featureCheck'
|
import { featureCheck } from '@utils/helpers/featureCheck'
|
||||||
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
|
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
|
||||||
@ -82,14 +81,7 @@ const TabSharedHashtag: React.FC<TabSharedStackScreenProps<'Tab-Shared-Hashtag'>
|
|||||||
})
|
})
|
||||||
}, [canFollowTags, data?.following, isFetching])
|
}, [canFollowTags, data?.following, isFetching])
|
||||||
|
|
||||||
return (
|
return <Timeline queryKey={queryKey} />
|
||||||
<Timeline
|
|
||||||
queryKey={queryKey}
|
|
||||||
customProps={{
|
|
||||||
renderItem: ({ item }) => <TimelineDefault item={item} queryKey={queryKey} />
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TabSharedHashtag
|
export default TabSharedHashtag
|
||||||
|
@ -11,7 +11,8 @@ import apiInstance from '@utils/api/instance'
|
|||||||
import { featureCheck } from '@utils/helpers/featureCheck'
|
import { featureCheck } from '@utils/helpers/featureCheck'
|
||||||
import { useNavState } from '@utils/navigation/navigators'
|
import { useNavState } from '@utils/navigation/navigators'
|
||||||
import { queryClient } from '@utils/queryHooks'
|
import { queryClient } from '@utils/queryHooks'
|
||||||
import { getAccountStorage } from '@utils/storage/actions'
|
import { StorageAccount } from '@utils/storage/account'
|
||||||
|
import { getAccountStorage, setAccountStorage } from '@utils/storage/actions'
|
||||||
import { AxiosError } from 'axios'
|
import { AxiosError } from 'axios'
|
||||||
import { uniqBy } from 'lodash'
|
import { uniqBy } from 'lodash'
|
||||||
import { searchLocalStatus } from './search'
|
import { searchLocalStatus } from './search'
|
||||||
@ -57,7 +58,25 @@ export const queryFunctionTimeline = async ({
|
|||||||
pageParam
|
pageParam
|
||||||
}: QueryFunctionContext<QueryKeyTimeline>) => {
|
}: QueryFunctionContext<QueryKeyTimeline>) => {
|
||||||
const page = queryKey[1]
|
const page = queryKey[1]
|
||||||
let params: { [key: string]: string } = { limit: 40, ...pageParam }
|
|
||||||
|
let marker: string | undefined
|
||||||
|
if (page.page === 'Following' && !pageParam?.offset && !pageParam?.min_id && !pageParam?.max_id) {
|
||||||
|
const storedMarker = getAccountStorage.string('read_marker_following')
|
||||||
|
if (storedMarker) {
|
||||||
|
await apiInstance<Mastodon.Status[]>({
|
||||||
|
method: 'get',
|
||||||
|
url: 'timelines/home',
|
||||||
|
params: { limit: 1, min_id: storedMarker }
|
||||||
|
}).then(res => {
|
||||||
|
if (res.body.length) {
|
||||||
|
marker = storedMarker
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let params: { [key: string]: string } = marker
|
||||||
|
? { limit: 40, max_id: marker }
|
||||||
|
: { limit: 40, ...pageParam }
|
||||||
|
|
||||||
switch (page.page) {
|
switch (page.page) {
|
||||||
case 'Following':
|
case 'Following':
|
||||||
@ -431,7 +450,6 @@ const useTimelineMutation = ({
|
|||||||
updateStatusProperty(params, navigationState)
|
updateStatusProperty(params, navigationState)
|
||||||
break
|
break
|
||||||
case 'editItem':
|
case 'editItem':
|
||||||
console.log('YES!!!')
|
|
||||||
editItem(params)
|
editItem(params)
|
||||||
break
|
break
|
||||||
case 'deleteItem':
|
case 'deleteItem':
|
||||||
|
@ -24,6 +24,7 @@ export type AccountV0 = {
|
|||||||
'auth.account.domain': string // used for username
|
'auth.account.domain': string // used for username
|
||||||
'auth.account.avatar_static': string
|
'auth.account.avatar_static': string
|
||||||
version: string
|
version: string
|
||||||
|
read_marker_following?: string
|
||||||
// number
|
// number
|
||||||
// boolean
|
// boolean
|
||||||
// object
|
// object
|
||||||
|
Loading…
Reference in New Issue
Block a user