1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00

Merge branch 'main' into candidate

This commit is contained in:
xmflsct
2023-01-06 01:41:59 +01:00
23 changed files with 465 additions and 332 deletions

View File

@ -16,7 +16,7 @@ PODS:
- ExpoModulesCore - ExpoModulesCore
- EXNotifications (0.17.0): - EXNotifications (0.17.0):
- ExpoModulesCore - ExpoModulesCore
- Expo (47.0.10): - Expo (47.0.11):
- ExpoModulesCore - ExpoModulesCore
- ExpoCrypto (12.1.0): - ExpoCrypto (12.1.0):
- ExpoModulesCore - ExpoModulesCore
@ -400,6 +400,8 @@ PODS:
- React-Core - React-Core
- SDWebImage (~> 5.14.3) - SDWebImage (~> 5.14.3)
- SDWebImageWebPCoder (~> 0.9.1) - SDWebImageWebPCoder (~> 0.9.1)
- RNFlashList (1.4.0):
- React-Core
- RNGestureHandler (2.8.0): - RNGestureHandler (2.8.0):
- React-Core - React-Core
- RNReanimated (2.13.0): - RNReanimated (2.13.0):
@ -521,6 +523,7 @@ DEPENDENCIES:
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)" - "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
- RNFastImage (from `../node_modules/react-native-fast-image`) - RNFastImage (from `../node_modules/react-native-fast-image`)
- "RNFlashList (from `../node_modules/@shopify/flash-list`)"
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNReanimated (from `../node_modules/react-native-reanimated`) - RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`) - RNScreens (from `../node_modules/react-native-screens`)
@ -680,6 +683,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-clipboard/clipboard" :path: "../node_modules/@react-native-clipboard/clipboard"
RNFastImage: RNFastImage:
:path: "../node_modules/react-native-fast-image" :path: "../node_modules/react-native-fast-image"
RNFlashList:
:path: "../node_modules/@shopify/flash-list"
RNGestureHandler: RNGestureHandler:
:path: "../node_modules/react-native-gesture-handler" :path: "../node_modules/react-native-gesture-handler"
RNReanimated: RNReanimated:
@ -705,7 +710,7 @@ SPEC CHECKSUMS:
EXFileSystem: 60602b6eefa6873f97172c684b7537c9760b50d6 EXFileSystem: 60602b6eefa6873f97172c684b7537c9760b50d6
EXFont: 319606bfe48c33b5b5063fb0994afdc496befe80 EXFont: 319606bfe48c33b5b5063fb0994afdc496befe80
EXNotifications: babce2a87b7922051354fcfe7a74dd279b7e272a EXNotifications: babce2a87b7922051354fcfe7a74dd279b7e272a
Expo: a694d89d2461fdfc6b977bf489bf7d341ed03bca Expo: dedd83acfd4d70cbec6ac2f1b4433462d95c70bc
ExpoCrypto: 6eb2a5ede7d95b7359a5f0391ee0c5d2ecd144b3 ExpoCrypto: 6eb2a5ede7d95b7359a5f0391ee0c5d2ecd144b3
ExpoHaptics: 129d3f8d44c2205adcdf8db760602818463d5437 ExpoHaptics: 129d3f8d44c2205adcdf8db760602818463d5437
ExpoKeepAwake: 69b59d0a8d2b24de9f82759c39b3821fec030318 ExpoKeepAwake: 69b59d0a8d2b24de9f82759c39b3821fec030318
@ -770,6 +775,7 @@ SPEC CHECKSUMS:
RNCAsyncStorage: 8616bd5a58af409453ea4e1b246521bb76578d60 RNCAsyncStorage: 8616bd5a58af409453ea4e1b246521bb76578d60
RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd
RNFastImage: 756ab178acb5e3f11d8b0a931956fbd9da8d6e54 RNFastImage: 756ab178acb5e3f11d8b0a931956fbd9da8d6e54
RNFlashList: 399bf6a0db68f594ad2c86aaff3ea39564f39f8a
RNGestureHandler: 62232ba8f562f7dea5ba1b3383494eb5bf97a4d3 RNGestureHandler: 62232ba8f562f7dea5ba1b3383494eb5bf97a4d3
RNReanimated: ce445c233a6ff5600223484a88ad5704945d972a RNReanimated: ce445c233a6ff5600223484a88ad5704945d972a
RNScreens: 34cc502acf1b916c582c60003dc3089fa01dc66d RNScreens: 34cc502acf1b916c582c60003dc3089fa01dc66d

View File

@ -39,10 +39,11 @@
"@react-navigation/stack": "^6.3.10", "@react-navigation/stack": "^6.3.10",
"@sentry/react-native": "4.12.0", "@sentry/react-native": "4.12.0",
"@sharcoux/slider": "^6.1.1", "@sharcoux/slider": "^6.1.1",
"@tanstack/react-query": "^4.20.4", "@shopify/flash-list": "^1.4.0",
"@tanstack/react-query": "^4.20.9",
"axios": "^1.2.2", "axios": "^1.2.2",
"diff": "^5.1.0", "diff": "^5.1.0",
"expo": "^47.0.10", "expo": "^47.0.11",
"expo-auth-session": "^3.8.0", "expo-auth-session": "^3.8.0",
"expo-av": "^13.1.0", "expo-av": "^13.1.0",
"expo-constants": "^14.1.0", "expo-constants": "^14.1.0",
@ -93,7 +94,7 @@
"zeego": "^1.0.2" "zeego": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.20.7", "@babel/core": "^7.20.12",
"@babel/plugin-proposal-optional-chaining": "^7.20.7", "@babel/plugin-proposal-optional-chaining": "^7.20.7",
"@babel/preset-typescript": "^7.18.6", "@babel/preset-typescript": "^7.18.6",
"@expo/config": "^7.0.3", "@expo/config": "^7.0.3",

View File

@ -1,12 +1,13 @@
import haptics from '@components/haptics' import haptics from '@components/haptics'
import Icon from '@components/Icon' import Icon from '@components/Icon'
import { FlashList } from '@shopify/flash-list'
import { InfiniteData, useQueryClient } from '@tanstack/react-query' import { InfiniteData, useQueryClient } from '@tanstack/react-query'
import { QueryKeyTimeline, TimelineData, useTimelineQuery } from '@utils/queryHooks/timeline' import { QueryKeyTimeline, TimelineData, useTimelineQuery } from '@utils/queryHooks/timeline'
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, useCallback, useRef, useState } from 'react' import React, { RefObject, useCallback, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { FlatList, LayoutChangeEvent, Platform, StyleSheet, Text, View } from 'react-native' import { LayoutChangeEvent, Platform, StyleSheet, Text, View } from 'react-native'
import { Circle } from 'react-native-animated-spinkit' import { Circle } from 'react-native-animated-spinkit'
import Animated, { import Animated, {
Extrapolate, Extrapolate,
@ -19,7 +20,7 @@ import Animated, {
} from 'react-native-reanimated' } from 'react-native-reanimated'
export interface Props { export interface Props {
flRef: RefObject<FlatList<any>> flRef: RefObject<FlashList<any>>
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
scrollY: Animated.SharedValue<number> scrollY: Animated.SharedValue<number>
fetchingType: Animated.SharedValue<0 | 1 | 2> fetchingType: Animated.SharedValue<0 | 1 | 2>

View File

@ -169,9 +169,9 @@ const TimelineActions: React.FC = () => {
<Icon name='MessageCircle' color={iconColor} size={StyleConstants.Font.Size.L} /> <Icon name='MessageCircle' color={iconColor} size={StyleConstants.Font.Size.L} />
{status.replies_count > 0 ? ( {status.replies_count > 0 ? (
<CustomText <CustomText
fontStyle='S'
style={{ style={{
color: colors.secondary, color: colors.secondary,
fontSize: StyleConstants.Font.Size.M,
marginLeft: StyleConstants.Spacing.XS marginLeft: StyleConstants.Spacing.XS
}} }}
> >
@ -194,12 +194,12 @@ const TimelineActions: React.FC = () => {
/> />
{status.reblogs_count > 0 ? ( {status.reblogs_count > 0 ? (
<CustomText <CustomText
fontStyle='S'
style={{ style={{
color: color:
status.visibility === 'private' && !ownAccount status.visibility === 'private' && !ownAccount
? colors.disabled ? colors.disabled
: color(status.reblogged), : color(status.reblogged),
fontSize: StyleConstants.Font.Size.M,
marginLeft: StyleConstants.Spacing.XS marginLeft: StyleConstants.Spacing.XS
}} }}
> >
@ -216,12 +216,8 @@ const TimelineActions: React.FC = () => {
<Icon name='Heart' color={color(status.favourited)} size={StyleConstants.Font.Size.L} /> <Icon name='Heart' color={color(status.favourited)} size={StyleConstants.Font.Size.L} />
{status.favourites_count > 0 ? ( {status.favourites_count > 0 ? (
<CustomText <CustomText
style={{ fontStyle='S'
color: color(status.favourited), style={{ color: color(status.favourited), marginLeft: StyleConstants.Spacing.XS }}
fontSize: StyleConstants.Font.Size.M,
marginLeft: StyleConstants.Spacing.XS,
marginTop: 0
}}
> >
{status.favourites_count} {status.favourites_count}
</CustomText> </CustomText>

View File

@ -1,5 +1,6 @@
import ComponentSeparator from '@components/Separator' import ComponentSeparator from '@components/Separator'
import { useScrollToTop } from '@react-navigation/native' import { useScrollToTop } from '@react-navigation/native'
import { FlashList, FlashListProps } from '@shopify/flash-list'
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'
@ -7,16 +8,16 @@ import { 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'
import { FlatList, FlatListProps, Platform, RefreshControl } from 'react-native' import { Platform, RefreshControl } from 'react-native'
import Animated, { useAnimatedScrollHandler, useSharedValue } from 'react-native-reanimated' import Animated, { useAnimatedScrollHandler, useSharedValue } from 'react-native-reanimated'
import TimelineEmpty from './Empty' 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(FlashList)
export interface Props { export interface Props {
flRef?: RefObject<FlatList<any>> flRef?: RefObject<FlashList<any>>
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
queryOptions?: Omit< queryOptions?: Omit<
UseInfiniteQueryOptions<any>, UseInfiniteQueryOptions<any>,
@ -24,7 +25,7 @@ export interface Props {
> >
disableRefresh?: boolean disableRefresh?: boolean
disableInfinity?: boolean disableInfinity?: boolean
customProps: Partial<FlatListProps<any>> & Pick<FlatListProps<any>, 'renderItem'> customProps: Partial<FlashListProps<any>> & Pick<FlashListProps<any>, 'renderItem'>
} }
const Timeline: React.FC<Props> = ({ const Timeline: React.FC<Props> = ({
@ -55,7 +56,7 @@ const Timeline: React.FC<Props> = ({
} }
}) })
const flRef = useRef<FlatList>(null) const flRef = useRef<FlashList<any>>(null)
const scrollY = useSharedValue(0) const scrollY = useSharedValue(0)
const fetchingType = useSharedValue<0 | 1 | 2>(0) const fetchingType = useSharedValue<0 | 1 | 2>(0)
@ -92,6 +93,7 @@ const Timeline: React.FC<Props> = ({
} }
}) })
// @ts-ignore
useScrollToTop(flRef) useScrollToTop(flRef)
useGlobalStorageListener('account.active', () => useGlobalStorageListener('account.active', () =>
flRef.current?.scrollToOffset({ offset: 0, animated: false }) flRef.current?.scrollToOffset({ offset: 0, animated: false })
@ -108,12 +110,10 @@ const Timeline: React.FC<Props> = ({
/> />
<AnimatedFlatList <AnimatedFlatList
ref={customFLRef || flRef} ref={customFLRef || flRef}
estimatedItemSize={200}
scrollEventThrottle={16} scrollEventThrottle={16}
onScroll={onScroll} onScroll={onScroll}
windowSize={7}
data={flattenPages(data)} data={flattenPages(data)}
initialNumToRender={6}
maxToRenderPerBatch={3}
onEndReached={() => !disableInfinity && !isFetchingNextPage && fetchNextPage()} onEndReached={() => !disableInfinity && !isFetchingNextPage && fetchNextPage()}
onEndReachedThreshold={0.75} onEndReachedThreshold={0.75}
ListFooterComponent={ ListFooterComponent={

View File

@ -1,11 +1,12 @@
import { useNavigation } from '@react-navigation/native' import { useNavigation } from '@react-navigation/native'
import { NativeStackNavigationProp } from '@react-navigation/native-stack' import { NativeStackNavigationProp } from '@react-navigation/native-stack'
import { RootStackParamList } from '@utils/navigation/navigators' import { RootStackParamList, useNavState } from '@utils/navigation/navigators'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
const menuAt = ({ account }: { account: Mastodon.Account }): ContextMenu[][] => { const menuAt = ({ account }: { account: Mastodon.Account }): ContextMenu[][] => {
const { t } = useTranslation('componentContextMenu') const { t } = useTranslation('componentContextMenu')
const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>() const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>()
const navigationState = useNavState()
const menus: ContextMenu[][] = [] const menus: ContextMenu[][] = []
@ -17,7 +18,8 @@ const menuAt = ({ account }: { account: Mastodon.Account }): ContextMenu[][] =>
navigation.navigate('Screen-Compose', { navigation.navigate('Screen-Compose', {
type: 'conversation', type: 'conversation',
accts: [account.acct], accts: [account.acct],
visibility: 'direct' visibility: 'direct',
navigationState
}), }),
disabled: false, disabled: false,
destructive: false, destructive: false,
@ -33,7 +35,8 @@ const menuAt = ({ account }: { account: Mastodon.Account }): ContextMenu[][] =>
navigation.navigate('Screen-Compose', { navigation.navigate('Screen-Compose', {
type: 'conversation', type: 'conversation',
accts: [account.acct], accts: [account.acct],
visibility: 'public' visibility: 'public',
navigationState
}), }),
disabled: false, disabled: false,
destructive: false, destructive: false,

View File

@ -5,12 +5,13 @@ import { MAX_MEDIA_ATTACHMENTS } from '@components/mediaSelector'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { useActionSheet } from '@expo/react-native-action-sheet' import { useActionSheet } from '@expo/react-native-action-sheet'
import { useNavigation } from '@react-navigation/native' import { useNavigation } from '@react-navigation/native'
import { FlashList } from '@shopify/flash-list'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import layoutAnimation from '@utils/styles/layoutAnimation' import layoutAnimation from '@utils/styles/layoutAnimation'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React, { RefObject, useContext, useEffect, useRef } from 'react' import React, { RefObject, useContext, useEffect, useRef } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { FlatList, Pressable, StyleSheet, View } from 'react-native' import { Pressable, StyleSheet, View } from 'react-native'
import { Circle } from 'react-native-animated-spinkit' import { Circle } from 'react-native-animated-spinkit'
import FastImage from 'react-native-fast-image' import FastImage from 'react-native-fast-image'
import ComposeContext from '../../utils/createContext' import ComposeContext from '../../utils/createContext'
@ -30,7 +31,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
const { colors } = useTheme() const { colors } = useTheme()
const navigation = useNavigation<any>() const navigation = useNavigation<any>()
const flatListRef = useRef<FlatList>(null) const flatListRef = useRef<FlashList<any>>(null)
const sensitiveOnPress = () => const sensitiveOnPress = () =>
composeDispatch({ composeDispatch({
@ -222,10 +223,11 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
{t('content.root.footer.attachments.sensitive')} {t('content.root.footer.attachments.sensitive')}
</CustomText> </CustomText>
</Pressable> </Pressable>
<FlatList <FlashList
horizontal horizontal
ref={flatListRef} ref={flatListRef}
decelerationRate={0} decelerationRate={0}
estimatedItemSize={100}
pagingEnabled={false} pagingEnabled={false}
snapToAlignment='center' snapToAlignment='center'
renderItem={renderAttachment} renderItem={renderAttachment}

View File

@ -7,7 +7,7 @@ import ComposeRoot from '@screens/Compose/Root'
import { formatText } from '@screens/Compose/utils/processText' import { formatText } from '@screens/Compose/utils/processText'
import { useQueryClient } from '@tanstack/react-query' import { useQueryClient } from '@tanstack/react-query'
import { handleError } from '@utils/api/helpers' import { handleError } from '@utils/api/helpers'
import { RootStackScreenProps } from '@utils/navigation/navigators' import { RootStackScreenProps, useNavState } from '@utils/navigation/navigators'
import { useInstanceQuery } from '@utils/queryHooks/instance' import { useInstanceQuery } from '@utils/queryHooks/instance'
import { usePreferencesQuery } from '@utils/queryHooks/preferences' import { usePreferencesQuery } from '@utils/queryHooks/preferences'
import { searchLocalStatus } from '@utils/queryHooks/search' import { searchLocalStatus } from '@utils/queryHooks/search'
@ -347,13 +347,19 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
switch (params?.type) { switch (params?.type) {
case undefined: case undefined:
case 'conversation':
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: ['Timeline', { page: 'Following' }], queryKey: ['Timeline', { page: 'Following' }],
exact: false exact: false
}) })
break break
case 'conversation':
case 'edit': // doesn't work case 'edit': // doesn't work
// mutateTimeline.mutate({
// type: 'editItem',
// status: res,
// navigationState: params.navigationState
// })
// break
case 'deleteEdit': case 'deleteEdit':
case 'reply': case 'reply':
for (const navState of params.navigationState) { for (const navState of params.navigationState) {

View File

@ -3,12 +3,12 @@ import haptics from '@components/haptics'
import ComponentHashtag from '@components/Hashtag' import ComponentHashtag from '@components/Hashtag'
import { displayMessage } from '@components/Message' import { displayMessage } from '@components/Message'
import ComponentSeparator from '@components/Separator' import ComponentSeparator from '@components/Separator'
import { FlashList } from '@shopify/flash-list'
import { TabMeStackScreenProps } from '@utils/navigation/navigators' import { TabMeStackScreenProps } from '@utils/navigation/navigators'
import { useFollowedTagsQuery, useTagsMutation } from '@utils/queryHooks/tags' import { useFollowedTagsQuery, useTagsMutation } from '@utils/queryHooks/tags'
import { flattenPages } from '@utils/queryHooks/utils' import { flattenPages } from '@utils/queryHooks/utils'
import React, { useEffect } from 'react' import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { FlatList } from 'react-native-gesture-handler'
const TabMeFollowedTags: React.FC<TabMeStackScreenProps<'Tab-Me-FollowedTags'>> = ({ const TabMeFollowedTags: React.FC<TabMeStackScreenProps<'Tab-Me-FollowedTags'>> = ({
navigation navigation
@ -49,8 +49,8 @@ const TabMeFollowedTags: React.FC<TabMeStackScreenProps<'Tab-Me-FollowedTags'>>
}) })
return ( return (
<FlatList <FlashList
style={{ flex: 1 }} estimatedItemSize={70}
data={flattenData} data={flattenData}
renderItem={({ item }) => ( renderItem={({ item }) => (
<ComponentHashtag <ComponentHashtag

View File

@ -3,6 +3,7 @@ import Button from '@components/Button'
import haptics from '@components/haptics' import haptics from '@components/haptics'
import { displayMessage } from '@components/Message' import { displayMessage } from '@components/Message'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { FlashList } from '@shopify/flash-list'
import { TabMeStackScreenProps } from '@utils/navigation/navigators' import { TabMeStackScreenProps } from '@utils/navigation/navigators'
import { import {
QueryKeyListAccounts, QueryKeyListAccounts,
@ -14,7 +15,7 @@ import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react' import React from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { FlatList, View } from 'react-native' import { View } from 'react-native'
const TabMeListAccounts: React.FC<TabMeStackScreenProps<'Tab-Me-List-Accounts'>> = ({ const TabMeListAccounts: React.FC<TabMeStackScreenProps<'Tab-Me-List-Accounts'>> = ({
route: { params } route: { params }
@ -51,7 +52,7 @@ const TabMeListAccounts: React.FC<TabMeStackScreenProps<'Tab-Me-List-Accounts'>>
}) })
return ( return (
<FlatList <FlashList
data={flattenPages(data)} data={flattenPages(data)}
renderItem={({ item, index }) => ( renderItem={({ item, index }) => (
<ComponentAccount <ComponentAccount

View File

@ -1,13 +1,14 @@
import haptics from '@components/haptics' import haptics from '@components/haptics'
import { MenuRow } from '@components/Menu' import { MenuRow } from '@components/Menu'
import { LOCALES } from '@i18n/locales' import { LOCALES } from '@i18n/locales'
import { FlashList } from '@shopify/flash-list'
import { TabMeStackScreenProps } from '@utils/navigation/navigators' import { TabMeStackScreenProps } from '@utils/navigation/navigators'
import { setChannels } from '@utils/push/constants' import { setChannels } from '@utils/push/constants'
import { getGlobalStorage, useGlobalStorage } from '@utils/storage/actions' import { getGlobalStorage, useGlobalStorage } from '@utils/storage/actions'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import React from 'react' import React from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { FlatList, Platform } from 'react-native' import { Platform } from 'react-native'
const TabMeSettingsLanguage: React.FC<TabMeStackScreenProps<'Tab-Me-Settings-Language'>> = ({ const TabMeSettingsLanguage: React.FC<TabMeStackScreenProps<'Tab-Me-Settings-Language'>> = ({
navigation navigation
@ -33,7 +34,7 @@ const TabMeSettingsLanguage: React.FC<TabMeStackScreenProps<'Tab-Me-Settings-Lan
} }
return ( return (
<FlatList <FlashList
style={{ flex: 1, paddingHorizontal: StyleConstants.Spacing.Global.PagePadding }} style={{ flex: 1, paddingHorizontal: StyleConstants.Spacing.Global.PagePadding }}
data={languages} data={languages}
renderItem={({ item }) => { renderItem={({ item }) => {

View File

@ -9,7 +9,7 @@ import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React, { useContext } from 'react' import React, { useContext } from 'react'
import { Dimensions, Pressable, View } from 'react-native' import { Dimensions, Pressable, View } from 'react-native'
import { FlatList } from 'react-native-gesture-handler' import { ScrollView } from 'react-native-gesture-handler'
import AccountContext from './Context' import AccountContext from './Context'
const AccountAttachments: React.FC = () => { const AccountAttachments: React.FC = () => {
@ -39,22 +39,23 @@ const AccountAttachments: React.FC = () => {
if (!flattenData.length) return null if (!flattenData.length) return null
return ( return (
<View <ScrollView
style={{ style={{
flex: 1, flex: 1,
flexDirection: 'row',
height: width + StyleConstants.Spacing.Global.PagePadding * 2, height: width + StyleConstants.Spacing.Global.PagePadding * 2,
paddingVertical: StyleConstants.Spacing.Global.PagePadding, paddingVertical: StyleConstants.Spacing.Global.PagePadding,
borderTopWidth: 1, borderTopWidth: 1,
borderTopColor: colors.border borderTopColor: colors.border
}} }}
>
<FlatList
horizontal horizontal
data={flattenData} showsHorizontalScrollIndicator={false}
renderItem={({ item, index }) => { >
{flattenData.map((item, index) => {
if (index === DISPLAY_AMOUNT - 1) { if (index === DISPLAY_AMOUNT - 1) {
return ( return (
<Pressable <Pressable
key={index}
onPress={() => { onPress={() => {
account && navigation.push('Tab-Shared-Attachments', { account }) account && navigation.push('Tab-Shared-Attachments', { account })
}} }}
@ -82,9 +83,9 @@ const AccountAttachments: React.FC = () => {
} else { } else {
return ( return (
<GracefullyImage <GracefullyImage
key={index}
uri={{ uri={{
original: original: item.media_attachments[0]?.preview_url || item.media_attachments[0]?.url,
item.media_attachments[0]?.preview_url || item.media_attachments[0]?.url,
remote: item.media_attachments[0]?.remote_url remote: item.media_attachments[0]?.remote_url
}} }}
blurhash={ blurhash={
@ -96,10 +97,8 @@ const AccountAttachments: React.FC = () => {
/> />
) )
} }
}} })}
showsHorizontalScrollIndicator={false} </ScrollView>
/>
</View>
) )
} }

View File

@ -6,6 +6,7 @@ import CustomText from '@components/Text'
import TimelineAttachment from '@components/Timeline/Shared/Attachment' import TimelineAttachment from '@components/Timeline/Shared/Attachment'
import StatusContext from '@components/Timeline/Shared/Context' import StatusContext from '@components/Timeline/Shared/Context'
import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created' import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created'
import { FlashList } from '@shopify/flash-list'
import removeHTML from '@utils/helpers/removeHTML' import removeHTML from '@utils/helpers/removeHTML'
import { TabSharedStackScreenProps } from '@utils/navigation/navigators' import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
import { useStatusHistory } from '@utils/queryHooks/statusesHistory' import { useStatusHistory } from '@utils/queryHooks/statusesHistory'
@ -14,7 +15,7 @@ import { useTheme } from '@utils/styles/ThemeManager'
import { diffChars, diffWords } from 'diff' import { diffChars, diffWords } from 'diff'
import React, { useEffect } from 'react' import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { FlatList, View } from 'react-native' import { View } from 'react-native'
const SCRIPTS_WITHOUT_BOUNDARIES = [ const SCRIPTS_WITHOUT_BOUNDARIES = [
'my', 'my',
@ -158,8 +159,8 @@ const TabSharedHistory: React.FC<TabSharedStackScreenProps<'Tab-Shared-History'>
).length ).length
return ( return (
<FlatList <FlashList
style={{ flex: 1, minHeight: '100%' }} estimatedItemSize={100}
data={dataReversed} data={dataReversed}
renderItem={({ item, index }) => ( renderItem={({ item, index }) => (
<ContentView <ContentView

View File

@ -3,18 +3,20 @@ import Icon from '@components/Icon'
import ComponentSeparator from '@components/Separator' import ComponentSeparator from '@components/Separator'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import TimelineDefault from '@components/Timeline/Default' import TimelineDefault from '@components/Timeline/Default'
import { FlashList } from '@shopify/flash-list'
import { useQuery } from '@tanstack/react-query' import { useQuery } from '@tanstack/react-query'
import apiGeneral from '@utils/api/general' import apiGeneral from '@utils/api/general'
import apiInstance from '@utils/api/instance' import apiInstance from '@utils/api/instance'
import { urlMatcher } from '@utils/helpers/urlMatcher' import { urlMatcher } from '@utils/helpers/urlMatcher'
import { TabSharedStackScreenProps } from '@utils/navigation/navigators' import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
import { queryClient } from '@utils/queryHooks'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline' import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
import { getAccountStorage } from '@utils/storage/actions' import { getAccountStorage } 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, { useEffect, useRef, useState } from 'react' import React, { useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Alert, FlatList, Pressable, View } from 'react-native' import { Alert, Pressable, View } from 'react-native'
import { Circle } from 'react-native-animated-spinkit' import { Circle } from 'react-native-animated-spinkit'
import { Path, Svg } from 'react-native-svg' import { Path, Svg } from 'react-native-svg'
@ -65,18 +67,15 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
), ),
headerLeft: () => <HeaderLeft onPress={() => navigation.goBack()} /> headerLeft: () => <HeaderLeft onPress={() => navigation.goBack()} />
}) })
navigation.setParams({ toot, queryKey: toot._remote ? queryKey.remote : queryKey.local }) navigation.setParams({ toot, queryKey: queryKey.local })
}, [hasRemoteContent]) }, [hasRemoteContent])
const flRef = useRef<FlatList>(null) const flRef = useRef<FlashList<Mastodon.Status>>(null)
const scrolled = useRef(false) const scrolled = useRef(false)
const match = urlMatcher(toot.url || toot.uri) const match = urlMatcher(toot.url || toot.uri)
const finalData = useRef<(Mastodon.Status & { key?: string })[]>([
{ ...toot, _level: 0, key: 'cached' }
])
const highlightIndex = useRef<number>(0) const highlightIndex = useRef<number>(0)
const queryLocal = useQuery( const query = useQuery<{ pages: { body: (Mastodon.Status & { _key?: 'cached' })[] }[] }>(
queryKey.local, queryKey.local,
async () => { async () => {
const context = await apiInstance<{ const context = await apiInstance<{
@ -85,30 +84,30 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
}>({ }>({
method: 'get', method: 'get',
url: `statuses/${toot.id}/context` url: `statuses/${toot.id}/context`
}).then(res => res.body)
highlightIndex.current = context.ancestors.length
const statuses = [...context.ancestors, { ...toot }, ...context.descendants]
return {
pages: [
{
body: statuses.map((status, index) => {
if (index < highlightIndex.current || status.id === toot.id) {
return { ...status, _level: 0 }
} else {
const repliedLevel: number =
statuses.find(s => s.id === status.in_reply_to_id)?._level || 0
return { ...status, _level: repliedLevel + 1 }
}
}) })
}
const statuses: (Mastodon.Status & { _level?: number })[] = [
...context.body.ancestors,
{ ...toot },
...context.body.descendants
] ]
const highlight = context.body.ancestors.length
highlightIndex.current = highlight
for (const [index, status] of statuses.entries()) {
if (index < highlight || status.id === toot.id) {
statuses[index]._level = 0
continue
} }
const repliedLevel = statuses.find(s => s.id === status.in_reply_to_id)?._level
statuses[index]._level = (repliedLevel || 0) + 1
}
return { pages: [{ body: statuses }] }
}, },
{ {
initialData: { pages: [{ body: [{ ...toot, _level: 0, _key: 'cached' }] }] },
enabled: !toot._remote, enabled: !toot._remote,
staleTime: 0, staleTime: 0,
refetchOnMount: true, refetchOnMount: true,
@ -118,9 +117,6 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
return return
} }
if (finalData.current[0].key === 'cached') {
finalData.current = data.pages[0].body
if (!scrolled.current) { if (!scrolled.current) {
scrolled.current = true scrolled.current = true
const pointer = data.pages[0].body.findIndex(({ id }) => id === toot.id) const pointer = data.pages[0].body.findIndex(({ id }) => id === toot.id)
@ -142,9 +138,8 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
} }
} }
} }
}
) )
useQuery( useQuery<Mastodon.Status[]>(
queryKey.remote, queryKey.remote,
async () => { async () => {
const domain = match?.domain const domain = match?.domain
@ -165,30 +160,22 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
url: `api/v1/statuses/${id}/context` url: `api/v1/statuses/${id}/context`
}).then(res => res.body) }).then(res => res.body)
if (!context) { if (!context?.ancestors.length && !context?.descendants.length) {
return Promise.reject('Cannot retrieve remote context') return Promise.resolve([])
} }
const statuses: (Mastodon.Status & { _level?: number })[] = [ highlightIndex.current = context.ancestors.length
...context.ancestors,
{ ...toot },
...context.descendants
]
const highlight = context.ancestors.length const statuses = [...context.ancestors, { ...toot }, ...context.descendants]
highlightIndex.current = highlight
for (const [index, status] of statuses.entries()) { return statuses.map((status, index) => {
if (index < highlight || status.id === toot.id) { if (index < highlightIndex.current || status.id === toot.id) {
statuses[index]._level = 0 return { ...status, _level: 0 }
continue
} }
const repliedLevel = statuses.find(s => s.id === status.in_reply_to_id)?._level const repliedLevel: number = statuses.find(s => s.id === status.in_reply_to_id)?._level || 0
statuses[index]._level = (repliedLevel || 0) + 1 return { ...status, _level: repliedLevel + 1 }
} })
return { pages: [{ body: statuses }] }
}, },
{ {
enabled: enabled:
@ -197,39 +184,57 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
staleTime: 0, staleTime: 0,
refetchOnMount: true, refetchOnMount: true,
onSuccess: data => { onSuccess: data => {
if (finalData.current.length < 1 && data.pages[0].body.length < 1) { if (query.data.pages[0].body.length < 1 && data.length < 1) {
navigation.goBack() navigation.goBack()
return return
} }
if (finalData.current.length < data.pages[0].body.length) { if (query.data.pages[0].body.length < data.length) {
finalData.current = data.pages[0].body.map(remote => { queryClient.cancelQueries(queryKey.local)
const localMatch = finalData.current.find(local => local.uri === remote.uri) queryClient.setQueryData<{
pages: { body: Mastodon.Status[] }[]
}>(queryKey.local, old => {
if (!old) return old
setHasRemoteContent(true)
return {
pages: [
{
body: data.map(remote => {
const localMatch = query.data.pages[0].body.find(
local => local.uri === remote.uri
)
if (localMatch) { if (localMatch) {
delete localMatch.key delete localMatch._key
return localMatch return localMatch
} else { } else {
remote._remote = true return {
...remote,
remote.account._remote = true _remote: true,
remote.mentions = remote.mentions.map(mention => ({ ...mention, _remote: true })) account: { ...remote.account, _remote: true },
if (remote.reblog) { mentions: remote.mentions.map(mention => ({ ...mention, _remote: true })),
remote.reblog.account._remote = true ...(remote.reblog && {
remote.reblog.mentions = remote.mentions.map(mention => ({ reblog: {
...remote.reblog,
_remote: true,
account: { ...remote.reblog.account, _remote: true },
mentions: remote.reblog.mentions.map(mention => ({
...mention, ...mention,
_remote: true _remote: true
})) }))
} }
})
return remote }
}
})
}
]
} }
}) })
setHasRemoteContent(true)
} }
scrolled.current = true scrolled.current = true
const pointer = data.pages[0].body.findIndex(({ id }) => id === toot.id) const pointer = data.findIndex(({ id }) => id === toot.id)
if (pointer < 1) return if (pointer < 1) return
const length = flRef.current?.props.data?.length const length = flRef.current?.props.data?.length
if (!length) return if (!length) return
@ -254,22 +259,21 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
const ARC = StyleConstants.Avatar.XS / 4 const ARC = StyleConstants.Avatar.XS / 4
return ( return (
<FlatList <FlashList
ref={flRef} ref={flRef}
scrollEventThrottle={16} estimatedItemSize={100}
windowSize={7} data={query.data.pages?.[0].body}
data={finalData.current}
renderItem={({ item, index }) => { renderItem={({ item, index }) => {
const prev = finalData.current[index - 1]?._level || 0 const prev = query.data.pages[0].body[index - 1]?._level || 0
const curr = item._level const curr = item._level || 0
const next = finalData.current[index + 1]?._level || 0 const next = query.data.pages[0].body[index + 1]?._level || 0
return ( return (
<View <View
style={{ style={{
paddingLeft: paddingLeft:
index > highlightIndex.current index > highlightIndex.current
? Math.min(item._level - 1, MAX_LEVEL) * StyleConstants.Spacing.S ? Math.min((item._level || 0) - 1, MAX_LEVEL) * StyleConstants.Spacing.S
: undefined : undefined
}} }}
onLayout={({ onLayout={({
@ -382,8 +386,6 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
</View> </View>
) )
}} }}
initialNumToRender={6}
maxToRenderPerBatch={3}
ItemSeparatorComponent={({ leadingItem }) => { ItemSeparatorComponent={({ leadingItem }) => {
return ( return (
<> <>
@ -412,21 +414,6 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
</> </>
) )
}} }}
onScrollToIndexFailed={error => {
const offset = error.averageItemLength * error.index
flRef.current?.scrollToOffset({ offset })
try {
error.index < finalData.current.length &&
setTimeout(
() =>
flRef.current?.scrollToIndex({
index: error.index,
viewOffset: 100
}),
500
)
} catch {}
}}
ListFooterComponent={ ListFooterComponent={
<View <View
style={{ style={{
@ -436,7 +423,7 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
marginHorizontal: StyleConstants.Spacing.M marginHorizontal: StyleConstants.Spacing.M
}} }}
> >
{queryLocal.isFetching ? ( {query.isFetching ? (
<Circle size={StyleConstants.Font.Size.L} color={colors.secondary} /> <Circle size={StyleConstants.Font.Size.L} color={colors.secondary} />
) : null} ) : null}
</View> </View>

View File

@ -3,6 +3,7 @@ import { HeaderLeft } from '@components/Header'
import Icon from '@components/Icon' import Icon from '@components/Icon'
import ComponentSeparator from '@components/Separator' import ComponentSeparator from '@components/Separator'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { FlashList } from '@shopify/flash-list'
import apiInstance from '@utils/api/instance' import apiInstance from '@utils/api/instance'
import { TabSharedStackScreenProps } from '@utils/navigation/navigators' import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
import { SearchResult } from '@utils/queryHooks/search' import { SearchResult } from '@utils/queryHooks/search'
@ -14,7 +15,6 @@ import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { View } from 'react-native' import { View } from 'react-native'
import { Circle, Flow } from 'react-native-animated-spinkit' import { Circle, Flow } from 'react-native-animated-spinkit'
import { FlatList } from 'react-native-gesture-handler'
const TabSharedUsers: React.FC<TabSharedStackScreenProps<'Tab-Shared-Users'>> = ({ const TabSharedUsers: React.FC<TabSharedStackScreenProps<'Tab-Shared-Users'>> = ({
navigation, navigation,
@ -44,9 +44,9 @@ const TabSharedUsers: React.FC<TabSharedStackScreenProps<'Tab-Shared-Users'>> =
const [isSearching, setIsSearching] = useState(false) const [isSearching, setIsSearching] = useState(false)
return ( return (
<FlatList <FlashList
windowSize={7}
data={flattenPages(data)} data={flattenPages(data)}
estimatedItemSize={72}
style={{ style={{
minHeight: '100%', minHeight: '100%',
paddingVertical: StyleConstants.Spacing.Global.PagePadding paddingVertical: StyleConstants.Spacing.Global.PagePadding

View File

@ -41,6 +41,7 @@ export type RootStackParamList = {
accts: Mastodon.Account['acct'][] accts: Mastodon.Account['acct'][]
visibility: ComposeState['visibility'] visibility: ComposeState['visibility']
text?: string // For contacting tooot only text?: string // For contacting tooot only
navigationState: (QueryKeyTimeline | undefined)[]
} }
| { | {
type: 'share' type: 'share'

View File

@ -5,7 +5,7 @@ export const queryClient = new QueryClient({
queries: { queries: {
staleTime: 1000 * 60 * 5, staleTime: 1000 * 60 * 5,
retry: (failureCount, error: any) => { retry: (failureCount, error: any) => {
if (error?.status === 404) { if ([401, 404].includes(error?.status)) {
return false return false
} }
if (failureCount <= 3) { if (failureCount <= 3) {

View File

@ -16,6 +16,7 @@ import { AxiosError } from 'axios'
import { uniqBy } from 'lodash' import { uniqBy } from 'lodash'
import { searchLocalStatus } from './search' import { searchLocalStatus } from './search'
import deleteItem from './timeline/deleteItem' import deleteItem from './timeline/deleteItem'
import editItem from './timeline/editItem'
import updateStatusProperty from './timeline/updateStatusProperty' import updateStatusProperty from './timeline/updateStatusProperty'
export type QueryKeyTimeline = [ export type QueryKeyTimeline = [
@ -284,8 +285,13 @@ export type MutationVarsTimelineUpdateAccountProperty = {
} }
} }
export type MutationVarsTimelineEditItem = {
type: 'editItem'
status: Mastodon.Status
navigationState: (QueryKeyTimeline | undefined)[]
}
export type MutationVarsTimelineDeleteItem = { export type MutationVarsTimelineDeleteItem = {
// This is for deleting status and conversation
type: 'deleteItem' type: 'deleteItem'
source: 'statuses' | 'conversations' source: 'statuses' | 'conversations'
id: Mastodon.Status['id'] id: Mastodon.Status['id']
@ -300,6 +306,7 @@ export type MutationVarsTimelineDomainBlock = {
export type MutationVarsTimeline = export type MutationVarsTimeline =
| MutationVarsTimelineUpdateStatusProperty | MutationVarsTimelineUpdateStatusProperty
| MutationVarsTimelineUpdateAccountProperty | MutationVarsTimelineUpdateAccountProperty
| MutationVarsTimelineEditItem
| MutationVarsTimelineDeleteItem | MutationVarsTimelineDeleteItem
| MutationVarsTimelineDomainBlock | MutationVarsTimelineDomainBlock
@ -365,6 +372,8 @@ const mutationFunction = async (params: MutationVarsTimeline) => {
} }
}) })
} }
case 'editItem':
return { body: params.status }
case 'deleteItem': case 'deleteItem':
return apiInstance<Mastodon.Conversation>({ return apiInstance<Mastodon.Conversation>({
method: 'delete', method: 'delete',
@ -418,6 +427,10 @@ const useTimelineMutation = ({
case 'updateStatusProperty': case 'updateStatusProperty':
updateStatusProperty(params, navigationState) updateStatusProperty(params, navigationState)
break break
case 'editItem':
console.log('YES!!!')
editItem(params)
break
case 'deleteItem': case 'deleteItem':
deleteItem(params, navigationState) deleteItem(params, navigationState)
break break

View File

@ -10,20 +10,17 @@ const deleteItem = (
if (!key) continue if (!key) continue
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(key, old => { queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(key, old => {
if (old) { if (!old) return old
let foundToot: boolean = false
old.pages = old.pages.map(page => {
if (foundToot) return page
page.body = (page.body as Mastodon.Status[]).filter( return {
(item: Mastodon.Status) => item.id !== id ...old,
pages: old.pages.map(page => ({
...page,
body: (page.body as Mastodon.Status[]).filter(
status => status.id !== id && status.reblog?.id !== id
) )
}))
return page
})
} }
return old
}) })
} }
} }

View File

@ -0,0 +1,46 @@
import { InfiniteData } from '@tanstack/react-query'
import { queryClient } from '@utils/queryHooks'
import { MutationVarsTimelineEditItem, TimelineData } from '../timeline'
const editItem = ({ status, navigationState }: MutationVarsTimelineEditItem) => {
for (const key of navigationState) {
if (!key) continue
queryClient.setQueryData<InfiniteData<TimelineData>>(key, old => {
if (!old) return old
let updated: boolean = false
return {
...old,
pages: old.pages.map(page => {
if (updated) return page
if (typeof (page.body as Mastodon.Notification[])[0].type === 'string') {
;(page.body as Mastodon.Notification[]).forEach(no => {
if (no.status?.reblog?.id === status.id) {
updated = true
no.status.reblog = { ...status }
} else if (no.status?.id === status.id) {
updated = true
no.status = { ...status }
}
})
} else {
;(page.body as Mastodon.Status[]).forEach(toot => {
if (toot.reblog?.id === status.id) {
updated = true
toot.reblog = { ...status }
} else if (toot.id === status.id) {
updated = true
toot = { ...status }
}
})
}
return page
})
}
})
}
}
export default editItem

View File

@ -39,10 +39,13 @@ const updateStatusProperty = (
for (const key of navigationState) { for (const key of navigationState) {
if (!key) continue if (!key) continue
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(key, old => { queryClient.setQueryData<InfiniteData<TimelineData>>(key, old => {
if (old) { if (!old) return old
let updated: boolean = false let updated: boolean = false
old.pages = old.pages.map(page => { return {
...old,
pages: old.pages.map(page => {
if (updated) return page if (updated) return page
if (typeof (page.body as Mastodon.Conversation[])[0].unread === 'boolean') { if (typeof (page.body as Mastodon.Conversation[])[0].unread === 'boolean') {
@ -73,7 +76,6 @@ const updateStatusProperty = (
return page return page
}) })
} }
return old
}) })
} }
} }

View File

@ -9,4 +9,4 @@ export const infinitePageParams = {
} }
export const flattenPages = <T>(data: InfiniteData<PagedResponse<T[]>> | undefined): T[] | [] => export const flattenPages = <T>(data: InfiniteData<PagedResponse<T[]>> | undefined): T[] | [] =>
data?.pages.map(page => page.body).flat() || [] data?.pages.flatMap(page => page.body) || []

272
yarn.lock
View File

@ -40,7 +40,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@babel/core@npm:^7.13.16, @babel/core@npm:^7.14.0, @babel/core@npm:^7.20.7": "@babel/core@npm:^7.13.16, @babel/core@npm:^7.14.0":
version: 7.20.7 version: 7.20.7
resolution: "@babel/core@npm:7.20.7" resolution: "@babel/core@npm:7.20.7"
dependencies: dependencies:
@ -63,6 +63,29 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@babel/core@npm:^7.20.12":
version: 7.20.12
resolution: "@babel/core@npm:7.20.12"
dependencies:
"@ampproject/remapping": ^2.1.0
"@babel/code-frame": ^7.18.6
"@babel/generator": ^7.20.7
"@babel/helper-compilation-targets": ^7.20.7
"@babel/helper-module-transforms": ^7.20.11
"@babel/helpers": ^7.20.7
"@babel/parser": ^7.20.7
"@babel/template": ^7.20.7
"@babel/traverse": ^7.20.12
"@babel/types": ^7.20.7
convert-source-map: ^1.7.0
debug: ^4.1.0
gensync: ^1.0.0-beta.2
json5: ^2.2.2
semver: ^6.3.0
checksum: 62e6c3e2149a70b5c9729ef5f0d3e2e97e9dcde89fc039c8d8e3463d5d7ba9b29ee84d10faf79b61532ac1645aa62f2bd42338320617e6e3a8a4d8e2a27076e7
languageName: node
linkType: hard
"@babel/generator@npm:^7.14.0, @babel/generator@npm:^7.20.7": "@babel/generator@npm:^7.14.0, @babel/generator@npm:^7.20.7":
version: 7.20.7 version: 7.20.7
resolution: "@babel/generator@npm:7.20.7" resolution: "@babel/generator@npm:7.20.7"
@ -222,6 +245,22 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@babel/helper-module-transforms@npm:^7.20.11":
version: 7.20.11
resolution: "@babel/helper-module-transforms@npm:7.20.11"
dependencies:
"@babel/helper-environment-visitor": ^7.18.9
"@babel/helper-module-imports": ^7.18.6
"@babel/helper-simple-access": ^7.20.2
"@babel/helper-split-export-declaration": ^7.18.6
"@babel/helper-validator-identifier": ^7.19.1
"@babel/template": ^7.20.7
"@babel/traverse": ^7.20.10
"@babel/types": ^7.20.7
checksum: 29319ebafa693d48756c6ba0d871677bb0037e0da084fbe221a17c38d57093fc8aa38543c07d76e788266a937976e37ab4901971ca7f237c5ab45f524b9ecca0
languageName: node
linkType: hard
"@babel/helper-optimise-call-expression@npm:^7.18.6": "@babel/helper-optimise-call-expression@npm:^7.18.6":
version: 7.18.6 version: 7.18.6
resolution: "@babel/helper-optimise-call-expression@npm:7.18.6" resolution: "@babel/helper-optimise-call-expression@npm:7.18.6"
@ -1475,6 +1514,24 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@babel/traverse@npm:^7.20.10, @babel/traverse@npm:^7.20.12":
version: 7.20.12
resolution: "@babel/traverse@npm:7.20.12"
dependencies:
"@babel/code-frame": ^7.18.6
"@babel/generator": ^7.20.7
"@babel/helper-environment-visitor": ^7.18.9
"@babel/helper-function-name": ^7.19.0
"@babel/helper-hoist-variables": ^7.18.6
"@babel/helper-split-export-declaration": ^7.18.6
"@babel/parser": ^7.20.7
"@babel/types": ^7.20.7
debug: ^4.1.0
globals: ^11.1.0
checksum: d758b355ab4f1e87984524b67785fa23d74e8a45d2ceb8bcf4d5b2b0cd15ee160db5e68c7078808542805774ca3802e2eafb1b9638afa4cd7f9ecabd0ca7fd56
languageName: node
linkType: hard
"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.6, @babel/types@npm:^7.18.9, @babel/types@npm:^7.19.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.2, @babel/types@npm:^7.20.5, @babel/types@npm:^7.20.7, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": "@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.6, @babel/types@npm:^7.18.9, @babel/types@npm:^7.19.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.2, @babel/types@npm:^7.20.5, @babel/types@npm:^7.20.7, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3":
version: 7.20.7 version: 7.20.7
resolution: "@babel/types@npm:7.20.7" resolution: "@babel/types@npm:7.20.7"
@ -1518,15 +1575,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@expo/cli@npm:0.4.10": "@expo/cli@npm:0.4.11":
version: 0.4.10 version: 0.4.11
resolution: "@expo/cli@npm:0.4.10" resolution: "@expo/cli@npm:0.4.11"
dependencies: dependencies:
"@babel/runtime": ^7.14.0 "@babel/runtime": ^7.14.0
"@expo/code-signing-certificates": 0.0.5 "@expo/code-signing-certificates": 0.0.5
"@expo/config": ~7.0.2 "@expo/config": ~7.0.2
"@expo/config-plugins": ~5.0.3 "@expo/config-plugins": ~5.0.3
"@expo/dev-server": 0.1.123 "@expo/dev-server": 0.1.124
"@expo/devcert": ^1.0.0 "@expo/devcert": ^1.0.0
"@expo/json-file": ^8.2.35 "@expo/json-file": ^8.2.35
"@expo/metro-config": ~0.5.0 "@expo/metro-config": ~0.5.0
@ -1585,7 +1642,7 @@ __metadata:
wrap-ansi: ^7.0.0 wrap-ansi: ^7.0.0
bin: bin:
expo-internal: build/bin/cli expo-internal: build/bin/cli
checksum: e01658746d04f08f88bca522b18072959f0ef55cc332e6251499de51dfa98e9081e0b70318601a57b8a7a88c16aceaadc116718d8e3049b40668b031f78577d6 checksum: 6623f9a77444b8dffe3a73a5bb8a6ef21da1da0c0e5d60a3fd4c67545dd82bd915e22b0f7db39066e67befe3f6689dfe73f41c11d1723dbd9c19cac7a48dfaa7
languageName: node languageName: node
linkType: hard linkType: hard
@ -1667,15 +1724,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@expo/dev-server@npm:0.1.123": "@expo/dev-server@npm:0.1.124":
version: 0.1.123 version: 0.1.124
resolution: "@expo/dev-server@npm:0.1.123" resolution: "@expo/dev-server@npm:0.1.124"
dependencies: dependencies:
"@expo/bunyan": 4.0.0 "@expo/bunyan": 4.0.0
"@expo/metro-config": ~0.5.1 "@expo/metro-config": ~0.5.1
"@expo/osascript": 2.0.33 "@expo/osascript": 2.0.33
"@expo/spawn-async": ^1.5.0 "@expo/spawn-async": ^1.5.0
body-parser: 1.19.0 body-parser: ^1.20.1
chalk: ^4.0.0 chalk: ^4.0.0
connect: ^3.7.0 connect: ^3.7.0
fs-extra: 9.0.0 fs-extra: 9.0.0
@ -1687,7 +1744,7 @@ __metadata:
semver: 7.3.2 semver: 7.3.2
serialize-error: 6.0.0 serialize-error: 6.0.0
temp-dir: ^2.0.0 temp-dir: ^2.0.0
checksum: 55e158f192435d8779d3b6e8b56b0b15586f9ae7775a98d3edb03bae28fe82d37e2b1aa3c1972c672b15a5baf2787066bab378352b1f8314051bfdf383077b6c checksum: ebb632a3f2f1605976255d22388943249757a15533831fbd08ee0b4e4c7b96d8553f74ae05fa414c4e67a01840ee2217866f40bc86947f4a0098c7750acd1f31
languageName: node languageName: node
linkType: hard linkType: hard
@ -3252,6 +3309,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@shopify/flash-list@npm:^1.4.0":
version: 1.4.0
resolution: "@shopify/flash-list@npm:1.4.0"
dependencies:
recyclerlistview: 4.2.0
tslib: 2.4.0
peerDependencies:
"@babel/runtime": "*"
react: "*"
react-native: "*"
checksum: c6510b0d6ae6404fe92ede0c918ba184bc2b27ed39c627eebad16a6542792cb34e750e2004e1a9ce165f9d729f1af0555cba1e4c224fd52bfd2a600fdc9e2a65
languageName: node
linkType: hard
"@sideway/address@npm:^4.1.3": "@sideway/address@npm:^4.1.3":
version: 4.1.4 version: 4.1.4
resolution: "@sideway/address@npm:4.1.4" resolution: "@sideway/address@npm:4.1.4"
@ -3275,18 +3346,18 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@tanstack/query-core@npm:4.20.4": "@tanstack/query-core@npm:4.20.9":
version: 4.20.4 version: 4.20.9
resolution: "@tanstack/query-core@npm:4.20.4" resolution: "@tanstack/query-core@npm:4.20.9"
checksum: bdb652296e4093d8cb042a67b9c035bc0a756e09a3b12aeb070068b07adc1c71174c2e6108f2a8c3322a26cb73ba57f431326aa0b813c81621674b9cc208cd93 checksum: 679551353e6d5adcae771bc78b64959a6ecf4f85c1f74952b38b18a7425374cf84dc2e461cf6048be206d8bbac265468d36231f7f9d0b6689504a0e069dd5ac6
languageName: node languageName: node
linkType: hard linkType: hard
"@tanstack/react-query@npm:^4.20.4": "@tanstack/react-query@npm:^4.20.9":
version: 4.20.4 version: 4.20.9
resolution: "@tanstack/react-query@npm:4.20.4" resolution: "@tanstack/react-query@npm:4.20.9"
dependencies: dependencies:
"@tanstack/query-core": 4.20.4 "@tanstack/query-core": 4.20.9
use-sync-external-store: ^1.2.0 use-sync-external-store: ^1.2.0
peerDependencies: peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0
@ -3297,7 +3368,7 @@ __metadata:
optional: true optional: true
react-native: react-native:
optional: true optional: true
checksum: ba9e2f175c58bde592c0ad14285f289585474763f8d68072d651fa75263a3a7f75eead5b62aa3140db133b95468498bc58817d07513f6f857be2bd8031b491da checksum: 4fc953d774c5c0f7f332f014dfb2fb9865387ae6e849fdf551e2ad70f07d55fbdbc4c6afb27a1f90bce3a2348bd1adf67ab78a4bc2cdf8d3e5ff90128730b467
languageName: node languageName: node
linkType: hard linkType: hard
@ -4109,21 +4180,23 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"body-parser@npm:1.19.0": "body-parser@npm:^1.20.1":
version: 1.19.0 version: 1.20.1
resolution: "body-parser@npm:1.19.0" resolution: "body-parser@npm:1.20.1"
dependencies: dependencies:
bytes: 3.1.0 bytes: 3.1.2
content-type: ~1.0.4 content-type: ~1.0.4
debug: 2.6.9 debug: 2.6.9
depd: ~1.1.2 depd: 2.0.0
http-errors: 1.7.2 destroy: 1.2.0
http-errors: 2.0.0
iconv-lite: 0.4.24 iconv-lite: 0.4.24
on-finished: ~2.3.0 on-finished: 2.4.1
qs: 6.7.0 qs: 6.11.0
raw-body: 2.4.0 raw-body: 2.5.1
type-is: ~1.6.17 type-is: ~1.6.18
checksum: 490231b4c89bbd43112762f7ba8e5342c174a6c9f64284a3b0fcabf63277e332f8316765596f1e5b15e4f3a6cf0422e005f4bb3149ed3a224bb025b7a36b9ac1 unpipe: 1.0.0
checksum: f1050dbac3bede6a78f0b87947a8d548ce43f91ccc718a50dd774f3c81f2d8b04693e52acf62659fad23101827dd318da1fb1363444ff9a8482b886a3e4a5266
languageName: node languageName: node
linkType: hard linkType: hard
@ -4285,10 +4358,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"bytes@npm:3.1.0": "bytes@npm:3.1.2":
version: 3.1.0 version: 3.1.2
resolution: "bytes@npm:3.1.0" resolution: "bytes@npm:3.1.2"
checksum: 7c3b21c5d9d44ed455460d5d36a31abc6fa2ce3807964ba60a4b03fd44454c8cf07bb0585af83bfde1c5cc2ea4bbe5897bc3d18cd15e0acf25a3615a35aba2df checksum: e4bcd3948d289c5127591fbedf10c0b639ccbf00243504e4e127374a15c3bc8eed0d28d4aaab08ff6f1cf2abc0cce6ba3085ed32f4f90e82a5683ce0014e1b6e
languageName: node languageName: node
linkType: hard linkType: hard
@ -5135,7 +5208,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"depd@npm:^1.1.2, depd@npm:~1.1.2": "depd@npm:^1.1.2":
version: 1.1.2 version: 1.1.2
resolution: "depd@npm:1.1.2" resolution: "depd@npm:1.1.2"
checksum: 6b406620d269619852885ce15965272b829df6f409724415e0002c8632ab6a8c0a08ec1f0bd2add05dc7bd7507606f7e2cc034fa24224ab829580040b835ecd9 checksum: 6b406620d269619852885ce15965272b829df6f409724415e0002c8632ab6a8c0a08ec1f0bd2add05dc7bd7507606f7e2cc034fa24224ab829580040b835ecd9
@ -5732,12 +5805,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"expo@npm:^47.0.10": "expo@npm:^47.0.11":
version: 47.0.10 version: 47.0.11
resolution: "expo@npm:47.0.10" resolution: "expo@npm:47.0.11"
dependencies: dependencies:
"@babel/runtime": ^7.14.0 "@babel/runtime": ^7.14.0
"@expo/cli": 0.4.10 "@expo/cli": 0.4.11
"@expo/config": 7.0.3 "@expo/config": 7.0.3
"@expo/config-plugins": 5.0.4 "@expo/config-plugins": 5.0.4
"@expo/vector-icons": ^13.0.0 "@expo/vector-icons": ^13.0.0
@ -5764,7 +5837,7 @@ __metadata:
optional: true optional: true
bin: bin:
expo: bin/cli.js expo: bin/cli.js
checksum: 6bde0837544b83941588e53fcfab35a3ca6bdb49695f71d923158dd1145d627fc9f312e64cf1c8bf0ad7a5083652fd352a490e2994d85b2ad384744dddcd19bf checksum: 5e470d7b0c94ddade3f77e4e5038f025635f432f1e56a9e541455f5e71b5f4919c7c756639b5bf31ff6b877ad254a77290efe0305d48712e5406c76f3c8b7e77
languageName: node languageName: node
linkType: hard linkType: hard
@ -6558,19 +6631,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"http-errors@npm:1.7.2":
version: 1.7.2
resolution: "http-errors@npm:1.7.2"
dependencies:
depd: ~1.1.2
inherits: 2.0.3
setprototypeof: 1.1.1
statuses: ">= 1.5.0 < 2"
toidentifier: 1.0.0
checksum: 5534b0ae08e77f5a45a2380f500e781f6580c4ff75b816cb1f09f99a290b57e78a518be6d866db1b48cca6b052c09da2c75fc91fb16a2fe3da3c44d9acbb9972
languageName: node
linkType: hard
"http-errors@npm:2.0.0": "http-errors@npm:2.0.0":
version: 2.0.0 version: 2.0.0
resolution: "http-errors@npm:2.0.0" resolution: "http-errors@npm:2.0.0"
@ -6719,13 +6779,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"inherits@npm:2.0.3":
version: 2.0.3
resolution: "inherits@npm:2.0.3"
checksum: 78cb8d7d850d20a5e9a7f3620db31483aa00ad5f722ce03a55b110e5a723539b3716a3b463e2b96ce3fe286f33afc7c131fa2f91407528ba80cea98a7545d4c0
languageName: node
linkType: hard
"ini@npm:~1.3.0": "ini@npm:~1.3.0":
version: 1.3.8 version: 1.3.8
resolution: "ini@npm:1.3.8" resolution: "ini@npm:1.3.8"
@ -7438,6 +7491,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"json5@npm:^2.2.2":
version: 2.2.3
resolution: "json5@npm:2.2.3"
bin:
json5: lib/cli.js
checksum: 2a7436a93393830bce797d4626275152e37e877b265e94ca69c99e3d20c2b9dab021279146a39cdb700e71b2dd32a4cebd1514cd57cee102b1af906ce5040349
languageName: node
linkType: hard
"jsonfile@npm:^2.1.0": "jsonfile@npm:^2.1.0":
version: 2.4.0 version: 2.4.0
resolution: "jsonfile@npm:2.4.0" resolution: "jsonfile@npm:2.4.0"
@ -7595,7 +7657,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"lodash.debounce@npm:^4.0.8": "lodash.debounce@npm:4.0.8, lodash.debounce@npm:^4.0.8":
version: 4.0.8 version: 4.0.8
resolution: "lodash.debounce@npm:4.0.8" resolution: "lodash.debounce@npm:4.0.8"
checksum: a3f527d22c548f43ae31c861ada88b2637eb48ac6aa3eb56e82d44917971b8aa96fbb37aa60efea674dc4ee8c42074f90f7b1f772e9db375435f6c83a19b3bc6 checksum: a3f527d22c548f43ae31c861ada88b2637eb48ac6aa3eb56e82d44917971b8aa96fbb37aa60efea674dc4ee8c42074f90f7b1f772e9db375435f6c83a19b3bc6
@ -9203,7 +9265,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"prop-types@npm:*, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": "prop-types@npm:*, prop-types@npm:15.8.1, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1":
version: 15.8.1 version: 15.8.1
resolution: "prop-types@npm:15.8.1" resolution: "prop-types@npm:15.8.1"
dependencies: dependencies:
@ -9240,10 +9302,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"qs@npm:6.7.0": "qs@npm:6.11.0, qs@npm:^6.9.1":
version: 6.7.0 version: 6.11.0
resolution: "qs@npm:6.7.0" resolution: "qs@npm:6.11.0"
checksum: dfd5f6adef50e36e908cfa70a6233871b5afe66fbaca37ecc1da352ba29eb2151a3797991948f158bb37fccde51bd57845cb619a8035287bfc24e4591172c347 dependencies:
side-channel: ^1.0.4
checksum: 6e1f29dd5385f7488ec74ac7b6c92f4d09a90408882d0c208414a34dd33badc1a621019d4c799a3df15ab9b1d0292f97c1dd71dc7c045e69f81a8064e5af7297
languageName: node languageName: node
linkType: hard linkType: hard
@ -9254,15 +9318,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"qs@npm:^6.9.1":
version: 6.11.0
resolution: "qs@npm:6.11.0"
dependencies:
side-channel: ^1.0.4
checksum: 6e1f29dd5385f7488ec74ac7b6c92f4d09a90408882d0c208414a34dd33badc1a621019d4c799a3df15ab9b1d0292f97c1dd71dc7c045e69f81a8064e5af7297
languageName: node
linkType: hard
"query-string@npm:^5.0.1": "query-string@npm:^5.0.1":
version: 5.1.1 version: 5.1.1
resolution: "query-string@npm:5.1.1" resolution: "query-string@npm:5.1.1"
@ -9318,15 +9373,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"raw-body@npm:2.4.0": "raw-body@npm:2.5.1":
version: 2.4.0 version: 2.5.1
resolution: "raw-body@npm:2.4.0" resolution: "raw-body@npm:2.5.1"
dependencies: dependencies:
bytes: 3.1.0 bytes: 3.1.2
http-errors: 1.7.2 http-errors: 2.0.0
iconv-lite: 0.4.24 iconv-lite: 0.4.24
unpipe: 1.0.0 unpipe: 1.0.0
checksum: 6343906939e018c6e633a34a938a5d6d1e93ffcfa48646e00207d53b418e941953b521473950c079347220944dc75ba10e7b3c08bf97e3ac72c7624882db09bb checksum: 5362adff1575d691bb3f75998803a0ffed8c64eabeaa06e54b4ada25a0cd1b2ae7f4f5ec46565d1bec337e08b5ac90c76eaa0758de6f72a633f025d754dec29e
languageName: node languageName: node
linkType: hard linkType: hard
@ -9922,6 +9977,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"recyclerlistview@npm:4.2.0":
version: 4.2.0
resolution: "recyclerlistview@npm:4.2.0"
dependencies:
lodash.debounce: 4.0.8
prop-types: 15.8.1
ts-object-utils: 0.0.5
peerDependencies:
react: ">= 15.2.1"
react-native: ">= 0.30.0"
checksum: 6cba6a99fb487067c509112b94e3d4d3905d782bbcb7af2cffbd57c601a4650d670e4eee5fec18d195d58ff6ec01a47288c5510379a2f37da3c5fc0a58860441
languageName: node
linkType: hard
"regenerate-unicode-properties@npm:^10.1.0": "regenerate-unicode-properties@npm:^10.1.0":
version: 10.1.0 version: 10.1.0
resolution: "regenerate-unicode-properties@npm:10.1.0" resolution: "regenerate-unicode-properties@npm:10.1.0"
@ -10439,13 +10508,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"setprototypeof@npm:1.1.1":
version: 1.1.1
resolution: "setprototypeof@npm:1.1.1"
checksum: a8bee29c1c64c245d460ce53f7460af8cbd0aceac68d66e5215153992cc8b3a7a123416353e0c642060e85cc5fd4241c92d1190eec97eda0dcb97436e8fcca3b
languageName: node
linkType: hard
"setprototypeof@npm:1.2.0": "setprototypeof@npm:1.2.0":
version: 1.2.0 version: 1.2.0
resolution: "setprototypeof@npm:1.2.0" resolution: "setprototypeof@npm:1.2.0"
@ -10778,7 +10840,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"statuses@npm:>= 1.5.0 < 2, statuses@npm:~1.5.0": "statuses@npm:~1.5.0":
version: 1.5.0 version: 1.5.0
resolution: "statuses@npm:1.5.0" resolution: "statuses@npm:1.5.0"
checksum: c469b9519de16a4bb19600205cffb39ee471a5f17b82589757ca7bd40a8d92ebb6ed9f98b5a540c5d302ccbc78f15dc03cc0280dd6e00df1335568a5d5758a5c checksum: c469b9519de16a4bb19600205cffb39ee471a5f17b82589757ca7bd40a8d92ebb6ed9f98b5a540c5d302ccbc78f15dc03cc0280dd6e00df1335568a5d5758a5c
@ -11195,13 +11257,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"toidentifier@npm:1.0.0":
version: 1.0.0
resolution: "toidentifier@npm:1.0.0"
checksum: 199e6bfca1531d49b3506cff02353d53ec987c9ee10ee272ca6484ed97f1fc10fb77c6c009079ca16d5c5be4a10378178c3cacdb41ce9ec954c3297c74c6053e
languageName: node
linkType: hard
"toidentifier@npm:1.0.1": "toidentifier@npm:1.0.1":
version: 1.0.1 version: 1.0.1
resolution: "toidentifier@npm:1.0.1" resolution: "toidentifier@npm:1.0.1"
@ -11213,7 +11268,7 @@ __metadata:
version: 0.0.0-use.local version: 0.0.0-use.local
resolution: "tooot@workspace:." resolution: "tooot@workspace:."
dependencies: dependencies:
"@babel/core": ^7.20.7 "@babel/core": ^7.20.12
"@babel/plugin-proposal-optional-chaining": ^7.20.7 "@babel/plugin-proposal-optional-chaining": ^7.20.7
"@babel/preset-typescript": ^7.18.6 "@babel/preset-typescript": ^7.18.6
"@expo/config": ^7.0.3 "@expo/config": ^7.0.3
@ -11239,7 +11294,8 @@ __metadata:
"@react-navigation/stack": ^6.3.10 "@react-navigation/stack": ^6.3.10
"@sentry/react-native": 4.12.0 "@sentry/react-native": 4.12.0
"@sharcoux/slider": ^6.1.1 "@sharcoux/slider": ^6.1.1
"@tanstack/react-query": ^4.20.4 "@shopify/flash-list": ^1.4.0
"@tanstack/react-query": ^4.20.9
"@types/diff": ^5.0.2 "@types/diff": ^5.0.2
"@types/linkify-it": ^3.0.2 "@types/linkify-it": ^3.0.2
"@types/lodash": ^4.14.191 "@types/lodash": ^4.14.191
@ -11254,7 +11310,7 @@ __metadata:
chalk: ^4.1.2 chalk: ^4.1.2
diff: ^5.1.0 diff: ^5.1.0
dotenv: ^16.0.3 dotenv: ^16.0.3
expo: ^47.0.10 expo: ^47.0.11
expo-auth-session: ^3.8.0 expo-auth-session: ^3.8.0
expo-av: ^13.1.0 expo-av: ^13.1.0
expo-constants: ^14.1.0 expo-constants: ^14.1.0
@ -11329,6 +11385,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ts-object-utils@npm:0.0.5":
version: 0.0.5
resolution: "ts-object-utils@npm:0.0.5"
checksum: 83c48fbdaba392fb2c01cea53b267ed5538d2bb44fc6c3eecc10bcfabc1780bfa6ec8569b52bbf0140d9b521d9049d5f15884e12286918244d463d854dbc73cb
languageName: node
linkType: hard
"tslib@npm:2.4.0":
version: 2.4.0
resolution: "tslib@npm:2.4.0"
checksum: 8c4aa6a3c5a754bf76aefc38026134180c053b7bd2f81338cb5e5ebf96fefa0f417bff221592bf801077f5bf990562f6264fecbc42cd3309b33872cb6fc3b113
languageName: node
linkType: hard
"tslib@npm:^1.9.0, tslib@npm:^1.9.3": "tslib@npm:^1.9.0, tslib@npm:^1.9.3":
version: 1.14.1 version: 1.14.1
resolution: "tslib@npm:1.14.1" resolution: "tslib@npm:1.14.1"
@ -11378,7 +11448,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"type-is@npm:~1.6.17": "type-is@npm:~1.6.18":
version: 1.6.18 version: 1.6.18
resolution: "type-is@npm:1.6.18" resolution: "type-is@npm:1.6.18"
dependencies: dependencies: