import { create } from 'zustand';
export type AppLockDialogMode = 'set' | 'change' | 'disable';
interface AppLockState {
/**
* Has the gate been initialized from on-disk settings yet? Until
* this flips to `true` the gate renders nothing — guarantees the
* library/reader can never flash on screen before the lock screen
* does.
*/
isInitialized: boolean;
/**
* Session-scoped unlock flag. `true` if there is no PIN configured
* OR the user has entered the correct PIN since this page load.
* Flipping back to `false` is reserved for future re-lock-on-resume
* work; today nothing calls `lock()` after the initial unlock.
*/
isUnlocked: boolean;
/** Cached copy of the PIN salt + hash — mirrors `SystemSettings`. */
pinHash: string | null;
pinSalt: string | null;
/** Called once from `Providers` after `loadSettings` resolves. */
initialize: (config: { enabled: boolean; hash?: string; salt?: string }) => void;
/** Called by `` after a verified PIN entry. */
unlock: () => void;
/** Reserved for future re-lock work (background timeout, etc.). */
lock: () => void;
/** Called from the settings dialog after persisting a new/changed PIN. */
setPin: (hash: string, salt: string) => void;
/** Called from the settings dialog after disabling the lock. */
clearPin: () => void;
/**
* Which app-lock dialog (if any) is currently open. Lifted out of
* `SettingsMenu` because that component unmounts when its dropdown
* closes — local dialog state would never get to render.
*/
dialogMode: AppLockDialogMode | null;
openDialog: (mode: AppLockDialogMode) => void;
closeDialog: () => void;
}
export const useAppLockStore = create((set) => ({
isInitialized: false,
isUnlocked: true,
pinHash: null,
pinSalt: null,
initialize: ({ enabled, hash, salt }) =>
set({
isInitialized: true,
isUnlocked: !enabled,
pinHash: hash ?? null,
pinSalt: salt ?? null,
}),
unlock: () => set({ isUnlocked: true }),
lock: () => set({ isUnlocked: false }),
setPin: (hash, salt) => set({ pinHash: hash, pinSalt: salt }),
clearPin: () => set({ pinHash: null, pinSalt: null, isUnlocked: true }),
dialogMode: null,
openDialog: (mode) => set({ dialogMode: mode }),
closeDialog: () => set({ dialogMode: null }),
}));