From 2bb79c4209435e3046fd83e056e09fc4634ee1b2 Mon Sep 17 00:00:00 2001 From: Panagiotis Papadopoulos Date: Sat, 8 Feb 2025 11:55:16 +0100 Subject: [PATCH 1/5] feat: "friendly number handling" for note erasure timeouts --- .../options/other/note_erasure_timeout.ts | 88 +++++++++++++++++-- src/routes/api/options.ts | 1 + src/services/options_init.ts | 1 + src/services/options_interface.ts | 1 + 4 files changed, 82 insertions(+), 9 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 876cf36d3..6b187a825 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 @@ -11,26 +11,62 @@ const TPL = `

${t("note_erasure_timeout.note_erasure_description")}

- - + +
+ + + +

${t("note_erasure_timeout.manual_erasing_description")}

- + `; export default class NoteErasureTimeoutOptions extends OptionsWidget { - private $eraseEntitiesAfterTimeInSeconds!: JQuery; - private $eraseDeletedNotesButton!: JQuery; + private $eraseEntitiesAfterTime!: JQuery; + private $eraseEntitiesAfterTimeScale!: JQuery; + private $eraseDeletedNotesButton!: JQuery; + private eraseEntitiesAfterTimeInSeconds!: string | number; doRender() { this.$widget = $(TPL); - this.$eraseEntitiesAfterTimeInSeconds = this.$widget.find(".erase-entities-after-time-in-seconds"); - this.$eraseEntitiesAfterTimeInSeconds.on("change", () => this.updateOption("eraseEntitiesAfterTimeInSeconds", this.$eraseEntitiesAfterTimeInSeconds.val())); + this.$eraseEntitiesAfterTime = this.$widget.find("#erase-entities-after-time"); + this.$eraseEntitiesAfterTimeScale = this.$widget.find("#erase-entities-after-time-scale"); - this.$eraseDeletedNotesButton = this.$widget.find(".erase-deleted-notes-now-button"); + 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.$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")); @@ -39,6 +75,40 @@ export default class NoteErasureTimeoutOptions extends OptionsWidget { } async optionsLoaded(options: OptionMap) { - this.$eraseEntitiesAfterTimeInSeconds.val(options.eraseEntitiesAfterTimeInSeconds); + 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; + } + } diff --git a/src/routes/api/options.ts b/src/routes/api/options.ts index 257344cab..14cb7ec42 100644 --- a/src/routes/api/options.ts +++ b/src/routes/api/options.ts @@ -12,6 +12,7 @@ import type { OptionNames } from "../../services/options_interface.js"; // options allowed to be updated directly in the Options dialog const ALLOWED_OPTIONS = new Set([ "eraseEntitiesAfterTimeInSeconds", + "eraseEntitiesAfterTimeScale", "protectedSessionTimeout", "revisionSnapshotTimeInterval", "revisionSnapshotNumberLimit", diff --git a/src/services/options_init.ts b/src/services/options_init.ts index dedd1a896..bb962835d 100644 --- a/src/services/options_init.ts +++ b/src/services/options_init.ts @@ -105,6 +105,7 @@ const defaultOptions: DefaultOption[] = [ { name: "rightPaneVisible", value: "true", isSynced: false }, { name: "nativeTitleBarVisible", value: "false", isSynced: false }, { name: "eraseEntitiesAfterTimeInSeconds", value: "604800", isSynced: true }, // default is 7 days + { name: "eraseEntitiesAfterTimeScale", value: "86400", isSynced: true }, // default 86400 seconds = Day { name: "hideArchivedNotes_main", value: "false", isSynced: false }, { name: "debugModeEnabled", value: "false", isSynced: false }, { name: "headingStyle", value: "underline", isSynced: true }, diff --git a/src/services/options_interface.ts b/src/services/options_interface.ts index 2632b7b2e..f3a92383b 100644 --- a/src/services/options_interface.ts +++ b/src/services/options_interface.ts @@ -61,6 +61,7 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions Date: Tue, 11 Feb 2025 08:43:18 +0100 Subject: [PATCH 2/5] chore: add i18n TODO (it does not make sense yet, to expose these as i18n, as I will be refactoring this whole thing into a standalone widget) --- .../widgets/type_widgets/options/other/note_erasure_timeout.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6b187a825..5daffee33 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 @@ -14,7 +14,7 @@ const TPL = `
- + diff --git a/src/public/translations/cn/translation.json b/src/public/translations/cn/translation.json index 1d844f21d..3525f7a27 100644 --- a/src/public/translations/cn/translation.json +++ b/src/public/translations/cn/translation.json @@ -1134,7 +1134,7 @@ "note_erasure_timeout": { "note_erasure_timeout_title": "笔记清理超时", "note_erasure_description": "被删除的笔记(以及属性、历史版本等)最初仅被标记为“删除”,可以从“最近修改”对话框中恢复它们。经过一段时间后,已删除的笔记会被“清理”,这意味着它们的内容将无法恢复。此设置允许您配置从删除到清除笔记之间的时间长度。", - "erase_notes_after_x_seconds": "在笔记删除 X 秒后清理", + "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 b0c9a91c6..9d318b7c2 100644 --- a/src/public/translations/de/translation.json +++ b/src/public/translations/de/translation.json @@ -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_x_seconds": "Notizen nach X Sekunden löschen", + "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 36fdccb4d..c3529c19a 100644 --- a/src/public/translations/en/translation.json +++ b/src/public/translations/en/translation.json @@ -1158,7 +1158,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_x_seconds": "Erase notes after X seconds", + "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 8499975a8..c789d3c2e 100644 --- a/src/public/translations/es/translation.json +++ b/src/public/translations/es/translation.json @@ -1153,7 +1153,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_x_seconds": "Borrar notas después de X segundos", + "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 7a680560d..9e13ba005 100644 --- a/src/public/translations/fr/translation.json +++ b/src/public/translations/fr/translation.json @@ -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_x_seconds": "Effacer les notes après X secondes", + "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 9f4c1ade9..151dbaba1 100644 --- a/src/public/translations/ro/translation.json +++ b/src/public/translations/ro/translation.json @@ -830,7 +830,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_x_seconds": "Elimină notițele șterse după X secunde", + "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 e80761cb2..463ec858f 100644 --- a/src/public/translations/tw/translation.json +++ b/src/public/translations/tw/translation.json @@ -1112,7 +1112,7 @@ "note_erasure_timeout": { "note_erasure_timeout_title": "筆記清理超時", "note_erasure_description": "被刪除的筆記(以及屬性、歷史版本等)最初僅被標記為「刪除」,可以從「最近修改」對話框中恢復它們。經過一段時間後,已刪除的筆記會被「清理」,這意味著它們的內容將無法恢復。此設定允許您設定從刪除到清除筆記之間的時間長度。", - "erase_notes_after_x_seconds": "在筆記刪除 X 秒後清理", + "erase_notes_after": "Erase notes after", "manual_erasing_description": "您還可以手動觸發清理(不考慮上述定義的超時):", "erase_deleted_notes_now": "立即清理已刪除的筆記", "deleted_notes_erased": "已刪除的筆記已被清理。" From e79c742d56e5a73e504b8f4865c5048e4888144f Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 13 Feb 2025 22:19:02 +0200 Subject: [PATCH 4/5] feat(i18n): translate duration units --- .../type_widgets/options/other/note_erasure_timeout.ts | 8 ++++---- src/public/translations/en/translation.json | 6 ++++++ src/public/translations/ro/translation.json | 6 ++++++ 3 files changed, 16 insertions(+), 4 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 159b56e8d..0d13b4a6d 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 @@ -16,10 +16,10 @@ const TPL = `
diff --git a/src/public/translations/en/translation.json b/src/public/translations/en/translation.json index c3529c19a..8825780fa 100644 --- a/src/public/translations/en/translation.json +++ b/src/public/translations/en/translation.json @@ -1648,5 +1648,11 @@ }, "help-button": { "title": "Open the relevant help page" + }, + "duration": { + "seconds": "Seconds", + "minutes": "Minutes", + "hours": "Hours", + "days": "Days" } } diff --git a/src/public/translations/ro/translation.json b/src/public/translations/ro/translation.json index 151dbaba1..352d0a634 100644 --- a/src/public/translations/ro/translation.json +++ b/src/public/translations/ro/translation.json @@ -1644,5 +1644,11 @@ "geo-map": { "create-child-note-title": "Crează o notiță nouă și adaug-o pe hartă", "unable-to-load-map": "Nu s-a putut încărca harta." + }, + "duration": { + "days": "zile", + "hours": "ore", + "minutes": "minute", + "seconds": "secunde" } } From 4b9667b75681ad04468d138d3fb7abd22b30798d Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 13 Feb 2025 22:21:09 +0200 Subject: [PATCH 5/5] feat(settings): make duration selector slightly smaller --- .../type_widgets/options/other/note_erasure_timeout.ts | 8 +++++++- src/public/stylesheets/style.css | 2 +- 2 files changed, 8 insertions(+), 2 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 0d13b4a6d..99161f9a9 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 @@ -15,7 +15,7 @@ const TPL = `
- @@ -27,6 +27,12 @@ const TPL = `

${t("note_erasure_timeout.manual_erasing_description")}

+ +
`; export default class NoteErasureTimeoutOptions extends OptionsWidget { diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index a85b87e62..efdc101eb 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -1641,4 +1641,4 @@ body.electron.platform-darwin:not(.native-titlebar) .tab-row-container { background: var(--main-background-color); box-shadow: 0px 10px 20px rgba(0, 0, 0, var(--dropdown-shadow-opacity)); border-radius: 4px; -} \ No newline at end of file +}