diff --git a/App.tsx b/App.tsx
index 67a67c16..a736e37f 100644
--- a/App.tsx
+++ b/App.tsx
@@ -1,5 +1,5 @@
import * as SplashScreen from 'expo-splash-screen'
-import React, { useEffect, useState } from 'react'
+import React, { useCallback, useEffect, useState } from 'react'
import { QueryClient, QueryClientProvider } from 'react-query'
import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/integration/react'
@@ -8,6 +8,7 @@ import { Index } from '@root/Index'
import { persistor, store } from '@root/store'
import ThemeManager from '@utils/styles/ThemeManager'
import { resetLocal, updateLocal } from '@root/utils/slices/instancesSlice'
+import client from '@root/api/client'
const queryClient = new QueryClient()
@@ -22,6 +23,8 @@ const queryClient = new QueryClient()
const App: React.FC = () => {
const [appLoaded, setAppLoaded] = useState(false)
+ const [startVerification, setStartVerification] = useState(false)
+ const [localCorrupt, setLocalCorrupt] = useState(false)
useEffect(() => {
const delaySplash = async () => {
try {
@@ -45,38 +48,66 @@ const App: React.FC = () => {
}
}, [appLoaded])
+ const onBeforeLift = useCallback(() => setStartVerification(true), [])
+ useEffect(() => {
+ const verifyCredentials = async () => {
+ const localUrl = store.getState().instances.local.url
+ const localToken = store.getState().instances.local.token
+
+ if (localUrl && localToken) {
+ client({
+ method: 'get',
+ instance: 'remote',
+ instanceDomain: localUrl,
+ url: `accounts/verify_credentials`,
+ headers: { Authorization: `Bearer ${localToken}` }
+ })
+ .then(res => {
+ if (res.body.id !== store.getState().instances.local.account.id) {
+ store.dispatch(resetLocal())
+ setLocalCorrupt(true)
+ setAppLoaded(true)
+ }
+ })
+ .catch(() => {
+ store.dispatch(resetLocal())
+ setLocalCorrupt(true)
+ setAppLoaded(true)
+ })
+ } else {
+ setAppLoaded(true)
+ }
+ }
+
+ if (startVerification) {
+ verifyCredentials()
+ }
+ }, [startVerification])
+
+ const main = useCallback(
+ bootstrapped => {
+ if (bootstrapped && appLoaded) {
+ require('@root/i18n/i18n')
+ return (
+
+
+
+ )
+ } else {
+ return null
+ }
+ },
+ [appLoaded]
+ )
+
return (
{
- const localUrl = store.getState().instances.local.url
- const localToken = store.getState().instances.local.token
- if (localUrl && localToken) {
- const dispatchStatus = await store.dispatch(
- updateLocal({ url: localUrl, token: localToken })
- )
- if (dispatchStatus.type.includes('/rejected')) {
- store.dispatch(resetLocal())
- }
- }
- setAppLoaded(true)
- }}
- >
- {bootstrapped => {
- if (bootstrapped) {
- require('@root/i18n/i18n')
- return (
-
-
-
- )
- } else {
- return null
- }
- }}
-
+ onBeforeLift={onBeforeLift}
+ children={main}
+ />
)
diff --git a/src/Index.tsx b/src/Index.tsx
index 320fa505..98cd674d 100644
--- a/src/Index.tsx
+++ b/src/Index.tsx
@@ -3,7 +3,7 @@ import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
import { NavigationContainer } from '@react-navigation/native'
import { enableScreens } from 'react-native-screens'
-import React from 'react'
+import React, { useEffect } from 'react'
import { StatusBar } from 'react-native'
import Toast from 'react-native-toast-message'
import { Feather } from '@expo/vector-icons'
@@ -16,7 +16,7 @@ import ScreenMe from '@screens/Me'
import { themes } from '@utils/styles/themes'
import { useTheme } from '@utils/styles/ThemeManager'
import getCurrentTab from '@utils/getCurrentTab'
-import { toastConfig } from '@components/toast'
+import { toast, toastConfig } from '@components/toast'
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
import { getLocalUrl } from './utils/slices/instancesSlice'
@@ -32,7 +32,11 @@ export type RootStackParamList = {
'Screen-Me': undefined
}
-export const Index: React.FC = () => {
+export interface Props {
+ localCorrupt: boolean
+}
+
+export const Index: React.FC = ({ localCorrupt }) => {
const localInstance = useSelector(getLocalUrl)
const { i18n } = useTranslation()
const { mode, theme } = useTheme()
@@ -41,6 +45,18 @@ export const Index: React.FC = () => {
dark = 'light-content'
}
+ useEffect(() => {
+ const showLocalCorrect = localCorrupt
+ ? toast({
+ type: 'error',
+ content: '登录已过期',
+ description: '请重新登录',
+ autoHide: false
+ })
+ : undefined
+ return showLocalCorrect
+ }, [localCorrupt])
+
return (
<>
diff --git a/src/components/toast.tsx b/src/components/toast.tsx
index 26fe3fca..bd39b7b6 100644
--- a/src/components/toast.tsx
+++ b/src/components/toast.tsx
@@ -63,13 +63,21 @@ const ToastBase = ({ config }: { config: Config }) => {
>
-
- {config.text1}
-
+
+
+ {config.text1}
+
+ {config.text2 && (
+
+ {config.text2}
+
+ )}
+
)
@@ -91,11 +99,18 @@ const styles = StyleSheet.create({
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
+ alignItems: 'center',
padding: StyleConstants.Spacing.M
},
- text: {
- fontSize: StyleConstants.Font.Size.M,
+ texts: {
marginLeft: StyleConstants.Spacing.S
+ },
+ text1: {
+ fontSize: StyleConstants.Font.Size.M
+ },
+ text2: {
+ fontSize: StyleConstants.Font.Size.S,
+ marginTop: StyleConstants.Spacing.S
}
})