Files
JKVideo/store/authStore.ts
Developer 1e0931b5d1 fix: 登录后头像不更新 — 将 getUserInfo 合并进 login()
登录流程之前分两步:login() 只设 isLoggedIn,getUserInfo/setProfile
由 LoginModal 调用。网络抖动或 B站 session 传播延迟时 getUserInfo
抛错被静默吞掉,face 不更新,直到下次启动 restore() 才修复。

修复:login() 内部完成 getUserInfo + 持久化,LoginModal 只需
await login() 后关闭弹窗,不再重复获取头像。
2026-03-26 01:16:20 +08:00

71 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { create } from 'zustand';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { getUserInfo } from '../services/bilibili';
import { getSecure, setSecure, deleteSecure } from '../utils/secureStorage';
interface AuthState {
sessdata: string | null;
uid: string | null;
username: string | null;
face: string | null;
isLoggedIn: boolean;
login: (sessdata: string, uid: string, username?: string) => Promise<void>;
logout: () => Promise<void>;
restore: () => Promise<void>;
setProfile: (face: string, username: string, uid: string) => void;
}
export const useAuthStore = create<AuthState>((set) => ({
sessdata: null,
uid: null,
username: null,
face: null,
isLoggedIn: false,
login: async (sessdata, uid, username) => {
await setSecure('SESSDATA', sessdata);
// Migrate: remove SESSDATA from AsyncStorage if it was there before
await AsyncStorage.removeItem('SESSDATA').catch(() => {});
set({ sessdata, uid: uid || null, username: username || null, isLoggedIn: true });
// 登录后立即拉取用户信息,确保当前 session 头像可用(不依赖调用方 setProfile
try {
const info = await getUserInfo();
await AsyncStorage.multiSet([
['UID', String(info.mid)],
['USERNAME', info.uname],
['FACE', info.face],
]);
set({ face: info.face, username: info.uname, uid: String(info.mid) });
} catch {}
},
logout: async () => {
await deleteSecure('SESSDATA');
await AsyncStorage.multiRemove(['UID', 'USERNAME', 'FACE']);
set({ sessdata: null, uid: null, username: null, face: null, isLoggedIn: false });
},
restore: async () => {
// Try SecureStore first, fallback to AsyncStorage for migration
let sessdata = await getSecure('SESSDATA');
if (!sessdata) {
sessdata = await AsyncStorage.getItem('SESSDATA');
if (sessdata) {
// Migrate from AsyncStorage to SecureStore
await setSecure('SESSDATA', sessdata);
await AsyncStorage.removeItem('SESSDATA');
}
}
if (sessdata) {
set({ sessdata, isLoggedIn: true });
try {
const info = await getUserInfo();
await AsyncStorage.setItem('FACE', info.face);
set({ face: info.face, username: info.uname, uid: String(info.mid) });
} catch {}
}
},
setProfile: (face, username, uid) => set({ face, username, uid }),
}));