UI: reuse attachment count and duration formatters #310

Open
opened 2026-09-28 07:32:23 +00:00 by kayg · 1 comment
Owner

Evidence

Two formatting rules are implemented more than once in the UI:

  • packages/ui/src/components/calendar/attachments.ts:82-83 owns attachmentCountLabel(). packages/ui/src/components/composer/DraftStack.svelte:42-43 repeats the singular/plural rule for attachment counts. DraftStack can keep Empty draft for zero items.
  • packages/ui/src/time.ts:368-373 owns formatDuration(). apps/web/src/lib/composer/recorder.svelte.ts:44-46 defines another helper with the same name. The first rounds milliseconds and can show hours; the second floors milliseconds and always shows minutes. The difference can show the same duration differently at a second boundary or after one hour.

The file-size formatter and the memoised date formatter already have one shared owner.

Rule

The reuse gate says duplicated logic is a defect.

Fix

Use the shared attachment label for positive counts. Make the duration display contract explicit, then call one shared formatter from both places or add a named option for the required clock form and rounding rule.

Owner

packages/ui/src/components/calendar/attachments.ts owns the attachment count label. packages/ui/src/time.ts owns duration formatting. The Composer should call those shared helpers.

## Evidence Two formatting rules are implemented more than once in the UI: - `packages/ui/src/components/calendar/attachments.ts:82-83` owns `attachmentCountLabel()`. `packages/ui/src/components/composer/DraftStack.svelte:42-43` repeats the singular/plural rule for attachment counts. DraftStack can keep `Empty draft` for zero items. - `packages/ui/src/time.ts:368-373` owns `formatDuration()`. `apps/web/src/lib/composer/recorder.svelte.ts:44-46` defines another helper with the same name. The first rounds milliseconds and can show hours; the second floors milliseconds and always shows minutes. The difference can show the same duration differently at a second boundary or after one hour. The file-size formatter and the memoised date formatter already have one shared owner. ## Rule The reuse gate says duplicated logic is a defect. ## Fix Use the shared attachment label for positive counts. Make the duration display contract explicit, then call one shared formatter from both places or add a named option for the required clock form and rounding rule. ## Owner `packages/ui/src/components/calendar/attachments.ts` owns the attachment count label. `packages/ui/src/time.ts` owns duration formatting. The Composer should call those shared helpers.
Author
Owner

Consistency-hunt update from current dev at dfb5964a2fcf13dc8b9a50a319eee09bc386f322 (2026-09-30). Both prior duplicates remain: DraftStack.svelte:43 repeats the attachment singular/plural rule from packages/ui/src/components/calendar/attachments.ts:82, and apps/web/src/lib/composer/recorder.svelte.ts:44 has another duration formatter beside packages/ui/src/time.ts:388. A new file-size formatter appears in apps/web/src/lib/mail/MailView.svelte:147; Files already owns formatSize() at apps/web/src/lib/files/model.ts:332. Mail uses 1024-based KB/MB; Files uses decimal units and localized byte wording, so preserve the difference with a named format option if both policies are needed.

Rule: duplicated formatting logic has one owner. Fix: share the attachment and duration helpers, and extend the size helper with an explicit unit policy. Owners: packages/ui/src/components/calendar/attachments.ts, packages/ui/src/time.ts, and the existing Files size helper in apps/web/src/lib/files/model.ts (or promote it once if Mail cannot depend on Files).

Consistency-hunt update from current `dev` at `dfb5964a2fcf13dc8b9a50a319eee09bc386f322` (2026-09-30). Both prior duplicates remain: `DraftStack.svelte:43` repeats the attachment singular/plural rule from `packages/ui/src/components/calendar/attachments.ts:82`, and `apps/web/src/lib/composer/recorder.svelte.ts:44` has another duration formatter beside `packages/ui/src/time.ts:388`. A new file-size formatter appears in `apps/web/src/lib/mail/MailView.svelte:147`; Files already owns `formatSize()` at `apps/web/src/lib/files/model.ts:332`. Mail uses 1024-based `KB`/`MB`; Files uses decimal units and localized byte wording, so preserve the difference with a named format option if both policies are needed. Rule: duplicated formatting logic has one owner. Fix: share the attachment and duration helpers, and extend the size helper with an explicit unit policy. Owners: `packages/ui/src/components/calendar/attachments.ts`, `packages/ui/src/time.ts`, and the existing Files size helper in `apps/web/src/lib/files/model.ts` (or promote it once if Mail cannot depend on Files).
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#310
No description provided.