diff --git a/frontend/index.html b/frontend/index.html index 3ab5f16..5dd3c48 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -2,12 +2,9 @@ - + label_ids). A few operations have no offline meaning -// yet (account auth, device linking) — those reject with a clear message -// rather than silently failing; the board, editor, attachments, capture, filters, -// labels, checklists, reminders, import and export all work fully offline. +// parameters (labelIds -> label_ids). Operations with no offline meaning (account +// auth, device linking) reject with a clear message. import { invoke } from "../desktop/bridge"; import type { Note, NoteRevision } from "../stores/notes"; @@ -58,7 +55,7 @@ export const local: Repo = { snoozeReminder: (id, minutes) => invoke("notes_snooze_reminder", { id, minutes }), setLabels: (id, labelIds) => invoke("notes_set_labels", { id, labelIds }), updateItem: (id, itemId, changes) => invoke("notes_update_item", { id, itemId, changes }), - // Kept on this device and uploaded by the next sync once linked (#5168). The bytes + // Kept on this device and uploaded by the next sync once linked. The bytes // go as the raw IPC body; the name is percent-encoded because a header carries // only ASCII. uploadAttachment: async (id, file) => @@ -91,7 +88,7 @@ export const local: Repo = { sendTestEmail: () => Promise.reject<{ to: string }>(new Error(NEEDS_SERVER)), }, - // Sharing is between accounts on a server, so these go to the linked one (#5175). + // Sharing is between accounts on a server, so these go to the linked one. // Unlinked, each rejects with the core's explanation, which the dialog shows. shares: { directory: () => invoke("shares_directory"), diff --git a/frontend/src/adapters/repo.ts b/frontend/src/adapters/repo.ts index f402716..bc10616 100644 --- a/frontend/src/adapters/repo.ts +++ b/frontend/src/adapters/repo.ts @@ -1,13 +1,9 @@ -// The data-source seam. Stores/views talk to this typed repository interface -// instead of reaching for the HTTP client directly, so the SAME UI can run -// against the REST backend (web + a server-connected desktop) or a fully-local -// on-device source (offline desktop). `rest.ts` implements it over `api/client`; -// `local.ts` (M10.5) implements it over Tauri `invoke`; `index.ts` picks one. +// The data-source seam. Stores and views talk to this interface, so the same UI runs +// against the REST backend (`rest.ts`) or the desktop's on-device store (`local.ts`, +// over Tauri `invoke`); `index.ts` picks one. // -// Keep this interface a thin, semantic mirror of the current calls: every method -// maps 1:1 to a backend operation and returns the same shape the stores already -// consume. Client-side logic (list reconciliation, optimistic updates, toasts) -// stays in the stores — the repo is data access only. +// Each method maps 1:1 to a backend operation. Client-side logic (reconciliation, +// optimistic updates, toasts) stays in the stores; the repo is data access only. import type { Note, NoteFacets, NoteView, NoteRevision } from "../stores/notes"; import type { Label } from "../stores/labels"; @@ -45,7 +41,7 @@ export interface ChecklistItemChanges { } -// ---- sharing (#5174) --------------------------------------------------------- +// ---- sharing ----------------------------------------------------------------- /** A person on this instance, as the member directory shows them. */ export interface Member { @@ -54,7 +50,7 @@ export interface Member { email: string; } -/** A group the admin made, as the directory shows it (#5177). */ +/** A group the admin made, as the directory shows it. */ export interface ShareGroup { id: string; name: string; diff --git a/frontend/src/adapters/rest.ts b/frontend/src/adapters/rest.ts index 62853dd..6474ccd 100644 --- a/frontend/src/adapters/rest.ts +++ b/frontend/src/adapters/rest.ts @@ -1,8 +1,6 @@ -// REST implementation of the repository seam: maps each semantic operation to the -// existing HTTP endpoint via `api/client`. This is the ONLY place that knows about -// URL paths, query strings, and multipart bodies. Behaviour here must stay a -// verbatim mirror of the calls the stores/views made before the seam existed — the -// web app is unchanged; the offline `local.ts` source (M10.5) is the alternative. +// The REST implementation of the repository seam: each operation is an HTTP endpoint +// via `api/client`. The only place that knows URL paths, query strings and multipart +// bodies. import { api } from "../api/client"; import type { Note, NoteRevision } from "../stores/notes"; @@ -26,9 +24,7 @@ import type { StorageUse, } from "./repo"; -// Render a board query to the GET /api/notes query string. Mirrors the param -// building that used to live in notes.store.load()/TimelineView (order-preserving; -// query-param order is irrelevant to the server, but kept close for review). +// Render a board query to the GET /api/notes query string. function notesQuery(q: NoteListQuery): string { const params = new URLSearchParams(); params.set("filter", q.view); diff --git a/frontend/src/components/AccountList.vue b/frontend/src/components/AccountList.vue index 3c29324..309e2dd 100644 --- a/frontend/src/components/AccountList.vue +++ b/frontend/src/components/AccountList.vue @@ -6,9 +6,9 @@ import { appLink } from "../router/links"; import OneTimeSecret from "./OneTimeSecret.vue"; import { useRowAction, useLoad } from "../composables/useAction"; -// Admin: the accounts on this instance, and a password reset link for any of them -// (#5173). The admin hands the link over; a person can also mail one to themselves -// when the server can send email (#5266). +// Admin: the accounts on this instance, and a password reset link for any of them. +// The admin hands the link over; a person can also mail one to themselves when the +// server can send email. const session = useSessionStore(); diff --git a/frontend/src/components/ActivityList.vue b/frontend/src/components/ActivityList.vue index d9b505e..7e6d036 100644 --- a/frontend/src/components/ActivityList.vue +++ b/frontend/src/components/ActivityList.vue @@ -6,7 +6,7 @@ import { formatShortDateTime } from "../notes/datetime"; import { useLoad } from "../composables/useAction"; import ScrollSentinel from "./ScrollSentinel.vue"; -// Admin: what has happened to accounts on this instance, newest first (#2939 §5). +// Admin: what has happened to accounts on this instance, newest first. // Kept for `audit_retention_days` (Settings → Security). interface AuditEvent { diff --git a/frontend/src/components/AppShell.vue b/frontend/src/components/AppShell.vue index 7b10058..b4bbf8e 100644 --- a/frontend/src/components/AppShell.vue +++ b/frontend/src/components/AppShell.vue @@ -36,18 +36,11 @@ const ui = useUiStore(); // Sync is a desktop-app concern: the web build already IS the server's UI. const desktopApp = isDesktop(); -// The build, for the dim line at the foot of the rail (#3181). +// The build, for the dim line at the foot of the rail. Never blank: "unknown" when +// missing, since this is the only answer to "which build is this?". // -// NEVER BLANK. "unknown" is the honest answer when the value is missing, and an -// empty space is a bug that reads as a design choice. Note 3127 §5: with version -// tags gone this is the only answer to "which build is this?", so it has to be -// either right or visibly absent. -// -// One slot, two artifacts, and that is deliberate rather than sloppy. In the -// browser `repo` is `rest`, so this is the SERVER's version; in the desktop shell -// `repo` is `local` and `config_get` returns the desktop build's own. Each surface -// names the thing the person is actually looking at. A linked server's version is -// a different question and Sync answers it separately. +// In the browser it is the server's version; in the desktop shell `config_get` +// returns the desktop build's own. A linked server's version is shown on Sync. const buildVersion = computed(() => config.version || "unknown"); const buildLabel = computed( () => `Inkwell ${desktopApp ? "desktop" : "server"} build ${buildVersion.value}`, @@ -55,7 +48,7 @@ const buildLabel = computed( const managing = ref(false); -// The rail lists the few tags in use, not all of them (#5931); "All tags" opens the +// The rail lists the few tags in use, not all of them; "All tags" opens the // rest in place, below everything else, so nothing is pushed out of view. const viewer = computed(() => session.user?.id ?? "local"); const tagViews = ref({}); @@ -209,16 +202,8 @@ onBeforeUnmount(() => { const BOARD_ROUTES = new Set(["board", "archive", "trash", "label"]); /** - * Search is a FACET, not a destination. - * - * It used to navigate to a `/search` view backed by a different endpoint with no - * facets at all — so the one screen you landed on when you searched was the one - * screen where you could not also narrow by tag, which is precisely what tags are - * for (note 2930). Now it writes `?q=` into the board's URL, beside any labels - * already there, and the same AND-ed query serves both. - * - * Existing facets are preserved, so "filter by #grocery, then search" and the reverse - * both work. + * Search is a facet, not a destination: it writes `?q=` into the board's URL beside + * any tags already there, so search and tag filters combine in either order. */ function onSearch(value: string) { searchText.value = value; @@ -233,9 +218,8 @@ function onSearch(value: string) { }, 250); } -// The URL is the filter state (see notes/facets.ts), so the box READS from it rather -// than holding its own copy — which is also what keeps it in step with the Filters -// panel's Clear button. +// The URL is the filter state (notes/facets.ts), so the box reads from it rather than +// holding a copy, and the Filters panel's Clear button clears it too. watch( () => route.query.q, (q) => { @@ -260,26 +244,21 @@ async function signOut() {