DRY pass #2, batch 5, F17: the web's smaller pairs (#5372)

- desktop/bridge.ts listen<T>(): the no-op-off-desktop event listener
  that onSynced, onCaptured and onReminderDue each wrote.
- size.ts roughSize(): one decimal below 10, none above, for the client
  download sizes (MB) and the storage line (GB).
- BaseModal's title prop draws the heading row and close button that
  LabelsModal and ShareDialog each built.
- SyncView: switchChannel and switchSource share recheck(); the four
  update-card radios render from two option lists.

Kept: the board's and the shell's is-typing guards (they ignore different
elements), the drawer's nav beside the palette's commands (one is a laid-
out list with tags between its entries, the other a command list), the
status pills (each colours differently), and plurals (the copy is the
operator's call, raised in #5371).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 14:48:31 -04:00
co-authored by Claude Opus 5.5
parent 6e4c4930cb
commit 3dd47fa178
8 changed files with 104 additions and 101 deletions
+14 -9
View File
@@ -32,6 +32,17 @@ export interface IntegrationStatus {
appimage_path: string | null;
}
/**
* Run `handler` with each payload of a desktop event. Returns an unlisten function,
* or a no-op where there is no event API (the web build, or a desktop runtime that
* doesn't expose one).
*/
async function listen<T>(event: string, handler: (payload: T) => void): Promise<() => void> {
const events = window.__TAURI__?.event;
if (!events) return () => {};
return events.listen<T>(event, (e) => handler(e.payload));
}
/** True when running inside the Tauri desktop shell (vs. the web build). */
export function isDesktop(): boolean {
return typeof window !== "undefined" && !!window.__TAURI__;
@@ -200,9 +211,7 @@ const SYNCED_EVENT = "inkwell://synced";
* there, so there is nothing to hear.
*/
export async function onSynced(handler: (cycle: LastCycle) => void): Promise<() => void> {
const events = window.__TAURI__?.event;
if (!events) return () => {};
return events.listen<LastCycle>(SYNCED_EVENT, (e) => handler(e.payload));
return listen<LastCycle>(SYNCED_EVENT, handler);
}
export const sync = {
@@ -295,9 +304,7 @@ export const capture = {
* what it has until its next load, which is a stale list rather than a broken one.
*/
export async function onCaptured(handler: () => void): Promise<() => void> {
const events = window.__TAURI__?.event;
if (!events) return () => {};
return events.listen(CAPTURED_EVENT, () => handler());
return listen(CAPTURED_EVENT, () => handler());
}
/** A reminder the desktop's reminder worker found due (desktop/src-tauri/src/reminders.rs). */
@@ -319,7 +326,5 @@ const REMINDER_DUE_EVENT = "inkwell://reminder-due";
* Returns an unlisten function, or a no-op where there is no event API.
*/
export async function onReminderDue(handler: (reminder: DueReminder) => void): Promise<() => void> {
const events = window.__TAURI__?.event;
if (!events) return () => {};
return events.listen<DueReminder>(REMINDER_DUE_EVENT, (e) => handler(e.payload));
return listen<DueReminder>(REMINDER_DUE_EVENT, handler);
}