Files
QRGen/gui/src-frontend/src/store/qrContext.tsx
T

66 lines
2.1 KiB
TypeScript

import React, { createContext, useContext, useReducer, useEffect, type ReactNode } from 'react';
import { Store } from '@tauri-apps/plugin-store';
import type { QrState, QrAction, HistoryEntry } from '../types';
const initialState: QrState = {
mode: 'text',
formData: {},
config: { level: 'M', margin: 4, moduleSize: 8 },
preview: null,
history: [],
loading: false,
};
function qrReducer(state: QrState, action: QrAction): QrState {
switch (action.type) {
case 'SET_MODE':
return { ...state, mode: action.payload, formData: {}, preview: null };
case 'SET_FORM_DATA':
return { ...state, formData: action.payload };
case 'SET_CONFIG':
return { ...state, config: { ...state.config, ...action.payload } };
case 'SET_PREVIEW':
return { ...state, preview: action.payload, loading: false };
case 'SET_LOADING':
return { ...state, loading: action.payload };
case 'SET_HISTORY':
return { ...state, history: action.payload };
case 'ADD_HISTORY':
return { ...state, history: [action.payload, ...state.history].slice(0, 50) };
case 'REMOVE_HISTORY':
return { ...state, history: state.history.filter(h => h.id !== action.payload) };
case 'RESET':
return { ...initialState, history: state.history };
default:
return state;
}
}
const QrContext = createContext<{
state: QrState;
dispatch: React.Dispatch<QrAction>;
} | null>(null);
export function QrProvider({ children }: { children: ReactNode }) {
const [state, dispatch] = useReducer(qrReducer, initialState);
// 启动时从 store 加载持久化的历史记录
useEffect(() => {
(async () => {
try {
const store = await Store.load('history.json');
const history = await store.get<HistoryEntry[]>('qr-history') || [];
dispatch({ type: 'SET_HISTORY', payload: history });
} catch { /* store 不可用时忽略 */ }
})();
}, []);
return <QrContext.Provider value={{ state, dispatch }}>{children}</QrContext.Provider>;
}
export function useQrState() {
const ctx = useContext(QrContext);
if (!ctx) throw new Error('useQrState must be inside QrProvider');
return ctx;
}