This commit is contained in:
Zhiyuan Zheng 2021-01-27 00:35:34 +01:00
parent 9ae1612a96
commit 41bfeed56f
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
24 changed files with 558 additions and 457 deletions

3
.gitignore vendored
View File

@ -14,4 +14,5 @@ web-build/
.DS_Store
.env
coverage/
coverage/
builds/

19
App.tsx
View File

@ -1,26 +1,27 @@
import { ActionSheetProvider } from '@expo/react-native-action-sheet'
import i18n from '@root/i18n/i18n'
import Index from '@root/Index'
import dev from '@root/startup/dev'
import sentry from '@root/startup/sentry'
import log from '@root/startup/log'
import audio from '@root/startup/audio'
import onlineStatus from '@root/startup/onlineStatus'
import dev from '@root/startup/dev'
import log from '@root/startup/log'
import netInfo from '@root/startup/netInfo'
import onlineStatus from '@root/startup/onlineStatus'
import sentry from '@root/startup/sentry'
import { persistor, store } from '@root/store'
import { getSettingsLanguage } from '@utils/slices/settingsSlice'
import ThemeManager from '@utils/styles/ThemeManager'
import * as SplashScreen from 'expo-splash-screen'
import React, { useCallback, useEffect, useState } from 'react'
import { LogBox, Platform } from 'react-native'
import { enableScreens } from 'react-native-screens'
import { QueryClient, QueryClientProvider } from 'react-query'
import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/integration/react'
import { LogBox, Platform } from 'react-native'
if (Platform.OS === 'android') {
LogBox.ignoreLogs(['Setting a timer for a long period of time'])
}
dev()
sentry()
audio()
@ -68,12 +69,12 @@ const App: React.FC = () => {
}
}, [])
const main = useCallback(
const children = useCallback(
bootstrapped => {
log('log', 'App', 'bootstrapped')
if (bootstrapped) {
log('log', 'App', 'loading actual app :)')
require('@root/i18n/i18n')
i18n.changeLanguage(getSettingsLanguage(store.getState()))
return (
<ActionSheetProvider>
<ThemeManager>
@ -94,7 +95,7 @@ const App: React.FC = () => {
<PersistGate
persistor={persistor}
onBeforeLift={onBeforeLift}
children={main}
children={children}
/>
</Provider>
</QueryClientProvider>

View File

@ -37,7 +37,7 @@ export default (): ExpoConfig => ({
]
},
ios: {
buildNumber: '2',
buildNumber: '4',
config: { usesNonExemptEncryption: false },
bundleIdentifier: 'com.xmflsct.app.tooot',
googleServicesFile: './configs/GoogleService-Info.plist',
@ -50,7 +50,7 @@ export default (): ExpoConfig => ({
zh: './src/i18n/zh-Hans/system.json'
},
android: {
versionCode: 2,
versionCode: 4,
package: 'com.xmflsct.app.tooot',
googleServicesFile: './configs/google-services.json',
permissions: ['CAMERA', 'VIBRATE']

18
build/android.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
if [ $# -ne 1 ]; then
echo "Arguments incorrect. Use 'xxx'"
exit 1
fi
JAVA_HOME=`/usr/libexec/java_home -v 1.8.0` \
EXPO_USERNAME='xmflsct' \
EXPO_PASSWORD=',8d_AJ1HmYJo8lbve&QoB40t3ImGdF)Dd' \
EXPO_ANDROID_KEYSTORE_PASSWORD="9c54265087704801ba5d3d88809110a1" \
EXPO_ANDROID_KEY_PASSWORD="748bb2e11529497dad7831c409175b94" \
turtle build:android \
--release-channel $1 \
--type app-bundle \
--keystore-path ./tooot.jks \
--keystore-alias "QHhtZmxzY3QvdG9vb3Q=" \
--build-dir ./builds

View File

@ -6,7 +6,8 @@
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject",
"test": "jest --watchAll"
"test": "jest --watchAll",
"release": "./publish/publish.sh"
},
"dependencies": {
"@expo/react-native-action-sheet": "^3.8.0",

8
publish/publish.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
if [ $# -ne 1 ]; then
echo "Arguments incorrect"
exit 1
fi
expo publish --release-channel=$1

View File

@ -1,7 +1,6 @@
import { useNavigation } from '@react-navigation/native'
import { InstanceLocal, localAddInstance } from '@utils/slices/instancesSlice'
import * as AuthSession from 'expo-auth-session'
import Constants from 'expo-constants'
import React, { useEffect } from 'react'
import { useQueryClient } from 'react-query'
import { useDispatch } from 'react-redux'
@ -16,17 +15,9 @@ export interface Props {
const InstanceAuth = React.memo(
({ instanceDomain, instanceUri, appData, goBack }: Props) => {
let redirectUri: string
switch (Constants.manifest.releaseChannel) {
case 'production':
case 'staging':
case 'testing':
redirectUri = 'tooot://expo-auth-session'
break
default:
redirectUri = 'exp://127.0.0.1:19000'
break
}
const redirectUri = AuthSession.makeRedirectUri({ useProxy: false })
const navigation = useNavigation()
const queryClient = useQueryClient()
const dispatch = useDispatch()

View File

@ -23,11 +23,11 @@ const Names: React.FC<{ accounts: Mastodon.Account[] }> = ({ accounts }) => {
return (
<Text numberOfLines={1}>
<Text style={[styles.namesLeading, { color: theme.secondary }]}>
{t('shared.header.conversation.withAccounts')}{' '}
{t('shared.header.conversation.withAccounts')}
</Text>
{accounts.map((account, index) => (
<Text key={account.id} numberOfLines={1}>
{index !== 0 ? ', ' : undefined}
{index !== 0 ? t('common:separator') : undefined}
<ParseEmojis
content={account.display_name || account.username}
emojis={account.emojis}

View File

@ -15,5 +15,6 @@ export default {
error: {
message: '{{function}} failed, please retry'
}
}
},
separator: ', '
}

View File

@ -1,15 +1,12 @@
import { store } from '@root/store'
import { getSettingsLanguage, supportedLngs } from '@utils/slices/settingsSlice'
import i18next from 'i18next'
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'
import en from '@root/i18n/en/_all'
import zh_Hans from '@root/i18n/zh-Hans/_all'
i18next.use(initReactI18next).init({
lng: getSettingsLanguage(store.getState()),
i18n.use(initReactI18next).init({
lng: 'en',
fallbackLng: 'en',
supportedLngs: supportedLngs,
ns: ['common'],
defaultNS: 'common',
@ -23,7 +20,11 @@ i18next.use(initReactI18next).init({
interpolation: {
escapeValue: false
}
},
react: {
useSuspense: false
},
debug: true
})
export default i18next
export default i18n

View File

@ -15,5 +15,6 @@ export default {
error: {
message: '{{function}}失败,请重试'
}
}
},
separator: ''
}

View File

@ -24,7 +24,7 @@ const ScreenLocal = React.memo(
}, [])
return (
<Stack.Navigator
<Stack.Navigator
screenOptions={{
headerLeft: () => null,
headerRight: () => (

View File

@ -1,310 +1,23 @@
import analytics from '@components/analytics'
import Button from '@components/Button'
import haptics from '@components/haptics'
import Icon from '@components/Icon'
import { MenuContainer, MenuRow } from '@components/Menu'
import { useActionSheet } from '@expo/react-native-action-sheet'
import { persistor } from '@root/store'
import {
getLocalActiveIndex,
getLocalInstances
} from '@utils/slices/instancesSlice'
import {
changeAnalytics,
changeBrowser,
changeLanguage,
changeTheme,
getSettingsAnalytics,
getSettingsBrowser,
getSettingsLanguage,
getSettingsTheme
} from '@utils/slices/settingsSlice'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import Constants from 'expo-constants'
import * as Linking from 'expo-linking'
import * as StoreReview from 'expo-store-review'
import prettyBytes from 'pretty-bytes'
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { StyleSheet, Text } from 'react-native'
import { CacheManager } from 'react-native-expo-image-cache'
import React from 'react'
import { ScrollView } from 'react-native-gesture-handler'
import { useDispatch, useSelector } from 'react-redux'
const DevDebug: React.FC = () => {
const { showActionSheetWithOptions } = useActionSheet()
const localActiveIndex = useSelector(getLocalActiveIndex)
const localInstances = useSelector(getLocalInstances)
return (
<MenuContainer>
<MenuRow
title={'Local active index'}
content={typeof localActiveIndex + ' - ' + localActiveIndex}
onPress={() => {}}
/>
<MenuRow
title={'Saved local instances'}
content={localInstances.length.toString()}
iconBack='ChevronRight'
onPress={() =>
showActionSheetWithOptions(
{
options: localInstances
.map(instance => {
return instance.url + ': ' + instance.account.id
})
.concat(['Cancel']),
cancelButtonIndex: localInstances.length
},
buttonIndex => {}
)
}
/>
<Button
type='text'
content={'Purge secure storage'}
style={{
marginHorizontal: StyleConstants.Spacing.Global.PagePadding * 2,
marginBottom: StyleConstants.Spacing.Global.PagePadding * 2
}}
destructive
onPress={() => persistor.purge()}
/>
<Button
type='text'
content={'Crash test'}
style={{
marginHorizontal: StyleConstants.Spacing.Global.PagePadding * 2,
marginBottom: StyleConstants.Spacing.Global.PagePadding * 2
}}
destructive
onPress={() => {
throw new Error('Testing crash')
}}
/>
</MenuContainer>
)
}
import SettingsAnalytics from './Settings/Analytics'
import SettingsApp from './Settings/App'
import SettingsDev from './Settings/Dev'
import SettingsTooot from './Settings/Tooot'
const ScreenMeSettings: React.FC = () => {
const { showActionSheetWithOptions } = useActionSheet()
const { t, i18n } = useTranslation('meSettings')
const { setTheme, theme } = useTheme()
const settingsLanguage = useSelector(getSettingsLanguage)
const settingsTheme = useSelector(getSettingsTheme)
const settingsBrowser = useSelector(getSettingsBrowser)
const settingsAnalytics = useSelector(getSettingsAnalytics)
const dispatch = useDispatch()
const [cacheSize, setCacheSize] = useState<number>()
useEffect(() => {
CacheManager.getCacheSize().then(size => setCacheSize(size))
}, [])
return (
<ScrollView>
<MenuContainer>
<MenuRow
title={t('content.language.heading')}
content={t(`content.language.options.${settingsLanguage}`)}
iconBack='ChevronRight'
onPress={() => {
const availableLanguages = Object.keys(
i18n.services.resourceStore.data
)
const options = availableLanguages
.map(language => t(`content.language.options.${language}`))
.concat(t('content.language.options.cancel'))
<SettingsApp />
<SettingsTooot />
<SettingsAnalytics />
showActionSheetWithOptions(
{
title: t('content.language.heading'),
options,
cancelButtonIndex: options.length - 1
},
buttonIndex => {
if (buttonIndex < options.length) {
analytics('settings_language_press', {
current: i18n.language,
new: availableLanguages[buttonIndex]
})
haptics('Success')
// @ts-ignore
dispatch(changeLanguage(availableLanguages[buttonIndex]))
i18n.changeLanguage(availableLanguages[buttonIndex])
}
}
)
}}
/>
<MenuRow
title={t('content.theme.heading')}
content={t(`content.theme.options.${settingsTheme}`)}
iconBack='ChevronRight'
onPress={() =>
showActionSheetWithOptions(
{
title: t('content.theme.heading'),
options: [
t('content.theme.options.auto'),
t('content.theme.options.light'),
t('content.theme.options.dark'),
t('content.theme.options.cancel')
],
cancelButtonIndex: 3
},
buttonIndex => {
switch (buttonIndex) {
case 0:
analytics('settings_appearance_press', {
current: settingsTheme,
new: 'auto'
})
haptics('Success')
dispatch(changeTheme('auto'))
break
case 1:
analytics('settings_appearance_press', {
current: settingsTheme,
new: 'light'
})
haptics('Success')
dispatch(changeTheme('light'))
setTheme('light')
break
case 2:
analytics('settings_appearance_press', {
current: settingsTheme,
new: 'dark'
})
haptics('Success')
dispatch(changeTheme('dark'))
setTheme('dark')
break
}
}
)
}
/>
<MenuRow
title={t('content.browser.heading')}
content={t(`content.browser.options.${settingsBrowser}`)}
iconBack='ChevronRight'
onPress={() =>
showActionSheetWithOptions(
{
title: t('content.browser.heading'),
options: [
t('content.browser.options.internal'),
t('content.browser.options.external'),
t('content.browser.options.cancel')
],
cancelButtonIndex: 2
},
buttonIndex => {
switch (buttonIndex) {
case 0:
analytics('settings_browser_press', {
current: settingsBrowser,
new: 'internal'
})
haptics('Success')
dispatch(changeBrowser('internal'))
break
case 1:
analytics('settings_browser_press', {
current: settingsBrowser,
new: 'external'
})
haptics('Success')
dispatch(changeBrowser('external'))
break
}
}
)
}
/>
</MenuContainer>
<MenuContainer>
<MenuRow
title={t('content.cache.heading')}
content={
cacheSize ? prettyBytes(cacheSize) : t('content.cache.empty')
}
iconBack='ChevronRight'
onPress={async () => {
analytics('settings_cache_press', {
size: cacheSize ? prettyBytes(cacheSize) : 'empty'
})
await CacheManager.clearCache()
haptics('Success')
setCacheSize(0)
}}
/>
</MenuContainer>
<MenuContainer>
<MenuRow
title={t('content.support.heading')}
content={
<Icon
name='Heart'
size={StyleConstants.Font.Size.M}
color={theme.red}
/>
}
iconBack='ChevronRight'
onPress={() => {
analytics('settings_support_press')
Linking.openURL('https://www.patreon.com/xmflsct')
}}
/>
<MenuRow
title={t('content.review.heading')}
content={
<Icon
name='Star'
size={StyleConstants.Font.Size.M}
color='#FF9500'
/>
}
iconBack='ChevronRight'
onPress={() => {
analytics('settings_review_press')
StoreReview.isAvailableAsync().then(() =>
StoreReview.requestReview()
)
}}
/>
</MenuContainer>
<MenuContainer>
<MenuRow
title={t('content.analytics.heading')}
description={t('content.analytics.description')}
switchValue={settingsAnalytics}
switchOnValueChange={() =>
dispatch(changeAnalytics(!settingsAnalytics))
}
/>
<Text style={[styles.version, { color: theme.secondary }]}>
{t('content.version', { version: Constants.manifest.version })}
</Text>
</MenuContainer>
{__DEV__ || Constants.manifest.releaseChannel === 'testing' ? (
<DevDebug />
{__DEV__ || Constants.manifest.releaseChannel?.includes('testing') ? (
<SettingsDev />
) : null}
</ScrollView>
)
}
const styles = StyleSheet.create({
version: {
textAlign: 'center',
...StyleConstants.FontStyle.S,
marginTop: StyleConstants.Spacing.M
}
})
export default ScreenMeSettings

View File

@ -0,0 +1,46 @@
import { MenuContainer, MenuRow } from '@components/Menu'
import {
changeAnalytics,
getSettingsAnalytics
} from '@utils/slices/settingsSlice'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import Constants from 'expo-constants'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { StyleSheet, Text } from 'react-native'
import { useDispatch, useSelector } from 'react-redux'
const SettingsAnalytics: React.FC = () => {
const dispatch = useDispatch()
const { theme } = useTheme()
const { t } = useTranslation('meSettings')
const settingsAnalytics = useSelector(getSettingsAnalytics)
return (
<MenuContainer>
<MenuRow
title={t('content.analytics.heading')}
description={t('content.analytics.description')}
switchValue={settingsAnalytics}
switchOnValueChange={() =>
dispatch(changeAnalytics(!settingsAnalytics))
}
/>
<Text style={[styles.version, { color: theme.secondary }]}>
{t('content.version', { version: Constants.manifest.version })}
</Text>
</MenuContainer>
)
}
const styles = StyleSheet.create({
version: {
textAlign: 'center',
...StyleConstants.FontStyle.S,
marginTop: StyleConstants.Spacing.M
}
})
export default SettingsAnalytics

View File

@ -0,0 +1,175 @@
import analytics from '@components/analytics'
import haptics from '@components/haptics'
import { MenuContainer, MenuRow } from '@components/Menu'
import { useActionSheet } from '@expo/react-native-action-sheet'
import i18n from '@root/i18n/i18n'
import {
changeBrowser,
changeLanguage,
changeTheme,
getSettingsLanguage,
getSettingsTheme,
getSettingsBrowser
} from '@utils/slices/settingsSlice'
import { useTheme } from '@utils/styles/ThemeManager'
import prettyBytes from 'pretty-bytes'
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { CacheManager } from 'react-native-expo-image-cache'
import { useDispatch, useSelector } from 'react-redux'
const SettingsApp: React.FC = () => {
const dispatch = useDispatch()
const { showActionSheetWithOptions } = useActionSheet()
const { setTheme } = useTheme()
const { t } = useTranslation('meSettings')
const settingsLanguage = useSelector(getSettingsLanguage)
const settingsTheme = useSelector(getSettingsTheme)
const settingsBrowser = useSelector(getSettingsBrowser)
const [cacheSize, setCacheSize] = useState<number>()
useEffect(() => {
CacheManager.getCacheSize().then(size => setCacheSize(size))
}, [])
return (
<MenuContainer>
<MenuRow
title={t('content.language.heading')}
content={t(`content.language.options.${settingsLanguage}`)}
iconBack='ChevronRight'
onPress={() => {
const availableLanguages = Object.keys(
i18n.services.resourceStore.data
)
const options = availableLanguages
.map(language => t(`content.language.options.${language}`))
.concat(t('content.language.options.cancel'))
showActionSheetWithOptions(
{
title: t('content.language.heading'),
options,
cancelButtonIndex: options.length - 1
},
buttonIndex => {
if (buttonIndex < options.length) {
analytics('settings_language_press', {
current: i18n.language,
new: availableLanguages[buttonIndex]
})
haptics('Success')
// @ts-ignore
dispatch(changeLanguage(availableLanguages[buttonIndex]))
i18n.changeLanguage(availableLanguages[buttonIndex])
}
}
)
}}
/>
<MenuRow
title={t('content.theme.heading')}
content={t(`content.theme.options.${settingsTheme}`)}
iconBack='ChevronRight'
onPress={() =>
showActionSheetWithOptions(
{
title: t('content.theme.heading'),
options: [
t('content.theme.options.auto'),
t('content.theme.options.light'),
t('content.theme.options.dark'),
t('content.theme.options.cancel')
],
cancelButtonIndex: 3
},
buttonIndex => {
switch (buttonIndex) {
case 0:
analytics('settings_appearance_press', {
current: settingsTheme,
new: 'auto'
})
haptics('Success')
dispatch(changeTheme('auto'))
break
case 1:
analytics('settings_appearance_press', {
current: settingsTheme,
new: 'light'
})
haptics('Success')
dispatch(changeTheme('light'))
setTheme('light')
break
case 2:
analytics('settings_appearance_press', {
current: settingsTheme,
new: 'dark'
})
haptics('Success')
dispatch(changeTheme('dark'))
setTheme('dark')
break
}
}
)
}
/>
<MenuRow
title={t('content.browser.heading')}
content={t(`content.browser.options.${settingsBrowser}`)}
iconBack='ChevronRight'
onPress={() =>
showActionSheetWithOptions(
{
title: t('content.browser.heading'),
options: [
t('content.browser.options.internal'),
t('content.browser.options.external'),
t('content.browser.options.cancel')
],
cancelButtonIndex: 2
},
buttonIndex => {
switch (buttonIndex) {
case 0:
analytics('settings_browser_press', {
current: settingsBrowser,
new: 'internal'
})
haptics('Success')
dispatch(changeBrowser('internal'))
break
case 1:
analytics('settings_browser_press', {
current: settingsBrowser,
new: 'external'
})
haptics('Success')
dispatch(changeBrowser('external'))
break
}
}
)
}
/>
<MenuRow
title={t('content.cache.heading')}
content={cacheSize ? prettyBytes(cacheSize) : t('content.cache.empty')}
iconBack='ChevronRight'
onPress={async () => {
analytics('settings_cache_press', {
size: cacheSize ? prettyBytes(cacheSize) : 'empty'
})
await CacheManager.clearCache()
haptics('Success')
setCacheSize(0)
}}
/>
</MenuContainer>
)
}
export default SettingsApp

View File

@ -0,0 +1,69 @@
import Button from '@components/Button'
import { MenuContainer, MenuRow } from '@components/Menu'
import { useActionSheet } from '@expo/react-native-action-sheet'
import { persistor } from '@root/store'
import {
getLocalActiveIndex,
getLocalInstances
} from '@utils/slices/instancesSlice'
import { StyleConstants } from '@utils/styles/constants'
import React from 'react'
import { useSelector } from 'react-redux'
const SettingsDev: React.FC = () => {
const { showActionSheetWithOptions } = useActionSheet()
const localActiveIndex = useSelector(getLocalActiveIndex)
const localInstances = useSelector(getLocalInstances)
return (
<MenuContainer>
<MenuRow
title={'Local active index'}
content={typeof localActiveIndex + ' - ' + localActiveIndex}
onPress={() => {}}
/>
<MenuRow
title={'Saved local instances'}
content={localInstances.length.toString()}
iconBack='ChevronRight'
onPress={() =>
showActionSheetWithOptions(
{
options: localInstances
.map(instance => {
return instance.url + ': ' + instance.account.id
})
.concat(['Cancel']),
cancelButtonIndex: localInstances.length
},
buttonIndex => {}
)
}
/>
<Button
type='text'
content={'Purge secure storage'}
style={{
marginHorizontal: StyleConstants.Spacing.Global.PagePadding * 2,
marginBottom: StyleConstants.Spacing.Global.PagePadding * 2
}}
destructive
onPress={() => persistor.purge()}
/>
<Button
type='text'
content={'Crash test'}
style={{
marginHorizontal: StyleConstants.Spacing.Global.PagePadding * 2,
marginBottom: StyleConstants.Spacing.Global.PagePadding * 2
}}
destructive
onPress={() => {
throw new Error('Testing crash')
}}
/>
</MenuContainer>
)
}
export default SettingsDev

View File

@ -0,0 +1,84 @@
import analytics from '@components/analytics'
import Icon from '@components/Icon'
import { MenuContainer, MenuRow } from '@components/Menu'
import { useNavigation } from '@react-navigation/native'
import { useSearchQuery } from '@utils/queryHooks/search'
import { getLocalActiveIndex } from '@utils/slices/instancesSlice'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import * as Linking from 'expo-linking'
import * as StoreReview from 'expo-store-review'
import * as WebBrowser from 'expo-web-browser'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
const SettingsTooot: React.FC = () => {
const localActiveIndex = useSelector(getLocalActiveIndex)
const navigation = useNavigation()
const { theme } = useTheme()
const { t } = useTranslation('meSettings')
const { isLoading, data } = useSearchQuery({
term: '@tooot@xmflsct.com',
options: { enabled: localActiveIndex !== null }
})
return (
<MenuContainer>
<MenuRow
title={t('content.support.heading')}
content={
<Icon
name='Heart'
size={StyleConstants.Font.Size.M}
color={theme.red}
/>
}
iconBack='ChevronRight'
onPress={() => {
analytics('settings_support_press')
Linking.openURL('https://www.patreon.com/xmflsct')
}}
/>
<MenuRow
title={t('content.review.heading')}
content={
<Icon name='Star' size={StyleConstants.Font.Size.M} color='#FF9500' />
}
iconBack='ChevronRight'
onPress={() => {
analytics('settings_review_press')
StoreReview.isAvailableAsync().then(() => StoreReview.requestReview())
}}
/>
<MenuRow
title={'联系 tooot'}
loading={isLoading}
content={
<Icon
name='Mail'
size={StyleConstants.Font.Size.M}
color={theme.secondary}
/>
}
iconBack='ChevronRight'
onPress={() => {
const foundAccounts = data?.accounts.filter(
account => account.acct === 'tooot@xmflsct.com'
)
if (foundAccounts?.length === 1) {
navigation.navigate('Screen-Shared-Compose', {
type: 'conversation',
accts: [foundAccounts[0].acct]
})
} else {
WebBrowser.openBrowserAsync('https://social.xmflsct.com/@tooot')
}
}}
/>
</MenuContainer>
)
}
export default SettingsTooot

View File

@ -128,7 +128,7 @@ const AccountAttachments = React.memo(
<Animated.View style={[styles.base, styleContainer]}>
<FlatList
horizontal
data={flattenData.splice(0, 4)}
data={flattenData.filter(status => !status.sensitive).splice(0, 4)}
renderItem={renderItem}
showsHorizontalScrollIndicator={false}
/>

View File

@ -1,5 +1,4 @@
import ComponentAccount from '@components/Account'
import analytics from '@components/analytics'
import ComponentHashtag from '@components/Hashtag'
import ComponentSeparator from '@components/Separator'
import TimelineDefault from '@components/Timelines/Timeline/Default'

View File

@ -12,7 +12,7 @@ import { persistReducer, persistStore } from 'redux-persist'
const secureStorage = createSecureStore()
const prefix = 'mastodon_app'
const prefix = 'ajieorjaiojwoirjwe'
const contextsPersistConfig = {
key: 'contexts',

View File

@ -1,22 +1,12 @@
import client from '@api/client'
import { AxiosError } from 'axios'
import Constants from 'expo-constants'
import * as AuthSession from 'expo-auth-session'
import { useQuery, UseQueryOptions } from 'react-query'
export type QueryKey = ['Apps', { instanceDomain?: string }]
const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
let redirectUri: string
switch (Constants.manifest.releaseChannel) {
case 'production':
case 'staging':
case 'testing':
redirectUri = 'tooot://expo-auth-session'
break
default:
redirectUri = 'exp://127.0.0.1:19000'
break
}
const redirectUri = AuthSession.makeRedirectUri({ useProxy: false })
const { instanceDomain } = queryKey[1]

View File

@ -38,7 +38,7 @@ const contextsSlice = createSlice({
initialState: contextsInitialState as ContextsState,
reducers: {
updateStoreReview: (state, action: PayloadAction<1>) => {
if (Constants.manifest.releaseChannel === 'production') {
if (Constants.manifest.releaseChannel?.includes('production')) {
state.storeReview.current = state.storeReview.current + action.payload
if (state.storeReview.current === state.storeReview.context) {
StoreReview.isAvailableAsync().then(() => StoreReview.requestReview())

View File

@ -3,8 +3,6 @@ import { RootState } from '@root/store'
import * as Analytics from 'expo-firebase-analytics'
import * as Localization from 'expo-localization'
export const supportedLngs = ['zh-Hans', 'en']
export type SettingsState = {
language: 'zh-Hans' | 'en'
theme: 'light' | 'dark' | 'auto'

212
yarn.lock
View File

@ -1056,15 +1056,15 @@
"@babel/preset-env" "^7.4.4"
"@babel/preset-typescript" "^7.3.3"
"@expo/config-plugins@1.0.14":
version "1.0.14"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-1.0.14.tgz#95ad608f64fa6c66a352197d7552880d7cc9fa06"
integrity sha512-BSzRsBIKWS6bw32eOI/wJCZqschzWSgnvGZGYgDPPtHf/zMariLnnsqoIC5HT4CO1B+sqkSMstK1gy8YVtJABQ==
"@expo/config-plugins@1.0.16":
version "1.0.16"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-1.0.16.tgz#e6fa84fc5f7d4354c34f2ca27dc9c70d828faa35"
integrity sha512-j94Seae1PHkHdUYN3GPphBOM+XdddEPh9BSer0llRcwIJyB3+eJzefyBQDgEDPvKmAAX+Psc2L5iZOOOuFyqaA==
dependencies:
"@expo/config-types" "^40.0.0-beta.2"
"@expo/configure-splash-screen" "0.3.2"
"@expo/image-utils" "0.3.10"
"@expo/json-file" "8.2.25"
"@expo/json-file" "8.2.26"
"@expo/plist" "0.0.11"
find-up "~5.0.0"
fs-extra "9.0.0"
@ -1080,16 +1080,16 @@
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-40.0.0-beta.2.tgz#4fea4ef5654d02218b02b0b3772529a9ce5b0471"
integrity sha512-t9pHCQMXOP4nwd7LGXuHkLlFy0JdfknRSCAeVF4Kw2/y+5OBbR9hW9ZVnetpBf0kORrekgiI7K/qDaa3hh5+Qg==
"@expo/config@3.3.23", "@expo/config@^3.2.3", "@expo/config@^3.3.15", "@expo/config@^3.3.18":
version "3.3.23"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-3.3.23.tgz#541000239ba59adefb2253bca6f049da6aa18ec8"
integrity sha512-s5rJI53E25Mc+1TVqTjLyoDNNH6QmFgRo5PsMj6/kHFa8bSvHQHeBjOIf5CA6wiHjdmmxgP6//4dIkJTgHdqFw==
"@expo/config@3.3.25", "@expo/config@^3.2.3", "@expo/config@^3.3.15", "@expo/config@^3.3.18":
version "3.3.25"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-3.3.25.tgz#41d7bd0adb447c937431c1e740bde43e6f1c8e77"
integrity sha512-b9V/2AqooybtQN7tgW6d8nrC/zSkUVocujqt1nIZQRmuEdJEG/7X9ZsZ9Dad1yjnbtZYgKF0S1q2s/V1ebFsvQ==
dependencies:
"@babel/core" "7.9.0"
"@expo/babel-preset-cli" "0.2.18"
"@expo/config-plugins" "1.0.14"
"@expo/config-plugins" "1.0.16"
"@expo/config-types" "^40.0.0-beta.2"
"@expo/json-file" "8.2.25"
"@expo/json-file" "8.2.26"
fs-extra "9.0.0"
getenv "0.7.0"
glob "7.1.6"
@ -1149,23 +1149,23 @@
semver "7.3.2"
tempy "0.3.0"
"@expo/json-file@8.2.25":
version "8.2.25"
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.2.25.tgz#3f7f403612efab98b6043868b8bb8b27a7189ed1"
integrity sha512-KFX6grWVzttaDskq/NK8ByqFPgpDZGFnyeZVeecGoKx5kU61zuR7/xQM04OvN6BNXq3jTUst1TyS8fXEfJuscA==
"@expo/json-file@8.2.26":
version "8.2.26"
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.2.26.tgz#2435224cd7e6288080252b4f6be3775762100588"
integrity sha512-9ahw1ztHtRhXE8/kTiOpXTXJ/Uq2lF8UlIIcJjoE5DCFA0epL8tnDiu6RDzXMhjhH1ytiojt2sYC4+lV29JPAA==
dependencies:
"@babel/code-frame" "~7.10.4"
fs-extra "9.0.0"
json5 "^1.0.1"
lodash "^4.17.15"
lodash "^4.17.19"
write-file-atomic "^2.3.0"
"@expo/metro-config@^0.1.16":
version "0.1.49"
resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.1.49.tgz#650af6b71554de4ae020406c1e1a3b6c5a3fb837"
integrity sha512-koaWdl4h7krJBBS5M/PdM67hD2ivVf8vJ6vbGgMnPNTlgRQXNKmYtAMg71/ajXJ6Z+dY7A56i7ccuTRc1Bz5dA==
version "0.1.51"
resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.1.51.tgz#c6c3394a05fe2fd8a60260c12d2fe3c7466197ac"
integrity sha512-wThYM0aUuVjb0UxDGY0yPjlhlmFXa79dDm7Olie9MDJfRqtZatSpueBveSwBA+HIa6CVHe+cOj2u5crMxU9CsA==
dependencies:
"@expo/config" "3.3.23"
"@expo/config" "3.3.25"
metro-react-native-babel-transformer "^0.58.0"
"@expo/plist@0.0.11":
@ -2091,9 +2091,9 @@
integrity sha512-tptvkyStulE9Jv/LVYSldvydAq3DVOwsfqmy3mTh3NWl1LZwE4gZwZ455jiRmW5StsJ3Q/Od/GGsN0FI8gHAXQ==
"@react-navigation/bottom-tabs@^5.11.2":
version "5.11.3"
resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-5.11.3.tgz#8f918954d22217696bc9d947ad441e207458a1e8"
integrity sha512-ez79zP21wtuHcnIm96fld4MXc9oOSpJCG78MTo/Jw+yZxZsQdF4N55ABiLfaQ/48QyZr8cfi0GkP/AYheZwm6A==
version "5.11.7"
resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-5.11.7.tgz#a1d220afe02b6897c0705ddc40265e65c01fa0ba"
integrity sha512-O8B/5GiME589fc6ltqV3iJxCdWXhplx+9i7tPbwx4SxKm1e1N9jdL9H8bsx+SWcMBelGfGeZ2WqRwMJzjQDT3Q==
dependencies:
color "^3.1.3"
react-native-iphone-x-helper "^1.3.0"
@ -2108,12 +2108,12 @@
query-string "^6.13.6"
react-is "^16.13.0"
"@react-navigation/core@^5.15.0":
version "5.15.0"
resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-5.15.0.tgz#fbec78a0b4c6e2f29e13a7cf7a86e83279fb5213"
integrity sha512-JesS2jRn6CC7ITzGaulZBVq7Z1EhFzT/9vXSFodJ1wDtprDJHLSjvPLuPcSw1dx9/1DRXj4iCeCBTIlDpNWJeA==
"@react-navigation/core@^5.15.1":
version "5.15.1"
resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-5.15.1.tgz#dab5192277c606d9acbea511dac407c2834b5fbe"
integrity sha512-GDCpIVQd0NgHYCSdUMY69hrpeWKuYgj5SIRqHI2sYh9OguwGcV52ZZOafc+pQuyfuiLLIMidw34jiqb47QrlhA==
dependencies:
"@react-navigation/routers" "^5.7.0"
"@react-navigation/routers" "^5.7.1"
escape-string-regexp "^4.0.0"
nanoid "^3.1.15"
query-string "^6.13.6"
@ -2128,25 +2128,25 @@
react-native-safe-area-view "^0.14.9"
"@react-navigation/native@^5.8.10":
version "5.9.0"
resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-5.9.0.tgz#fbea983d7142775b725de59dd18a5a856f26f480"
integrity sha512-IphWd6uITuEC4zEfWESPiM6EPUnpnYC4lsGK3m75mlxca/MWok4bUCX73OL/iBlCi9skFAGyP9XccFyrFEIHIg==
version "5.9.2"
resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-5.9.2.tgz#2075774c3627d58a324e1b5dfc5f4f356a1ab7e9"
integrity sha512-O8K+Lr6Vy25gTTyXAns9BVyFvwTkKqfFH0RpOimilYndUL6tlhV56oDSp7Hryjy8xsjx6ESWqr6eIu4sS3Z9nQ==
dependencies:
"@react-navigation/core" "^5.15.0"
"@react-navigation/core" "^5.15.1"
escape-string-regexp "^4.0.0"
nanoid "^3.1.15"
"@react-navigation/routers@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@react-navigation/routers/-/routers-5.7.0.tgz#fb780d60f5cba9206ed402f271c10986f921d68f"
integrity sha512-Du1OsLtEF2EEWo7GeFNoBRBi4aX4eHdFQXztNxeL/N3Gl3f8wc6Ys0XTWHgWlWQIspqOfup5YF3WQcLArunjvg==
"@react-navigation/routers@^5.7.1":
version "5.7.1"
resolved "https://registry.yarnpkg.com/@react-navigation/routers/-/routers-5.7.1.tgz#ba56cabdaabc521ef29c26529e868590949429b1"
integrity sha512-M5R4AFgJZ0uBUV+DjMyNy2HXRfvo0ldM+59Gj1NQWXaYnst3m0xJTfWiln94mnrbrHEq087gMP4ZLHGIJ8D1Ig==
dependencies:
nanoid "^3.1.15"
"@react-navigation/stack@^5.12.8":
version "5.13.0"
resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-5.13.0.tgz#3c00848642a4a966f497822f02494273f4d4c621"
integrity sha512-UorckfT7p7D5BLMJgpi8lY6duSV6WSG/NwidxWQK06u5bO0Uwxgx9sINjJZbS5+ijVJy8bB8SbG/I+H2bgT4eA==
version "5.14.2"
resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-5.14.2.tgz#6e48efa74a9b0fc29ff0a90fcbee161039b84d78"
integrity sha512-tt1eFn6HClyXVZiVQsPs3Q2MgoqmJdkQsyT9P4TBLxGsdib6r/oc++eVNc+G/6ws/kCquDdHq3fz1PNSCtyrJA==
dependencies:
color "^3.1.3"
react-native-iphone-x-helper "^1.3.0"
@ -2458,9 +2458,9 @@
"@types/node" "*"
"@types/hammerjs@^2.0.36":
version "2.0.36"
resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.36.tgz#17ce0a235e9ffbcdcdf5095646b374c2bf615a4c"
integrity sha512-7TUK/k2/QGpEAv/BCwSHlYu3NXZhQ9ZwBYpzr9tjlPIL2C5BeGhH3DmVavRx3ZNyELX5TLC91JTz/cen6AAtIQ==
version "2.0.37"
resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.37.tgz#4ba37b3ef9755ab7a91bf9fc39ee162cc1976070"
integrity sha512-lljqacGn4mUhD3KJUdP9dbl+Yst8+qkCrpqBytFHrWB6Ms1Rwh0My+KXPCVgDPwv1i67RtQDr3CVoM+dmLQuSg==
"@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1":
version "3.3.1"
@ -2557,9 +2557,9 @@
react-navigation "*"
"@types/react-redux@^7.1.12":
version "7.1.15"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.15.tgz#19075884db94101be762accef924d266a603fb1b"
integrity sha512-+piY42tUflPfI7y9Vy3UkG6MEMuJlrxfdtgeUcWmd5Z0qB57NXAPG6smkqu1DNXluo/KDyXPeRYhcFzMwt1BEA==
version "7.1.16"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.16.tgz#0fbd04c2500c12105494c83d4a3e45c084e3cb21"
integrity sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw==
dependencies:
"@types/hoist-non-react-statics" "^3.3.0"
"@types/react" "*"
@ -3470,9 +3470,9 @@ camelcase@^6.0.0:
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
caniuse-lite@^1.0.30001173:
version "1.0.30001178"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001178.tgz#3ad813b2b2c7d585b0be0a2440e1e233c6eabdbc"
integrity sha512-VtdZLC0vsXykKni8Uztx45xynytOi71Ufx9T8kHptSw9AL4dpqailUJJHavttuzUe1KYuBYtChiWv+BAb7mPmQ==
version "1.0.30001179"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001179.tgz#b0803883b4471a6c62066fb1752756f8afc699c8"
integrity sha512-blMmO0QQujuUWZKyVrD1msR4WNDAqb/UPO1Sw2WWsQ7deoM5bJiicKnWJ1Y0NS/aGINSnKPIWBMw5luX+NDUCA==
capture-exit@^2.0.0:
version "2.0.0"
@ -3936,9 +3936,9 @@ data-urls@^2.0.0:
whatwg-url "^8.0.0"
dayjs@^1.8.15:
version "1.10.3"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.3.tgz#cf3357c8e7f508432826371672ebf376cb7d619b"
integrity sha512-/2fdLN987N8Ki7Id8BUN2nhuiRyxTLumQnSQf9CNncFCyqFsSKb9TNhzRYcC8K8eJSJOKvbvkImo/MKKhNi4iw==
version "1.10.4"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.4.tgz#8e544a9b8683f61783f570980a8a80eaf54ab1e2"
integrity sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==
debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
version "2.6.9"
@ -4164,9 +4164,9 @@ ee-first@1.1.1:
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.3.634:
version "1.3.642"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.642.tgz#8b884f50296c2ae2a9997f024d0e3e57facc2b94"
integrity sha512-cev+jOrz/Zm1i+Yh334Hed6lQVOkkemk2wRozfMF4MtTR7pxf3r3L5Rbd7uX1zMcEqVJ7alJBnJL7+JffkC6FQ==
version "1.3.645"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.645.tgz#c0b269ae2ecece5aedc02dd4586397d8096affb1"
integrity sha512-T7mYop3aDpRHIQaUYcmzmh6j9MAe560n6ukqjJMbVC6bVTau7dSpvB18bcsBPPtOSe10cKxhJFtlbEzLa0LL1g==
emittery@^0.7.1:
version "0.7.2"
@ -4208,9 +4208,9 @@ entities@^1.1.1:
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
entities@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
version "2.2.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
envinfo@^7.7.2:
version "7.7.3"
@ -4253,16 +4253,16 @@ es-abstract@^1.18.0-next.1:
string.prototype.trimstart "^1.0.3"
es-get-iterator@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.1.tgz#b93ddd867af16d5118e00881396533c1c6647ad9"
integrity sha512-qorBw8Y7B15DVLaJWy6WdEV/ZkieBcu6QCq/xzWzGOKJqgG1j754vXRfZ3NY7HSShneqU43mPB4OkQBTkvHhFw==
version "1.1.2"
resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.2.tgz#9234c54aba713486d7ebde0220864af5e2b283f7"
integrity sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==
dependencies:
call-bind "^1.0.0"
get-intrinsic "^1.0.1"
call-bind "^1.0.2"
get-intrinsic "^1.1.0"
has-symbols "^1.0.1"
is-arguments "^1.0.4"
is-map "^2.0.1"
is-set "^2.0.1"
is-arguments "^1.1.0"
is-map "^2.0.2"
is-set "^2.0.2"
is-string "^1.0.5"
isarray "^2.0.5"
@ -4456,9 +4456,9 @@ expo-application@^2.2.1, expo-application@~2.4.1:
integrity sha512-VHDvXz55LIYdLoE1aR0AFycB1jz4ggbMToUbKAbCEjro+PdUNm/Gj8gQeFgH6wL2oAztQH4qJ+uiOwrw8SFK+Q==
expo-asset@~8.2.1:
version "8.2.1"
resolved "https://registry.yarnpkg.com/expo-asset/-/expo-asset-8.2.1.tgz#1b69724f29ca4260805f2e6368c4428d8ad90cc6"
integrity sha512-M97jZU83Gm6wWGkrCwTzDVlufQCmnrCbmW4AMOH6xl3XhwOpgsQ6m6xrwT0Sq1tto7JUuL0tPbB9vb9L7yLfyg==
version "8.2.2"
resolved "https://registry.yarnpkg.com/expo-asset/-/expo-asset-8.2.2.tgz#2b24faccfb7d895097623317bb0555901bbc4e7c"
integrity sha512-Ckiok7BFB6WjKNifa1b3mx2zGY8DnV2CttSQMTnMd6+0EOx1qOMsZDNkryJVpVOtpAetCdHWd5s9f2CdmosowA==
dependencies:
blueimp-md5 "^2.10.0"
invariant "^2.2.4"
@ -4491,7 +4491,15 @@ expo-blur@~8.2.2:
resolved "https://registry.yarnpkg.com/expo-blur/-/expo-blur-8.2.2.tgz#a7643d893afb7aed5512b25d5df22ee6083832c1"
integrity sha512-Xiklw60RUPIchHKzfvLTIuccVDTIQEAIPv02yJY2xFDujQKjE0NU0/Z5Z+zsEI9QOi82jX9NbR8gQ+8Mm3hDhA==
expo-constants@*, expo-constants@^9.3.3, expo-constants@~9.3.3:
expo-constants@*:
version "10.0.1"
resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-10.0.1.tgz#a6cf6998c70ef6e1772a7c4096723482194c5828"
integrity sha512-SnMIX1PnTz3AgGcFd+paCb8Ur0WfEiBjEZ7TxCdwpk7XVQO4etCzn6auNutCd4PBc4YVNvmKF9e0WFgLxy4NRQ==
dependencies:
"@expo/config" "^3.3.18"
uuid "^3.3.2"
expo-constants@^9.3.3, expo-constants@~9.3.3:
version "9.3.5"
resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-9.3.5.tgz#78085763e8ed100a5f2df7c682fd99631aa03d5e"
integrity sha512-qIlv2ffSjQl3wrvJwXYoNfQNfH/sK46EXcgyEQnQ1SAQO4ukwTEpG9j3fdW6aTiVEVrv/DsA1IaVRqKrUwSd3A==
@ -4506,9 +4514,9 @@ expo-crypto@^8.4.0, expo-crypto@~8.4.0:
integrity sha512-EHEFx5sHTDVIuQH8/juuecQWj1uQ7ClM98fKXPFcNYcBlYSCQvkik37hwfJC5WLcVnelFDpvZJmHxiTfB5GKCg==
expo-device@*:
version "3.0.0"
resolved "https://registry.yarnpkg.com/expo-device/-/expo-device-3.0.0.tgz#41be12d292ce15bb29c12ae748a2faab11c0e057"
integrity sha512-E3JxIF40K5GMGoChi3Nv6SuXCe3Tt30FmlOW4qDeQlLkM+goAEE9zzwUmkzzGVmdD0wU2XEs7aLqFcSUJZzslw==
version "3.1.1"
resolved "https://registry.yarnpkg.com/expo-device/-/expo-device-3.1.1.tgz#75dd1b4e61e9a2ed82afcefea4b458bd73aa596d"
integrity sha512-2Bg3a6zf680/bxxMfqMGyPMlrNOBjfKvuNJNIa80RsUauiJfhDix5zKRxEtrmwa/xoigoebmEV6QzE0vJ3Lseg==
dependencies:
ua-parser-js "^0.7.19"
@ -4588,12 +4596,13 @@ expo-linear-gradient@~8.4.0:
resolved "https://registry.yarnpkg.com/expo-linear-gradient/-/expo-linear-gradient-8.4.0.tgz#34e6f960b1971c57dacf7211c747ba490a76bf63"
integrity sha512-f9JOXaIl0MR8RBYRIud5UAsEi52oz81XhQs73VUpujemHjOyHmrZa6dqwf399YOwI/WBwbpcINcUIw/mCYE1mA==
expo-linking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/expo-linking/-/expo-linking-2.0.0.tgz#c39f610825e99ef0d10e8d82fbcf7beed8456b00"
integrity sha512-/48/+MHa96l3/YgL0uM/hbli+H0J8XXAUWgMCBpTIcmUc0POYw4Xp+7BhXcTbPRZsVoOiAHAmKIsEjFVTd5L+A==
expo-linking@~2.0.0, expo-linking@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/expo-linking/-/expo-linking-2.0.1.tgz#0ac0298039b0f7f6c109d7efbbb661efc1c56760"
integrity sha512-S+Bb5u1rlld6ZICKOQ4B/htHiIbtd9eJMpwXoWMcl68V+UNNxJisB5lUZePXWSoHlb0QbQfVOAf48u2WD588lQ==
dependencies:
expo-constants "~9.3.3"
invariant "^2.2.4"
qs "^6.5.0"
url-parse "^1.4.4"
@ -4673,9 +4682,9 @@ expo-web-browser@^8.6.0, expo-web-browser@~8.6.0:
compare-urls "^2.0.0"
expo@^40.0.0:
version "40.0.0"
resolved "https://registry.yarnpkg.com/expo/-/expo-40.0.0.tgz#6caf03587532cd18b482991332a8b75eeca2fcb7"
integrity sha512-LT6Ae/Ms0qtRyJlJsj/FMB5AQpj6nED39SY9KqY4zK/uFG+R7DJ/4VUzkPued1mWtRUrtaqR+t88pA3p0vAWcg==
version "40.0.1"
resolved "https://registry.yarnpkg.com/expo/-/expo-40.0.1.tgz#20ae9f9c787ba1662037094dfd6982380f2c0288"
integrity sha512-9NrhimvP44I1aDjGHMU4F0izCyfFTTYAQ6xZpWpuc+ZWRZqg8Zv62zNRlzBn+Ydaf1heSucnlJJ3Sp2gMdOEnQ==
dependencies:
"@babel/runtime" "^7.1.2"
"@expo/vector-icons" "^12.0.0"
@ -4692,7 +4701,7 @@ expo@^40.0.0:
expo-font "~8.4.0"
expo-keep-awake "~8.4.0"
expo-linear-gradient "~8.4.0"
expo-linking "~2.0.0"
expo-linking "~2.0.1"
expo-location "~10.0.0"
expo-permissions "~10.0.0"
expo-secure-store "~9.3.0"
@ -4987,9 +4996,9 @@ find-up@~5.0.0:
path-exists "^4.0.0"
follow-redirects@^1.10.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.1.tgz#5f69b813376cee4fd0474a3aba835df04ab763b7"
integrity sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==
version "1.13.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.2.tgz#dd73c8effc12728ba5cf4259d760ea5fb83e3147"
integrity sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==
fontfaceobserver@^2.1.0:
version "2.1.0"
@ -5108,10 +5117,10 @@ get-caller-file@^2.0.1:
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-intrinsic@^1.0.1, get-intrinsic@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49"
integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==
get-intrinsic@^1.0.1, get-intrinsic@^1.0.2, get-intrinsic@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.0.tgz#892e62931e6938c8a23ea5aaebcfb67bd97da97e"
integrity sha512-M11rgtQp5GZMZzDL7jLTNxbDfurpzuau5uqRWDPvlHjfvg3TdScAZo96GLvhMjImrmR8uAt0FS2RLoMrfWGKlg==
dependencies:
function-bind "^1.1.1"
has "^1.0.3"
@ -5586,7 +5595,7 @@ is-accessor-descriptor@^1.0.0:
dependencies:
kind-of "^6.0.0"
is-arguments@^1.0.4:
is-arguments@^1.0.4, is-arguments@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9"
integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==
@ -5725,7 +5734,7 @@ is-generator-fn@^2.0.0:
resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118"
integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==
is-map@^2.0.1:
is-map@^2.0.1, is-map@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127"
integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==
@ -5781,7 +5790,7 @@ is-regex@^1.1.1:
dependencies:
has-symbols "^1.0.1"
is-set@^2.0.1:
is-set@^2.0.1, is-set@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec"
integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==
@ -7851,9 +7860,9 @@ nocache@^2.1.0:
integrity sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==
nock@^13.0.5:
version "13.0.5"
resolved "https://registry.yarnpkg.com/nock/-/nock-13.0.5.tgz#a618c6f86372cb79fac04ca9a2d1e4baccdb2414"
integrity sha512-1ILZl0zfFm2G4TIeJFW0iHknxr2NyA+aGCMTjDVUsBY4CkMRispF1pfIYkTRdAR/3Bg+UzdEuK0B6HczMQZcCg==
version "13.0.6"
resolved "https://registry.yarnpkg.com/nock/-/nock-13.0.6.tgz#9f90573ea6e84883b94eeac374d1c73460afed56"
integrity sha512-W81UZ1Tv21SWDZcA8Lu9LXYVl2gO9ADY5GadC6gFV9690h4TXz0oCkEoMckN/sPMHkDA79Ka9dXga9Mt1+j+Sg==
dependencies:
debug "^4.1.0"
json-stringify-safe "^5.0.1"
@ -8771,14 +8780,9 @@ react-native-safe-area-view@^0.14.9:
hoist-non-react-statics "^2.3.1"
react-native-screens@~2.15.0:
version "2.15.1"
resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-2.15.1.tgz#f7512932ecff7327b57fb0bda58e49e9bf8ee5f2"
integrity sha512-cdcBHLizteH0RNn6QSw0ftQWWsAjolte/uuISoDBfllxka7sabT1i56C2Wus25KGGowaYT3DEz0zMFunS2GNJQ==
react-native-shimmer-placeholder@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/react-native-shimmer-placeholder/-/react-native-shimmer-placeholder-2.0.6.tgz#a6626d955945edb1aa01f8863f3e039a738d53d1"
integrity sha512-eq0Jxi/j/WseijfSeNjoAsaz1164XUCDvKpG/+My+c5YeVMfjTnl9SwoVAIr9uOpuDXXia67j8xME+eFJZvBXw==
version "2.15.2"
resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-2.15.2.tgz#a449700e895b462937211ec72ed6f09652758f06"
integrity sha512-CagNf2APXkVoRlF3Mugr264FbKbrBg9eXUkqhIPVeZB8EsdS8XPrnt99yj/pzmT+yJMBY0dGrjXT8+68WYh6YQ==
react-native-svg@12.1.0:
version "12.1.0"
@ -8847,9 +8851,9 @@ react-navigation@*, react-navigation@^4.4.3:
"@react-navigation/native" "^3.8.3"
react-query@^3.5.6:
version "3.5.16"
resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.5.16.tgz#172771a8cdb83b85c353ac32f1e30bfca27893d7"
integrity sha512-zOJimWPC0o2h8fta0uMc+pmFIBgfVkfCvEAeUbrlsbA6m42CFPgyRBJt6kiYjsZ/WRuJl+WIaAh/P27oUXETNw==
version "3.6.0"
resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.6.0.tgz#3da307a4a4cb6ea95f9c95b7e50b5281d5244e4d"
integrity sha512-39ptLt4qaKO1DE+ta6SpPutweEgDvUQj/KlebC+okJ9Nxbs5ExxKV8RYlLeop6vdDFyiMmwYrt1POiF8oWGh1A==
dependencies:
"@babel/runtime" "^7.5.5"
match-sorter "^6.0.2"