From 55b3bf6036d01408a8d5268da20d6f83e3d1f1d0 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 9 Jul 2025 21:12:18 +0300 Subject: [PATCH 01/57] feat(popup_editor): create an empty modal with auto-trigger --- apps/client/src/layouts/desktop_layout.ts | 4 +- .../src/widgets/dialogs/popup_editor.ts | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 apps/client/src/widgets/dialogs/popup_editor.ts diff --git a/apps/client/src/layouts/desktop_layout.ts b/apps/client/src/layouts/desktop_layout.ts index d47b112f6..81fda813c 100644 --- a/apps/client/src/layouts/desktop_layout.ts +++ b/apps/client/src/layouts/desktop_layout.ts @@ -94,6 +94,7 @@ import ToggleReadOnlyButton from "../widgets/floating_buttons/toggle_read_only_b import PngExportButton from "../widgets/floating_buttons/png_export_button.js"; import RefreshButton from "../widgets/floating_buttons/refresh_button.js"; import { applyModals } from "./layout_commons.js"; +import PopupEditorDialog from "../widgets/dialogs/popup_editor.js"; export default class DesktopLayout { @@ -257,7 +258,8 @@ export default class DesktopLayout { // Desktop-specific dialogs. .child(new PasswordNoteSetDialog()) - .child(new UploadAttachmentsDialog()); + .child(new UploadAttachmentsDialog()) + .child(new PopupEditorDialog()); applyModals(rootContainer); return rootContainer; diff --git a/apps/client/src/widgets/dialogs/popup_editor.ts b/apps/client/src/widgets/dialogs/popup_editor.ts new file mode 100644 index 000000000..3090e31f6 --- /dev/null +++ b/apps/client/src/widgets/dialogs/popup_editor.ts @@ -0,0 +1,42 @@ +import { openDialog } from "../../services/dialog.js"; +import BasicWidget from "../basic_widget.js"; + +const TPL = /*html*/`\ + +`; + +export default class PopupEditorDialog extends BasicWidget { + + constructor() { + super(); + setTimeout(() => { + this.openPopupEditorEvent("7mLWh47uEPEp"); + }, 750); + } + + doRender() { + this.$widget = $(TPL); + } + + async refresh() { + + } + + async openPopupEditorEvent(noteId: string) { + await this.refresh(); + openDialog(this.$widget); + } +} From bfec44aa5ae763995458fa3d826d50a2d4053203 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 9 Jul 2025 21:20:16 +0300 Subject: [PATCH 02/57] refactor(popup_editor): inject note detail widget --- apps/client/src/layouts/desktop_layout.ts | 3 ++- apps/client/src/widgets/dialogs/popup_editor.ts | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/client/src/layouts/desktop_layout.ts b/apps/client/src/layouts/desktop_layout.ts index 81fda813c..e522e6f19 100644 --- a/apps/client/src/layouts/desktop_layout.ts +++ b/apps/client/src/layouts/desktop_layout.ts @@ -259,7 +259,8 @@ export default class DesktopLayout { // Desktop-specific dialogs. .child(new PasswordNoteSetDialog()) .child(new UploadAttachmentsDialog()) - .child(new PopupEditorDialog()); + .child(new PopupEditorDialog() + .child(new NoteDetailWidget())); applyModals(rootContainer); return rootContainer; diff --git a/apps/client/src/widgets/dialogs/popup_editor.ts b/apps/client/src/widgets/dialogs/popup_editor.ts index 3090e31f6..6cb2eea58 100644 --- a/apps/client/src/widgets/dialogs/popup_editor.ts +++ b/apps/client/src/widgets/dialogs/popup_editor.ts @@ -1,5 +1,6 @@ import { openDialog } from "../../services/dialog.js"; import BasicWidget from "../basic_widget.js"; +import Container from "../containers/container.js"; const TPL = /*html*/`\ `; -export default class PopupEditorDialog extends BasicWidget { +export default class PopupEditorDialog extends Container { constructor() { super(); @@ -28,7 +29,13 @@ export default class PopupEditorDialog extends BasicWidget { } doRender() { - this.$widget = $(TPL); + // This will populate this.$widget with the content of the children. + super.doRender(); + + // Now we wrap it in the modal. + const $newWidget = $(TPL); + $newWidget.find(".modal-body").append(this.$widget.children()); + this.$widget = $newWidget; } async refresh() { From e49473fbd3d0cc56ec1939cb791008d2033efa70 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 9 Jul 2025 21:20:24 +0300 Subject: [PATCH 03/57] refactor(client): unused import --- apps/client/src/widgets/containers/container.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/client/src/widgets/containers/container.ts b/apps/client/src/widgets/containers/container.ts index 679fa11a8..236feffdd 100644 --- a/apps/client/src/widgets/containers/container.ts +++ b/apps/client/src/widgets/containers/container.ts @@ -1,5 +1,5 @@ -import type { default as Component, TypedComponent } from "../../components/component.js"; -import BasicWidget, { TypedBasicWidget } from "../basic_widget.js"; +import type { TypedComponent } from "../../components/component.js"; +import { TypedBasicWidget } from "../basic_widget.js"; export default class Container> extends TypedBasicWidget { doRender() { From e7467f6446a7626433c7894f2aa3f460d964371c Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 9 Jul 2025 21:44:42 +0300 Subject: [PATCH 04/57] feat(popup_editor): get editor to show up if note is open somewhere else --- apps/client/src/widgets/dialogs/popup_editor.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/client/src/widgets/dialogs/popup_editor.ts b/apps/client/src/widgets/dialogs/popup_editor.ts index 6cb2eea58..6e9c34e99 100644 --- a/apps/client/src/widgets/dialogs/popup_editor.ts +++ b/apps/client/src/widgets/dialogs/popup_editor.ts @@ -1,4 +1,6 @@ +import NoteContext from "../../components/note_context.js"; import { openDialog } from "../../services/dialog.js"; +import froca from "../../services/froca.js"; import BasicWidget from "../basic_widget.js"; import Container from "../containers/container.js"; @@ -21,10 +23,12 @@ const TPL = /*html*/`\ export default class PopupEditorDialog extends Container { + private noteId?: string; + constructor() { super(); setTimeout(() => { - this.openPopupEditorEvent("7mLWh47uEPEp"); + this.openPopupEditorEvent("vdJ8utb0A0Kd"); }, 750); } @@ -39,10 +43,21 @@ export default class PopupEditorDialog extends Container { } async refresh() { + if (!this.noteId) { + console.warn("Popup editor noteId is not set, cannot refresh."); + return; + } + const noteContext = new NoteContext("_popup-editor"); + noteContext.setNote(this.noteId); + + this.handleEventInChildren("setNoteContext", { + noteContext: noteContext + }) } async openPopupEditorEvent(noteId: string) { + this.noteId = noteId; await this.refresh(); openDialog(this.$widget); } From 5adca76a9ab1b2fdd92890d1361a2f82cd82e39f Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 9 Jul 2025 21:56:11 +0300 Subject: [PATCH 05/57] refactor(popup_editor): better error handling --- .../src/widgets/dialogs/popup_editor.ts | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/apps/client/src/widgets/dialogs/popup_editor.ts b/apps/client/src/widgets/dialogs/popup_editor.ts index 6e9c34e99..eb543c3ed 100644 --- a/apps/client/src/widgets/dialogs/popup_editor.ts +++ b/apps/client/src/widgets/dialogs/popup_editor.ts @@ -45,20 +45,28 @@ export default class PopupEditorDialog extends Container { async refresh() { if (!this.noteId) { console.warn("Popup editor noteId is not set, cannot refresh."); - return; + return false; + } + + const note = await froca.getNote(this.noteId); + if (!note) { + console.warn(`Popup editor note with ID ${this.noteId} not found.`); + return false; } const noteContext = new NoteContext("_popup-editor"); - noteContext.setNote(this.noteId); + await noteContext.setNote(note.noteId); - this.handleEventInChildren("setNoteContext", { + await this.handleEventInChildren("setNoteContext", { noteContext: noteContext - }) + }); + return true; } async openPopupEditorEvent(noteId: string) { this.noteId = noteId; - await this.refresh(); - openDialog(this.$widget); + if (await this.refresh()) { + openDialog(this.$widget); + } } } From 04593cb2d7288ca128db07fa34fd60501960e962 Mon Sep 17 00:00:00 2001 From: "Romain DEP." Date: Thu, 10 Jul 2025 13:15:41 +0200 Subject: [PATCH 06/57] fix(options): display a less ambiguous/scary message after performing a consistency check. The current message could easily be misinterpreted as an instruction for the user to go fix issues --- apps/client/src/translations/en/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/src/translations/en/translation.json b/apps/client/src/translations/en/translation.json index cf79ca8c1..6a448c2f8 100644 --- a/apps/client/src/translations/en/translation.json +++ b/apps/client/src/translations/en/translation.json @@ -1025,7 +1025,7 @@ "title": "Consistency Checks", "find_and_fix_button": "Find and fix consistency issues", "finding_and_fixing_message": "Finding and fixing consistency issues...", - "issues_fixed_message": "Consistency issues should be fixed." + "issues_fixed_message": "Any consistency issue which may have been found is now fixed." }, "database_anonymization": { "title": "Database Anonymization", From 0c17a13462a67111db63698e049f59c1857369d9 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 10 Jul 2025 14:57:32 +0300 Subject: [PATCH 07/57] fix(popup_editor): current tab events interfering --- apps/client/src/widgets/dialogs/popup_editor.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/apps/client/src/widgets/dialogs/popup_editor.ts b/apps/client/src/widgets/dialogs/popup_editor.ts index eb543c3ed..107cfe0aa 100644 --- a/apps/client/src/widgets/dialogs/popup_editor.ts +++ b/apps/client/src/widgets/dialogs/popup_editor.ts @@ -1,3 +1,4 @@ +import type { EventNames, EventData } from "../../components/app_context.js"; import NoteContext from "../../components/note_context.js"; import { openDialog } from "../../services/dialog.js"; import froca from "../../services/froca.js"; @@ -28,7 +29,7 @@ export default class PopupEditorDialog extends Container { constructor() { super(); setTimeout(() => { - this.openPopupEditorEvent("vdJ8utb0A0Kd"); + this.openPopupEditorEvent("f4sIt7iRg0Lc"); }, 750); } @@ -57,9 +58,7 @@ export default class PopupEditorDialog extends Container { const noteContext = new NoteContext("_popup-editor"); await noteContext.setNote(note.noteId); - await this.handleEventInChildren("setNoteContext", { - noteContext: noteContext - }); + await this.handleEventInChildren("activeContextChanged", { noteContext }); return true; } @@ -69,4 +68,14 @@ export default class PopupEditorDialog extends Container { openDialog(this.$widget); } } + + handleEventInChildren(name: T, data: EventData): Promise | null { + // Avoid events related to the current tab interfere with our popup. + if (["noteSwitched", "noteSwitchedAndActivated"].includes(name)) { + return Promise.resolve(); + } + + return super.handleEventInChildren(name, data); + } + } From cb5a7714901a334b1141c769b5e6ea030dcacef8 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 10 Jul 2025 15:07:48 +0300 Subject: [PATCH 08/57] feat(popup_editor): add editable note title and icon --- apps/client/src/layouts/desktop_layout.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/client/src/layouts/desktop_layout.ts b/apps/client/src/layouts/desktop_layout.ts index e522e6f19..4693d76aa 100644 --- a/apps/client/src/layouts/desktop_layout.ts +++ b/apps/client/src/layouts/desktop_layout.ts @@ -260,6 +260,14 @@ export default class DesktopLayout { .child(new PasswordNoteSetDialog()) .child(new UploadAttachmentsDialog()) .child(new PopupEditorDialog() + .child(new FlexContainer("row") + .class("title-row") + .css("height", "50px") + .css("min-height", "50px") + .css("align-items", "center") + .cssBlock(".title-row > * { margin: 5px; }") + .child(new NoteIconWidget()) + .child(new NoteTitleWidget())) .child(new NoteDetailWidget())); applyModals(rootContainer); From fa0c01591ae0b568525dab9e25905443eb8efdf4 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 10 Jul 2025 15:25:07 +0300 Subject: [PATCH 09/57] feat(popup_editor): integrate note title + icon into modal header --- apps/client/src/layouts/desktop_layout.ts | 2 - .../src/widgets/dialogs/popup_editor.ts | 37 +++++++++++++++++-- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/apps/client/src/layouts/desktop_layout.ts b/apps/client/src/layouts/desktop_layout.ts index 4693d76aa..c91417a40 100644 --- a/apps/client/src/layouts/desktop_layout.ts +++ b/apps/client/src/layouts/desktop_layout.ts @@ -262,8 +262,6 @@ export default class DesktopLayout { .child(new PopupEditorDialog() .child(new FlexContainer("row") .class("title-row") - .css("height", "50px") - .css("min-height", "50px") .css("align-items", "center") .cssBlock(".title-row > * { margin: 5px; }") .child(new NoteIconWidget()) diff --git a/apps/client/src/widgets/dialogs/popup_editor.ts b/apps/client/src/widgets/dialogs/popup_editor.ts index 107cfe0aa..2e5aca3af 100644 --- a/apps/client/src/widgets/dialogs/popup_editor.ts +++ b/apps/client/src/widgets/dialogs/popup_editor.ts @@ -7,15 +7,40 @@ import Container from "../containers/container.js"; const TPL = /*html*/`\