Spaces:
Paused
Paused
| """localStorage integration for Gradio via JavaScript injection. | |
| Provides JavaScript code that syncs session state with browser localStorage. | |
| """ | |
| # localStorage keys | |
| STORAGE_KEY_SESSION = "fdam_current_session" | |
| STORAGE_KEY_HISTORY = "fdam_assessment_history" | |
| STORAGE_KEY_IMAGES = "fdam_image_refs" # References only, not actual bytes | |
| # JavaScript code for localStorage operations | |
| LOCALSTORAGE_JS = """ | |
| <script> | |
| (function() { | |
| // FDAM localStorage utilities | |
| window.fdamStorage = { | |
| KEYS: { | |
| SESSION: 'fdam_current_session', | |
| HISTORY: 'fdam_assessment_history', | |
| IMAGE_REFS: 'fdam_image_refs' | |
| }, | |
| // Save current session | |
| saveSession: function(sessionJson) { | |
| try { | |
| localStorage.setItem(this.KEYS.SESSION, sessionJson); | |
| console.log('[FDAM] Session saved to localStorage'); | |
| return true; | |
| } catch (e) { | |
| console.error('[FDAM] Failed to save session:', e); | |
| return false; | |
| } | |
| }, | |
| // Load current session | |
| loadSession: function() { | |
| try { | |
| const data = localStorage.getItem(this.KEYS.SESSION); | |
| if (data) { | |
| console.log('[FDAM] Session loaded from localStorage'); | |
| return data; | |
| } | |
| } catch (e) { | |
| console.error('[FDAM] Failed to load session:', e); | |
| } | |
| return null; | |
| }, | |
| // Save assessment history | |
| saveHistory: function(historyJson) { | |
| try { | |
| localStorage.setItem(this.KEYS.HISTORY, historyJson); | |
| console.log('[FDAM] History saved to localStorage'); | |
| return true; | |
| } catch (e) { | |
| console.error('[FDAM] Failed to save history:', e); | |
| return false; | |
| } | |
| }, | |
| // Load assessment history | |
| loadHistory: function() { | |
| try { | |
| const data = localStorage.getItem(this.KEYS.HISTORY); | |
| if (data) { | |
| console.log('[FDAM] History loaded from localStorage'); | |
| return data; | |
| } | |
| } catch (e) { | |
| console.error('[FDAM] Failed to load history:', e); | |
| } | |
| return null; | |
| }, | |
| // Clear all FDAM data | |
| clearAll: function() { | |
| try { | |
| localStorage.removeItem(this.KEYS.SESSION); | |
| localStorage.removeItem(this.KEYS.HISTORY); | |
| localStorage.removeItem(this.KEYS.IMAGE_REFS); | |
| console.log('[FDAM] All localStorage data cleared'); | |
| return true; | |
| } catch (e) { | |
| console.error('[FDAM] Failed to clear storage:', e); | |
| return false; | |
| } | |
| }, | |
| // Get storage usage info | |
| getStorageInfo: function() { | |
| try { | |
| let total = 0; | |
| for (let key in localStorage) { | |
| if (key.startsWith('fdam_')) { | |
| total += localStorage.getItem(key).length; | |
| } | |
| } | |
| return { | |
| used_bytes: total, | |
| used_kb: (total / 1024).toFixed(2), | |
| limit_kb: 5120 // ~5MB typical limit | |
| }; | |
| } catch (e) { | |
| return { error: e.message }; | |
| } | |
| } | |
| }; | |
| // Expose to global scope for Gradio callbacks | |
| window.saveSession = window.fdamStorage.saveSession.bind(window.fdamStorage); | |
| window.loadSession = window.fdamStorage.loadSession.bind(window.fdamStorage); | |
| window.saveHistory = window.fdamStorage.saveHistory.bind(window.fdamStorage); | |
| window.loadHistory = window.fdamStorage.loadHistory.bind(window.fdamStorage); | |
| console.log('[FDAM] localStorage utilities loaded'); | |
| })(); | |
| </script> | |
| """ | |
| # JavaScript functions for Gradio event handlers | |
| JS_SAVE_SESSION = """ | |
| async (sessionJson) => { | |
| if (window.fdamStorage) { | |
| window.fdamStorage.saveSession(sessionJson); | |
| } | |
| return sessionJson; | |
| } | |
| """ | |
| JS_LOAD_SESSION = """ | |
| async () => { | |
| if (window.fdamStorage) { | |
| return window.fdamStorage.loadSession() || '{}'; | |
| } | |
| return '{}'; | |
| } | |
| """ | |
| JS_SAVE_HISTORY = """ | |
| async (historyJson) => { | |
| if (window.fdamStorage) { | |
| window.fdamStorage.saveHistory(historyJson); | |
| } | |
| return historyJson; | |
| } | |
| """ | |
| JS_LOAD_HISTORY = """ | |
| async () => { | |
| if (window.fdamStorage) { | |
| return window.fdamStorage.loadHistory() || '{"assessments":[],"current_session_id":null}'; | |
| } | |
| return '{"assessments":[],"current_session_id":null}'; | |
| } | |
| """ | |
| # JavaScript to auto-load session on page load | |
| JS_AUTO_LOAD = """ | |
| async () => { | |
| // Small delay to ensure Gradio is fully loaded | |
| await new Promise(resolve => setTimeout(resolve, 500)); | |
| if (window.fdamStorage) { | |
| const session = window.fdamStorage.loadSession(); | |
| const history = window.fdamStorage.loadHistory(); | |
| return [session || '{}', history || '{"assessments":[],"current_session_id":null}']; | |
| } | |
| return ['{}', '{"assessments":[],"current_session_id":null}']; | |
| } | |
| """ | |
| def get_head_html(additional_scripts: str = "") -> str: | |
| """Get HTML to inject into Gradio head for localStorage support. | |
| Args: | |
| additional_scripts: Optional additional HTML/JS to include. | |
| Returns: | |
| Combined HTML string for head injection. | |
| """ | |
| return LOCALSTORAGE_JS + additional_scripts | |
| def create_save_trigger_js(field_updates: dict[str, str]) -> str: | |
| """Create JavaScript that triggers save after field updates. | |
| Args: | |
| field_updates: Mapping of field name to value expression | |
| Returns: | |
| JavaScript code string | |
| """ | |
| updates = ", ".join(f'"{k}": {v}' for k, v in field_updates.items()) | |
| return f""" | |
| async (currentSession, ...values) => {{ | |
| try {{ | |
| const session = JSON.parse(currentSession || '{{}}'); | |
| const updates = {{ {updates} }}; | |
| Object.assign(session, updates); | |
| session.updated_at = new Date().toISOString(); | |
| const newSession = JSON.stringify(session); | |
| if (window.fdamStorage) {{ | |
| window.fdamStorage.saveSession(newSession); | |
| }} | |
| return newSession; | |
| }} catch (e) {{ | |
| console.error('[FDAM] Save trigger error:', e); | |
| return currentSession; | |
| }} | |
| }} | |
| """ | |