feat(Settings): add wrote flag to SavedJson and update writeSettings logic to indicate if files were written

This commit is contained in:
Jaime Idolpx 2026-06-11 21:55:45 -04:00
parent 199ae0e3d8
commit d9f95c6864
2 changed files with 18 additions and 9 deletions

View File

@ -413,7 +413,9 @@ export default function DeviceDetailOverlay({
)} )}
</div> </div>
{deviceData.cache !== undefined && ( {(deviceData.cache !== undefined ||
(deviceData.base_url ?? '').includes('://') ||
(deviceData.url ?? '').includes('://')) && (
<div> <div>
<label className="text-sm text-neutral-500 block mb-2">Cache</label> <label className="text-sm text-neutral-500 block mb-2">Cache</label>
<div className="flex gap-2"> <div className="flex gap-2">

View File

@ -167,6 +167,8 @@ export async function readSettings(): Promise<ReadSettingsResult | null> {
export interface SavedJson { export interface SavedJson {
configJson: string; configJson: string;
devicesJson: string; devicesJson: string;
/** True if at least one file was actually written. */
wrote: boolean;
} }
/** Serialize config into the two canonical JSON strings without writing anything. */ /** Serialize config into the two canonical JSON strings without writing anything. */
@ -175,6 +177,7 @@ export function serializeConfig(config: SettingsConfig): SavedJson {
return { return {
configJson: JSON.stringify(mainConfig, null, 2) + '\n', configJson: JSON.stringify(mainConfig, null, 2) + '\n',
devicesJson: JSON.stringify({ devices }, null, 2) + '\n', devicesJson: JSON.stringify({ devices }, null, 2) + '\n',
wrote: false,
}; };
} }
@ -195,7 +198,7 @@ export async function writeSettings(
const writeConfig = !lastSaved || next.configJson !== lastSaved.configJson; const writeConfig = !lastSaved || next.configJson !== lastSaved.configJson;
const writeDevices = !lastSaved || next.devicesJson !== lastSaved.devicesJson; const writeDevices = !lastSaved || next.devicesJson !== lastSaved.devicesJson;
if (!writeConfig && !writeDevices) return next; if (!writeConfig && !writeDevices) return { ...next, wrote: false };
try { await createFolder(SETTINGS_DIR, true); } catch { /* exists */ } try { await createFolder(SETTINGS_DIR, true); } catch { /* exists */ }
@ -216,7 +219,7 @@ export async function writeSettings(
} }
} catch { /* /sd unreachable — skip mirror */ } } catch { /* /sd unreachable — skip mirror */ }
return next; return { ...next, wrote: true };
} }
export type SaveStatus = export type SaveStatus =
@ -327,12 +330,16 @@ export function useSettings(): UseSettingsResult {
setPendingCount(0); setPendingCount(0);
setSaveStatus('saving'); setSaveStatus('saving');
try { try {
lastSavedRef.current = await writeSettings(configRef.current, lastSavedRef.current); const result = await writeSettings(configRef.current, lastSavedRef.current);
lastSavedRef.current = result;
if (result.wrote) {
setSaveStatus('saved'); setSaveStatus('saved');
// Drop the "saved" badge after a short delay so it doesn't linger.
savedTimerRef.current = window.setTimeout(() => { savedTimerRef.current = window.setTimeout(() => {
setSaveStatus((s) => (s === 'saved' ? 'idle' : s)); setSaveStatus((s) => (s === 'saved' ? 'idle' : s));
}, SAVED_INDICATOR_MS); }, SAVED_INDICATOR_MS);
} else {
setSaveStatus('idle');
}
} catch (e) { } catch (e) {
// Roll back: the change is still pending. // Roll back: the change is still pending.
dirtyRef.current = true; dirtyRef.current = true;