refactor: migrate img tags to next/image and fix hook usage
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
/**
|
||||
* Auth 状态机(XState v5)
|
||||
*
|
||||
* 原始 Dart: lib/ui/auth/bloc/auth_bloc.dart + auth_state.dart + auth_event.dart
|
||||
*
|
||||
* 本轮迁移:社交登录改由 NextAuth 处理(`@/lib/auth/nextauth`),状态机仅保留
|
||||
* 邮箱注册/登录 + 通用 reset 事件。社交登录走 `new AuthPlatform("google").signIn()` /
|
||||
* `new AuthPlatform("facebook").signIn()`。
|
||||
*/
|
||||
import { setup, fromPromise, assign } from "xstate";
|
||||
|
||||
import type { LoginType } from "@/models/auth/login-type";
|
||||
import { authRepository } from "@/data/repositories/auth_repository";
|
||||
import { AuthStorage } from "@/data/storage/auth/auth_storage";
|
||||
import { Result } from "@/utils/result";
|
||||
|
||||
import { AuthState, initialState } from "./auth-state";
|
||||
import type { AuthEvent } from "./auth-events";
|
||||
|
||||
// 重新导出 State / Event 类型,保持 machine 文件的公共 API 不变
|
||||
export type { AuthState } from "./auth-state";
|
||||
export { initialState } from "./auth-state";
|
||||
export type { AuthEvent } from "./auth-events";
|
||||
|
||||
// ============================================================
|
||||
// Helpers
|
||||
// ============================================================
|
||||
async function readGuestId(): Promise<string | undefined> {
|
||||
const r = await AuthStorage.getInstance().getDeviceId();
|
||||
if (r.success && r.data != null) {
|
||||
return r.data;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Actors(异步服务)
|
||||
// ============================================================
|
||||
// 邮箱登录 actor 仅调 authRepository.emailLogin 拿业务 token。
|
||||
// 本轮起不再调 /api/auth/marker 写 cookie(统一迁到 NextAuth session
|
||||
// cookie 检测,邮箱登录 proxy 行为在后续轮恢复)。
|
||||
|
||||
const emailLoginActor = fromPromise<LoginType, { email: string; password: string }>(
|
||||
async ({ input }) => {
|
||||
const guestId = await readGuestId();
|
||||
const result = await authRepository.emailLogin({ ...input, guestId });
|
||||
if (Result.isErr(result)) throw result.error;
|
||||
return "email" as LoginType;
|
||||
},
|
||||
);
|
||||
|
||||
const emailRegisterThenLoginActor = fromPromise<
|
||||
LoginType,
|
||||
{ email: string; password: string; username: string; confirmPassword: string }
|
||||
>(async ({ input }) => {
|
||||
const guestId = await readGuestId();
|
||||
|
||||
const registerResult = await authRepository.register({ ...input, guestId });
|
||||
if (Result.isErr(registerResult)) throw registerResult.error;
|
||||
|
||||
// 注册后自动登录(对齐 Dart 行为)
|
||||
const loginResult = await authRepository.emailLogin({
|
||||
email: input.email,
|
||||
password: input.password,
|
||||
guestId,
|
||||
});
|
||||
if (Result.isErr(loginResult)) throw loginResult.error;
|
||||
return "email" as LoginType;
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// Machine
|
||||
// ============================================================
|
||||
export const authMachine = setup({
|
||||
types: {
|
||||
context: {} as AuthState,
|
||||
events: {} as AuthEvent,
|
||||
},
|
||||
actors: {
|
||||
emailLogin: emailLoginActor,
|
||||
emailRegisterThenLogin: emailRegisterThenLoginActor,
|
||||
},
|
||||
}).createMachine({
|
||||
id: "auth",
|
||||
initial: "idle",
|
||||
context: initialState,
|
||||
states: {
|
||||
idle: {
|
||||
on: {
|
||||
AuthPanelModeChanged: {
|
||||
actions: assign({
|
||||
authPanelMode: ({ event }) => event.mode,
|
||||
errorMessage: null,
|
||||
}),
|
||||
},
|
||||
AuthModeChanged: {
|
||||
actions: assign({
|
||||
authMode: ({ event }) => event.mode,
|
||||
errorMessage: null,
|
||||
}),
|
||||
},
|
||||
AuthFormCleared: {
|
||||
actions: assign({
|
||||
email: "",
|
||||
password: "",
|
||||
username: "",
|
||||
confirmPassword: "",
|
||||
errorMessage: null,
|
||||
}),
|
||||
},
|
||||
AuthReset: {
|
||||
actions: assign(() => initialState),
|
||||
},
|
||||
AuthEmailLoginSubmitted: "loadingEmailLogin",
|
||||
AuthEmailRegisterSubmitted: "loadingEmailRegister",
|
||||
// 社交登录已迁移到 NextAuth + AuthPlatform 类
|
||||
// 状态机保留事件以兼容旧调用方(实际不再触发)
|
||||
AuthGoogleLoginSubmitted: {},
|
||||
AuthFacebookLoginSubmitted: {},
|
||||
AuthAppleLoginSubmitted: {
|
||||
actions: assign({
|
||||
errorMessage: "Apple login not implemented",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
loadingEmailLogin: {
|
||||
invoke: {
|
||||
src: "emailLogin",
|
||||
input: ({ event }) => {
|
||||
if (event.type !== "AuthEmailLoginSubmitted")
|
||||
return { email: "", password: "" };
|
||||
return { email: event.email, password: event.password };
|
||||
},
|
||||
onDone: {
|
||||
target: "success",
|
||||
actions: assign({
|
||||
loginType: ({ event }) => event.output,
|
||||
errorMessage: null,
|
||||
}),
|
||||
},
|
||||
onError: {
|
||||
target: "idle",
|
||||
actions: assign({
|
||||
errorMessage: ({ event }) =>
|
||||
event.error instanceof Error ? event.error.message : String(event.error),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
loadingEmailRegister: {
|
||||
invoke: {
|
||||
src: "emailRegisterThenLogin",
|
||||
input: ({ event }) => {
|
||||
if (event.type !== "AuthEmailRegisterSubmitted")
|
||||
return { email: "", password: "", username: "", confirmPassword: "" };
|
||||
return {
|
||||
email: event.email,
|
||||
password: event.password,
|
||||
username: event.username,
|
||||
confirmPassword: event.confirmPassword,
|
||||
};
|
||||
},
|
||||
onDone: {
|
||||
target: "success",
|
||||
actions: assign({
|
||||
loginType: ({ event }) => event.output,
|
||||
errorMessage: null,
|
||||
}),
|
||||
},
|
||||
onError: {
|
||||
target: "idle",
|
||||
actions: assign({
|
||||
errorMessage: ({ event }) =>
|
||||
event.error instanceof Error ? event.error.message : String(event.error),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
success: {
|
||||
// 终态:业务层通过 state.matches("success") 判断
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export type AuthMachine = typeof authMachine;
|
||||
Reference in New Issue
Block a user