v1.2: overwrite confirm, transfer speed/ETA, settings + themes, fused macOS titlebar
- Overwrite confirmation: name-collision detection before enqueue; dialog shows source vs destination (size, mtime, 'newer' badge) with per-item Skip/Replace and batch Skip all / Replace all; type mismatches auto-skip with a toast; cancel aborts the whole operation - Transfer speed + ETA: UI computes smoothed bytes/sec from progress deltas (callback bus makes deltas meaningful); shown in the expanded queue rows and the status-bar summary; unit follows the speed-unit setting - Settings: bun-side SettingsStore (settings.json, 0600, atomic) + get/save RPC; SettingsService; gear popover on the tab row (theme segmented control, speed unit); persisted across restarts - Light theme: data-theme on <html> drives token overrides; absent = follow OS - macOS fused titlebar: hiddenInset + trafficLightOffset, tab row becomes the draggable titlebar (app-region drag/no-drag classes); other platforms keep a separate titlebar (gated by a platform value injected via window preload) - README: known-issues note for the upstream Bun/Electrobun FFI crash Verified: tsc + ui build clean; SettingsStore roundtrip + 0600 headless; app boots and the UI fetches settings over RPC at startup. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { DEFAULT_SETTINGS, type AppSettings } from "../../shared/types";
|
||||
import { appDataDir } from "./paths";
|
||||
|
||||
/** App settings persisted bun-side (WKWebView localStorage on views:// is unreliable). */
|
||||
export class SettingsStore {
|
||||
private readonly file = path.join(appDataDir(), "settings.json");
|
||||
|
||||
async load(): Promise<AppSettings> {
|
||||
try {
|
||||
const data = JSON.parse(await fs.readFile(this.file, "utf8"));
|
||||
return { ...DEFAULT_SETTINGS, ...data };
|
||||
} catch {
|
||||
return { ...DEFAULT_SETTINGS };
|
||||
}
|
||||
}
|
||||
|
||||
async save(settings: AppSettings): Promise<void> {
|
||||
await fs.mkdir(path.dirname(this.file), { recursive: true });
|
||||
const tmp = `${this.file}.tmp`;
|
||||
await fs.writeFile(tmp, JSON.stringify(settings, null, "\t"), { mode: 0o600 });
|
||||
await fs.rename(tmp, this.file);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user