From 2a19be5ab692e338363c73466bf4bf15e1ec0cb5 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Fri, 16 Jan 2026 09:35:51 +0200 Subject: [PATCH] refactor(client): extract fnote icon logic in commons --- apps/client/src/entities/fnote.ts | 53 ++++--------------- apps/client/src/widgets/layout/StatusBar.tsx | 4 +- packages/commons/src/index.ts | 1 + packages/commons/src/lib/notes.ts | 54 ++++++++++++++++++++ 4 files changed, 67 insertions(+), 45 deletions(-) create mode 100644 packages/commons/src/lib/notes.ts diff --git a/apps/client/src/entities/fnote.ts b/apps/client/src/entities/fnote.ts index 83255e488..f161d7adb 100644 --- a/apps/client/src/entities/fnote.ts +++ b/apps/client/src/entities/fnote.ts @@ -1,4 +1,4 @@ -import { MIME_TYPES_DICT } from "@triliumnext/commons"; +import { getNoteIcon } from "@triliumnext/commons"; import cssClassManager from "../services/css_class_manager.js"; import type { Froca } from "../services/froca-interface.js"; @@ -13,25 +13,6 @@ import type { AttributeType, default as FAttribute } from "./fattribute.js"; const LABEL = "label"; const RELATION = "relation"; -export const NOTE_TYPE_ICONS = { - file: "bx bx-file", - image: "bx bx-image", - code: "bx bx-code", - render: "bx bx-extension", - search: "bx bx-file-find", - relationMap: "bx bxs-network-chart", - book: "bx bx-book", - noteMap: "bx bxs-network-chart", - mermaid: "bx bx-selection", - canvas: "bx bx-pen", - webView: "bx bx-globe-alt", - launcher: "bx bx-link", - doc: "bx bxs-file-doc", - contentWidget: "bx bxs-widget", - mindMap: "bx bx-sitemap", - aiChat: "bx bx-bot" -}; - /** * There are many different Note types, some of which are entirely opaque to the * end user. Those types should be used only for checking against, they are @@ -582,32 +563,18 @@ export default class FNote { } getIcon() { - return `tn-icon ${this.#getIconInternal()}`; - } - - #getIconInternal() { const iconClassLabels = this.getLabels("iconClass"); const workspaceIconClass = this.getWorkspaceIconClass(); - if (iconClassLabels && iconClassLabels.length > 0) { - return iconClassLabels[0].value; - } else if (workspaceIconClass) { - return workspaceIconClass; - } else if (this.noteId === "root") { - return "bx bx-home-alt-2"; - } - if (this.noteId === "_share") { - return "bx bx-share-alt"; - } else if (this.type === "text") { - if (this.isFolder()) { - return "bx bx-folder"; - } - return "bx bx-note"; - } else if (this.type === "code") { - const correspondingMimeType = MIME_TYPES_DICT.find(m => m.mime === this.mime); - return correspondingMimeType?.icon ?? NOTE_TYPE_ICONS.code; - } - return NOTE_TYPE_ICONS[this.type]; + const icon = getNoteIcon({ + noteId: this.noteId, + type: this.type, + mime: this.mime, + iconClass: iconClassLabels.length > 0 ? iconClassLabels[0].value : undefined, + workspaceIconClass, + isFolder: this.isFolder.bind(this) + }); + return `tn-icon ${icon}`; } getColorClass() { diff --git a/apps/client/src/widgets/layout/StatusBar.tsx b/apps/client/src/widgets/layout/StatusBar.tsx index 82cbe013c..903aeca3b 100644 --- a/apps/client/src/widgets/layout/StatusBar.tsx +++ b/apps/client/src/widgets/layout/StatusBar.tsx @@ -1,6 +1,6 @@ import "./StatusBar.css"; -import { Locale, NoteType } from "@triliumnext/commons"; +import { Locale, NOTE_TYPE_ICONS, NoteType } from "@triliumnext/commons"; import { Dropdown as BootstrapDropdown } from "bootstrap"; import clsx from "clsx"; import { type ComponentChildren, RefObject } from "preact"; @@ -9,7 +9,7 @@ import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "p import { CommandNames } from "../../components/app_context"; import NoteContext from "../../components/note_context"; -import FNote, { NOTE_TYPE_ICONS } from "../../entities/fnote"; +import FNote from "../../entities/fnote"; import attributes from "../../services/attributes"; import { t } from "../../services/i18n"; import { ViewScope } from "../../services/link"; diff --git a/packages/commons/src/index.ts b/packages/commons/src/index.ts index 6fb65baac..1ae730a56 100644 --- a/packages/commons/src/index.ts +++ b/packages/commons/src/index.ts @@ -12,3 +12,4 @@ export * from "./lib/ws_api.js"; export * from "./lib/attribute_names.js"; export * from "./lib/utils.js"; export * from "./lib/dayjs.js"; +export * from "./lib/notes.js"; diff --git a/packages/commons/src/lib/notes.ts b/packages/commons/src/lib/notes.ts new file mode 100644 index 000000000..315744dd5 --- /dev/null +++ b/packages/commons/src/lib/notes.ts @@ -0,0 +1,54 @@ +/** + * @module notes Common logic for notes (across front-end and back-end) + */ + +import { MIME_TYPES_DICT } from "./mime_type.js"; +import { NoteType } from "./rows.js"; + +export const NOTE_TYPE_ICONS = { + file: "bx bx-file", + image: "bx bx-image", + code: "bx bx-code", + render: "bx bx-extension", + search: "bx bx-file-find", + relationMap: "bx bxs-network-chart", + book: "bx bx-book", + noteMap: "bx bxs-network-chart", + mermaid: "bx bx-selection", + canvas: "bx bx-pen", + webView: "bx bx-globe-alt", + launcher: "bx bx-link", + doc: "bx bxs-file-doc", + contentWidget: "bx bxs-widget", + mindMap: "bx bx-sitemap", + aiChat: "bx bx-bot" +}; + +export function getNoteIcon({ noteId, type, mime, iconClass, workspaceIconClass, isFolder }: { + noteId: string; + type: NoteType; + mime: string; + iconClass: string | undefined; + workspaceIconClass: string | undefined; + isFolder: () => boolean; +}) { + if (iconClass) { + return iconClass; + } else if (workspaceIconClass) { + return workspaceIconClass; + } else if (noteId === "root") { + return "bx bx-home-alt-2"; + } + if (noteId === "_share") { + return "bx bx-share-alt"; + } else if (type === "text") { + if (isFolder()) { + return "bx bx-folder"; + } + return "bx bx-note"; + } else if (type === "code") { + const correspondingMimeType = MIME_TYPES_DICT.find(m => m.mime === mime); + return correspondingMimeType?.icon ?? NOTE_TYPE_ICONS.code; + } + return NOTE_TYPE_ICONS[type]; +}