修复部分已知问题
This commit is contained in:
71
App.tsx
71
App.tsx
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user