feat(auth): add pending action queue and api auth wrapper

This commit is contained in:
zetaloop
2026-02-22 08:29:18 +08:00
parent dc629c9472
commit 8ce3b8a8b5
3 changed files with 38 additions and 7 deletions
+24
View File
@@ -0,0 +1,24 @@
import { useLoginDialogStore } from "@/store/login-dialog"
type RequestExecutor<T> = () => Promise<T>
interface RequestOptions {
onUnauthorized?: () => void
}
export async function requestWithAuth<T>(executor: RequestExecutor<T>, options?: RequestOptions) {
try {
return await executor()
} catch (error) {
if (error instanceof Error && error.message === "UNAUTHORIZED") {
if (options?.onUnauthorized) {
useLoginDialogStore.getState().openLoginDialog(options.onUnauthorized)
} else {
useLoginDialogStore.getState().openLoginDialog()
}
return null
}
throw error
}
}
+1
View File
@@ -1,4 +1,5 @@
export { getChatSessionById, listChatMessages, listChatSessions } from "./chat"
export { requestWithAuth } from "./client"
export { listComments, listCommentsByPost } from "./comments"
export { getDisputeByOrderId, listDisputes } from "./disputes"
export { isFavorited, listFavorites, listFavoritesByUser } from "./favorites"
+13 -7
View File
@@ -2,7 +2,7 @@ import { create } from "zustand"
interface LoginDialogState {
open: boolean
pendingAction: (() => void) | null
pendingActions: Array<() => void>
openLoginDialog: (action?: () => void) => void
closeLoginDialog: () => void
consumePendingAction: () => void
@@ -10,12 +10,18 @@ interface LoginDialogState {
export const useLoginDialogStore = create<LoginDialogState>((set, get) => ({
open: false,
pendingAction: null,
openLoginDialog: (action) => set({ open: true, pendingAction: action ?? null }),
closeLoginDialog: () => set({ open: false, pendingAction: null }),
pendingActions: [],
openLoginDialog: (action) =>
set((state) => ({
open: true,
pendingActions: action ? [...state.pendingActions, action] : state.pendingActions,
})),
closeLoginDialog: () => set({ open: false, pendingActions: [] }),
consumePendingAction: () => {
const action = get().pendingAction
set({ pendingAction: null })
action?.()
const actions = get().pendingActions
set({ pendingActions: [] })
actions.forEach((action) => {
action()
})
},
}))