diff --git a/app.config.js b/app.config.js
index cd08500..cda3d97 100644
--- a/app.config.js
+++ b/app.config.js
@@ -10,7 +10,7 @@ export const IOS_UNIVERSAL_LINK = 'duooomi.bowong.cn'
// 原生版本,原生代码变更时需要更新此版本号
export const VERSION = '1.5.0'
// JavaScript版本,JS代码变更时需要更新此版本号
-export const APP_VERSION = 'dev202602041525'
+export const APP_VERSION = 'dev202602041658'
const ALIPAY_SCHEMA = 'alipay2021006119657394'
const ALIPAY_SCHEMA_SANDBOX = 'alipay9021000158673972'
diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx
index bad7817..1047ddf 100644
--- a/app/(tabs)/_layout.tsx
+++ b/app/(tabs)/_layout.tsx
@@ -61,10 +61,6 @@ const CustomTabBar = observer(function CustomTabBar(props: any) {
const activeRouteName = routes[activeIndex]?.name || 'index'
const handleChange = (route: string) => {
- // if (!isLogin && route !== 'index') {
- // props.navigation.push('auth')
- // return
- // }
props.navigation.navigate(route)
}
return
@@ -74,23 +70,11 @@ export default function Layout() {
const router = useRouter()
useEffect(() => {
const timer = setTimeout(() => {
- router.replace('(tabs)/sync')
+ router.replace('/(tabs)/sync')
}, 100) // 小延迟确保导航准备好
return () => clearTimeout(timer)
}, [router])
- useEffect(() => {
- // 配置WebBrowser
- // const setupWebBrowser = async () => {
- // try {
- // await configureWebBrowser()
- // } catch (error) {
- // console.warn('Failed to configure WebBrowser:', error)
- // }
- // }
- // setupWebBrowser()
- }, [])
-
return }>
}
diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx
index 94d8225..f5c6e0a 100644
--- a/app/(tabs)/index.tsx
+++ b/app/(tabs)/index.tsx
@@ -68,6 +68,7 @@ const Index = observer(function Index() {
useEffect(() => {
console.log('expo env------------', process.env.EXPO_PUBLIC_ENV)
+ userStore.getUserData()
}, [])
/** ================= refs(核心) ================= */
diff --git a/app/_layout.tsx b/app/_layout.tsx
index 37062bb..0df309c 100644
--- a/app/_layout.tsx
+++ b/app/_layout.tsx
@@ -1,13 +1,13 @@
import '../global.css'
import 'react-native-reanimated'
-import { DarkTheme, DefaultTheme, ThemeProvider, useIsFocused } from '@react-navigation/native'
+import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'
import * as Sentry from '@sentry/react-native'
import { useKeepAwake } from 'expo-keep-awake'
-import { router, Stack, useNavigationContainerRef, usePathname } from 'expo-router'
+import { Stack, useNavigationContainerRef, usePathname } from 'expo-router'
import { ShareIntentProvider } from 'expo-share-intent'
import { StatusBar } from 'expo-status-bar'
-import { useCallback, useEffect } from 'react'
+import { useEffect } from 'react'
import { GestureHandlerRootView } from 'react-native-gesture-handler'
import { KeyboardProvider } from 'react-native-keyboard-controller'
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context'
@@ -17,8 +17,6 @@ import { bleManager } from '@/ble/managers/bleManager'
import { HotUpdate } from '@/components/hot-update'
import { useColorScheme } from '@/hooks/use-color-scheme'
import { setupGlobalFetchLogger } from '@/lib/fetch-logger'
-import { useUserSession } from '@/stores/userStore'
-import { storage } from '@/utils'
const isProd = process.env.EXPO_PUBLIC_ENV !== 'development'
@@ -40,6 +38,8 @@ export const unstable_settings = {
function RootLayout() {
const ref = useNavigationContainerRef()
+ const currentRoute = usePathname()
+
useEffect(() => {
if (!ref?.current) return
@@ -92,15 +92,15 @@ function RootLayout() {
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
@@ -110,24 +110,16 @@ function RootLayout() {
function Providers({ children }: { children: React.ReactNode }) {
const colorScheme = useColorScheme()
const currentRoute = usePathname()
+ // const session = useUserSession()
- useUserSession()
useKeepAwake()
- const isFocused = useIsFocused()
-
- const loadLogin = useCallback(async () => {
- const isLogin = await storage.get('isLogin')
- if (!isLogin && currentRoute !== '/auth') {
- router.replace('/auth')
- }
- }, [currentRoute])
-
- useEffect(() => {
- if (isFocused) {
- loadLogin()
- }
- }, [isFocused, loadLogin])
+ // useEffect(() => {
+ // if (session.isPending) return
+ // if (!isLoggedIn && !currentRoute.includes('/auth')) {
+ // router.replace('/auth')
+ // }
+ // }, [session.isPending, isLoggedIn, currentRoute])
return (
diff --git a/app/auth.tsx b/app/auth.tsx
index 7955413..eada799 100644
--- a/app/auth.tsx
+++ b/app/auth.tsx
@@ -8,7 +8,7 @@ import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'
import { APP_VERSION, VERSION } from '@/app.config'
import BannerSection from '@/components/BannerSection'
-import { getSession, phoneNumber, setAuthToken, signIn } from '@/lib/auth'
+import { phoneNumber, setAuthToken, signIn } from '@/lib/auth'
import { isValidPhone } from '@/utils'
const APP_NAME = '多米'
@@ -33,50 +33,19 @@ export default function Auth() {
const [currentBranch, setCurrentBranch] = useState('unknown')
const countdownTimerRef = useRef | null>(null)
- // 获取当前分支信息
useEffect(() => {
- const getBranchInfo = async () => {
- try {
- if (!Updates.isEnabled) {
- setCurrentBranch('development')
- return
- }
-
- // 方法1: 使用 Updates.manifest (同步)
- const manifest = Updates.manifest
-
- // 方法2: 或者尝试从更新中获取
- let branch = 'production' // 默认值
-
- if (manifest?.extra?.eas?.branch) {
- branch = manifest.extra.eas.branch
- } else if (manifest?.metadata?.branchName) {
- branch = manifest.metadata.branchName
- } else if (Updates.channel) {
- branch = Updates.channel
- }
-
- // 方法3: 尝试获取当前运行的更新信息
- try {
- const currentlyRunning = await Updates.fetchUpdateAsync()
- if (currentlyRunning.manifest?.extra?.eas?.branch) {
- branch = currentlyRunning.manifest.extra.eas.branch
- }
- } catch (e) {
- console.log('Failed to fetch current update:', e)
- }
-
- setCurrentBranch(branch)
- console.log('Current branch:', branch)
- console.log('Updates.channel:', Updates.channel)
- console.log('Manifest:', manifest)
- } catch (error) {
- console.warn('Failed to get branch info:', error)
- setCurrentBranch('unknown')
- }
+ if (!Updates.isEnabled) {
+ setCurrentBranch('development')
+ return
+ }
+ const manifest = Updates.manifest
+ if (manifest?.extra?.eas?.branch) {
+ setCurrentBranch(manifest.extra.eas.branch)
+ } else if (Updates.channel) {
+ setCurrentBranch(Updates.channel)
+ } else {
+ setCurrentBranch('production')
}
-
- getBranchInfo()
}, [])
const canSendCode = useMemo(() => {
@@ -174,29 +143,24 @@ export default function Auth() {
setLoading(true)
Toast.showLoading({ title: '正在验证...' })
try {
- // 验证验证码,如果后端配置了 signUpOnVerification,新用户会自动注册并创建 session
- // disableSession: false 表示验证成功后创建 session(自动登录)
- await new Promise((resolve, reject) => {
- phoneNumber.verify(
- { phoneNumber: phone, code: code, disableSession: false },
- {
- onSuccess: async (ctx: any) => {
- const authToken = ctx.response.headers.get('set-auth-token')
- if (authToken) {
- setAuthToken(authToken)
- }
- await getSession()
- Toast.show({ title: '登录成功!' })
- setTimeout(() => {
- router.replace('/(tabs)')
- }, 500)
- },
- onError: (ctx: any) => {
- reject(new Error(ctx.error.message))
- },
+ const result = await phoneNumber.verify(
+ { phoneNumber: phone, code: code, disableSession: false },
+ {
+ onSuccess: async (ctx: any) => {
+ const authToken = ctx.response.headers.get('set-auth-token')
+ if (authToken) {
+ setAuthToken(authToken)
+ }
},
- )
- })
+ },
+ )
+
+ if (result.error) {
+ Toast.show({ title: result.error.message || '验证失败' })
+ } else {
+ Toast.show({ title: '登录成功!' })
+ router.replace('/(tabs)')
+ }
} catch (error: any) {
console.error('登录/注册失败:', error)
Toast.show({ title: error.message || '操作失败,请稍后重试' })
diff --git a/lib/auth.ts b/lib/auth.ts
index 6f2cd36..846dd2a 100644
--- a/lib/auth.ts
+++ b/lib/auth.ts
@@ -85,6 +85,9 @@ export const authClient = createAuthClient({
trustedOrigins: ['duooomi://', 'https://api.mixvideo.bowong.cc'],
storage,
scheme: 'duooomi',
+ sessionOptions: {
+ refetchOnWindowFocus: false,
+ },
fetchOptions: {
headers: {
'x-ownerid': OWNER_ID,
diff --git a/lib/fetch-logger.ts b/lib/fetch-logger.ts
index 2c07544..8b182ba 100644
--- a/lib/fetch-logger.ts
+++ b/lib/fetch-logger.ts
@@ -1,6 +1,3 @@
-import { storage as storage2 } from '../utils/storage'
-import { storage } from './storage.native'
-
interface FetchLoggerOptions {
enableLogging?: boolean
logRequest?: boolean
@@ -26,26 +23,7 @@ export const createFetchWithLogger = (options: FetchLoggerOptions = {}) => {
const method = init?.method || 'GET'
try {
- const token = await storage.getItem('token')
-
- if (token) {
- init = {
- ...init,
- headers: {
- ...init?.headers,
- authorization: `Bearer ${token}`,
- },
- }
- }
-
const response = await originalFetch(input, init)
-
- if (response.status === 401) {
- console.warn('🔐 401 未授权,清空登录状态')
- // router.replace('/auth')
- storage2.set('isLogin', false)
- }
-
return response
} catch (error) {
const duration = Date.now() - startTime
diff --git a/stores/userStore.ts b/stores/userStore.ts
index 8c0fd7d..36aaa5c 100644
--- a/stores/userStore.ts
+++ b/stores/userStore.ts
@@ -1,15 +1,13 @@
import { root } from '@repo/core'
import { DeviceController } from '@repo/sdk'
import * as Application from 'expo-application'
+import { router } from 'expo-router'
import { makeAutoObservable, runInAction } from 'mobx'
-import { useEffect } from 'react'
import { Platform } from 'react-native'
-import { signOut as authSignOut, useSession } from '@/lib/auth'
+import { getSession, signOut as authSignOut } from '@/lib/auth'
import { storage } from '@/utils'
-// console.log('useSession---------------', useSession)
-
interface User {
id: string
email: string
@@ -33,17 +31,17 @@ interface User {
interface Session {
user?: User
session?: {
- id: string
- userId: string
expiresAt: Date
+ token: string
createdAt: Date
updatedAt: Date
+ ipAddress?: string | null
+ userAgent?: string | null
+ userId: string
+ impersonatedBy?: string | null
activeOrganizationId?: string | null
activeTeamId?: string | null
- impersonatedBy?: string | null
- ipAddress?: string | null
- token?: string | null
- userAgent?: string | null
+ id: string
}
}
@@ -77,18 +75,31 @@ class UserStore {
await storage.set('isLogin', !!user)
}
- // 设置会话信息
- async setSession(session: Session | null) {
- runInAction(() => {
- this.session = session
- this.user = session?.user || null
- this.isLogin = !!session?.user
+ async getUserData() {
+ const sessionRes = await getSession()
- if (session?.user) {
- this.bindDevice()
- }
+ // console.log('getUserData sessionRes--------:', JSON.stringify(sessionRes))
+
+ const data = sessionRes.data
+ if (!data) {
+ this.reset()
+ router.replace('/auth')
+ return
+ }
+
+ const { session, user } = data
+
+ // console.log('获取用户信息--------:', JSON.stringify(data))
+
+ runInAction(() => {
+ this.session = { session, user }
+ this.user = user || null
+ this.isLogin = !!user
})
- await storage.set('isLogin', !!session?.user)
+
+ if (user?.id) {
+ this.bindDevice()
+ }
}
// 设置加载状态
@@ -118,18 +129,13 @@ class UserStore {
}
}
- // 从session更新用户状态
- updateFromSession(sessionData: Session | null) {
- this.setSession(sessionData)
- }
-
// 重置store状态
reset() {
- this.user = null
this.session = null
this.isLoading = false
this.error = null
this.scannedQR = null
+ this.setUser(null)
}
// ==================== 二维码相关方法 ====================
@@ -180,16 +186,3 @@ class UserStore {
// 创建单例实例
export const userStore = new UserStore()
-
-// 创建一个hook来使用session数据更新store
-export const useUserSession = () => {
- const session = useSession()
-
- // 使用useEffect在副作用中更新store状态,避免在render过程中修改
- useEffect(() => {
- userStore.setLoading(session.isPending)
- userStore.updateFromSession(session.data)
- }, [session.isPending, session.data])
-
- return session
-}