This commit is contained in:
oneao committed 2026-03-03 22:05:25 +08:00
1 parent c0531c1d0a
commit 46106d0c76
13 files changed
+171 -146

No files matched your search

@@ -57,7 +57,7 @@ export default function TabsLayout() {
" "
onPress={() => { onPress={() => {
setShowNavDrawer(false) setShowNavDrawer(false)
router.push(item.path) router.navigate(item.path)
}} }}
> >
<LucideIcon icon={item.icon} size={24} strokeWidth={2} clickable={false} /> <LucideIcon icon={item.icon} size={24} strokeWidth={2} clickable={false} />
@@ -2,9 +2,11 @@ import React, { useState } from 'react'
import { Text, View } from 'react-native' import { Text, View } from 'react-native'
import { AButton, AModal } from '@/components/common/ao' import { AButton, AModal } from '@/components/common/ao'
import AnimatedSwitch from '@/components/common/ao/Switch' import AnimatedSwitch from '@/components/common/ao/Switch'
import { useSpaceStore } from '@/store/space'
export default function TestScreen() { export default function TestScreen() {
const [showDissolve, setShowDissolve] = useState(false) const [showDissolve, setShowDissolve] = useState(false)
const spaceStore = useSpaceStore()
return ( return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
@@ -12,7 +14,7 @@ export default function TestScreen() {
setShowDissolve(true) setShowDissolve(true)
}} }}
> >
测试 {spaceStore.currentSpace?.space_id}
</AButton> </AButton>
<AModal <AModal
title="提示" title="提示"
@@ -26,21 +26,21 @@ export default function Index() {
{/* <AButton {/* <AButton
className="w-full" className="w-full"
onPress={() => router.replace('/money')} onPress={() => ('/money')}
> >
开始使用 开始使用
</AButton> */} </AButton> */}
<View className="flex flex-row gap-3 mt-4"> <View className="flex flex-row gap-3 mt-4">
<AButton <AButton
className="flex-1" className="flex-1"
onPress={() => router.replace('/money')} onPress={() => ('/money')}
> >
创建空间 创建空间
</AButton> </AButton>
<AButton <AButton
className="flex-1" className="flex-1"
variant="outline" variant="outline"
onPress={() => router.replace('/money')} onPress={() => ('/money')}
> >
加入空间 加入空间
</AButton> </AButton>
+13 -5
View File
@@ -42,9 +42,10 @@ export function ErrorBoundary({ error, retry }: ErrorBoundaryProps) {
export default function RootLayout() { export default function RootLayout() {
const pathname = usePathname() const pathname = usePathname()
const navStore = useNavStore()
const appStore = useAppStore() const appStore = useAppStore()
const navStore = useNavStore()
const [fontsLoaded] = useFonts({ const [fontsLoaded] = useFonts({
SpaceMono: require('@/static/fonts/SpaceMono-Regular.ttf'), SpaceMono: require('@/static/fonts/SpaceMono-Regular.ttf'),
}) })
@@ -54,12 +55,19 @@ export default function RootLayout() {
}, [pathname]) }, [pathname])
useEffect(() => { useEffect(() => {
if (!fontsLoaded) { if (!fontsLoaded)
return return
const bootstrap = async () => {
try {
await appStore.init()
}
finally {
SplashScreen.hideAsync()
}
} }
SplashScreen.hideAsync()
// appStore.init().finally(() => { bootstrap()
// })
}, [fontsLoaded]) }, [fontsLoaded])
return ( return (
+23 -19
View File
@@ -1,18 +1,22 @@
import { useEvent } from 'expo' import { useEvent } from 'expo'
// import ExpoQQ from 'expo-qq' // import ExpoQQ from 'expo-qq'
import { useRouter } from 'expo-router' import { useNavigation, useRouter } from 'expo-router'
// import ExpoWeChat from 'expo-wechat' // import ExpoWeChat from 'expo-wechat'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Image, Text, View } from 'react-native' import { Image, Text, View } from 'react-native'
import { toast } from 'sonner-native'
import { AButton, ACheckbox } from '@/components/common/ao' import { AButton, ACheckbox } from '@/components/common/ao'
import CustomHeader from '@/components/custom/Header' import CustomHeader from '@/components/custom/Header'
import { IconQq, IconWeixin } from '@/components/iconfont' import { IconQq, IconWeixin } from '@/components/iconfont'
import { loginQqApi, loginWxApi } from '@/request/api/auth' import { loginQqApi, loginWxApi } from '@/request/api/auth'
import { useAppStore } from '@/store/app' import { useAppStore } from '@/store/app'
import { useSpaceStore } from '@/store/space'
import { useUserStore } from '@/store/user' import { useUserStore } from '@/store/user'
import { toast } from '@/utils/toast'
export default function Auth() { export default function Auth() {
const appStore = useAppStore()
const navigation = useNavigation()
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [isAgree, setIsAgree] = useState(true) const [isAgree, setIsAgree] = useState(true)
const [form, setForm] = useState({ const [form, setForm] = useState({
@@ -23,7 +27,6 @@ export default function Auth() {
const router = useRouter() const router = useRouter()
const userStore = useUserStore() const userStore = useUserStore()
const appStore = useAppStore()
// const onLoginFinished = useEvent(ExpoQQ, 'onLoginFinished') // const onLoginFinished = useEvent(ExpoQQ, 'onLoginFinished')
// const onGetUserInfo = useEvent(ExpoQQ, 'onGetUserInfo') // const onGetUserInfo = useEvent(ExpoQQ, 'onGetUserInfo')
@@ -44,9 +47,7 @@ export default function Auth() {
// // 检查微信是否安装 // // 检查微信是否安装
// const isInstalled = await ExpoWeChat.isWXAppInstalled() // const isInstalled = await ExpoWeChat.isWXAppInstalled()
// if (!isInstalled) { // if (!isInstalled) {
// toast.show({ // toast.warning(onLoginFinished?.errorMessage || '请先安装微信')
// title: onLoginFinished?.errorMessage || '请先安装微信',
// })
// setLoading(false) // setLoading(false)
// return // return
// } // }
@@ -70,9 +71,7 @@ export default function Auth() {
// } // }
// if (!onLoginFinished.success) { // if (!onLoginFinished.success) {
// toast.show({ // toast.warning(onLoginFinished?.errorMessage || '授权失败,请检查手机是否安装 QQ 或确认授权')
// title: onLoginFinished?.errorMessage || '授权失败,请检查手机是否安装 QQ 或确认授权',
// })
// setLoading(false) // setLoading(false)
// return // return
// } // }
@@ -81,9 +80,7 @@ export default function Auth() {
// try { // try {
// const tokenInfo = await ExpoQQ.getLoginTokenInfo() // const tokenInfo = await ExpoQQ.getLoginTokenInfo()
// if (!tokenInfo.openId) { // if (!tokenInfo.openId) {
// toast.show({ // toast.warning(tokenInfo?.errorMessage || '授权失败,请检查手机是否安装 QQ 或确认授权')
// title: tokenInfo?.errorMessage || '授权失败,请检查手机是否安装 QQ 或确认授权',
// })
// setLoading(false) // setLoading(false)
// return // return
// } // }
@@ -126,8 +123,7 @@ export default function Auth() {
// nickname: loginRes.data.nickname, // nickname: loginRes.data.nickname,
// avatar: loginRes.data.avatar, // avatar: loginRes.data.avatar,
// }) // })
// await appStore.init()
// router.push('/space/manage')
// } // }
// } // }
// catch (err) { // catch (err) {
@@ -161,7 +157,7 @@ export default function Auth() {
// avatar: loginRes.data.avatar, // avatar: loginRes.data.avatar,
// }) // })
// router.push('/') // await appStore.init()
// } // }
// } // }
// catch (err) { // catch (err) {
@@ -180,19 +176,27 @@ export default function Auth() {
// handleLogin() // handleLogin()
// }, [authResult]) // }, [authResult])
function testLogin() { async function testLogin() {
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo3NjY3ODU5ODIxNjUwNjEsImlhdCI6MTc2OTM0ODI0Nn0.17ZNaHD3HSLM8dVn_JQK-gvsG9MKj47IRYV9D4xZkzs // eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo3NjY3ODU5ODIxNjUwNjEsImlhdCI6MTc2OTM0ODI0Nn0.17ZNaHD3HSLM8dVn_JQK-gvsG9MKj47IRYV9D4xZkzs
userStore.setUserInfo({ userStore.setUserInfo({
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo3NzgxMTUwMzIxMDA5MzMsImlhdCI6MTc3MjE5MDQ0Mn0.GF611RBvU47QuW2s4kOcdvh88ieIbHu7M_SmWeBOqLY', token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo3Nzk4OTU0MTkxMjE3MzMsImlhdCI6MTc3MjU0MDU1OH0.M5KqfPWdpOAlCCtZrJRxwKc8bRpGBjEt9BNCfgBZgnc',
id: 778115032100933, id: 778115032100933,
nickname: 'Zhang', nickname: 'Zhang',
avatar: 'http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100', avatar: 'http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100',
}) })
// appStore.init() await appStore.init()
router.replace('/') // navigationRef.reset({
// index: 0,
// routes: [{
// name: '(tabs)' as never,
// }],
// })
// console.log(navigation.getState()?.routeNames)
// ('/')
} }
return ( return (
@@ -84,8 +84,8 @@ export default function AuthSpace() {
<Pressable <Pressable
key={item.space_id} key={item.space_id}
onPress={() => { onPress={() => {
router.push({ router.navigate({
pathname: '/space/manage/sub-page/settings', pathname: '/space/sub-page/settings',
params: { params: {
spaceId: item.space_id, spaceId: item.space_id,
}, },
@@ -238,11 +238,12 @@ export default function AuthSpace() {
)} )}
> >
{ {
loading ? ( loading
<View className="flex-1 items-center justify-center"> ? (
<ActivityIndicator size="large" color="#333" /> <View className="flex-1 items-center justify-center">
</View> <ActivityIndicator size="large" color="#333" />
) </View>
)
: spaces.length === 0 : spaces.length === 0
? ( ? (
<View className="flex-1 items-center justify-center mt-12"> <View className="flex-1 items-center justify-center mt-12">
@@ -251,7 +252,8 @@ export default function AuthSpace() {
description="请选择 创建 或 加入 空间" description="请选择 创建 或 加入 空间"
/> />
</View> </View>
) : ( )
: (
<Sortable.Grid <Sortable.Grid
scrollableRef={scrollableRef} scrollableRef={scrollableRef}
keyExtractor={(item: UserSpace) => { keyExtractor={(item: UserSpace) => {
@@ -334,7 +336,7 @@ export default function AuthSpace() {
<AButton <AButton
className="rounded-full" className="rounded-full"
loading={createLoading} loading={createLoading}
onPress={() => { onPress={async () => {
if (!createForm.name) { if (!createForm.name) {
toast.warning('请输入空间名称') toast.warning('请输入空间名称')
return return
@@ -343,7 +345,7 @@ export default function AuthSpace() {
setCreateLoading(true) setCreateLoading(true)
try { try {
createSpaceApi({ await createSpaceApi({
name: createForm.name, name: createForm.name,
member_name: userStore.userInfo.nickname, member_name: userStore.userInfo.nickname,
sort_number: spaces.length, sort_number: spaces.length,
@@ -101,71 +101,63 @@ export default function Invite() {
<CustomHeader title="分享空间" /> <CustomHeader title="分享空间" />
{ {
loading ? ( loading
<View className="flex-1 items-center justify-center"> ? (
<ActivityIndicator size="large" color="#333" /> <View className="flex-1 items-center justify-center">
</View> <ActivityIndicator size="large" color="#333" />
) : (
<View className="px-5 pt-6">
{/* 邀请码卡片 */}
<View className="bg-white rounded-2xl p-6 items-center">
<Text className="text-gray-500 text-sm mb-3">
复制邀请码邀请家庭成员加入
</Text>
<Text className="text-4xl font-bold tracking-[8px] text-gray-900 mb-4">
{space?.invite_code}
</Text>
<View className="flex-row gap-3">
<AButton
onPress={copyInviteCode}
className="rounded-full flex-1"
leftIcon={
<LucideIcon icon="Copy" size={16} color="#fff" clickable={false} />
}
>
复制邀请码
</AButton>
{
userStore.userInfo.id === space?.owner_id && (
<AButton
variant="outline"
className="rounded-full px-4"
leftIcon={
<LucideIcon icon="RefreshCw" size={16} clickable={false} />
}
loading={refreshLoading}
onPress={refreshInviteCode}
>
刷新
</AButton>
)
}
</View> </View>
</View> )
: (
<View className="px-5 pt-6">
<View className="bg-white rounded-2xl p-6 items-center">
<Text className="text-gray-500 text-sm mb-3">
复制邀请码邀请家庭成员加入
</Text>
<View className="my-8"> <Text className="text-4xl font-bold tracking-[8px] text-gray-900 mb-4">
<ADivider direction="horizontal" text="或扫描二维码" /> {space?.invite_code}
</View> </Text>
{/* 二维码卡片 */} <View className="flex-row gap-3">
<TouchableOpacity <AButton
activeOpacity={0.9} onPress={copyInviteCode}
onPress={() => setPreviewVisible(true)} className="rounded-full flex-1"
className="bg-white rounded-2xl py-8 items-center" leftIcon={
> <LucideIcon icon="Copy" size={16} color="#fff" clickable={false} />
<QRCode }
size={160} >
value={qrcode || ''} 复制邀请码
/> </AButton>
</TouchableOpacity>
</View> {userStore.userInfo.id === space?.owner_id && (
) <AButton
variant="outline"
className="rounded-full px-4"
leftIcon={
<LucideIcon icon="RefreshCw" size={16} clickable={false} />
}
loading={refreshLoading}
onPress={refreshInviteCode}
>
刷新
</AButton>
)}
</View>
</View>
<View className="my-8">
<ADivider direction="horizontal" text="或扫描二维码" />
</View>
<TouchableOpacity
activeOpacity={0.9}
onPress={() => setPreviewVisible(true)}
className="bg-white rounded-2xl py-8 items-center"
>
<QRCode size={160} value={qrcode || ''} />
</TouchableOpacity>
</View>
)
} }
{/* 全屏预览(无动画) */} {/* 全屏预览(无动画) */}
@@ -1,5 +1,5 @@
import type { UserSpace } from '@/types/space' import type { UserSpace } from '@/types/space'
import { router, useFocusEffect, useLocalSearchParams } from 'expo-router' import { router, useFocusEffect, useLocalSearchParams, useNavigation } from 'expo-router'
import { useCallback, useEffect, useRef, useState } from 'react' import { useCallback, useEffect, useRef, useState } from 'react'
import { ActivityIndicator, Text, TouchableOpacity, View } from 'react-native' import { ActivityIndicator, Text, TouchableOpacity, View } from 'react-native'
import { KeyboardAvoidingView } from 'react-native-keyboard-controller' import { KeyboardAvoidingView } from 'react-native-keyboard-controller'
@@ -15,6 +15,7 @@ import {
ActionsheetDragIndicatorWrapper, ActionsheetDragIndicatorWrapper,
} from '@/components/ui/actionsheet' } from '@/components/ui/actionsheet'
import { dissolveSpaceApi, enterSpaceApi, exitSpaceApi, getSpaceSettingsApi, updateSpaceDefaultApi, updateSpaceMemberNameApi, updateSpaceNameApi } from '@/request/api/space' import { dissolveSpaceApi, enterSpaceApi, exitSpaceApi, getSpaceSettingsApi, updateSpaceDefaultApi, updateSpaceMemberNameApi, updateSpaceNameApi } from '@/request/api/space'
import { useNavStore } from '@/store/navigation'
import { useSpaceStore } from '@/store/space' import { useSpaceStore } from '@/store/space'
import { useUserStore } from '@/store/user' import { useUserStore } from '@/store/user'
@@ -62,6 +63,7 @@ function Item({
export default function Settings() { export default function Settings() {
const userStore = useUserStore() const userStore = useUserStore()
const spaceStore = useSpaceStore() const spaceStore = useSpaceStore()
const navStore = useNavStore()
const params = useLocalSearchParams<{ spaceId: string }>() const params = useLocalSearchParams<{ spaceId: string }>()
const { spaceId } = params const { spaceId } = params
@@ -102,6 +104,16 @@ export default function Settings() {
} }
}, [showName]) }, [showName])
useEffect(() => {
if (showMemberName) {
const timer = setTimeout(() => {
memberNameInputRef.current?.focus()
}, 300)
return () => clearTimeout(timer)
}
}, [showMemberName])
useFocusEffect( useFocusEffect(
useCallback(() => { useCallback(() => {
if (spaceId) { if (spaceId) {
@@ -147,7 +159,7 @@ export default function Settings() {
}) })
try { try {
enterSpaceApi({ await enterSpaceApi({
space_id: space.space_id, space_id: space.space_id,
}).then((res) => { }).then((res) => {
if (res.isSuccess) { if (res.isSuccess) {
@@ -156,7 +168,8 @@ export default function Settings() {
space_id: space.space_id, space_id: space.space_id,
role: space.role, role: space.role,
}) })
router.navigate('/money')
navStore.replace('(tabs)')
} }
}) })
} }
@@ -258,7 +271,7 @@ export default function Settings() {
title="邀请" title="邀请"
onPress={() => { onPress={() => {
router.navigate({ router.navigate({
pathname: '/space/manage/sub-page/invite', pathname: '/space/sub-page/invite',
params: { params: {
space_id: space.space_id, space_id: space.space_id,
}, },
@@ -279,7 +292,7 @@ export default function Settings() {
title="空间成员" title="空间成员"
onPress={() => { onPress={() => {
router.navigate({ router.navigate({
pathname: '/space/manage/sub-page/member', pathname: '/space/sub-page/member',
params: { params: {
space_id: space.space_id, space_id: space.space_id,
}, },
@@ -3,19 +3,21 @@ import { useState } from 'react'
import { Text, TouchableOpacity, View } from 'react-native' import { Text, TouchableOpacity, View } from 'react-native'
import CustomHeader from '@/components/custom/Header' import CustomHeader from '@/components/custom/Header'
import { useAppStore } from '@/store/app' import { useAppStore } from '@/store/app'
import { useNavStore } from '@/store/navigation'
export default function Share() { export default function Share() {
const router = useRouter() const router = useRouter()
const appStore = useAppStore() const appStore = useAppStore()
const navStore = useNavStore()
const [showExitModal, setShowExitModal] = useState(false) const [showExitModal, setShowExitModal] = useState(false)
function exitLogin() { function exitLogin() {
setShowExitModal(false) setShowExitModal(false)
// appStore.reset() appStore.reset()
router.replace('/auth') navStore.replace('/auth')
} }
return ( return (
+13 -2
View File
@@ -4,6 +4,7 @@ import { axiosRequestAdapter } from '@alova/adapter-axios'
import { createAlova } from 'alova' import { createAlova } from 'alova'
import { toast } from 'sonner-native' import { toast } from 'sonner-native'
import { useNavStore } from '@/store/navigation' import { useNavStore } from '@/store/navigation'
import { useSpaceStore } from '@/store/space'
import { useUserStore } from '@/store/user' import { useUserStore } from '@/store/user'
enum HttpCode { enum HttpCode {
@@ -11,6 +12,7 @@ enum HttpCode {
Unauthorized = 1001, Unauthorized = 1001,
Fail = 500, Fail = 500,
BusinessError = 2000, BusinessError = 2000,
SystemError = 3000,
} }
// 仅保留「无需登录」接口 // 仅保留「无需登录」接口
@@ -29,8 +31,8 @@ function isWhiteListed(url: string) {
} }
const alovaInstance = createAlova({ const alovaInstance = createAlova({
// baseURL: 'http://192.168.5.6:8086/app', baseURL: 'http://192.168.5.6:8086/app',
baseURL: 'http://192.168.1.137:8086/app', // baseURL: 'http://192.168.1.137:8086/app',
requestAdapter: axiosRequestAdapter(), requestAdapter: axiosRequestAdapter(),
timeout: 5000, timeout: 5000,
cacheFor: null, cacheFor: null,
@@ -54,6 +56,10 @@ const alovaInstance = createAlova({
toast.error(resData.message || '业务异常,请稍后再试') toast.error(resData.message || '业务异常,请稍后再试')
return result return result
} }
else if (resData.code === HttpCode.SystemError) {
toast.error(resData.message || '系统异常,请稍后再试')
return result
}
return result return result
}, },
@@ -69,6 +75,7 @@ const alovaInstance = createAlova({
return return
const userStore = useUserStore.getState() const userStore = useUserStore.getState()
const spaceStore = useSpaceStore.getState()
// 未登录直接拦截 // 未登录直接拦截
if (!userStore.isLoggedIn()) { if (!userStore.isLoggedIn()) {
@@ -78,6 +85,10 @@ const alovaInstance = createAlova({
// 注入 JWT // 注入 JWT
method.config.headers.Token = userStore.userInfo!.token method.config.headers.Token = userStore.userInfo!.token
if (spaceStore.inSpace()) {
method.config.headers.SPACE_ID = spaceStore.currentSpace?.space_id
}
}, },
}) })
+15 -35
View File
@@ -1,65 +1,45 @@
import { create } from 'zustand' import { create } from 'zustand'
import { enterDefaultSpaceApi } from '@/request/api/space' import { enterDefaultSpaceApi } from '@/request/api/space'
import { getUserSpaceApi } from '@/request/api/user'
import { useMoneyCategoryStore } from './moneyCategory'
import { useNavStore } from './navigation' import { useNavStore } from './navigation'
import { useSpaceStore } from './space' import { useSpaceStore } from './space'
import { useUserStore } from './user' import { useUserStore } from './user'
interface AppState { interface AppState {
ready: boolean
setReady: (v: boolean) => void
init: () => Promise<void> init: () => Promise<void>
reset: () => void reset: () => void
} }
export const useAppStore = create<AppState>((set, get) => ({ export const useAppStore = create<AppState>((set, get) => ({
ready: false,
setReady: (v: boolean) => set({ ready: v }),
init: async () => { init: async () => {
if (get().ready)
return
const userStore = useUserStore.getState() const userStore = useUserStore.getState()
const navStore = useNavStore.getState() const navStore = useNavStore.getState()
const moneyCategoryStore = useMoneyCategoryStore.getState()
const spaceStore = useSpaceStore.getState() const spaceStore = useSpaceStore.getState()
// 如果没登录,跳转到登录页,但不退出初始化
if (!userStore.isLoggedIn()) { if (!userStore.isLoggedIn()) {
navStore.navigateToAuth() // navStore.navigateToAuth()
navStore.replace(`/auth`)
return return
} }
try { if (spaceStore.inSpace())
// 1️⃣ 初始化默认空间(如果用户当前没选中空间) return
if (!spaceStore.inSpace()) {
const res = await enterDefaultSpaceApi()
if (res.isSuccess) {
if (res.data.space_id === 0) {
// 跳转到空间管理页面
}
spaceStore.setCurrentSpace(res.data)
}
}
// 2️⃣ 初始化分类 const res = await enterDefaultSpaceApi()
await moneyCategoryStore.init() if (!res.isSuccess)
return
const space = res.data
if (space.space_id === 0) {
navStore.navigateTo(`/space`)
} }
catch (err) { else {
console.error('App init error:', err) spaceStore.setCurrentSpace(space)
}
finally { navStore.replace(`(tabs)`)
// 5️⃣ 初始化完成
set({ ready: true })
} }
}, },
reset: () => { reset: () => {
set({ ready: false })
useMoneyCategoryStore.getState().clear()
useUserStore.getState().clear() useUserStore.getState().clear()
useSpaceStore.getState().clear() useSpaceStore.getState().clear()
}, },
+13 -2
View File
@@ -1,5 +1,5 @@
import type { icons } from 'lucide-react-native' import type { icons } from 'lucide-react-native'
import { router } from 'expo-router' import { router, useNavigation } from 'expo-router'
import { create } from 'zustand' import { create } from 'zustand'
export interface NavItem { export interface NavItem {
@@ -11,8 +11,10 @@ export interface NavItem {
interface NavState { interface NavState {
navMenus: NavItem[] navMenus: NavItem[]
pathname: string pathname: string
replace: (p: string) => void
setPathname: (p: string) => void setPathname: (p: string) => void
navigateToAuth: () => void navigateToAuth: () => void
navigateTo: (p: string) => void
setNavMenus: (menus: NavItem[]) => void setNavMenus: (menus: NavItem[]) => void
} }
@@ -21,7 +23,7 @@ const DEFAULT_NAV_MENUS: NavItem[] = [
{ label: '恋爱记', path: '/love', icon: 'Heart' }, { label: '恋爱记', path: '/love', icon: 'Heart' },
{ label: '聊天', path: '/chat', icon: 'MessageCircle' }, { label: '聊天', path: '/chat', icon: 'MessageCircle' },
{ label: '个人中心', path: '/user', icon: 'CircleUserRound' }, { label: '个人中心', path: '/user', icon: 'CircleUserRound' },
{ label: '空间管理', path: '/space/manage', icon: 'Earth' }, { label: '空间管理', path: '/space', icon: 'Earth' },
] ]
export const useNavStore = create<NavState>()( export const useNavStore = create<NavState>()(
@@ -37,6 +39,15 @@ export const useNavStore = create<NavState>()(
router.replace('/auth') router.replace('/auth')
} }
}, },
navigateTo: (p: string) => {
router.navigate(p)
},
replace: (p: string) => {
if (router.canDismiss()) {
router.dismissAll()
}
router.replace(p)
},
setNavMenus: navMenus => set({ navMenus }), setNavMenus: navMenus => set({ navMenus }),
}), }),
) )