From c0714a92d547b68ba3afdee08e75e5c401572df2 Mon Sep 17 00:00:00 2001 From: Panagiotis Papadopoulos Date: Sun, 16 Feb 2025 13:46:20 +0100 Subject: [PATCH 01/24] feat(time_selector): add time_selector options widget --- .../type_widgets/options/time_selector.ts | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/public/app/widgets/type_widgets/options/time_selector.ts diff --git a/src/public/app/widgets/type_widgets/options/time_selector.ts b/src/public/app/widgets/type_widgets/options/time_selector.ts new file mode 100644 index 000000000..49c149f75 --- /dev/null +++ b/src/public/app/widgets/type_widgets/options/time_selector.ts @@ -0,0 +1,126 @@ +import OptionsWidget from "./options_widget.js"; +import toastService from "../../../services/toast.js"; +import { t } from "../../../services/i18n.js"; +import type { OptionDefinitions, OptionMap } from "../../../../../services/options_interface.js"; + + +type TimeSelectorConstructor = { + widgetId: string; + widgetLabelId: string; + optionValueId: keyof OptionDefinitions; + optionTimeScaleId: keyof OptionDefinitions; +}; + + +const TPL = (options: Pick) => ` +
+ +
+ + +
+
+ + +`; + +export default class TimeSelector extends OptionsWidget { + + private $timeValueInput!: JQuery; + private $timeScaleSelect!: JQuery; + private internalTimeInSeconds!: string | number; + private widgetId: string; + private widgetLabelId: string; + private optionValueId: keyof OptionDefinitions; + private optionTimeScaleId: keyof OptionDefinitions; + + constructor(options: TimeSelectorConstructor) { + super(); + this.widgetId = options.widgetId; + this.widgetLabelId = options.widgetLabelId; + this.optionValueId = options.optionValueId; + this.optionTimeScaleId = options.optionTimeScaleId; + } + + doRender() { + this.$widget = $(TPL({ + widgetId: this.widgetId, + widgetLabelId: this.widgetLabelId + })); + + this.$timeValueInput = this.$widget.find(`#${this.widgetId}`); + this.$timeScaleSelect = this.$widget.find(`#${this.widgetId}-time-scale`); + + this.$timeValueInput.on("change", () => { + const time = this.$timeValueInput.val(); + const timeScale = this.$timeScaleSelect.val(); + + if (!this.handleTimeValidation() || typeof timeScale !== "string" || !time) return; + + this.internalTimeInSeconds = this.convertTime(time, timeScale).toOption(); + this.updateOption(this.optionValueId, this.internalTimeInSeconds); + + }); + + this.$timeScaleSelect.on("change", () => { + + const timeScale = this.$timeScaleSelect.val(); + + if (!this.handleTimeValidation() || typeof timeScale !== "string") return; + + //calculate the new displayed value + const displayedTime = this.convertTime(this.internalTimeInSeconds, timeScale).toDisplay(); + + this.updateOption(this.optionTimeScaleId, timeScale); + this.$timeValueInput.val(displayedTime).trigger("change"); + + }); + + } + + async optionsLoaded(options: OptionMap) { + this.internalTimeInSeconds = options[this.optionValueId]; + const displayedTime = this.convertTime(options[this.optionValueId], options[this.optionTimeScaleId]).toDisplay(); + this.$timeValueInput.val(displayedTime); + this.$timeScaleSelect.val(options[this.optionTimeScaleId]); + } + + + convertTime(time: string | number, timeScale: string | number) { + + const value = typeof time === "number" ? time : parseInt(time); + if (Number.isNaN(value)) { + throw new Error(`Time needs to be a valid integer, but received: ${time}`); + } + + const operand = typeof timeScale === "number" ? timeScale : parseInt(timeScale); + if (Number.isNaN(operand) || operand < 1) { + throw new Error(`TimeScale needs to be a valid integer >= 1, but received: ${timeScale}`); + } + + return { + toOption: () => Math.ceil(value * operand), + toDisplay: () => Math.ceil(value / operand), + } + + } + + handleTimeValidation() { + if (this.$timeValueInput.is(":invalid")) { + // TriliumNextTODO: i18n + toastService.showMessage("The entered time value is not a valid number."); + return false + } + return true; + } + +} \ No newline at end of file From e0e530b2195a45698c765f7006a9646920b1fa5b Mon Sep 17 00:00:00 2001 From: Panagiotis Papadopoulos Date: Sun, 16 Feb 2025 13:56:05 +0100 Subject: [PATCH 02/24] feat(time_selector): use time_selector in note_erasure_timeout --- .../options/other/note_erasure_timeout.ts | 107 +++--------------- 1 file changed, 17 insertions(+), 90 deletions(-) diff --git a/src/public/app/widgets/type_widgets/options/other/note_erasure_timeout.ts b/src/public/app/widgets/type_widgets/options/other/note_erasure_timeout.ts index 99161f9a9..f06274c03 100644 --- a/src/public/app/widgets/type_widgets/options/other/note_erasure_timeout.ts +++ b/src/public/app/widgets/type_widgets/options/other/note_erasure_timeout.ts @@ -3,76 +3,40 @@ import server from "../../../../services/server.js"; import toastService from "../../../../services/toast.js"; import { t } from "../../../../services/i18n.js"; import type { OptionMap } from "../../../../../../services/options_interface.js"; +import TimeSelector from "../time_selector.js"; const TPL = `

${t("note_erasure_timeout.note_erasure_timeout_title")}

-

${t("note_erasure_timeout.note_erasure_description")}

+`; -
- -
- - - -
-
- +const TPL2 = `

${t("note_erasure_timeout.manual_erasing_description")}

- - -
`; -export default class NoteErasureTimeoutOptions extends OptionsWidget { +export default class NoteErasureTimeoutOptions extends TimeSelector { - private $eraseEntitiesAfterTime!: JQuery; - private $eraseEntitiesAfterTimeScale!: JQuery; private $eraseDeletedNotesButton!: JQuery; - private eraseEntitiesAfterTimeInSeconds!: string | number; + + constructor() { + super( { + widgetId: "erase-entities-after", + widgetLabelId: "note_erasure_timeout.erase_notes_after", + optionValueId: "eraseEntitiesAfterTimeInSeconds", + optionTimeScaleId: "eraseEntitiesAfterTimeScale" + }) + super.doRender(); + + } doRender() { - this.$widget = $(TPL); - this.$eraseEntitiesAfterTime = this.$widget.find("#erase-entities-after-time"); - this.$eraseEntitiesAfterTimeScale = this.$widget.find("#erase-entities-after-time-scale"); - this.$eraseEntitiesAfterTime.on("change", () => { - const time = this.$eraseEntitiesAfterTime.val(); - const timeScale = this.$eraseEntitiesAfterTimeScale.val(); - - if (!this.handleTimeValidation() || typeof timeScale !== "string" || !time) return; - - this.eraseEntitiesAfterTimeInSeconds = this.convertTime(time, timeScale).toOption(); - this.updateOption("eraseEntitiesAfterTimeInSeconds", this.eraseEntitiesAfterTimeInSeconds); - - }); - - this.$eraseEntitiesAfterTimeScale.on("change", () => { - - const timeScale = this.$eraseEntitiesAfterTimeScale.val(); - - if (!this.handleTimeValidation() || typeof timeScale !== "string") return; - - //calculate the new displayed value - const displayedTime = this.convertTime(this.eraseEntitiesAfterTimeInSeconds, timeScale).toDisplay(); - - this.updateOption("eraseEntitiesAfterTimeScale", timeScale); - this.$eraseEntitiesAfterTime.val(displayedTime).trigger("change"); - - }); + this.$widget = $(TPL).append(this.$widget).append(TPL2); this.$eraseDeletedNotesButton = this.$widget.find("#erase-deleted-notes-now-button"); + this.$eraseDeletedNotesButton.on("click", () => { server.post("notes/erase-deleted-notes-now").then(() => { toastService.showMessage(t("note_erasure_timeout.deleted_notes_erased")); @@ -80,41 +44,4 @@ export default class NoteErasureTimeoutOptions extends OptionsWidget { }); } - async optionsLoaded(options: OptionMap) { - this.eraseEntitiesAfterTimeInSeconds = options.eraseEntitiesAfterTimeInSeconds; - - const displayedTime = this.convertTime(options.eraseEntitiesAfterTimeInSeconds, options.eraseEntitiesAfterTimeScale).toDisplay(); - this.$eraseEntitiesAfterTime.val(displayedTime); - this.$eraseEntitiesAfterTimeScale.val(options.eraseEntitiesAfterTimeScale); - } - - - convertTime(time: string | number, timeScale: string | number) { - - const value = typeof time === "number" ? time : parseInt(time); - if (Number.isNaN(value)) { - throw new Error(`Time needs to be a valid integer, but received: ${time}`); - } - - const operand = typeof timeScale === "number" ? timeScale : parseInt(timeScale); - if (Number.isNaN(operand) || operand < 1) { - throw new Error(`TimeScale needs to be a valid integer >= 1, but received: ${timeScale}`); - } - - return { - toOption: () => Math.ceil(value * operand), - toDisplay: () => Math.ceil(value / operand), - } - - } - - handleTimeValidation() { - if (this.$eraseEntitiesAfterTime.is(":invalid")) { - // TriliumNextTODO: i18n - toastService.showMessage("The entered time value is not a valid number."); - return false - } - return true; - } - } From f672054441bc45042ed814357286a824f0321a25 Mon Sep 17 00:00:00 2001 From: Panagiotis Papadopoulos Date: Sun, 16 Feb 2025 14:00:28 +0100 Subject: [PATCH 03/24] feat(time_selector): use time_selector in attachment_erasure_timeout --- .../other/attachment_erasure_timeout.ts | 29 ++++++++++--------- src/routes/api/options.ts | 1 + src/services/options_init.ts | 3 +- src/services/options_interface.ts | 1 + 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts b/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts index 48ce0cb0d..c384dce10 100644 --- a/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts +++ b/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts @@ -2,33 +2,37 @@ import OptionsWidget from "../options_widget.js"; import server from "../../../../services/server.js"; import toastService from "../../../../services/toast.js"; import { t } from "../../../../services/i18n.js"; -import type { OptionMap } from "../../../../../../services/options_interface.js"; +import TimeSelector from "../time_selector.js"; const TPL = `

${t("attachment_erasure_timeout.attachment_erasure_timeout")}

${t("attachment_erasure_timeout.attachment_auto_deletion_description")}

+`; -
- - -
- +const TPL2 = `

${t("attachment_erasure_timeout.manual_erasing_description")}

`; -export default class AttachmentErasureTimeoutOptions extends OptionsWidget { +export default class AttachmentErasureTimeoutOptions extends TimeSelector { - private $eraseUnusedAttachmentsAfterTimeInSeconds!: JQuery; private $eraseUnusedAttachmentsNowButton!: JQuery; + constructor() { + super({ + widgetId: "erase-unused-attachments-after", + widgetLabelId: "attachment_erasure_timeout.erase_attachments_after_x_seconds", + optionValueId: "eraseUnusedAttachmentsAfterSeconds", + optionTimeScaleId: "eraseUnusedAttachmentsAfterTimeScale" + }) + super.doRender() + } + doRender() { - this.$widget = $(TPL); - this.$eraseUnusedAttachmentsAfterTimeInSeconds = this.$widget.find(".erase-unused-attachments-after-time-in-seconds"); - this.$eraseUnusedAttachmentsAfterTimeInSeconds.on("change", () => this.updateOption("eraseUnusedAttachmentsAfterSeconds", this.$eraseUnusedAttachmentsAfterTimeInSeconds.val())); + this.$widget = $(TPL).append(this.$widget).append(TPL2); this.$eraseUnusedAttachmentsNowButton = this.$widget.find(".erase-unused-attachments-now-button"); this.$eraseUnusedAttachmentsNowButton.on("click", () => { @@ -38,7 +42,4 @@ export default class AttachmentErasureTimeoutOptions extends OptionsWidget { }); } - async optionsLoaded(options: OptionMap) { - this.$eraseUnusedAttachmentsAfterTimeInSeconds.val(options.eraseUnusedAttachmentsAfterSeconds); - } } diff --git a/src/routes/api/options.ts b/src/routes/api/options.ts index 14cb7ec42..33cd5fa8c 100644 --- a/src/routes/api/options.ts +++ b/src/routes/api/options.ts @@ -61,6 +61,7 @@ const ALLOWED_OPTIONS = new Set([ "checkForUpdates", "disableTray", "eraseUnusedAttachmentsAfterSeconds", + "eraseUnusedAttachmentsAfterTimeScale", "disableTray", "customSearchEngineName", "customSearchEngineUrl", diff --git a/src/services/options_init.ts b/src/services/options_init.ts index bb962835d..3bb87703e 100644 --- a/src/services/options_init.ts +++ b/src/services/options_init.ts @@ -122,7 +122,8 @@ const defaultOptions: DefaultOption[] = [ { name: "highlightsList", value: '["bold","italic","underline","color","bgColor"]', isSynced: true }, { name: "checkForUpdates", value: "true", isSynced: true }, { name: "disableTray", value: "false", isSynced: false }, - { name: "eraseUnusedAttachmentsAfterSeconds", value: "2592000", isSynced: true }, + { name: "eraseUnusedAttachmentsAfterSeconds", value: "2592000", isSynced: true }, // default 30 days + { name: "eraseUnusedAttachmentsAfterTimeScale", value: "86400", isSynced: true }, // default 86400 seconds = Day { name: "customSearchEngineName", value: "DuckDuckGo", isSynced: true }, { name: "customSearchEngineUrl", value: "https://duckduckgo.com/?q={keyword}", isSynced: true }, { name: "promotedAttributesOpenInRibbon", value: "true", isSynced: true }, diff --git a/src/services/options_interface.ts b/src/services/options_interface.ts index f3a92383b..fb234240c 100644 --- a/src/services/options_interface.ts +++ b/src/services/options_interface.ts @@ -67,6 +67,7 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions Date: Sun, 16 Feb 2025 14:10:13 +0100 Subject: [PATCH 04/24] i18n(time_selector): translate invalid_input message --- src/public/app/widgets/type_widgets/options/time_selector.ts | 3 +-- src/public/translations/en/translation.json | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/public/app/widgets/type_widgets/options/time_selector.ts b/src/public/app/widgets/type_widgets/options/time_selector.ts index 49c149f75..d364cb095 100644 --- a/src/public/app/widgets/type_widgets/options/time_selector.ts +++ b/src/public/app/widgets/type_widgets/options/time_selector.ts @@ -116,8 +116,7 @@ export default class TimeSelector extends OptionsWidget { handleTimeValidation() { if (this.$timeValueInput.is(":invalid")) { - // TriliumNextTODO: i18n - toastService.showMessage("The entered time value is not a valid number."); + toastService.showMessage(t("time_selector.invalid_input")); return false } return true; diff --git a/src/public/translations/en/translation.json b/src/public/translations/en/translation.json index 392ea89ae..636b3732a 100644 --- a/src/public/translations/en/translation.json +++ b/src/public/translations/en/translation.json @@ -1655,5 +1655,8 @@ "minutes": "Minutes", "hours": "Hours", "days": "Days" + }, + "time_selector": { + "invalid_input": "The entered time value is not a valid number." } } From 793b0c9fe89dcfc057c0d152b3ff12bff5838cc6 Mon Sep 17 00:00:00 2001 From: Panagiotis Papadopoulos Date: Sun, 16 Feb 2025 15:27:18 +0100 Subject: [PATCH 05/24] feat(time_selector): add possibility to omit time scales --- .../type_widgets/options/time_selector.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/public/app/widgets/type_widgets/options/time_selector.ts b/src/public/app/widgets/type_widgets/options/time_selector.ts index d364cb095..1bd413022 100644 --- a/src/public/app/widgets/type_widgets/options/time_selector.ts +++ b/src/public/app/widgets/type_widgets/options/time_selector.ts @@ -9,19 +9,22 @@ type TimeSelectorConstructor = { widgetLabelId: string; optionValueId: keyof OptionDefinitions; optionTimeScaleId: keyof OptionDefinitions; + includedTimeScales?: Set; }; +type TimeSelectorScale = "seconds" | "minutes" | "hours" | "days"; -const TPL = (options: Pick) => ` + +const TPL = (options: Omit) => `
@@ -42,6 +45,7 @@ export default class TimeSelector extends OptionsWidget { private widgetLabelId: string; private optionValueId: keyof OptionDefinitions; private optionTimeScaleId: keyof OptionDefinitions; + private includedTimeScales: Set; constructor(options: TimeSelectorConstructor) { super(); @@ -49,12 +53,14 @@ export default class TimeSelector extends OptionsWidget { this.widgetLabelId = options.widgetLabelId; this.optionValueId = options.optionValueId; this.optionTimeScaleId = options.optionTimeScaleId; + this.includedTimeScales = (!options.includedTimeScales) ? new Set(["seconds", "minutes", "hours", "days"]) : options.includedTimeScales; } doRender() { this.$widget = $(TPL({ widgetId: this.widgetId, - widgetLabelId: this.widgetLabelId + widgetLabelId: this.widgetLabelId, + includedTimeScales: this.includedTimeScales, })); this.$timeValueInput = this.$widget.find(`#${this.widgetId}`); From 10ba4672020219ce526c1eec7c23bc83ac44f10f Mon Sep 17 00:00:00 2001 From: Panagiotis Papadopoulos Date: Sun, 16 Feb 2025 18:13:52 +0100 Subject: [PATCH 06/24] chore(prettier): run prettier on time_selector related files --- .../other/attachment_erasure_timeout.ts | 6 ++-- .../options/other/note_erasure_timeout.ts | 8 ++--- .../type_widgets/options/time_selector.ts | 35 +++++++------------ 3 files changed, 17 insertions(+), 32 deletions(-) diff --git a/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts b/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts index c384dce10..65cd61ce6 100644 --- a/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts +++ b/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts @@ -18,7 +18,6 @@ const TPL2 = ` `; export default class AttachmentErasureTimeoutOptions extends TimeSelector { - private $eraseUnusedAttachmentsNowButton!: JQuery; constructor() { @@ -27,8 +26,8 @@ export default class AttachmentErasureTimeoutOptions extends TimeSelector { widgetLabelId: "attachment_erasure_timeout.erase_attachments_after_x_seconds", optionValueId: "eraseUnusedAttachmentsAfterSeconds", optionTimeScaleId: "eraseUnusedAttachmentsAfterTimeScale" - }) - super.doRender() + }); + super.doRender(); } doRender() { @@ -41,5 +40,4 @@ export default class AttachmentErasureTimeoutOptions extends TimeSelector { }); }); } - } diff --git a/src/public/app/widgets/type_widgets/options/other/note_erasure_timeout.ts b/src/public/app/widgets/type_widgets/options/other/note_erasure_timeout.ts index f06274c03..d71a2c370 100644 --- a/src/public/app/widgets/type_widgets/options/other/note_erasure_timeout.ts +++ b/src/public/app/widgets/type_widgets/options/other/note_erasure_timeout.ts @@ -17,22 +17,19 @@ const TPL2 = ` `; export default class NoteErasureTimeoutOptions extends TimeSelector { - private $eraseDeletedNotesButton!: JQuery; constructor() { - super( { + super({ widgetId: "erase-entities-after", widgetLabelId: "note_erasure_timeout.erase_notes_after", optionValueId: "eraseEntitiesAfterTimeInSeconds", optionTimeScaleId: "eraseEntitiesAfterTimeScale" - }) + }); super.doRender(); - } doRender() { - this.$widget = $(TPL).append(this.$widget).append(TPL2); this.$eraseDeletedNotesButton = this.$widget.find("#erase-deleted-notes-now-button"); @@ -43,5 +40,4 @@ export default class NoteErasureTimeoutOptions extends TimeSelector { }); }); } - } diff --git a/src/public/app/widgets/type_widgets/options/time_selector.ts b/src/public/app/widgets/type_widgets/options/time_selector.ts index 1bd413022..dc95b0a77 100644 --- a/src/public/app/widgets/type_widgets/options/time_selector.ts +++ b/src/public/app/widgets/type_widgets/options/time_selector.ts @@ -3,7 +3,6 @@ import toastService from "../../../services/toast.js"; import { t } from "../../../services/i18n.js"; import type { OptionDefinitions, OptionMap } from "../../../../../services/options_interface.js"; - type TimeSelectorConstructor = { widgetId: string; widgetLabelId: string; @@ -14,7 +13,6 @@ type TimeSelectorConstructor = { type TimeSelectorScale = "seconds" | "minutes" | "hours" | "days"; - const TPL = (options: Omit) => `
@@ -37,7 +35,6 @@ const TPL = (options: Omit`; export default class TimeSelector extends OptionsWidget { - private $timeValueInput!: JQuery; private $timeScaleSelect!: JQuery; private internalTimeInSeconds!: string | number; @@ -53,15 +50,17 @@ export default class TimeSelector extends OptionsWidget { this.widgetLabelId = options.widgetLabelId; this.optionValueId = options.optionValueId; this.optionTimeScaleId = options.optionTimeScaleId; - this.includedTimeScales = (!options.includedTimeScales) ? new Set(["seconds", "minutes", "hours", "days"]) : options.includedTimeScales; + this.includedTimeScales = !options.includedTimeScales ? new Set(["seconds", "minutes", "hours", "days"]) : options.includedTimeScales; } doRender() { - this.$widget = $(TPL({ - widgetId: this.widgetId, - widgetLabelId: this.widgetLabelId, - includedTimeScales: this.includedTimeScales, - })); + this.$widget = $( + TPL({ + widgetId: this.widgetId, + widgetLabelId: this.widgetLabelId, + includedTimeScales: this.includedTimeScales + }) + ); this.$timeValueInput = this.$widget.find(`#${this.widgetId}`); this.$timeScaleSelect = this.$widget.find(`#${this.widgetId}-time-scale`); @@ -74,11 +73,9 @@ export default class TimeSelector extends OptionsWidget { this.internalTimeInSeconds = this.convertTime(time, timeScale).toOption(); this.updateOption(this.optionValueId, this.internalTimeInSeconds); - }); this.$timeScaleSelect.on("change", () => { - const timeScale = this.$timeScaleSelect.val(); if (!this.handleTimeValidation() || typeof timeScale !== "string") return; @@ -88,9 +85,7 @@ export default class TimeSelector extends OptionsWidget { this.updateOption(this.optionTimeScaleId, timeScale); this.$timeValueInput.val(displayedTime).trigger("change"); - }); - } async optionsLoaded(options: OptionMap) { @@ -100,12 +95,10 @@ export default class TimeSelector extends OptionsWidget { this.$timeScaleSelect.val(options[this.optionTimeScaleId]); } - convertTime(time: string | number, timeScale: string | number) { - const value = typeof time === "number" ? time : parseInt(time); if (Number.isNaN(value)) { - throw new Error(`Time needs to be a valid integer, but received: ${time}`); + throw new Error(`Time needs to be a valid integer, but received: ${time}`); } const operand = typeof timeScale === "number" ? timeScale : parseInt(timeScale); @@ -115,17 +108,15 @@ export default class TimeSelector extends OptionsWidget { return { toOption: () => Math.ceil(value * operand), - toDisplay: () => Math.ceil(value / operand), - } - + toDisplay: () => Math.ceil(value / operand) + }; } handleTimeValidation() { if (this.$timeValueInput.is(":invalid")) { toastService.showMessage(t("time_selector.invalid_input")); - return false + return false; } return true; } - -} \ No newline at end of file +} From ccbed7bbc375997ba8ea6926c3978d4ba7722b4c Mon Sep 17 00:00:00 2001 From: Panagiotis Papadopoulos Date: Sun, 16 Feb 2025 18:17:55 +0100 Subject: [PATCH 07/24] feat(time_selector): use showError since this is an error --- src/public/app/widgets/type_widgets/options/time_selector.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/public/app/widgets/type_widgets/options/time_selector.ts b/src/public/app/widgets/type_widgets/options/time_selector.ts index dc95b0a77..7e12f5fbd 100644 --- a/src/public/app/widgets/type_widgets/options/time_selector.ts +++ b/src/public/app/widgets/type_widgets/options/time_selector.ts @@ -114,7 +114,7 @@ export default class TimeSelector extends OptionsWidget { handleTimeValidation() { if (this.$timeValueInput.is(":invalid")) { - toastService.showMessage(t("time_selector.invalid_input")); + toastService.showError(t("time_selector.invalid_input")); return false; } return true; From fc8f805b28f3d50952e0d6755e88019446a939da Mon Sep 17 00:00:00 2001 From: Panagiotis Papadopoulos Date: Mon, 17 Feb 2025 06:52:29 +0100 Subject: [PATCH 08/24] i18n(time_selector): adjust attachment erasure message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit as we now are allowing entering the time in other formats (minutes, hours, days) – it doesn't make sense for the label to say "after X seconds". --- .../type_widgets/options/other/attachment_erasure_timeout.ts | 2 +- src/public/translations/cn/translation.json | 4 ++-- src/public/translations/de/translation.json | 4 ++-- src/public/translations/en/translation.json | 4 ++-- src/public/translations/es/translation.json | 4 ++-- src/public/translations/fr/translation.json | 4 ++-- src/public/translations/ro/translation.json | 4 ++-- src/public/translations/tw/translation.json | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts b/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts index 65cd61ce6..01c730287 100644 --- a/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts +++ b/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts @@ -23,7 +23,7 @@ export default class AttachmentErasureTimeoutOptions extends TimeSelector { constructor() { super({ widgetId: "erase-unused-attachments-after", - widgetLabelId: "attachment_erasure_timeout.erase_attachments_after_x_seconds", + widgetLabelId: "attachment_erasure_timeout.erase_attachments_after", optionValueId: "eraseUnusedAttachmentsAfterSeconds", optionTimeScaleId: "eraseUnusedAttachmentsAfterTimeScale" }); diff --git a/src/public/translations/cn/translation.json b/src/public/translations/cn/translation.json index 3525f7a27..7a8ef18a8 100644 --- a/src/public/translations/cn/translation.json +++ b/src/public/translations/cn/translation.json @@ -1122,7 +1122,7 @@ "attachment_erasure_timeout": { "attachment_erasure_timeout": "附件清理超时", "attachment_auto_deletion_description": "如果附件在一段时间后不再被笔记引用,它们将自动被删除(并被清理)。", - "erase_attachments_after_x_seconds": "在附件在笔记中未被使用 X 秒后清理", + "erase_attachments_after": "Erase unused attachments after:", "manual_erasing_description": "您还可以手动触发清理(而不考虑上述定义的超时时间):", "erase_unused_attachments_now": "立即清理未使用的附件笔记", "unused_attachments_erased": "未使用的附件已被删除。" @@ -1134,7 +1134,7 @@ "note_erasure_timeout": { "note_erasure_timeout_title": "笔记清理超时", "note_erasure_description": "被删除的笔记(以及属性、历史版本等)最初仅被标记为“删除”,可以从“最近修改”对话框中恢复它们。经过一段时间后,已删除的笔记会被“清理”,这意味着它们的内容将无法恢复。此设置允许您配置从删除到清除笔记之间的时间长度。", - "erase_notes_after": "Erase notes after", + "erase_notes_after": "Erase notes after:", "manual_erasing_description": "您还可以手动触发清理(不考虑上述定义的超时):", "erase_deleted_notes_now": "立即清理已删除的笔记", "deleted_notes_erased": "已删除的笔记已被清理。" diff --git a/src/public/translations/de/translation.json b/src/public/translations/de/translation.json index 9d318b7c2..2beacba53 100644 --- a/src/public/translations/de/translation.json +++ b/src/public/translations/de/translation.json @@ -1090,7 +1090,7 @@ "attachment_erasure_timeout": { "attachment_erasure_timeout": "Zeitüberschreitung beim Löschen von Anhängen", "attachment_auto_deletion_description": "Anhänge werden automatisch gelöscht (und gelöscht), wenn sie nach einer definierten Zeitspanne nicht mehr in ihrer Notiz referenziert werden.", - "erase_attachments_after_x_seconds": "Anhänge nach X Sekunden löschen, nachdem sie nicht in der Notiz verwendet wurden", + "erase_attachments_after": "Erase unused attachments after:", "manual_erasing_description": "Du kannst das Löschen auch manuell auslösen (ohne Berücksichtigung des oben definierten Timeouts):", "erase_unused_attachments_now": "Lösche jetzt nicht verwendete Anhangnotizen", "unused_attachments_erased": "Nicht verwendete Anhänge wurden gelöscht." @@ -1102,7 +1102,7 @@ "note_erasure_timeout": { "note_erasure_timeout_title": "Beachte das Zeitlimit für die Löschung", "note_erasure_description": "Deleted notes (and attributes, revisions...) are at first only marked as deleted and it is possible to recover them from Recent Notes dialog. After a period of time, deleted notes are \"erased\" which means their content is not recoverable anymore. This setting allows you to configure the length of the period between deleting and erasing the note.", - "erase_notes_after": "Notizen löschen nach", + "erase_notes_after": "Notizen löschen nach:", "manual_erasing_description": "Du kannst das Löschen auch manuell auslösen (ohne Berücksichtigung des oben definierten Timeouts):", "erase_deleted_notes_now": "Jetzt gelöschte Notizen löschen", "deleted_notes_erased": "Gelöschte Notizen wurden gelöscht." diff --git a/src/public/translations/en/translation.json b/src/public/translations/en/translation.json index 636b3732a..9a8b92176 100644 --- a/src/public/translations/en/translation.json +++ b/src/public/translations/en/translation.json @@ -1147,7 +1147,7 @@ "attachment_erasure_timeout": { "attachment_erasure_timeout": "Attachment Erasure Timeout", "attachment_auto_deletion_description": "Attachments get automatically deleted (and erased) if they are not referenced by their note anymore after a defined time out.", - "erase_attachments_after_x_seconds": "Erase attachments after X seconds of not being used in its note", + "erase_attachments_after": "Erase unused attachments after:", "manual_erasing_description": "You can also trigger erasing manually (without considering the timeout defined above):", "erase_unused_attachments_now": "Erase unused attachment notes now", "unused_attachments_erased": "Unused attachments have been erased." @@ -1159,7 +1159,7 @@ "note_erasure_timeout": { "note_erasure_timeout_title": "Note Erasure Timeout", "note_erasure_description": "Deleted notes (and attributes, revisions...) are at first only marked as deleted and it is possible to recover them from Recent Notes dialog. After a period of time, deleted notes are \"erased\" which means their content is not recoverable anymore. This setting allows you to configure the length of the period between deleting and erasing the note.", - "erase_notes_after": "Erase notes after", + "erase_notes_after": "Erase notes after:", "manual_erasing_description": "You can also trigger erasing manually (without considering the timeout defined above):", "erase_deleted_notes_now": "Erase deleted notes now", "deleted_notes_erased": "Deleted notes have been erased." diff --git a/src/public/translations/es/translation.json b/src/public/translations/es/translation.json index f23b90972..39904d266 100644 --- a/src/public/translations/es/translation.json +++ b/src/public/translations/es/translation.json @@ -1146,7 +1146,7 @@ "attachment_erasure_timeout": { "attachment_erasure_timeout": "Tiempo de espera para borrar archivos adjuntos", "attachment_auto_deletion_description": "Los archivos adjuntos se eliminan (y borran) automáticamente si ya no se hace referencia a ellos en su nota después de un tiempo de espera definido.", - "erase_attachments_after_x_seconds": "Borrar archivos adjuntos después de X segundos de no usarse en su nota", + "erase_attachments_after": "Erase unused attachments after:", "manual_erasing_description": "También puede activar el borrado manualmente (sin considerar el tiempo de espera definido anteriormente):", "erase_unused_attachments_now": "Borrar ahora los archivos adjuntos no utilizados en la nota", "unused_attachments_erased": "Los archivos adjuntos no utilizados se han eliminado." @@ -1158,7 +1158,7 @@ "note_erasure_timeout": { "note_erasure_timeout_title": "Tiempo de espera de borrado de notas", "note_erasure_description": "Las notas eliminadas (y los atributos, las revisiones ...) en principio solo están marcadas como eliminadas y es posible recuperarlas del diálogo de Notas recientes. Después de un período de tiempo, las notas eliminadas son \" borradas\", lo que significa que su contenido ya no es recuperable. Esta configuración le permite configurar la longitud del período entre eliminar y borrar la nota.", - "erase_notes_after": "Borrar notas después de", + "erase_notes_after": "Borrar notas después de:", "manual_erasing_description": "También puede activar el borrado manualmente (sin considerar el tiempo de espera definido anteriormente):", "erase_deleted_notes_now": "Borrar notas eliminadas ahora", "deleted_notes_erased": "Las notas eliminadas han sido borradas." diff --git a/src/public/translations/fr/translation.json b/src/public/translations/fr/translation.json index 9e13ba005..0f110fcab 100644 --- a/src/public/translations/fr/translation.json +++ b/src/public/translations/fr/translation.json @@ -1091,7 +1091,7 @@ "attachment_erasure_timeout": { "attachment_erasure_timeout": "Délai d'effacement des pièces jointes", "attachment_auto_deletion_description": "Les pièces jointes sont automatiquement supprimées (et effacées) si elles ne sont plus référencées par leur note après un certain délai.", - "erase_attachments_after_x_seconds": "Effacer les pièces jointes après X secondes sans utilisation dans sa note", + "erase_attachments_after": "Erase unused attachments after:", "manual_erasing_description": "Vous pouvez également déclencher l'effacement manuellement (sans tenir compte du délai défini ci-dessus) :", "erase_unused_attachments_now": "Effacez maintenant les pièces jointes inutilisées", "unused_attachments_erased": "Les pièces jointes inutilisées ont été effacées." @@ -1103,7 +1103,7 @@ "note_erasure_timeout": { "note_erasure_timeout_title": "Délai d'effacement des notes", "note_erasure_description": "Les notes supprimées (et les attributs, versions...) sont seulement marquées comme supprimées et il est possible de les récupérer à partir de la boîte de dialogue Notes récentes. Après un certain temps, les notes supprimées sont « effacées », ce qui signifie que leur contenu n'est plus récupérable. Ce paramètre vous permet de configurer la durée entre la suppression et l'effacement de la note.", - "erase_notes_after": "Effacer les notes après", + "erase_notes_after": "Effacer les notes après:", "manual_erasing_description": "Vous pouvez également déclencher l'effacement manuellement (sans tenir compte de la durée définie ci-dessus) :", "erase_deleted_notes_now": "Effacer les notes supprimées maintenant", "deleted_notes_erased": "Les notes supprimées ont été effacées." diff --git a/src/public/translations/ro/translation.json b/src/public/translations/ro/translation.json index f751350a1..e39d6071a 100644 --- a/src/public/translations/ro/translation.json +++ b/src/public/translations/ro/translation.json @@ -78,7 +78,7 @@ "attachment_erasure_timeout": { "attachment_auto_deletion_description": "Atașamentele se șterg automat (permanent) dacă nu sunt referențiate de către notița lor părinte după un timp prestabilit de timp.", "attachment_erasure_timeout": "Perioadă de ștergere a atașamentelor", - "erase_attachments_after_x_seconds": "Șterge atașamentele după X secunde după ce acestea n-au mai fost folosite într-o notiță", + "erase_attachments_after": "Erase unused attachments after:", "erase_unused_attachments_now": "Elimină atașamentele șterse acum", "manual_erasing_description": "Șterge acum toate atașamentele nefolosite din notițe", "unused_attachments_erased": "Atașamentele nefolosite au fost șterse." @@ -835,7 +835,7 @@ "note_erasure_timeout": { "deleted_notes_erased": "Notițele șterse au fost eliminate permanent.", "erase_deleted_notes_now": "Elimină notițele șterse acum", - "erase_notes_after": "Elimină notițele șterse după", + "erase_notes_after": "Elimină notițele șterse după:", "manual_erasing_description": "Se poate rula o eliminare manuală (fără a lua în considerare timpul definit mai sus):", "note_erasure_description": "Notițele șterse (precum și atributele, reviziile) sunt prima oară doar marcate drept șterse și este posibil să fie recuperate din ecranul Notițe recente. După o perioadă de timp, notițele șterse vor fi „eliminate”, caz în care conținutul lor nu se poate recupera. Această setare permite configurarea duratei de timp dintre ștergerea și eliminarea notițelor.", "note_erasure_timeout_title": "Timpul de eliminare automată a notițelor șterse" diff --git a/src/public/translations/tw/translation.json b/src/public/translations/tw/translation.json index 463ec858f..0cfe9c94f 100644 --- a/src/public/translations/tw/translation.json +++ b/src/public/translations/tw/translation.json @@ -1100,7 +1100,7 @@ "attachment_erasure_timeout": { "attachment_erasure_timeout": "附件清理超時", "attachment_auto_deletion_description": "如果附件在一段時間後不再被筆記引用,它們將自動被刪除(並被清理)。", - "erase_attachments_after_x_seconds": "在附件在筆記中未被使用 X 秒後清理", + "erase_attachments_after": "Erase unused attachments after:", "manual_erasing_description": "您還可以手動觸發清理(而不考慮上述定義的超時時間):", "erase_unused_attachments_now": "立即清理未使用的附件筆記", "unused_attachments_erased": "未使用的附件已被刪除。" @@ -1112,7 +1112,7 @@ "note_erasure_timeout": { "note_erasure_timeout_title": "筆記清理超時", "note_erasure_description": "被刪除的筆記(以及屬性、歷史版本等)最初僅被標記為「刪除」,可以從「最近修改」對話框中恢復它們。經過一段時間後,已刪除的筆記會被「清理」,這意味著它們的內容將無法恢復。此設定允許您設定從刪除到清除筆記之間的時間長度。", - "erase_notes_after": "Erase notes after", + "erase_notes_after": "Erase notes after:", "manual_erasing_description": "您還可以手動觸發清理(不考慮上述定義的超時):", "erase_deleted_notes_now": "立即清理已刪除的筆記", "deleted_notes_erased": "已刪除的筆記已被清理。" From d26d6687411959c8c14e84f37085586bcd9f897a Mon Sep 17 00:00:00 2001 From: Panagiotis Papadopoulos Date: Mon, 17 Feb 2025 09:00:44 +0100 Subject: [PATCH 09/24] feat(time_selector): avoid "template concatenation" --- .../options/other/attachment_erasure_timeout.ts | 9 +++++---- .../type_widgets/options/other/note_erasure_timeout.ts | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts b/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts index 01c730287..7af216cd0 100644 --- a/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts +++ b/src/public/app/widgets/type_widgets/options/other/attachment_erasure_timeout.ts @@ -9,9 +9,7 @@ const TPL = `

${t("attachment_erasure_timeout.attachment_erasure_timeout")}

${t("attachment_erasure_timeout.attachment_auto_deletion_description")}

-`; - -const TPL2 = ` +

${t("attachment_erasure_timeout.manual_erasing_description")}

@@ -31,7 +29,10 @@ export default class AttachmentErasureTimeoutOptions extends TimeSelector { } doRender() { - this.$widget = $(TPL).append(this.$widget).append(TPL2); + const $timeSelector = this.$widget; + this.$widget = $(TPL); + // inject TimeSelector widget template + this.$widget.find("#time-selector-placeholder").replaceWith($timeSelector); this.$eraseUnusedAttachmentsNowButton = this.$widget.find(".erase-unused-attachments-now-button"); this.$eraseUnusedAttachmentsNowButton.on("click", () => { diff --git a/src/public/app/widgets/type_widgets/options/other/note_erasure_timeout.ts b/src/public/app/widgets/type_widgets/options/other/note_erasure_timeout.ts index d71a2c370..b15e56074 100644 --- a/src/public/app/widgets/type_widgets/options/other/note_erasure_timeout.ts +++ b/src/public/app/widgets/type_widgets/options/other/note_erasure_timeout.ts @@ -9,9 +9,7 @@ const TPL = `

${t("note_erasure_timeout.note_erasure_timeout_title")}

${t("note_erasure_timeout.note_erasure_description")}

-`; - -const TPL2 = ` +

${t("note_erasure_timeout.manual_erasing_description")}

`; @@ -30,7 +28,10 @@ export default class NoteErasureTimeoutOptions extends TimeSelector { } doRender() { - this.$widget = $(TPL).append(this.$widget).append(TPL2); + const $timeSelector = this.$widget; + // inject TimeSelector widget template + this.$widget = $(TPL); + this.$widget.find("#time-selector-placeholder").replaceWith($timeSelector) this.$eraseDeletedNotesButton = this.$widget.find("#erase-deleted-notes-now-button"); From 5550885206272e0cceb8ea67b13a4717a06e8d21 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 17:42:15 +0200 Subject: [PATCH 10/24] fix(build): run prepare-dist for electron-forge:make --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index d48cdaf6e..f0dc10cb7 100644 --- a/package.json +++ b/package.json @@ -39,15 +39,15 @@ "electron:switch": "electron-rebuild", "electron-forge:start": "npm run build:prepare-dist && electron-forge start", - "electron-forge:make": "npm run build:webpack && npm run build:prepare-dist && electron-forge make", - "electron-forge:package": "electron-forge package", + "electron-forge:make": "npm run build:prepare-dist && electron-forge make", + "electron-forge:package": "npm run build:prepare-dist && electron-forge package", "docs:build-backend": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts", "docs:build-frontend": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js", "docs:build": "npm run docs:build-backend && npm run docs:build-frontend", "build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts", - "build:prepare-dist": "rimraf ./dist && tsc && tsx ./bin/copy-dist.ts", + "build:prepare-dist": "npm run build:webpack && rimraf ./dist && tsc && tsx ./bin/copy-dist.ts", "test": "cross-env TRILIUM_DATA_DIR=./integration-tests/db vitest", "test:coverage": "cross-env TRILIUM_DATA_DIR=./integration-tests/db vitest --coverage", From e39bee23aab9d7f7b1b8097bb9f3de044a949c76 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 18:07:36 +0200 Subject: [PATCH 11/24] fix(electron): background effects on fixed light/dark mode (closes #1209) --- src/public/app/desktop.ts | 19 +++++++++++++++++++ src/public/stylesheets/theme-next.css | 4 ++++ src/public/stylesheets/theme.css | 4 ++++ 3 files changed, 27 insertions(+) diff --git a/src/public/app/desktop.ts b/src/public/app/desktop.ts index b78074126..b546bf68c 100644 --- a/src/public/app/desktop.ts +++ b/src/public/app/desktop.ts @@ -50,6 +50,7 @@ function initOnElectron() { const currentWindow = electronRemote.getCurrentWindow(); const style = window.getComputedStyle(document.body); + initDarkOrLightMode(style); initTransparencyEffects(style, currentWindow); if (options.get("nativeTitleBarVisible") !== "true") { @@ -91,3 +92,21 @@ function initTransparencyEffects(style: CSSStyleDeclaration, currentWindow: Elec } } } + +/** + * Informs Electron that we prefer a dark or light theme. Apart from changing prefers-color-scheme at CSS level which is a side effect, + * this fixes color issues with background effects or native title bars. + * + * @param style the root CSS element to read variables from. + */ +function initDarkOrLightMode(style: CSSStyleDeclaration) { + let themeSource: typeof nativeTheme.themeSource = "system"; + + const themeStyle = style.getPropertyValue("--theme-style"); + if (style.getPropertyValue("--theme-style-auto") !== "true" && (themeStyle === "light" || themeStyle === "dark")) { + themeSource = themeStyle; + } + + const { nativeTheme } = utils.dynamicRequire("@electron/remote") as typeof ElectronRemote; + nativeTheme.themeSource = themeSource; +} diff --git a/src/public/stylesheets/theme-next.css b/src/public/stylesheets/theme-next.css index c740a3006..1c8a7d810 100644 --- a/src/public/stylesheets/theme-next.css +++ b/src/public/stylesheets/theme-next.css @@ -5,3 +5,7 @@ /* Import the dark color scheme when the system preference is set to dark mode */ @import url(./theme-next-dark.css) (prefers-color-scheme: dark); + +:root { + --theme-style-auto: true; +} diff --git a/src/public/stylesheets/theme.css b/src/public/stylesheets/theme.css index 35a22e516..6b8fee32d 100644 --- a/src/public/stylesheets/theme.css +++ b/src/public/stylesheets/theme.css @@ -5,3 +5,7 @@ /* Import the dark color scheme when the system preference is set to dark mode */ @import url(./theme-dark.css) (prefers-color-scheme: dark); + +:root { + --theme-style-auto: true; +} \ No newline at end of file From 7bcfb1df96bbf8fbfb25956e0dfd4352d56056f8 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 19:28:54 +0200 Subject: [PATCH 12/24] chore(docs): minor updates --- .../app/doc_notes/en/User Guide/!!!meta.json | 139 +----------------- .../Theme development/Reference.html | 54 ++++++- .../User Guide/User Guide/Installation.html | 38 ----- .../1_On Fedora Linux_Screenshot.png | Bin 45675 -> 0 bytes .../Installation/1_On Fedora Linux_image.png | Bin 1199 -> 0 bytes .../2_On Fedora Linux_Screenshot.png | Bin 11205 -> 0 bytes .../Installation/2_On Fedora Linux_image.png | Bin 1121 -> 0 bytes .../3_On Fedora Linux_Screenshot.png | Bin 34171 -> 0 bytes .../Installation/On Fedora Linux.html | 82 ----------- .../On Fedora Linux_Screenshot.png | Bin 13286 -> 0 bytes .../Installation/On Fedora Linux_image.png | Bin 1123 -> 0 bytes .../User Guide/Installation_Fedora_logo.svg | 10 -- .../Note Types/Book/Calendar View.html | 2 + .../Downloading responses from Goo.html | 48 +++++- .../app/doc_notes/en/User Guide/index.html | 2 +- .../doc_notes/en/User Guide/navigation.html | 6 - 16 files changed, 105 insertions(+), 276 deletions(-) delete mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation.html delete mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/1_On Fedora Linux_Screenshot.png delete mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/1_On Fedora Linux_image.png delete mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/2_On Fedora Linux_Screenshot.png delete mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/2_On Fedora Linux_image.png delete mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/3_On Fedora Linux_Screenshot.png delete mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux.html delete mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux_Screenshot.png delete mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux_image.png delete mode 100644 src/public/app/doc_notes/en/User Guide/User Guide/Installation_Fedora_logo.svg diff --git a/src/public/app/doc_notes/en/User Guide/!!!meta.json b/src/public/app/doc_notes/en/User Guide/!!!meta.json index b90fd4f50..4fb15df7f 100644 --- a/src/public/app/doc_notes/en/User Guide/!!!meta.json +++ b/src/public/app/doc_notes/en/User Guide/!!!meta.json @@ -1,6 +1,6 @@ { "formatVersion": 2, - "appVersion": "0.91.6-test-250214-024424", + "appVersion": "0.91.6-test-250217-024840", "files": [ { "isClone": false, @@ -11,7 +11,7 @@ "title": "User Guide", "notePosition": 20, "prefix": null, - "isExpanded": false, + "isExpanded": true, "type": "text", "mime": "text/html", "attributes": [ @@ -27,135 +27,6 @@ "attachments": [], "dirFileName": "User Guide", "children": [ - { - "isClone": false, - "noteId": "jrai60LsOhdk", - "notePath": [ - "OkOZllzB3fqN", - "jrai60LsOhdk" - ], - "title": "Installation", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "KPeRqBU7YSAY", - "isInheritable": false, - "position": 10 - }, - { - "type": "label", - "name": "hideChildrenOverview", - "value": "", - "isInheritable": false, - "position": 10 - } - ], - "format": "html", - "dataFileName": "Installation.html", - "attachments": [ - { - "attachmentId": "Mp9RaDeLtETz", - "title": "Fedora_logo.svg", - "role": "image", - "mime": "image/svg+xml", - "position": 10, - "dataFileName": "Installation_Fedora_logo.svg" - } - ], - "dirFileName": "Installation", - "children": [ - { - "isClone": false, - "noteId": "KPeRqBU7YSAY", - "notePath": [ - "OkOZllzB3fqN", - "jrai60LsOhdk", - "KPeRqBU7YSAY" - ], - "title": "On Fedora Linux", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "label", - "name": "iconClass", - "value": "bx bxl-tux", - "isInheritable": false, - "position": 10 - } - ], - "format": "html", - "dataFileName": "On Fedora Linux.html", - "attachments": [ - { - "attachmentId": "YHD8kyEhgkyZ", - "title": "Screenshot From 2025-02-05 19-30-50.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "On Fedora Linux_Screenshot.png" - }, - { - "attachmentId": "0CpZ5v5xUMia", - "title": "Screenshot From 2025-02-05 19-35-45.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_On Fedora Linux_Screenshot.png" - }, - { - "attachmentId": "9u7nBYvUbXJW", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "On Fedora Linux_image.png" - }, - { - "attachmentId": "ipGBq0moRvF3", - "title": "Screenshot From 2025-02-05 19-36-27.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "2_On Fedora Linux_Screenshot.png" - }, - { - "attachmentId": "fa83WbDUIB4G", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_On Fedora Linux_image.png" - }, - { - "attachmentId": "kcCWr0YXytOU", - "title": "Screenshot From 2025-02-05 19-30-30.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "3_On Fedora Linux_Screenshot.png" - }, - { - "attachmentId": "YF3JZy1qz7Fq", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "2_On Fedora Linux_image.png" - } - ] - } - ] - }, { "isClone": false, "noteId": "yoAe4jV2yzbd", @@ -166,7 +37,7 @@ "title": "Features", "notePosition": 40, "prefix": null, - "isExpanded": true, + "isExpanded": false, "type": "text", "mime": "text/html", "attributes": [], @@ -314,7 +185,7 @@ "title": "Note Types", "notePosition": 70, "prefix": null, - "isExpanded": true, + "isExpanded": false, "type": "text", "mime": "text/html", "attributes": [], @@ -548,7 +419,7 @@ "title": "Book", "notePosition": 30, "prefix": null, - "isExpanded": true, + "isExpanded": false, "type": "text", "mime": "text/html", "attributes": [ diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Reference.html b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Reference.html index e858513c1..59c2320c4 100644 --- a/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Reference.html +++ b/src/public/app/doc_notes/en/User Guide/User Guide/Advanced usage/Theme development/Reference.html @@ -13,6 +13,37 @@

Reference

+

Detecting mobile vs. desktop

+

The mobile layout is different than the one on the desktop. Use body.mobile and body.desktop to + differentiate between them.

body.mobile #root-widget {
+	/* Do something on mobile */
+}
+
+body.desktop #root-widget {
+	/* Do something on desktop */
+}
+

Do note that there is also a “tablet mode” in the mobile layout. For that + particular case media queries are required:

@media (max-width: 991px) {
+
+    #launcher-pane {
+
+        /* Do something on mobile layout */
+
+    }
+
+}
+
+
+
+@media (min-width: 992px) {
+
+    #launcher-pane {
+
+        /* Do something on mobile tablet + desktop layout */
+
+    }
+
+}

Detecting horizontal vs. vertical layout

The user can select between vertical layout (the classical one, where the launcher bar is on the left) and a horizontal layout (where the launcher @@ -85,14 +116,14 @@ body.electron:not(.native-titlebar) {

On macOS

On macOS the semaphore window buttons are enabled by default when the native title bar is disabled. The offset of the buttons can be adjusted - using:

body {
+          using:

body {
     --native-titlebar-darwin-x-offset: 12;
     --native-titlebar-darwin-y-offset: 14 !important;
 }

Background/transparency effects on Windows (Mica)

Windows 11 offers a special background/transparency effect called Mica, which can be enabled by themes by setting the --background-material variable - at body level:

body.electron.platform-win32 {
+          at body level:

body.electron.platform-win32 {
 	--background-material: tabbed; 
 }

The value can be either tabbed (especially useful for the horizontal @@ -104,12 +135,12 @@ body.electron:not(.native-titlebar) {

Theme capabilities are small adjustments done through CSS variables that can affect the layout or the visual aspect of the application.

In the tab bar, to display the icons of notes instead of the icon of the - workspace:

:root {
+          workspace:

:root {
 	--tab-note-icons: true;
 }

When a workspace is hoisted for a given tab, it is possible to get the background color of that workspace, for example to apply a small strip - on the tab instead of the whole background color:

.note-tab .note-tab-wrapper {
+          on the tab instead of the whole background color:

.note-tab .note-tab-wrapper {
     --tab-background-color: initial !important;
 }
 
@@ -127,6 +158,21 @@ body.electron:not(.native-titlebar) {
           href="../Custom%20resource%20providers.html">Custom resource providers.
           Basically import a font into Trilium and assign it #customResourceProvider=fonts/myfont.ttf and
           then import the font in CSS via /custom/fonts/myfont.ttf.

+

Dark and light themes

+

A light theme needs to have the following CSS:

:root {
+	--theme-style: light;
+}
+

if the theme is dark, then --theme-style needs to be dark.

+

If the theme is auto (e.g. supports both light or dark based on prefers-color-scheme) + it must also declare (in addition to setting --theme-style to + either light or dark):

:root {
+
+    --theme-style-auto: true;
+
+}
+

This will affect the behavior of the Electron application by informing + the operating system of the color preference (e.g. background effects will + appear correct on Windows).

diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Installation.html b/src/public/app/doc_notes/en/User Guide/User Guide/Installation.html deleted file mode 100644 index 058f84feb..000000000 --- a/src/public/app/doc_notes/en/User Guide/User Guide/Installation.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - Installation - - - -
-

Installation

- -
-

Desktop application

-
- - - - - - -
-
- -
-

Fedora -

-
-
-

Self-hosted server

-
-
- - - \ No newline at end of file diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Installation/1_On Fedora Linux_Screenshot.png b/src/public/app/doc_notes/en/User Guide/User Guide/Installation/1_On Fedora Linux_Screenshot.png deleted file mode 100644 index d519f9b75ac6f6f2243bb13769d9e8d81a94c19e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45675 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%0D)xiE|{;~ht_KF?WIf4$<1`|#mY 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 N002ovPDHLkV1nRuOt1g| diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Installation/2_On Fedora Linux_Screenshot.png b/src/public/app/doc_notes/en/User Guide/User Guide/Installation/2_On Fedora Linux_Screenshot.png deleted file mode 100644 index d7370a422124323846cbf969aed114ad8e04d271..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11205 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 i|KC?k|4;bv}bCTT9$Y!~>Crrbs9u2omDK zg9nL-H1QxjNF+o;+$upxL`VpUOVJXQpi0rYx3t>rcGvFCZrAzF+SQ7>rR|*M{FBYj znVmW3o9{Q@cg~)fqxk*)5WcFk!h_4zUOfL8fEJAGmEXPT0h0m9PB&skP8=4EvqhU$ z2-Mq_Ahw)!qPjlNn>NX|e&K#D+xH5hFgBkP_bm5|sFixP=mw1QjD5h!Hb& zkEo+7`=DZTCej^j?xY)Jw;DRBpqdR3kqvr=N+JOXj8gNi{ustnQ$?`|3`u z>5H@LGP=83-Rt}3KpfKY-&9L!s6U&8JYDI*!hAbY>;~L??#1@=Eok$# zgOb{^Ne;{zX+vL@E*o4yRKD_~Z+*qVO?n>n~An!{#ZM*(o8TL z71Vstu;+>s_h0+}#zbAt5i+8((oI-B)qz)^0#F#4nZvADKH0$?G%MGJwbK*e_J(k* zybbqW`q1DE&#oN3-3AYPYU2-tu>V>s&Oh+*bF%uFkZ4so@T&KI{amYw8^5`N(zM}*M-Vi?a2~sHf3>tV+uVK#adfsQ1J@aDR zU<>vvPWx#Z+cYZ)Yo;aO#xoyQ9sY;|W#6JrU^bmh6CTv}jx?$Y?}yG*y0P&@6K=im z!fH}5AUT{I0xT0+SlPnTUqtx~Cc!Q(ckzBt3w9vip#ka-J4z(y2%Gx82NWqUU?aiV zBW!#`NADNp53<1R3!%1ABVXqY@C4%-V;IK-28-FVX+K)*x-cFa#j^?MD4W9*%( zZ}x=yxfN`{a$qmJBmu@`zYOc`Ru_$&+R zTZ1@s)5Rlm3G3S^V)d3Xw&cx^^MKx#$@V*WAm$?Kf8{4Z#Rz!`N`i_J55$O>GNNJy z6#W;G659jBNTnCjrNs6CF;Z#OfRxxCAVw-J?VwcyQet|5*bpN=n4qN{5|((NBFk>b nGQK`4VxnBgra!E%7P5T-;wM=8HgQhz00000NkvXXu0mjf5R(}V diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Installation/3_On Fedora Linux_Screenshot.png b/src/public/app/doc_notes/en/User Guide/User Guide/Installation/3_On Fedora Linux_Screenshot.png deleted file mode 100644 index 6c3589ca4a8558384d9eb5d717f9f7b083294d16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34171 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�yB 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

6a!B=oygRidS%1BFuWnSm! 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 diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux.html b/src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux.html deleted file mode 100644 index 88ad36272..000000000 --- a/src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - On Fedora Linux - - - -

-

On Fedora Linux

- -
-

First, download a release from GitHub.

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 -
- -
-
In your file explorer, look for the .rpm file of TriliumNext.
2 -
- -
-
Right click the file and select Open With Software Install.
3 -
- -
-
-

GNOME Software will appear. Press the - .

-

You will be asked to confirm the action by entering your password.

-

After confirmation the software will start installing.

-

Once it's done the “Install” button will turn into - .

-
4 -
- -
-
After installation, the application will be available in the GNOME overview - section.
-
-
-
- - - \ No newline at end of file diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux_Screenshot.png b/src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux_Screenshot.png deleted file mode 100644 index fb0ce66ef59087f240276e04e5bfbdc526d03674..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13286 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 diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux_image.png b/src/public/app/doc_notes/en/User Guide/User Guide/Installation/On Fedora Linux_image.png deleted file mode 100644 index 5791f83ef852e15ad94c8b9ef89169e17dd494f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1123 zcmV-p1f2VcP){}j=#kdL@=X_dK(he-GOd`Ln}GQvor*EE zLZCEF!{U7n(dzne7n&r8`jrQAv#i)sn2hWci=xuW64I|+X3pmnIGaj5d~lW0os1-N zK>W_A#D*BDRFkB{_5d+bY2hFxwg-rjDpz-6Ln7;l5noJ5iSGdkN_U0n@&B~bWj~V zyOXQBqhw81M|W#_fBzgP(>>Zr2E<~$lRE#KZYd4*OtIipl^^p8Tu5_SQ2r!g;MIOd=|u-;`i)Mv;%WSxR8^f z!DdxZ^H#^Miyqv5`Sm{se`9M`UL#~gBzkk`|O?d%JY z;uLcFKjbf5L>X4DJ@x_jUxzR#+lKv1GLhfg#y{$t5i_~+d4Pjz`rOhwF={UymB^!J z?-g(Bae_uKLz@dzF^vJIzOUBA$GuKrK?U?E_bb6_VQ*7e3M5^4@ENo7U06KY&7in( z<9QH!E;ZrqtM=2F&7xr8=tN8$kbtZtD~~Rc@s~FQm+-MqkfJeW+?5aObxhw`&udoM z;{ZnXwPV+UjGv~l4O3IFYGM+uJ`Q5Vp?BC{_BGlB=hJGQ@SwhTq*YaT9Xeg*!}{YN zaP4UT4oyL?)L3!|vrK4bZ97YUh6)%=f?a&w%j=#VX+yrv08|g#N+jn9oBF;7WVGk9 zmEg3&PQId}=L-t@*x?IC@$9|MPpN6pF|L0Cw$4i95Kr9np{_BE9?2GLo0E>}H#%kw zcYV`+qd!*XmazrPfwE?N^2OTutZzE^)Gc3o=5*O{k-jv)HR+GcsS%bBXAE#o7J?oI$Ysp5A^65-`{~z zId;@HMR2g(%Oi6Ut8EmqW=k1SRQKaNV76s){BJxEcM1iD zQSkzbev3$n?Ezw>(gW#IVtarXskCcAN^B1hBbByx(5?X~F+D(Rh!I~*(AEwKOFU4< pwi~jH?~gJhH?o-ztG$hEUjPM@SikkV$6EjZ002ovPDHLkV1h@y8q)v( diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Installation_Fedora_logo.svg b/src/public/app/doc_notes/en/User Guide/User Guide/Installation_Fedora_logo.svg deleted file mode 100644 index 1ad9c15c8..000000000 --- a/src/public/app/doc_notes/en/User Guide/User Guide/Installation_Fedora_logo.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Book/Calendar View.html b/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Book/Calendar View.html index d5364a1e9..c01fe823f 100644 --- a/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Book/Calendar View.html +++ b/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Book/Calendar View.html @@ -74,6 +74,8 @@
+
  • Creating new notes from the calendar will respect the ~child:template relation + if set on the book note.
  • Interacting with events

      diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Scripting/Examples/Downloading responses from Goo.html b/src/public/app/doc_notes/en/User Guide/User Guide/Scripting/Examples/Downloading responses from Goo.html index 7e4955655..fdffa270d 100644 --- a/src/public/app/doc_notes/en/User Guide/User Guide/Scripting/Examples/Downloading responses from Goo.html +++ b/src/public/app/doc_notes/en/User Guide/User Guide/Scripting/Examples/Downloading responses from Goo.html @@ -12,7 +12,53 @@

      Downloading responses from Google Forms

      -
      +
      +

      This tutorials showcases a basic integration with Google Forms, where + we are able to download the responses of a form using the “Link to Sheets" + functionality.

      +

      Note that the link will be publicly accessible to everyone (however the + link is in a hard-to-guess format such as https://docs.google.com/spreadsheets/d/e/2PACX-1vTA8NU2_eZFhc8TFadCZPreBfvP7un8IHd6J0SchrLLw3ueGmntNZjwRmsH2ZRcp1pJYDAzMz1FmFaj/pub?output=csv). + Make sure you are not accidentally publishing sensitive information.

      +

      Obtaining the CSV link

      +
        +
      1. Open the Google Forms in a browser.
      2. +
      3. Select the “Responses” tab and click on “Link to Sheets”.
      4. +
      5. Select “Create a new spreadsheet” and press “Create”.
      6. +
      7. In Google Sheets, select File → Share → Publish to web.
      8. +
      9. In the “Publish to the web” screen, make sure the “Link” tab is selected + and instead of “Web page”, select “Comma-separated values (.csv)”.
      10. +
      11. Copy the given link which will be used for the upcoming script.
      12. +
      +

      Creating the script

      +

      Create a “JS Frontend” script:

      const CSV_URL = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTiwooLV2whjCSVa49dJ99p_G3_qhqHHRqttMjYCJVfLXVdTgUSNJu5K0rpqmaHYF2k7Vofi3o7gW82/pub?output=csv";
      +
      +
      +async function fetchData() {
      +
      +    try {
      +
      +        const response = await fetch(CSV_URL);
      +
      +        return await response.text();
      +
      +    } catch (e) {
      +
      +        api.showError(e.message);
      +
      +    }
      +
      +}
      +
      +const data = await fetchData();
      +console.log(data);
      +// Do something with the data.
      +

      Note that the data will be received as a string and there is no library + to do the CSV parsing for us. To do a very simple parsing of CSV:

      const content = data
      +	.split("\n")
      +	.slice(1)
      +	.map((row) => row.split(","));
      +

      This will return the data as an array of arrays.

      +
      diff --git a/src/public/app/doc_notes/en/User Guide/index.html b/src/public/app/doc_notes/en/User Guide/index.html index fc49dc742..c5c17da96 100644 --- a/src/public/app/doc_notes/en/User Guide/index.html +++ b/src/public/app/doc_notes/en/User Guide/index.html @@ -6,6 +6,6 @@ - + \ No newline at end of file diff --git a/src/public/app/doc_notes/en/User Guide/navigation.html b/src/public/app/doc_notes/en/User Guide/navigation.html index 85143e944..732ee6d61 100644 --- a/src/public/app/doc_notes/en/User Guide/navigation.html +++ b/src/public/app/doc_notes/en/User Guide/navigation.html @@ -9,12 +9,6 @@
      • User Guide
          -
        • Installation - -
        • Features
          • Export as PDF From 4dd531e0362c0ba184a17d0e7644ff130892a1e0 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 19:29:59 +0200 Subject: [PATCH 13/24] chore(release): 0.92.0-beta --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f0dc10cb7..2503ee043 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "trilium", "productName": "TriliumNext Notes", "description": "Build your personal knowledge base with TriliumNext Notes", - "version": "0.91.6", + "version": "0.92.0-beta", "license": "AGPL-3.0-only", "main": "./dist/electron-main.js", "author": { From fabafeac86e99f72291c919b5b4d469cfcaf2b5e Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 19:53:25 +0200 Subject: [PATCH 14/24] fix(ci): missing os name in server release artifact --- .github/workflows/nightly.yml | 1 + .github/workflows/release.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index f7cee700a..9eae4afd7 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -75,6 +75,7 @@ jobs: - name: Run the build uses: ./.github/actions/build-server with: + os: linux arch: ${{ matrix.arch }} - name: Publish release diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b7625a706..e6c5c7c2e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,6 +65,7 @@ jobs: - name: Run the build uses: ./.github/actions/build-server with: + os: linux arch: ${{ matrix.arch }} - name: Publish release From ed082f34d5853049766b4a01bff4aafc7bfd5b5a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 21:01:06 +0200 Subject: [PATCH 15/24] fix(ci): add missing zip for Windows --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b19145ca1..d7e80cfed 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,7 +29,7 @@ jobs: extension: [deb, rpm, zip, flatpak] - name: windows image: windows-latest - extension: exe + extension: [exe, zip] runs-on: ${{ matrix.os.image }} steps: - uses: actions/checkout@v4 From 558bee72e929afe6f7471d7557d76a4898d5a18f Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 21:15:12 +0200 Subject: [PATCH 16/24] fix(ci): add missing zip for Windows on nightly --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 9eae4afd7..c339fd37d 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -26,7 +26,7 @@ jobs: extension: [deb, rpm, zip, flatpak] - name: windows image: windows-latest - extension: exe + extension: [exe, zip] runs-on: ${{ matrix.os.image }} steps: - uses: actions/checkout@v4 From 237f2ead736cb2f19eb05ae342aded796554d5c1 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 21:16:53 +0200 Subject: [PATCH 17/24] fix(ci): server platform name missing due to invalid input --- .github/actions/build-server/action.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/actions/build-server/action.yml b/.github/actions/build-server/action.yml index cf8057c70..7423b8c4a 100644 --- a/.github/actions/build-server/action.yml +++ b/.github/actions/build-server/action.yml @@ -1,4 +1,7 @@ inputs: + os: + description: "One of the supported platforms: windows" + required: true arch: description: "The architecture to build for: x64, arm64" required: true From fd47412d513b11e4f058b6fc0a298b2bc45f19e2 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 21:22:58 +0200 Subject: [PATCH 18/24] chore(client/ts): port web_view --- .../type_widgets/{web_view.js => web_view.ts} | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) rename src/public/app/widgets/type_widgets/{web_view.js => web_view.ts} (75%) diff --git a/src/public/app/widgets/type_widgets/web_view.js b/src/public/app/widgets/type_widgets/web_view.ts similarity index 75% rename from src/public/app/widgets/type_widgets/web_view.js rename to src/public/app/widgets/type_widgets/web_view.ts index 5bfa74f05..57f2fc11a 100644 --- a/src/public/app/widgets/type_widgets/web_view.js +++ b/src/public/app/widgets/type_widgets/web_view.ts @@ -1,18 +1,20 @@ import { t } from "../../services/i18n.js"; import TypeWidget from "./type_widget.js"; import attributeService from "../../services/attributes.js"; +import type FNote from "../../entities/fnote.js"; +import type { EventData } from "../../components/app_context.js"; const TPL = `

            ${t("web_view.web_view")}

            - +

            ${t("web_view.embed_websites")}

            ${t("web_view.create_label")}

            ${t("web_view.disclaimer")}

            - +

            ${t("web_view.experimental_note")}

            @@ -20,6 +22,10 @@ const TPL = `
            `; export default class WebViewTypeWidget extends TypeWidget { + + private $noteDetailWebViewHelp!: JQuery; + private $noteDetailWebViewContent!: JQuery; + static getType() { return "webView"; } @@ -34,11 +40,15 @@ export default class WebViewTypeWidget extends TypeWidget { super.doRender(); } - async doRefresh(note) { + async doRefresh(note: FNote) { this.$widget.show(); this.$noteDetailWebViewHelp.hide(); this.$noteDetailWebViewContent.hide(); + if (!this.note) { + return; + } + const webViewSrc = this.note.getLabelValue("webViewSrc"); if (webViewSrc) { @@ -54,17 +64,19 @@ export default class WebViewTypeWidget extends TypeWidget { } cleanup() { - this.$noteDetailWebViewContent.removeAttribute("src"); + this.$noteDetailWebViewContent.removeAttr("src"); } setDimensions() { const $parent = this.$widget; - this.$noteDetailWebViewContent.height($parent.height()).width($parent.width()); + this.$noteDetailWebViewContent + .height($parent.height() ?? 0) + .width($parent.width() ?? 0); } - entitiesReloadedEvent({ loadResults }) { - if (loadResults.getAttributeRows().find((attr) => attr.name === "webViewSrc" && attributeService.isAffecting(attr, this.noteContext.note))) { + entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) { + if (loadResults.getAttributeRows().find((attr) => attr.name === "webViewSrc" && attributeService.isAffecting(attr, this.noteContext?.note))) { this.refresh(); } } From 59b474df35e9b2351f627dddf350353ad47c0fe6 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 21:26:00 +0200 Subject: [PATCH 19/24] feat(webview): render in browser using iframe --- src/public/app/widgets/type_widgets/web_view.ts | 5 ++++- src/public/translations/cn/translation.json | 2 +- src/public/translations/de/translation.json | 2 +- src/public/translations/en/translation.json | 2 +- src/public/translations/es/translation.json | 2 +- src/public/translations/fr/translation.json | 2 +- src/public/translations/ro/translation.json | 2 +- src/public/translations/tw/translation.json | 2 +- 8 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/public/app/widgets/type_widgets/web_view.ts b/src/public/app/widgets/type_widgets/web_view.ts index 57f2fc11a..cc2fb1cae 100644 --- a/src/public/app/widgets/type_widgets/web_view.ts +++ b/src/public/app/widgets/type_widgets/web_view.ts @@ -3,6 +3,9 @@ import TypeWidget from "./type_widget.js"; import attributeService from "../../services/attributes.js"; import type FNote from "../../entities/fnote.js"; import type { EventData } from "../../components/app_context.js"; +import utils from "../../services/utils.js"; + +const el = utils.isElectron() ? "webview" : "iframe"; const TPL = `
            @@ -18,7 +21,7 @@ const TPL = `

            ${t("web_view.experimental_note")}

            - + <${el} class="note-detail-web-view-content"> `; export default class WebViewTypeWidget extends TypeWidget { diff --git a/src/public/translations/cn/translation.json b/src/public/translations/cn/translation.json index 3525f7a27..54a94928f 100644 --- a/src/public/translations/cn/translation.json +++ b/src/public/translations/cn/translation.json @@ -990,7 +990,7 @@ "embed_websites": "网页视图类型的笔记允许您将网站嵌入到 Trilium 中。", "create_label": "首先,请创建一个带有您要嵌入的 URL 地址的标签,例如 #webViewSrc=\"https://www.bing.com\"", "disclaimer": "实验性功能免责声明", - "experimental_note": "网页视图是一种实验性的笔记类型,将来可能会被移除或大幅更改。网页视图只在桌面端有效。" + "experimental_note": "网页视图是一种实验性的笔记类型,将来可能会被移除或大幅更改。" }, "backend_log": { "refresh": "刷新" diff --git a/src/public/translations/de/translation.json b/src/public/translations/de/translation.json index 9d318b7c2..76f3bc74a 100644 --- a/src/public/translations/de/translation.json +++ b/src/public/translations/de/translation.json @@ -967,7 +967,7 @@ "embed_websites": "Hinweis vom Typ Web View ermöglicht das Einbetten von Websites in Trilium.", "create_label": "To start, please create a label with a URL address you want to embed, e.g. #webViewSrc=\"https://www.google.com\"", "disclaimer": "Haftungsausschluss zum experimentellen Status", - "experimental_note": "Web View ist ein experimenteller Notiztyp und könnte in Zukunft entfernt oder grundlegend geändert werden. Web View funktioniert auch nur im Desktop-Build." + "experimental_note": "Web View ist ein experimenteller Notiztyp und könnte in Zukunft entfernt oder grundlegend geändert werden." }, "backend_log": { "refresh": "Aktualisieren" diff --git a/src/public/translations/en/translation.json b/src/public/translations/en/translation.json index f8fdbc51a..37cc5c4fc 100644 --- a/src/public/translations/en/translation.json +++ b/src/public/translations/en/translation.json @@ -1007,7 +1007,7 @@ "embed_websites": "Note of type Web View allows you to embed websites into Trilium.", "create_label": "To start, please create a label with a URL address you want to embed, e.g. #webViewSrc=\"https://www.google.com\"", "disclaimer": "Disclaimer on the experimental status", - "experimental_note": "Web View is an experimental note type, and it might be removed or substantially changed in the future. Web View works also only in the desktop build." + "experimental_note": "Web View is an experimental note type, and it might be removed or substantially changed in the future." }, "backend_log": { "refresh": "Refresh" diff --git a/src/public/translations/es/translation.json b/src/public/translations/es/translation.json index f23b90972..ac2e1ddaa 100644 --- a/src/public/translations/es/translation.json +++ b/src/public/translations/es/translation.json @@ -1005,7 +1005,7 @@ "embed_websites": "La nota de tipo Web View le permite insertar sitios web en Trilium.", "create_label": "To start, please create a label with a URL address you want to embed, e.g. #webViewSrc=\"https://www.google.com\"", "disclaimer": "Descargo de responsabilidad sobre el estado experimental", - "experimental_note": "Web View es un tipo de nota experimental y es posible que se elimine o cambie sustancialmente en el futuro. Web View también funciona solo en la versión de escritorio." + "experimental_note": "Web View es un tipo de nota experimental y es posible que se elimine o cambie sustancialmente en el futuro." }, "backend_log": { "refresh": "Refrescar" diff --git a/src/public/translations/fr/translation.json b/src/public/translations/fr/translation.json index 9e13ba005..2a4bc3386 100644 --- a/src/public/translations/fr/translation.json +++ b/src/public/translations/fr/translation.json @@ -968,7 +968,7 @@ "embed_websites": "Les notes de type Affichage Web vous permet d'intégrer des sites Web dans Trilium.", "create_label": "Pour commencer, veuillez créer un label avec l'adresse URL que vous souhaitez intégrer, par ex. #webViewSrc=\"https://www.google.com\"", "disclaimer": "Avertissement sur le statut expérimental", - "experimental_note": "Affichage Web est un type de note expérimental et il pourrait être supprimé ou considérablement modifié à l'avenir. Affichage Web ne fonctionne que dans la version de bureau." + "experimental_note": "Affichage Web est un type de note expérimental et il pourrait être supprimé ou considérablement modifié à l'avenir." }, "backend_log": { "refresh": "Rafraîchir" diff --git a/src/public/translations/ro/translation.json b/src/public/translations/ro/translation.json index 1f768eea6..71f804919 100644 --- a/src/public/translations/ro/translation.json +++ b/src/public/translations/ro/translation.json @@ -1309,7 +1309,7 @@ "create_label": "Pentru a începe, creați o etichetă cu adresa URL de încorporat, e.g. #webViewSrc=\"https://www.google.com\"", "disclaimer": "Avertisment despre statutul experimental", "embed_websites": "Notițele de tip „Vizualizare web” permit încorporarea site-urilor web în Trilium.", - "experimental_note": "„Vizualizare web” este un tip experimental de notiță, și poate fi înlăturat sau schimbat substanțial în viitor. De asemenea, Web View funcționeză doar în aplicația desktop.", + "experimental_note": "„Vizualizare web” este un tip experimental de notiță, și poate fi înlăturat sau schimbat substanțial în viitor.", "web_view": "Vizualizare web" }, "wrap_lines": { diff --git a/src/public/translations/tw/translation.json b/src/public/translations/tw/translation.json index 463ec858f..02c232a58 100644 --- a/src/public/translations/tw/translation.json +++ b/src/public/translations/tw/translation.json @@ -972,7 +972,7 @@ "embed_websites": "網頁視圖類型的筆記允許您將網站嵌入到 Trilium 中。", "create_label": "首先,請新增一個帶有您要嵌入的 URL 地址的標籤,例如 #webViewSrc=\"https://www.bing.com\"", "disclaimer": "實驗性功能免責聲明", - "experimental_note": "網頁視圖是一種實驗性的筆記類型,將來可能會被移除或大幅更改。網頁視圖只在桌面端有效。" + "experimental_note": "網頁視圖是一種實驗性的筆記類型,將來可能會被移除或大幅更改。" }, "backend_log": { "refresh": "刷新" From ef3a75d58e59a96259fdc8fefa040a1e9618043a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 21:49:24 +0200 Subject: [PATCH 20/24] feat(webview): set up some sandboxing for `; + } else { + return ``; + } +} + export default class WebViewTypeWidget extends TypeWidget { private $noteDetailWebViewHelp!: JQuery; From b837c57d063e0e151b4e93a33124f4f4e618f25a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 21:49:34 +0200 Subject: [PATCH 21/24] chore(lock): update --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 842410e2a..db09f9241 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "trilium", - "version": "0.91.6", + "version": "0.92.0-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "trilium", - "version": "0.91.6", + "version": "0.92.0-beta", "license": "AGPL-3.0-only", "dependencies": { "@braintree/sanitize-url": "7.1.1", From c7d75b759c23cf8ebf8a575a626a748491905aba Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 21:50:59 +0200 Subject: [PATCH 22/24] feat(webview): remove disclaimer --- src/public/app/widgets/type_widgets/web_view.ts | 4 ---- src/public/translations/cn/translation.json | 2 -- src/public/translations/de/translation.json | 4 +--- src/public/translations/en/translation.json | 4 +--- src/public/translations/es/translation.json | 4 +--- src/public/translations/fr/translation.json | 4 +--- src/public/translations/ro/translation.json | 2 -- src/public/translations/tw/translation.json | 4 +--- 8 files changed, 5 insertions(+), 23 deletions(-) diff --git a/src/public/app/widgets/type_widgets/web_view.ts b/src/public/app/widgets/type_widgets/web_view.ts index 3e57bce03..a5aeef534 100644 --- a/src/public/app/widgets/type_widgets/web_view.ts +++ b/src/public/app/widgets/type_widgets/web_view.ts @@ -13,10 +13,6 @@ const TPL = `

            ${t("web_view.embed_websites")}

            ${t("web_view.create_label")}

            - -

            ${t("web_view.disclaimer")}

            - -

            ${t("web_view.experimental_note")}

            ${buildElement()} diff --git a/src/public/translations/cn/translation.json b/src/public/translations/cn/translation.json index 54a94928f..2fdd2bf8c 100644 --- a/src/public/translations/cn/translation.json +++ b/src/public/translations/cn/translation.json @@ -989,8 +989,6 @@ "web_view": "网页视图", "embed_websites": "网页视图类型的笔记允许您将网站嵌入到 Trilium 中。", "create_label": "首先,请创建一个带有您要嵌入的 URL 地址的标签,例如 #webViewSrc=\"https://www.bing.com\"", - "disclaimer": "实验性功能免责声明", - "experimental_note": "网页视图是一种实验性的笔记类型,将来可能会被移除或大幅更改。" }, "backend_log": { "refresh": "刷新" diff --git a/src/public/translations/de/translation.json b/src/public/translations/de/translation.json index 76f3bc74a..02962f1e1 100644 --- a/src/public/translations/de/translation.json +++ b/src/public/translations/de/translation.json @@ -965,9 +965,7 @@ "web_view": { "web_view": "Webansicht", "embed_websites": "Hinweis vom Typ Web View ermöglicht das Einbetten von Websites in Trilium.", - "create_label": "To start, please create a label with a URL address you want to embed, e.g. #webViewSrc=\"https://www.google.com\"", - "disclaimer": "Haftungsausschluss zum experimentellen Status", - "experimental_note": "Web View ist ein experimenteller Notiztyp und könnte in Zukunft entfernt oder grundlegend geändert werden." + "create_label": "To start, please create a label with a URL address you want to embed, e.g. #webViewSrc=\"https://www.google.com\"" }, "backend_log": { "refresh": "Aktualisieren" diff --git a/src/public/translations/en/translation.json b/src/public/translations/en/translation.json index 37cc5c4fc..a79be955c 100644 --- a/src/public/translations/en/translation.json +++ b/src/public/translations/en/translation.json @@ -1005,9 +1005,7 @@ "web_view": { "web_view": "Web View", "embed_websites": "Note of type Web View allows you to embed websites into Trilium.", - "create_label": "To start, please create a label with a URL address you want to embed, e.g. #webViewSrc=\"https://www.google.com\"", - "disclaimer": "Disclaimer on the experimental status", - "experimental_note": "Web View is an experimental note type, and it might be removed or substantially changed in the future." + "create_label": "To start, please create a label with a URL address you want to embed, e.g. #webViewSrc=\"https://www.google.com\"" }, "backend_log": { "refresh": "Refresh" diff --git a/src/public/translations/es/translation.json b/src/public/translations/es/translation.json index ac2e1ddaa..42508f205 100644 --- a/src/public/translations/es/translation.json +++ b/src/public/translations/es/translation.json @@ -1003,9 +1003,7 @@ "web_view": { "web_view": "Vista web", "embed_websites": "La nota de tipo Web View le permite insertar sitios web en Trilium.", - "create_label": "To start, please create a label with a URL address you want to embed, e.g. #webViewSrc=\"https://www.google.com\"", - "disclaimer": "Descargo de responsabilidad sobre el estado experimental", - "experimental_note": "Web View es un tipo de nota experimental y es posible que se elimine o cambie sustancialmente en el futuro." + "create_label": "To start, please create a label with a URL address you want to embed, e.g. #webViewSrc=\"https://www.google.com\"" }, "backend_log": { "refresh": "Refrescar" diff --git a/src/public/translations/fr/translation.json b/src/public/translations/fr/translation.json index 2a4bc3386..30b2769fb 100644 --- a/src/public/translations/fr/translation.json +++ b/src/public/translations/fr/translation.json @@ -966,9 +966,7 @@ "web_view": { "web_view": "Affichage Web", "embed_websites": "Les notes de type Affichage Web vous permet d'intégrer des sites Web dans Trilium.", - "create_label": "Pour commencer, veuillez créer un label avec l'adresse URL que vous souhaitez intégrer, par ex. #webViewSrc=\"https://www.google.com\"", - "disclaimer": "Avertissement sur le statut expérimental", - "experimental_note": "Affichage Web est un type de note expérimental et il pourrait être supprimé ou considérablement modifié à l'avenir." + "create_label": "Pour commencer, veuillez créer un label avec l'adresse URL que vous souhaitez intégrer, par ex. #webViewSrc=\"https://www.google.com\"" }, "backend_log": { "refresh": "Rafraîchir" diff --git a/src/public/translations/ro/translation.json b/src/public/translations/ro/translation.json index 71f804919..89cd4d64a 100644 --- a/src/public/translations/ro/translation.json +++ b/src/public/translations/ro/translation.json @@ -1307,9 +1307,7 @@ }, "web_view": { "create_label": "Pentru a începe, creați o etichetă cu adresa URL de încorporat, e.g. #webViewSrc=\"https://www.google.com\"", - "disclaimer": "Avertisment despre statutul experimental", "embed_websites": "Notițele de tip „Vizualizare web” permit încorporarea site-urilor web în Trilium.", - "experimental_note": "„Vizualizare web” este un tip experimental de notiță, și poate fi înlăturat sau schimbat substanțial în viitor.", "web_view": "Vizualizare web" }, "wrap_lines": { diff --git a/src/public/translations/tw/translation.json b/src/public/translations/tw/translation.json index 02c232a58..cceef17a9 100644 --- a/src/public/translations/tw/translation.json +++ b/src/public/translations/tw/translation.json @@ -970,9 +970,7 @@ "web_view": { "web_view": "網頁視圖", "embed_websites": "網頁視圖類型的筆記允許您將網站嵌入到 Trilium 中。", - "create_label": "首先,請新增一個帶有您要嵌入的 URL 地址的標籤,例如 #webViewSrc=\"https://www.bing.com\"", - "disclaimer": "實驗性功能免責聲明", - "experimental_note": "網頁視圖是一種實驗性的筆記類型,將來可能會被移除或大幅更改。" + "create_label": "首先,請新增一個帶有您要嵌入的 URL 地址的標籤,例如 #webViewSrc=\"https://www.bing.com\"" }, "backend_log": { "refresh": "刷新" From 16caae191e814f3491a0e50c74e88e0b2bc193b7 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 21:59:02 +0200 Subject: [PATCH 23/24] fix(geomap): stuck viewport and zoom when switching between two geomaps --- .../app/widgets/type_widgets/geo_map.ts | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/public/app/widgets/type_widgets/geo_map.ts b/src/public/app/widgets/type_widgets/geo_map.ts index 11de0b2b3..1c1a72e35 100644 --- a/src/public/app/widgets/type_widgets/geo_map.ts +++ b/src/public/app/widgets/type_widgets/geo_map.ts @@ -135,10 +135,22 @@ export default class GeoMapTypeWidget extends TypeWidget { throw new Error(t("geo-map.unable-to-load-map")); } - if (!this.note) { + this.#restoreViewportAndZoom(); + + // Restore markers. + await this.#reloadMarkers(); + + const updateFn = () => this.spacedUpdate.scheduleUpdate(); + map.on("moveend", updateFn); + map.on("zoomend", updateFn); + map.on("click", (e) => this.#onMapClicked(e)); + } + + async #restoreViewportAndZoom() { + const map = this.geoMapWidget.map; + if (!map || !this.note) { return; } - const blob = await this.note.getBlob(); let parsedContent: MapData = {}; @@ -150,14 +162,6 @@ export default class GeoMapTypeWidget extends TypeWidget { const center = parsedContent.view?.center ?? DEFAULT_COORDINATES; const zoom = parsedContent.view?.zoom ?? DEFAULT_ZOOM; map.setView(center, zoom); - - // Restore markers. - await this.#reloadMarkers(); - - const updateFn = () => this.spacedUpdate.scheduleUpdate(); - map.on("moveend", updateFn); - map.on("zoomend", updateFn); - map.on("click", (e) => this.#onMapClicked(e)); } async #reloadMarkers() { @@ -343,6 +347,7 @@ export default class GeoMapTypeWidget extends TypeWidget { async doRefresh(note: FNote) { await this.geoMapWidget.refresh(); + this.#restoreViewportAndZoom(); await this.#reloadMarkers(); } From 50d37bbcb1c55082fbf6d144ed36f75a11eb4877 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 17 Feb 2025 22:28:54 +0200 Subject: [PATCH 24/24] chore(client/ts): port note_type --- .../widgets/{note_type.js => note_type.ts} | 50 +++++++++++++++---- 1 file changed, 39 insertions(+), 11 deletions(-) rename src/public/app/widgets/{note_type.js => note_type.ts} (84%) diff --git a/src/public/app/widgets/note_type.js b/src/public/app/widgets/note_type.ts similarity index 84% rename from src/public/app/widgets/note_type.js rename to src/public/app/widgets/note_type.ts index 26a42bdb7..9b3b90665 100644 --- a/src/public/app/widgets/note_type.js +++ b/src/public/app/widgets/note_type.ts @@ -3,8 +3,19 @@ import mimeTypesService from "../services/mime_types.js"; import NoteContextAwareWidget from "./note_context_aware_widget.js"; import dialogService from "../services/dialog.js"; import { t } from "../services/i18n.js"; +import type FNote from "../entities/fnote.js"; +import type { NoteType } from "../entities/fnote.js"; +import type { EventData } from "../components/app_context.js"; -const NOTE_TYPES = [ +interface NoteTypeMapping { + type: NoteType; + mime?: string; + title: string; + isBeta?: boolean; + selectable: boolean; +} + +const NOTE_TYPES: NoteTypeMapping[] = [ // The suggested note type ordering method: insert the item into the corresponding group, // then ensure the items within the group are ordered alphabetically. @@ -67,9 +78,16 @@ const TPL = ` `; export default class NoteTypeWidget extends NoteContextAwareWidget { + + private dropdown!: bootstrap.Dropdown; + private $noteTypeDropdown!: JQuery; + private $noteTypeButton!: JQuery; + private $noteTypeDesc!: JQuery; + doRender() { this.$widget = $(TPL); + //@ts-ignore this.dropdown = bootstrap.Dropdown.getOrCreateInstance(this.$widget.find("[data-bs-toggle='dropdown']")); this.$widget.on("show.bs.dropdown", () => this.renderDropdown()); @@ -81,7 +99,7 @@ export default class NoteTypeWidget extends NoteContextAwareWidget { this.$widget.on("click", ".dropdown-item", () => this.dropdown.toggle()); } - async refreshWithNote(note) { + async refreshWithNote(note: FNote) { this.$noteTypeButton.prop("disabled", () => NOT_SELECTABLE_NOTE_TYPES.includes(note.type)); this.$noteTypeDesc.text(await this.findTypeTitle(note.type, note.mime)); @@ -93,8 +111,12 @@ export default class NoteTypeWidget extends NoteContextAwareWidget { async renderDropdown() { this.$noteTypeDropdown.empty(); + if (!this.note) { + return; + } + for (const noteType of NOTE_TYPES.filter((nt) => nt.selectable)) { - let $typeLink; + let $typeLink: JQuery; const $title = $("").text(noteType.title); if (noteType.isBeta) { @@ -110,7 +132,9 @@ export default class NoteTypeWidget extends NoteContextAwareWidget { const type = $typeLink.attr("data-note-type"); const noteType = NOTE_TYPES.find((nt) => nt.type === type); - this.save(noteType.type, noteType.mime); + if (noteType) { + this.save(noteType.type, noteType.mime); + } }); } else { this.$noteTypeDropdown.append(''); @@ -136,7 +160,7 @@ export default class NoteTypeWidget extends NoteContextAwareWidget { .on("click", (e) => { const $link = $(e.target).closest(".dropdown-item"); - this.save("code", $link.attr("data-mime-type")); + this.save("code", $link.attr("data-mime-type") ?? ""); }); if (this.note.type === "code" && this.note.mime === mimeType.mime) { @@ -149,7 +173,7 @@ export default class NoteTypeWidget extends NoteContextAwareWidget { } } - async findTypeTitle(type, mime) { + async findTypeTitle(type: NoteType, mime: string) { if (type === "code") { const mimeTypes = mimeTypesService.getMimeTypes(); const found = mimeTypes.find((mt) => mt.mime === mime); @@ -162,12 +186,12 @@ export default class NoteTypeWidget extends NoteContextAwareWidget { } } - async save(type, mime) { - if (type === this.note.type && mime === this.note.mime) { + async save(type: NoteType, mime?: string) { + if (type === this.note?.type && mime === this.note?.mime) { return; } - if (type !== this.note.type && !(await this.confirmChangeIfContent())) { + if (type !== this.note?.type && !(await this.confirmChangeIfContent())) { return; } @@ -175,16 +199,20 @@ export default class NoteTypeWidget extends NoteContextAwareWidget { } async confirmChangeIfContent() { + if (!this.note) { + return; + } + const blob = await this.note.getBlob(); - if (!blob.content || !blob.content.trim().length) { + if (!blob?.content || !blob.content.trim().length) { return true; } return await dialogService.confirm(t("note_types.confirm-change")); } - async entitiesReloadedEvent({ loadResults }) { + async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) { if (loadResults.isNoteReloaded(this.noteId)) { this.refresh(); }