mirror of
https://github.com/tooot-app/app
synced 2025-02-09 16:38:41 +01:00
commit
b94af5d8bb
@ -31,7 +31,7 @@ PODS:
|
||||
- EXJSONUtils
|
||||
- EXNotifications (0.15.2):
|
||||
- ExpoModulesCore
|
||||
- Expo (45.0.2):
|
||||
- Expo (45.0.3):
|
||||
- ExpoModulesCore
|
||||
- ExpoCrypto (10.2.0):
|
||||
- ExpoModulesCore
|
||||
@ -849,7 +849,7 @@ SPEC CHECKSUMS:
|
||||
EXJSONUtils: 2a74b8f40f1523cc3f92af99c91aa78201737a77
|
||||
EXManifests: 0c6134b7b6f3236a93a778c3f44ba1cfb3f9fa3d
|
||||
EXNotifications: ea9fc56d27d1fee229489c5d8f452c7f367c237e
|
||||
Expo: 27c7466cea6c8be416d8e50a0c0faa48cf8b4d1a
|
||||
Expo: 353cd6d2154838c0c8bb1072d3ac89eb535a2ef4
|
||||
ExpoCrypto: d0d0f3e20875dc450b4ec88f0fb608da5c2c6c17
|
||||
ExpoHaptics: ad58ec96a25e57579c14a47c7d71f0de0de8656a
|
||||
ExpoImageManipulator: b55580bbc7b10099c7707949903e7176a8542ee8
|
||||
|
@ -46,7 +46,7 @@
|
||||
"@sentry/react-native": "3.4.2",
|
||||
"@sharcoux/slider": "6.0.3",
|
||||
"axios": "0.27.2",
|
||||
"expo": "45.0.2",
|
||||
"expo": "45.0.3",
|
||||
"expo-auth-session": "3.6.0",
|
||||
"expo-av": "11.2.3",
|
||||
"expo-constants": "^13.1.1",
|
||||
@ -68,7 +68,7 @@
|
||||
"expo-updates": "0.13.1",
|
||||
"expo-video-thumbnails": "6.3.0",
|
||||
"expo-web-browser": "10.2.0",
|
||||
"i18next": "21.8.0",
|
||||
"i18next": "21.8.1",
|
||||
"li": "1.3.0",
|
||||
"lodash": "4.17.21",
|
||||
"react": "17.0.2",
|
||||
@ -118,7 +118,7 @@
|
||||
"babel-plugin-module-resolver": "4.1.0",
|
||||
"babel-plugin-transform-remove-console": "6.9.4",
|
||||
"chalk": "4.1.2",
|
||||
"dotenv": "16.0.0",
|
||||
"dotenv": "16.0.1",
|
||||
"patch-package": "6.4.7",
|
||||
"postinstall-postinstall": "2.1.0",
|
||||
"react-native-clean-project": "4.0.1",
|
||||
|
@ -1,11 +1,11 @@
|
||||
import ComponentSeparator from '@components/Separator'
|
||||
import { useScrollToTop } from '@react-navigation/native'
|
||||
import { useAppDispatch } from '@root/store'
|
||||
import { QueryKeyTimeline, useTimelineQuery } from '@utils/queryHooks/timeline'
|
||||
import {
|
||||
getInstanceActive,
|
||||
updateInstanceTimelineLookback
|
||||
} from '@utils/slices/instancesSlice'
|
||||
QueryKeyTimeline,
|
||||
TimelineData,
|
||||
useTimelineQuery
|
||||
} from '@utils/queryHooks/timeline'
|
||||
import { getInstanceActive } from '@utils/slices/instancesSlice'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { RefObject, useCallback, useRef } from 'react'
|
||||
@ -14,22 +14,12 @@ import {
|
||||
FlatListProps,
|
||||
Platform,
|
||||
RefreshControl,
|
||||
StyleSheet,
|
||||
ViewabilityConfigCallbackPairs
|
||||
StyleSheet
|
||||
} from 'react-native'
|
||||
import Animated, {
|
||||
useAnimatedScrollHandler,
|
||||
useSharedValue
|
||||
} from 'react-native-reanimated'
|
||||
import { InfiniteData, useQueryClient } from 'react-query'
|
||||
import { useSelector } from 'react-redux'
|
||||
import TimelineEmpty from './Timeline/Empty'
|
||||
import TimelineFooter from './Timeline/Footer'
|
||||
import TimelineRefresh, {
|
||||
SEPARATION_Y_1,
|
||||
SEPARATION_Y_2
|
||||
} from './Timeline/Refresh'
|
||||
|
||||
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList)
|
||||
|
||||
export interface Props {
|
||||
flRef?: RefObject<FlatList<any>>
|
||||
@ -46,17 +36,19 @@ const Timeline: React.FC<Props> = ({
|
||||
queryKey,
|
||||
disableRefresh = false,
|
||||
disableInfinity = false,
|
||||
lookback,
|
||||
customProps
|
||||
}) => {
|
||||
const { colors } = useTheme()
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
const {
|
||||
data,
|
||||
refetch,
|
||||
isFetching,
|
||||
isLoading,
|
||||
fetchPreviousPage,
|
||||
fetchNextPage,
|
||||
isFetchingPreviousPage,
|
||||
isFetchingNextPage
|
||||
} = useTimelineQuery({
|
||||
...queryKey[1],
|
||||
@ -65,6 +57,12 @@ const Timeline: React.FC<Props> = ({
|
||||
ios: ['dataUpdatedAt', 'isFetching'],
|
||||
android: ['dataUpdatedAt', 'isFetching', 'isLoading']
|
||||
}),
|
||||
getPreviousPageParam: firstPage =>
|
||||
firstPage?.links?.prev && {
|
||||
min_id: firstPage.links.prev,
|
||||
// https://github.com/facebook/react-native/issues/25239
|
||||
limit: '10'
|
||||
},
|
||||
getNextPageParam: lastPage =>
|
||||
lastPage?.links?.next && {
|
||||
max_id: lastPage.links.next
|
||||
@ -93,26 +91,6 @@ const Timeline: React.FC<Props> = ({
|
||||
)
|
||||
|
||||
const flRef = useRef<FlatList>(null)
|
||||
const scrollY = useSharedValue(0)
|
||||
const fetchingType = useSharedValue<0 | 1 | 2>(0)
|
||||
|
||||
const onScroll = useAnimatedScrollHandler(
|
||||
{
|
||||
onScroll: ({ contentOffset: { y } }) => {
|
||||
scrollY.value = y
|
||||
},
|
||||
onEndDrag: ({ contentOffset: { y } }) => {
|
||||
if (!disableRefresh && !isFetching) {
|
||||
if (y <= SEPARATION_Y_2) {
|
||||
fetchingType.value = 2
|
||||
} else if (y <= SEPARATION_Y_1) {
|
||||
fetchingType.value = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
[isFetching]
|
||||
)
|
||||
|
||||
const androidRefreshControl = Platform.select({
|
||||
android: {
|
||||
@ -128,27 +106,6 @@ const Timeline: React.FC<Props> = ({
|
||||
}
|
||||
})
|
||||
|
||||
const dispatch = useAppDispatch()
|
||||
const viewabilityPairs = useRef<ViewabilityConfigCallbackPairs>([
|
||||
{
|
||||
viewabilityConfig: {
|
||||
minimumViewTime: 10,
|
||||
viewAreaCoveragePercentThreshold: 10
|
||||
},
|
||||
onViewableItemsChanged: ({ viewableItems }) => {
|
||||
lookback &&
|
||||
dispatch(
|
||||
updateInstanceTimelineLookback({
|
||||
[lookback]: {
|
||||
queryKey,
|
||||
ids: viewableItems.map(item => item.key).slice(0, 3)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
useScrollToTop(flRef)
|
||||
useSelector(getInstanceActive, (prev, next) => {
|
||||
if (prev !== next) {
|
||||
@ -158,43 +115,44 @@ const Timeline: React.FC<Props> = ({
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<TimelineRefresh
|
||||
flRef={flRef}
|
||||
queryKey={queryKey}
|
||||
scrollY={scrollY}
|
||||
fetchingType={fetchingType}
|
||||
disableRefresh={disableRefresh}
|
||||
/>
|
||||
<AnimatedFlatList
|
||||
ref={customFLRef || flRef}
|
||||
scrollEventThrottle={16}
|
||||
onScroll={onScroll}
|
||||
windowSize={7}
|
||||
data={flattenData}
|
||||
initialNumToRender={6}
|
||||
maxToRenderPerBatch={3}
|
||||
style={styles.flatList}
|
||||
onEndReached={onEndReached}
|
||||
onEndReachedThreshold={0.75}
|
||||
ListFooterComponent={
|
||||
<TimelineFooter
|
||||
queryKey={queryKey}
|
||||
disableInfinity={disableInfinity}
|
||||
/>
|
||||
<FlatList
|
||||
ref={customFLRef || flRef}
|
||||
scrollEventThrottle={16}
|
||||
windowSize={7}
|
||||
data={flattenData}
|
||||
initialNumToRender={6}
|
||||
maxToRenderPerBatch={3}
|
||||
style={styles.flatList}
|
||||
onEndReached={onEndReached}
|
||||
onEndReachedThreshold={0.75}
|
||||
ListFooterComponent={
|
||||
<TimelineFooter queryKey={queryKey} disableInfinity={disableInfinity} />
|
||||
}
|
||||
ListEmptyComponent={<TimelineEmpty queryKey={queryKey} />}
|
||||
ItemSeparatorComponent={ItemSeparatorComponent}
|
||||
maintainVisibleContentPosition={{ minIndexForVisible: 0 }}
|
||||
refreshing={isFetchingPreviousPage}
|
||||
onRefresh={() => {
|
||||
if (!disableRefresh && !isFetchingPreviousPage) {
|
||||
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(
|
||||
queryKey,
|
||||
data => {
|
||||
if (data?.pages[0] && data.pages[0].body.length === 0) {
|
||||
return {
|
||||
pages: data.pages.slice(1),
|
||||
pageParams: data.pageParams.slice(1)
|
||||
}
|
||||
} else {
|
||||
return data
|
||||
}
|
||||
}
|
||||
)
|
||||
fetchPreviousPage()
|
||||
}
|
||||
ListEmptyComponent={<TimelineEmpty queryKey={queryKey} />}
|
||||
ItemSeparatorComponent={ItemSeparatorComponent}
|
||||
maintainVisibleContentPosition={{
|
||||
minIndexForVisible: 0
|
||||
}}
|
||||
{...(lookback && {
|
||||
viewabilityConfigCallbackPairs: viewabilityPairs.current
|
||||
})}
|
||||
{...androidRefreshControl}
|
||||
{...customProps}
|
||||
/>
|
||||
</>
|
||||
}}
|
||||
{...androidRefreshControl}
|
||||
{...customProps}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,32 +0,0 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { View } from 'react-native'
|
||||
|
||||
const TimelineLookback = React.memo(
|
||||
() => {
|
||||
const { t } = useTranslation('componentTimeline')
|
||||
const { colors } = useTheme()
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
padding: StyleConstants.Spacing.S,
|
||||
backgroundColor: colors.backgroundDefault
|
||||
}}
|
||||
>
|
||||
<CustomText fontStyle='S' style={{ color: colors.primaryDefault }}>
|
||||
{t('lookback.message')}
|
||||
</CustomText>
|
||||
</View>
|
||||
)
|
||||
},
|
||||
() => true
|
||||
)
|
||||
|
||||
export default TimelineLookback
|
@ -1,328 +0,0 @@
|
||||
import haptics from '@components/haptics'
|
||||
import Icon from '@components/Icon'
|
||||
import CustomText from '@components/Text'
|
||||
import {
|
||||
QueryKeyTimeline,
|
||||
TimelineData,
|
||||
useTimelineQuery
|
||||
} from '@utils/queryHooks/timeline'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { RefObject, useCallback, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { FlatList, Platform, View } from 'react-native'
|
||||
import { Circle } from 'react-native-animated-spinkit'
|
||||
import Animated, {
|
||||
Extrapolate,
|
||||
interpolate,
|
||||
runOnJS,
|
||||
useAnimatedReaction,
|
||||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
withTiming
|
||||
} from 'react-native-reanimated'
|
||||
import { InfiniteData, useQueryClient } from 'react-query'
|
||||
|
||||
export interface Props {
|
||||
flRef: RefObject<FlatList<any>>
|
||||
queryKey: QueryKeyTimeline
|
||||
scrollY: Animated.SharedValue<number>
|
||||
fetchingType: Animated.SharedValue<0 | 1 | 2>
|
||||
disableRefresh?: boolean
|
||||
}
|
||||
|
||||
const CONTAINER_HEIGHT = StyleConstants.Spacing.M * 2.5
|
||||
export const SEPARATION_Y_1 = -(
|
||||
CONTAINER_HEIGHT / 2 +
|
||||
StyleConstants.Font.Size.S / 2
|
||||
)
|
||||
export const SEPARATION_Y_2 = -(
|
||||
CONTAINER_HEIGHT * 1.5 +
|
||||
StyleConstants.Font.Size.S / 2
|
||||
)
|
||||
|
||||
const TimelineRefresh: React.FC<Props> = ({
|
||||
flRef,
|
||||
queryKey,
|
||||
scrollY,
|
||||
fetchingType,
|
||||
disableRefresh = false
|
||||
}) => {
|
||||
if (Platform.OS !== 'ios') {
|
||||
return null
|
||||
}
|
||||
if (disableRefresh) {
|
||||
return null
|
||||
}
|
||||
|
||||
const fetchingLatestIndex = useRef(0)
|
||||
const refetchActive = useRef(false)
|
||||
|
||||
const {
|
||||
refetch,
|
||||
isFetching,
|
||||
isLoading,
|
||||
fetchPreviousPage,
|
||||
hasPreviousPage,
|
||||
isFetchingNextPage
|
||||
} = useTimelineQuery({
|
||||
...queryKey[1],
|
||||
options: {
|
||||
getPreviousPageParam: firstPage =>
|
||||
firstPage?.links?.prev && {
|
||||
min_id: firstPage.links.prev,
|
||||
// https://github.com/facebook/react-native/issues/25239#issuecomment-731100372
|
||||
limit: '5'
|
||||
},
|
||||
select: data => {
|
||||
if (refetchActive.current) {
|
||||
data.pageParams = [data.pageParams[0]]
|
||||
data.pages = [data.pages[0]]
|
||||
refetchActive.current = false
|
||||
}
|
||||
return data
|
||||
},
|
||||
onSuccess: () => {
|
||||
if (fetchingLatestIndex.current > 0) {
|
||||
if (fetchingLatestIndex.current > 5) {
|
||||
clearFirstPage()
|
||||
fetchingLatestIndex.current = 0
|
||||
} else {
|
||||
if (hasPreviousPage) {
|
||||
fetchPreviousPage()
|
||||
fetchingLatestIndex.current++
|
||||
} else {
|
||||
clearFirstPage()
|
||||
fetchingLatestIndex.current = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const { t } = useTranslation('componentTimeline')
|
||||
const { colors } = useTheme()
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
const clearFirstPage = () => {
|
||||
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(
|
||||
queryKey,
|
||||
data => {
|
||||
if (data?.pages[0] && data.pages[0].body.length === 0) {
|
||||
return {
|
||||
pages: data.pages.slice(1),
|
||||
pageParams: data.pageParams.slice(1)
|
||||
}
|
||||
} else {
|
||||
return data
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
const prepareRefetch = () => {
|
||||
refetchActive.current = true
|
||||
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(
|
||||
queryKey,
|
||||
data => {
|
||||
if (data) {
|
||||
data.pageParams = [undefined]
|
||||
const newFirstPage: TimelineData = { body: [] }
|
||||
for (let page of data.pages) {
|
||||
// @ts-ignore
|
||||
newFirstPage.body.push(...page.body)
|
||||
if (newFirstPage.body.length > 10) break
|
||||
}
|
||||
data.pages = [newFirstPage]
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
)
|
||||
}
|
||||
const callRefetch = async () => {
|
||||
await refetch()
|
||||
setTimeout(() => flRef.current?.scrollToOffset({ offset: 1 }), 50)
|
||||
}
|
||||
|
||||
const [textRight, setTextRight] = useState(0)
|
||||
const arrowY = useAnimatedStyle(() => ({
|
||||
transform: [
|
||||
{
|
||||
translateY: interpolate(
|
||||
scrollY.value,
|
||||
[0, SEPARATION_Y_1],
|
||||
[
|
||||
-CONTAINER_HEIGHT / 2 - StyleConstants.Font.Size.M / 2,
|
||||
CONTAINER_HEIGHT / 2 - StyleConstants.Font.Size.S / 2
|
||||
],
|
||||
Extrapolate.CLAMP
|
||||
)
|
||||
}
|
||||
]
|
||||
}))
|
||||
const arrowTop = useAnimatedStyle(() => ({
|
||||
marginTop:
|
||||
scrollY.value < SEPARATION_Y_2
|
||||
? withTiming(CONTAINER_HEIGHT)
|
||||
: withTiming(0)
|
||||
}))
|
||||
|
||||
const arrowStage = useSharedValue(0)
|
||||
const onLayout = useCallback(
|
||||
({ nativeEvent }) => {
|
||||
if (nativeEvent.layout.x + nativeEvent.layout.width > textRight) {
|
||||
setTextRight(nativeEvent.layout.x + nativeEvent.layout.width)
|
||||
}
|
||||
},
|
||||
[textRight]
|
||||
)
|
||||
useAnimatedReaction(
|
||||
() => {
|
||||
if (isFetching) {
|
||||
return false
|
||||
}
|
||||
switch (arrowStage.value) {
|
||||
case 0:
|
||||
if (scrollY.value < SEPARATION_Y_1) {
|
||||
arrowStage.value = 1
|
||||
return true
|
||||
}
|
||||
return false
|
||||
case 1:
|
||||
if (scrollY.value < SEPARATION_Y_2) {
|
||||
arrowStage.value = 2
|
||||
return true
|
||||
}
|
||||
if (scrollY.value > SEPARATION_Y_1) {
|
||||
arrowStage.value = 0
|
||||
return false
|
||||
}
|
||||
return false
|
||||
case 2:
|
||||
if (scrollY.value > SEPARATION_Y_2) {
|
||||
arrowStage.value = 1
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
},
|
||||
data => {
|
||||
if (data) {
|
||||
runOnJS(haptics)('Light')
|
||||
}
|
||||
},
|
||||
[isFetching]
|
||||
)
|
||||
const wrapperStartLatest = () => {
|
||||
fetchingLatestIndex.current = 1
|
||||
}
|
||||
|
||||
useAnimatedReaction(
|
||||
() => {
|
||||
return fetchingType.value
|
||||
},
|
||||
data => {
|
||||
fetchingType.value = 0
|
||||
switch (data) {
|
||||
case 1:
|
||||
runOnJS(wrapperStartLatest)()
|
||||
runOnJS(clearFirstPage)()
|
||||
runOnJS(fetchPreviousPage)()
|
||||
break
|
||||
case 2:
|
||||
runOnJS(prepareRefetch)()
|
||||
runOnJS(callRefetch)()
|
||||
break
|
||||
}
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
const headerPadding = useAnimatedStyle(
|
||||
() => ({
|
||||
paddingTop:
|
||||
fetchingLatestIndex.current !== 0 ||
|
||||
(isFetching && !isLoading && !isFetchingNextPage)
|
||||
? withTiming(StyleConstants.Spacing.M * 2.5)
|
||||
: withTiming(0)
|
||||
}),
|
||||
[fetchingLatestIndex.current, isFetching, isFetchingNextPage, isLoading]
|
||||
)
|
||||
|
||||
return (
|
||||
<Animated.View style={headerPadding}>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: CONTAINER_HEIGHT * 2,
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
{isFetching ? (
|
||||
<View style={{ height: CONTAINER_HEIGHT, justifyContent: 'center' }}>
|
||||
<Circle
|
||||
size={StyleConstants.Font.Size.L}
|
||||
color={colors.secondary}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
height: CONTAINER_HEIGHT
|
||||
}}
|
||||
>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
lineHeight: CONTAINER_HEIGHT,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
onLayout={onLayout}
|
||||
children={t('refresh.fetchPreviousPage')}
|
||||
/>
|
||||
<Animated.View
|
||||
style={[
|
||||
{
|
||||
position: 'absolute',
|
||||
left: textRight + StyleConstants.Spacing.S
|
||||
},
|
||||
arrowY,
|
||||
arrowTop
|
||||
]}
|
||||
children={
|
||||
<Icon
|
||||
name='ArrowLeft'
|
||||
size={StyleConstants.Font.Size.M}
|
||||
color={colors.primaryDefault}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
style={{ height: CONTAINER_HEIGHT, justifyContent: 'center' }}
|
||||
>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
lineHeight: CONTAINER_HEIGHT,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
onLayout={onLayout}
|
||||
children={t('refresh.refetch')}
|
||||
/>
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
</Animated.View>
|
||||
)
|
||||
}
|
||||
|
||||
export default TimelineRefresh
|
24
yarn.lock
24
yarn.lock
@ -3902,10 +3902,10 @@ domutils@^2.8.0:
|
||||
domelementtype "^2.2.0"
|
||||
domhandler "^4.2.0"
|
||||
|
||||
dotenv@16.0.0:
|
||||
version "16.0.0"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.0.tgz#c619001253be89ebb638d027b609c75c26e47411"
|
||||
integrity sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==
|
||||
dotenv@16.0.1:
|
||||
version "16.0.1"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d"
|
||||
integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==
|
||||
|
||||
ee-first@1.1.1:
|
||||
version "1.1.1"
|
||||
@ -4372,10 +4372,10 @@ expo-web-browser@10.2.0, expo-web-browser@~10.2.0:
|
||||
dependencies:
|
||||
compare-urls "^2.0.0"
|
||||
|
||||
expo@45.0.2:
|
||||
version "45.0.2"
|
||||
resolved "https://registry.yarnpkg.com/expo/-/expo-45.0.2.tgz#d773d1b6f427bcdbfcb3da26274b35b2749c632c"
|
||||
integrity sha512-WRVNTEc2ZqstGwVIxCAfJUTsmhFVAWR4vNaF4kTDEQa2J5GHbFuSQbENYrTeLldLc5Q/60HX3xfxUu8pqqdjGA==
|
||||
expo@45.0.3:
|
||||
version "45.0.3"
|
||||
resolved "https://registry.yarnpkg.com/expo/-/expo-45.0.3.tgz#7682b4dd29c6ec9de440bc151c3aa43ec392ec6e"
|
||||
integrity sha512-xI22uW8ekA5152mcN1bgXLFOFO0a2eafHr0Kgq80BvV6MyYbkZS3M8trtjo9Cs6LVMMVgyc0MWI/2cd5sGjMgg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.14.0"
|
||||
"@expo/cli" "0.1.4"
|
||||
@ -5028,10 +5028,10 @@ https-proxy-agent@^5.0.0:
|
||||
agent-base "6"
|
||||
debug "4"
|
||||
|
||||
i18next@21.8.0:
|
||||
version "21.8.0"
|
||||
resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.8.0.tgz#2ad46a882fe1b793e499c47a934bb115b7c618b3"
|
||||
integrity sha512-opNd7cQj0PDlUX15hPjtzReRxy5/Rn405YvHTBEm1nf1YJhsqYFFFhHMwuU4NEHZNlrepHk5uK+CJbFtB+KO3w==
|
||||
i18next@21.8.1:
|
||||
version "21.8.1"
|
||||
resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.8.1.tgz#44e083ade3dfe08c8099882c560d3c7294cdf679"
|
||||
integrity sha512-uulZBD5kLME7Ucz8pFwpC7jXDjq4BHkio3b6GBw1ykXNHA8rIAk1S2t6zb2Ripf9OMetMkysiDRlPlCVqjvQeg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user