修复部分已知问题

This commit is contained in:
2025-11-22 16:38:36 +08:00
parent 2878783349
commit 7487be2bb5
8 changed files with 216 additions and 43 deletions

71
App.tsx
View File

@@ -32,8 +32,10 @@ const App: React.FC = () => {
// Default to 'zh' (Chinese)
const [language, setLanguage] = useState<Language>(() => (localStorage.getItem(STORAGE_KEYS.LANGUAGE) as Language) || 'zh');
const [chatSessions, setChatSessions] = useState<ChatSession[]>(() => {
const stored = localStorage.getItem(STORAGE_KEYS.CHAT_SESSIONS);
if (stored) return JSON.parse(stored);
try {
const stored = localStorage.getItem(STORAGE_KEYS.CHAT_SESSIONS);
if (stored) return JSON.parse(stored);
} catch (e) { console.error("Failed to load chat sessions", e); }
return [];
});
const [activeSessionId, setActiveSessionId] = useState<string>(() => localStorage.getItem(STORAGE_KEYS.ACTIVE_SESSION) || '');
@@ -65,14 +67,63 @@ const App: React.FC = () => {
const t = translations[language];
useEffect(() => { localStorage.setItem(STORAGE_KEYS.CHAT_SESSIONS, JSON.stringify(chatSessions)); }, [chatSessions]);
useEffect(() => { localStorage.setItem(STORAGE_KEYS.ACTIVE_SESSION, activeSessionId); }, [activeSessionId]);
useEffect(() => { localStorage.setItem(STORAGE_KEYS.TRANSLATION_HISTORY, JSON.stringify(translationHistory)); }, [translationHistory]);
useEffect(() => { localStorage.setItem(STORAGE_KEYS.READING_HISTORY, JSON.stringify(readingHistory)); }, [readingHistory]);
useEffect(() => { localStorage.setItem(STORAGE_KEYS.LISTENING_HISTORY, JSON.stringify(listeningHistory)); }, [listeningHistory]);
useEffect(() => { localStorage.setItem(STORAGE_KEYS.OCR_HISTORY, JSON.stringify(ocrHistory)); }, [ocrHistory]);
useEffect(() => { localStorage.setItem(STORAGE_KEYS.LANGUAGE, language); }, [language]);
useEffect(() => { localStorage.setItem(STORAGE_KEYS.SELECTED_MODEL, selectedModel); }, [selectedModel]);
// Safe Storage Helper to prevent white screen on QuotaExceededError
const saveToStorage = (key: string, data: any) => {
try {
const json = JSON.stringify(data);
localStorage.setItem(key, json);
} catch (e: any) {
// Check for QuotaExceededError
if (e.name === 'QuotaExceededError' || e.message?.includes('exceeded the quota')) {
console.warn(`Storage quota exceeded for key: ${key}`);
addToast('error', translations[language].common.storageFull);
// Attempt to recover by stripping heavy data (e.g., audioUrl from chats, base64 images from OCR)
if (key === STORAGE_KEYS.CHAT_SESSIONS && Array.isArray(data)) {
try {
// Create a lightweight version by removing audioUrl base64 strings
const leanData = (data as ChatSession[]).map(s => ({
...s,
messages: s.messages.map(m => ({
...m,
metadata: {
...m.metadata,
audioUrl: undefined // Remove cached audio to save space
}
}))
}));
localStorage.setItem(key, JSON.stringify(leanData));
addToast('info', translations[language].common.storageOptimized);
} catch (retryError) {
console.error("Failed to save even lean chat data", retryError);
}
} else if (key === STORAGE_KEYS.OCR_HISTORY && Array.isArray(data)) {
try {
// Create lightweight version by removing imagePreview
const leanData = (data as OCRRecord[]).map(r => ({
...r,
imagePreview: '' // Remove heavy base64 image
}));
localStorage.setItem(key, JSON.stringify(leanData));
addToast('info', translations[language].common.storageOptimized);
} catch (retryError) {
console.error("Failed to save even lean OCR data", retryError);
}
}
} else {
console.error("LocalStorage save failed", e);
}
}
};
useEffect(() => { saveToStorage(STORAGE_KEYS.CHAT_SESSIONS, chatSessions); }, [chatSessions]);
useEffect(() => { saveToStorage(STORAGE_KEYS.ACTIVE_SESSION, activeSessionId); }, [activeSessionId]);
useEffect(() => { saveToStorage(STORAGE_KEYS.TRANSLATION_HISTORY, translationHistory); }, [translationHistory]);
useEffect(() => { saveToStorage(STORAGE_KEYS.READING_HISTORY, readingHistory); }, [readingHistory]);
useEffect(() => { saveToStorage(STORAGE_KEYS.LISTENING_HISTORY, listeningHistory); }, [listeningHistory]);
useEffect(() => { saveToStorage(STORAGE_KEYS.OCR_HISTORY, ocrHistory); }, [ocrHistory]);
useEffect(() => { saveToStorage(STORAGE_KEYS.LANGUAGE, language); }, [language]);
useEffect(() => { saveToStorage(STORAGE_KEYS.SELECTED_MODEL, selectedModel); }, [selectedModel]);
useEffect(() => {
const activeSession = chatSessions.find(s => s.id === activeSessionId);