From 68156d2e74634ba509fbb58593154f83570e06ed Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Sat, 25 Apr 2026 01:47:37 +0530 Subject: [PATCH] refactor: centralize status visuals and improve connection indicator logic - Introduced a new `status-visuals.ts` file to centralize status icons and labels for consistency across the plugin. - Updated connection indicator logic in the settings tab to utilize the new centralized visuals. - Removed deprecated connection visual methods to streamline the codebase. - Enhanced error handling in the status bar to reflect the new status visuals structure. --- surfsense_obsidian/src/api-client.ts | 2 +- surfsense_obsidian/src/settings.ts | 42 +++--------------------- surfsense_obsidian/src/status-bar.ts | 22 +++---------- surfsense_obsidian/src/status-visuals.ts | 22 +++++++++++++ surfsense_obsidian/styles.css | 4 --- 5 files changed, 32 insertions(+), 60 deletions(-) create mode 100644 surfsense_obsidian/src/status-visuals.ts diff --git a/surfsense_obsidian/src/api-client.ts b/surfsense_obsidian/src/api-client.ts index 2cf81da0f..37f5ebb65 100644 --- a/surfsense_obsidian/src/api-client.ts +++ b/surfsense_obsidian/src/api-client.ts @@ -203,7 +203,7 @@ export class SurfSenseApiClient { const baseUrl = this.opts.getServerUrl().replace(/\/+$/, ""); const token = this.opts.getToken(); if (!token) { - throw new AuthError("Missing API token. Open SurfSense settings to paste one."); + throw new AuthError("Missing API token. Open plugin settings to paste one."); } if (Date.now() < this.authBlockedUntil) { throw new AuthError("Token rejected. Paste a fresh one in settings."); diff --git a/surfsense_obsidian/src/settings.ts b/surfsense_obsidian/src/settings.ts index 212667283..d8179d592 100644 --- a/surfsense_obsidian/src/settings.ts +++ b/surfsense_obsidian/src/settings.ts @@ -11,6 +11,7 @@ import { AttachmentsConfirmModal } from "./attachments-confirm-modal"; import { normalizeFolder, parseExcludePatterns } from "./excludes"; import { FolderSuggestModal } from "./folder-suggest-modal"; import type SurfSensePlugin from "./main"; +import { STATUS_VISUALS } from "./status-visuals"; import type { SearchSpace } from "./types"; /** Plugin settings tab. */ @@ -284,48 +285,15 @@ export class SurfSenseSettingTab extends PluginSettingTab { const indicator = heading.nameEl.createSpan({ cls: "surfsense-connection-indicator", }); - const visual = this.getConnectionVisual(); - indicator.addClass(`surfsense-connection-indicator--${visual.tone}`); + const visual = STATUS_VISUALS[this.plugin.lastStatus.kind]; + if (visual.isError) { + indicator.addClass("surfsense-connection-indicator--err"); + } setIcon(indicator, visual.icon); indicator.setAttr("aria-label", visual.label); indicator.setAttr("title", visual.label); } - private getConnectionVisual(): { - icon: string; - label: string; - tone: "ok" | "syncing" | "warn" | "err" | "muted"; - } { - const settings = this.plugin.settings; - const kind = this.plugin.lastStatus.kind; - - if (kind === "auth-error") { - return { icon: "lock", label: "API token invalid or expired", tone: "err" }; - } - if (kind === "error") { - return { icon: "alert-circle", label: "Connection error", tone: "err" }; - } - if (kind === "offline") { - return { icon: "wifi-off", label: "Server unreachable", tone: "warn" }; - } - - if (!settings.apiToken) { - return { icon: "circle", label: "Missing API token", tone: "muted" }; - } - if (!settings.searchSpaceId) { - return { icon: "circle", label: "Pick a search space", tone: "muted" }; - } - if (!settings.connectorId) { - return { icon: "circle", label: "Not connected yet", tone: "muted" }; - } - - if (kind === "syncing" || kind === "queued") { - return { icon: "refresh-ccw", label: "Connected and syncing", tone: "syncing" }; - } - - return { icon: "check-circle", label: "Connected", tone: "ok" }; - } - private async refreshSearchSpaces(): Promise { this.loadingSpaces = true; try { diff --git a/surfsense_obsidian/src/status-bar.ts b/surfsense_obsidian/src/status-bar.ts index 9ba85318b..30abea50c 100644 --- a/surfsense_obsidian/src/status-bar.ts +++ b/surfsense_obsidian/src/status-bar.ts @@ -1,5 +1,6 @@ import { setIcon } from "obsidian"; -import type { StatusKind, StatusState } from "./types"; +import { STATUS_VISUALS } from "./status-visuals"; +import type { StatusState } from "./types"; /** * Tiny status-bar adornment. @@ -8,21 +9,6 @@ import type { StatusKind, StatusState } from "./types"; * and Obsidian's lint doesn't complain about innerHTML. */ -interface StatusVisual { - icon: string; - label: string; - cls: string; -} - -const VISUALS: Record = { - idle: { icon: "check-circle", label: "Synced", cls: "" }, - syncing: { icon: "refresh-ccw", label: "Syncing", cls: "" }, - queued: { icon: "clock", label: "Queued", cls: "" }, - offline: { icon: "wifi-off", label: "Offline", cls: "" }, - "auth-error": { icon: "user-x", label: "Auth error", cls: "surfsense-status--err" }, - error: { icon: "alert-circle", label: "Error", cls: "surfsense-status--err" }, -}; - export class StatusBar { private readonly el: HTMLElement; private readonly icon: HTMLElement; @@ -41,9 +27,9 @@ export class StatusBar { } update(state: StatusState): void { - const visual = VISUALS[state.kind]; + const visual = STATUS_VISUALS[state.kind]; this.el.removeClass("surfsense-status--err"); - if (visual.cls) this.el.addClass(visual.cls); + if (visual.isError) this.el.addClass("surfsense-status--err"); setIcon(this.icon, visual.icon); let label = `SurfSense: ${visual.label}`; diff --git a/surfsense_obsidian/src/status-visuals.ts b/surfsense_obsidian/src/status-visuals.ts new file mode 100644 index 000000000..b7bd2e350 --- /dev/null +++ b/surfsense_obsidian/src/status-visuals.ts @@ -0,0 +1,22 @@ +import type { StatusKind } from "./types"; + +/** + * Single source of truth for status icons + labels. Both the status bar + * and the settings "Connection" heading render from this table so a change + * here updates both surfaces. + */ + +export interface StatusVisual { + icon: string; + label: string; + isError: boolean; +} + +export const STATUS_VISUALS: Record = { + idle: { icon: "check-circle", label: "Synced", isError: false }, + syncing: { icon: "refresh-ccw", label: "Syncing", isError: false }, + queued: { icon: "clock", label: "Queued", isError: false }, + offline: { icon: "wifi-off", label: "Offline", isError: false }, + "auth-error": { icon: "user-x", label: "Reauthenticate", isError: true }, + error: { icon: "alert-circle", label: "Error", isError: true }, +}; diff --git a/surfsense_obsidian/styles.css b/surfsense_obsidian/styles.css index f31590224..4aa831e6c 100644 --- a/surfsense_obsidian/styles.css +++ b/surfsense_obsidian/styles.css @@ -46,7 +46,3 @@ .surfsense-connection-indicator--err { color: var(--color-red); } - -.surfsense-connection-indicator--muted { - color: var(--text-muted); -}