From eebc8e241330cf37a1fb44cb98de7ae250356e5b Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 28 May 2026 11:20:07 -0400 Subject: [PATCH] refactor(dry-F2): centralize shared UI primitives (relative-time, toast, download-status) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - utils/date.js: add formatRelative(iso, {future,nullText}); migrate 6 sites (SourceRow, SubscriptionsTab, SourceHealthDot, SchedulerStatusBar + thin adapters in BackupRunsTable/SystemActivityTab for their '—' null text). PostCard (30d->absolute) and CredentialCard (mo/y buckets) intentionally keep bespoke formatters. - utils/toast.js: toast(opts) wraps the globalThis.window?.__fcToast?.(...) incantation; migrate 63 call sites across 24 files. - utils/downloadStatus.js: single source for the download-event status enum -> label/color/icon; collapse the 3 duplicate maps (DownloadStatChips, DownloadsFilterPopover, DownloadEventRow). Net -33 lines. Platform metadata was already centralized in platformColor.js. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../components/cleanup/MinDimensionCard.vue | 7 +++-- .../cleanup/SingleColorAuditCard.vue | 11 ++++---- .../cleanup/TransparencyAuditCard.vue | 11 ++++---- .../components/common/ErrorDetailModal.vue | 3 +- .../credentials/ExtensionKeyBar.vue | 7 +++-- .../downloads/DownloadDetailModal.vue | 5 ++-- .../components/downloads/DownloadEventRow.vue | 19 +++++-------- .../src/components/modal/SuggestionsPanel.vue | 5 ++-- .../components/settings/BackupRunsTable.vue | 10 ++----- .../settings/BrowserExtensionCard.vue | 11 ++++---- .../settings/CentroidRecomputeCard.vue | 3 +- .../components/settings/ImportTaskList.vue | 5 ++-- .../components/settings/MLBackfillCard.vue | 3 +- .../settings/MLThresholdSliders.vue | 3 +- .../components/settings/SystemActivityTab.vue | 10 ++----- .../settings/ThumbnailBackfillCard.vue | 3 +- .../subscriptions/ArtistCreateDialog.vue | 3 +- .../subscriptions/CredentialCard.vue | 5 ++-- .../subscriptions/DownloadStatChips.vue | 24 ++++++---------- .../subscriptions/DownloadsFilterPopover.vue | 12 ++------ .../components/subscriptions/DownloadsTab.vue | 9 +++--- .../subscriptions/MaintenanceMenu.vue | 9 +++--- .../subscriptions/SchedulerStatusBar.vue | 11 ++------ .../subscriptions/SourceHealthDot.vue | 28 +++++-------------- .../components/subscriptions/SourceRow.vue | 18 +----------- .../subscriptions/SubscriptionsTab.vue | 24 ++++++---------- frontend/src/stores/gallerySelection.js | 5 ++-- frontend/src/stores/import.js | 13 +++++---- frontend/src/stores/modal.js | 3 +- frontend/src/stores/seriesManage.js | 3 +- frontend/src/stores/suggestions.js | 5 ++-- frontend/src/utils/date.js | 19 +++++++++++++ frontend/src/utils/downloadStatus.js | 21 ++++++++++++++ frontend/src/utils/toast.js | 8 ++++++ 34 files changed, 166 insertions(+), 170 deletions(-) create mode 100644 frontend/src/utils/downloadStatus.js create mode 100644 frontend/src/utils/toast.js diff --git a/frontend/src/components/cleanup/MinDimensionCard.vue b/frontend/src/components/cleanup/MinDimensionCard.vue index 140d549..b018c6b 100644 --- a/frontend/src/components/cleanup/MinDimensionCard.vue +++ b/frontend/src/components/cleanup/MinDimensionCard.vue @@ -62,6 +62,7 @@ diff --git a/frontend/src/components/cleanup/SingleColorAuditCard.vue b/frontend/src/components/cleanup/SingleColorAuditCard.vue index ff2ecbe..08c6476 100644 --- a/frontend/src/components/cleanup/SingleColorAuditCard.vue +++ b/frontend/src/components/cleanup/SingleColorAuditCard.vue @@ -93,6 +93,7 @@ diff --git a/frontend/src/components/cleanup/TransparencyAuditCard.vue b/frontend/src/components/cleanup/TransparencyAuditCard.vue index 4e91ac0..6e26f99 100644 --- a/frontend/src/components/cleanup/TransparencyAuditCard.vue +++ b/frontend/src/components/cleanup/TransparencyAuditCard.vue @@ -80,6 +80,7 @@ diff --git a/frontend/src/components/common/ErrorDetailModal.vue b/frontend/src/components/common/ErrorDetailModal.vue index 021f3da..6c378b3 100644 --- a/frontend/src/components/common/ErrorDetailModal.vue +++ b/frontend/src/components/common/ErrorDetailModal.vue @@ -33,6 +33,7 @@ diff --git a/frontend/src/components/credentials/ExtensionKeyBar.vue b/frontend/src/components/credentials/ExtensionKeyBar.vue index 2563ec6..3453aec 100644 --- a/frontend/src/components/credentials/ExtensionKeyBar.vue +++ b/frontend/src/components/credentials/ExtensionKeyBar.vue @@ -26,6 +26,7 @@ diff --git a/frontend/src/components/downloads/DownloadDetailModal.vue b/frontend/src/components/downloads/DownloadDetailModal.vue index 35bb921..e8c4697 100644 --- a/frontend/src/components/downloads/DownloadDetailModal.vue +++ b/frontend/src/components/downloads/DownloadDetailModal.vue @@ -101,6 +101,7 @@ diff --git a/frontend/src/components/settings/BackupRunsTable.vue b/frontend/src/components/settings/BackupRunsTable.vue index dc15d24..0d12676 100644 --- a/frontend/src/components/settings/BackupRunsTable.vue +++ b/frontend/src/components/settings/BackupRunsTable.vue @@ -59,6 +59,8 @@ diff --git a/frontend/src/components/settings/BrowserExtensionCard.vue b/frontend/src/components/settings/BrowserExtensionCard.vue index 2a0bedb..b3d7a41 100644 --- a/frontend/src/components/settings/BrowserExtensionCard.vue +++ b/frontend/src/components/settings/BrowserExtensionCard.vue @@ -108,6 +108,7 @@ diff --git a/frontend/src/components/settings/CentroidRecomputeCard.vue b/frontend/src/components/settings/CentroidRecomputeCard.vue index 22bf4bd..1f49210 100644 --- a/frontend/src/components/settings/CentroidRecomputeCard.vue +++ b/frontend/src/components/settings/CentroidRecomputeCard.vue @@ -16,6 +16,7 @@ diff --git a/frontend/src/components/settings/ImportTaskList.vue b/frontend/src/components/settings/ImportTaskList.vue index 4eadf3c..a3c78e2 100644 --- a/frontend/src/components/settings/ImportTaskList.vue +++ b/frontend/src/components/settings/ImportTaskList.vue @@ -125,6 +125,7 @@ diff --git a/frontend/src/components/settings/MLThresholdSliders.vue b/frontend/src/components/settings/MLThresholdSliders.vue index 34304d3..8919e3b 100644 --- a/frontend/src/components/settings/MLThresholdSliders.vue +++ b/frontend/src/components/settings/MLThresholdSliders.vue @@ -17,6 +17,7 @@ diff --git a/frontend/src/components/settings/SystemActivityTab.vue b/frontend/src/components/settings/SystemActivityTab.vue index 0d6485c..fe9db71 100644 --- a/frontend/src/components/settings/SystemActivityTab.vue +++ b/frontend/src/components/settings/SystemActivityTab.vue @@ -154,6 +154,7 @@ import { computed, onMounted, onUnmounted, ref } from 'vue' import { useSystemActivityStore } from '../../stores/systemActivity.js' +import { formatRelative as fmtRelative } from '../../utils/date.js' import ErrorDetailModal from '../common/ErrorDetailModal.vue' import QueuesTable from './QueuesTable.vue' @@ -277,14 +278,7 @@ function formatDuration(ms) { return `${(ms / 60_000).toFixed(1)} min` } function formatRelative(iso) { - if (!iso) return '—' - const then = new Date(iso).getTime() - const now = Date.now() - const diff = Math.max(0, (now - then) / 1000) - if (diff < 60) return `${Math.floor(diff)}s ago` - if (diff < 3600) return `${Math.floor(diff / 60)}m ago` - if (diff < 86400) return `${Math.floor(diff / 3600)}h ago` - return `${Math.floor(diff / 86400)}d ago` + return fmtRelative(iso, { nullText: '—' }) } diff --git a/frontend/src/components/settings/ThumbnailBackfillCard.vue b/frontend/src/components/settings/ThumbnailBackfillCard.vue index 489c45f..37aab2a 100644 --- a/frontend/src/components/settings/ThumbnailBackfillCard.vue +++ b/frontend/src/components/settings/ThumbnailBackfillCard.vue @@ -16,6 +16,7 @@ diff --git a/frontend/src/components/subscriptions/ArtistCreateDialog.vue b/frontend/src/components/subscriptions/ArtistCreateDialog.vue index 8efde7d..c60afa5 100644 --- a/frontend/src/components/subscriptions/ArtistCreateDialog.vue +++ b/frontend/src/components/subscriptions/ArtistCreateDialog.vue @@ -20,6 +20,7 @@