diff --git a/src/services/hidden_subtree.ts b/src/services/hidden_subtree.ts index 59feb595e..bf5af3fa7 100644 --- a/src/services/hidden_subtree.ts +++ b/src/services/hidden_subtree.ts @@ -6,6 +6,8 @@ import noteService from "./notes.js"; import log from "./log.js"; import migrationService from "./migration.js"; import { t } from "i18next"; +import app_path from "./app_path.js"; +import { getHelpHiddenSubtreeData } from "./in_app_help.js"; const LBTPL_ROOT = "_lbTplRoot"; const LBTPL_BASE = "_lbTplBase"; @@ -16,21 +18,21 @@ const LBTPL_BUILTIN_WIDGET = "_lbTplBuiltinWidget"; const LBTPL_SPACER = "_lbTplSpacer"; const LBTPL_CUSTOM_WIDGET = "_lbTplCustomWidget"; -interface Attribute { +interface HiddenSubtreeAttribute { type: AttributeType; name: string; isInheritable?: boolean; value?: string; } -interface Item { +export interface HiddenSubtreeItem { notePosition?: number; id: string; title: string; type: NoteType; icon?: string; - attributes?: Attribute[]; - children?: Item[]; + attributes?: HiddenSubtreeAttribute[]; + children?: HiddenSubtreeItem[]; isExpanded?: boolean; baseSize?: string; growthFactor?: string; @@ -54,9 +56,9 @@ enum Command { * duplicate subtrees. This way, all instances will generate the same structure with the same IDs. */ -let hiddenSubtreeDefinition: Item; +let hiddenSubtreeDefinition: HiddenSubtreeItem; -function buildHiddenSubtreeDefinition(): Item { +function buildHiddenSubtreeDefinition(): HiddenSubtreeItem { return { id: "_hidden", title: t("hidden-subtree.root-title"), @@ -350,7 +352,8 @@ function buildHiddenSubtreeDefinition(): Item { id: "_help", title: t("hidden-subtree.user-guide"), type: "book", - icon: "bx-help-circle" + icon: "bx-help-circle", + children: getHelpHiddenSubtreeData() } ] }; @@ -374,7 +377,7 @@ function checkHiddenSubtree(force = false, extraOpts: CheckHiddenExtraOpts = {}) checkHiddenSubtreeRecursively("root", hiddenSubtreeDefinition, extraOpts); } -function checkHiddenSubtreeRecursively(parentNoteId: string, item: Item, extraOpts: CheckHiddenExtraOpts = {}) { +function checkHiddenSubtreeRecursively(parentNoteId: string, item: HiddenSubtreeItem, extraOpts: CheckHiddenExtraOpts = {}) { if (!item.id || !item.type || !item.title) { throw new Error(`Item does not contain mandatory properties: ${JSON.stringify(item)}`); } diff --git a/src/services/in_app_help.ts b/src/services/in_app_help.ts new file mode 100644 index 000000000..f53380af3 --- /dev/null +++ b/src/services/in_app_help.ts @@ -0,0 +1,47 @@ +import path from "path"; +import fs from "fs"; +import type { HiddenSubtreeItem } from "./hidden_subtree.js"; +import type NoteMeta from "./meta/note_meta.js"; +import type { NoteMetaFile } from "./meta/note_meta.js"; +import { fileURLToPath } from "url"; +import { isDev } from "./utils.js"; + +export function getHelpHiddenSubtreeData() { + const srcRoot = path.join(path.dirname(fileURLToPath(import.meta.url)), ".."); + const appDir = path.join(srcRoot, "public", isDev ? "app" : "app-dist"); + const helpDir = path.join(appDir, "doc_notes", "en", "User Guide"); + const metaFilePath = path.join(helpDir, "!!!meta.json"); + const metaFileContent = JSON.parse(fs.readFileSync(metaFilePath).toString("utf-8")); + + try { + return parseNoteMetaFile(metaFileContent as NoteMetaFile); + } catch (e) { + console.warn(e); + return []; + } +} + +function parseNoteMetaFile(noteMetaFile: NoteMetaFile): HiddenSubtreeItem[] { + if (!noteMetaFile.files) { + return []; + } + + const metaRoot = noteMetaFile.files[0]; + const items: HiddenSubtreeItem[] = []; + + for (const childMeta of metaRoot.children ?? []) { + items.push(parseNoteMeta(childMeta)); + } + + return items; +} + +function parseNoteMeta(noteMeta: NoteMeta): HiddenSubtreeItem { + const item: HiddenSubtreeItem = { + id: `_help_${noteMeta.noteId}`, + title: noteMeta.title, + type: "doc" + }; + + return item; +} diff --git a/src/services/meta/note_meta.ts b/src/services/meta/note_meta.ts index 0aaafb6b5..39051a88e 100644 --- a/src/services/meta/note_meta.ts +++ b/src/services/meta/note_meta.ts @@ -8,10 +8,10 @@ export interface NoteMetaFile { } export default interface NoteMeta { - noteId?: string; + noteId: string; notePath?: string[]; isClone?: boolean; - title?: string; + title: string; notePosition?: number; prefix?: string | null; isExpanded?: boolean;