diff --git a/src/public/app/widgets/ribbon_widgets/classic_editor_toolbar.js b/src/public/app/widgets/ribbon_widgets/classic_editor_toolbar.ts similarity index 75% rename from src/public/app/widgets/ribbon_widgets/classic_editor_toolbar.js rename to src/public/app/widgets/ribbon_widgets/classic_editor_toolbar.ts index 25f402842..1c6e7bc8a 100644 --- a/src/public/app/widgets/ribbon_widgets/classic_editor_toolbar.js +++ b/src/public/app/widgets/ribbon_widgets/classic_editor_toolbar.ts @@ -31,13 +31,26 @@ const TPL = `\ align-items: flex-end; position: absolute; left: 0; - bottom: 0; right: 0; overflow-x: auto; + overscroll-behavior: none; z-index: 500; user-select: none; } + @media (max-width: 991px) { + body.mobile .classic-toolbar-widget.visible { + bottom: calc(var(--tab-bar-height) + var(--launcher-pane-height) + var(--mobile-bottom-offset)); + } + } + + @media (min-width: 991px) { + body.mobile .classic-toolbar-widget.visible { + bottom: 0; + left: 25%; + } + } + body.mobile .classic-toolbar-widget.dropdown-active { height: 50vh; } @@ -64,6 +77,9 @@ const TPL = `\ * The ribbon item is active by default for text notes, as long as they are not in read-only mode. */ export default class ClassicEditorToolbar extends NoteContextAwareWidget { + + private observer: MutationObserver; + constructor() { super(); this.observer = new MutationObserver((e) => this.#onDropdownStateChanged(e)); @@ -83,7 +99,7 @@ export default class ClassicEditorToolbar extends NoteContextAwareWidget { if (utils.isMobile()) { // The virtual keyboard obscures the editing toolbar so we have to reposition by calculating the height of the keyboard. - window.visualViewport.addEventListener("resize", () => this.#adjustPosition()); + window.visualViewport?.addEventListener("resize", () => this.#adjustPosition()); window.addEventListener("scroll", () => this.#adjustPosition()); // Observe when a dropdown is expanded to apply a style that allows the dropdown to be visible, since we can't have the element both visible and the toolbar scrollable. @@ -95,13 +111,13 @@ export default class ClassicEditorToolbar extends NoteContextAwareWidget { } } - #onDropdownStateChanged(e) { - const dropdownActive = e.map((e) => e.target.ariaExpanded === "true").reduce((acc, e) => acc && e); + #onDropdownStateChanged(e: MutationRecord[]) { + const dropdownActive = e.map((e) => (e.target as any).ariaExpanded === "true").reduce((acc, e) => acc && e); this.$widget[0].classList.toggle("dropdown-active", dropdownActive); } #adjustPosition() { - let bottom = window.innerHeight - window.visualViewport.height; + let bottom = window.innerHeight - (window.visualViewport?.height || 0); if (bottom === 0) { // The keyboard is not visible, align it to the launcher bar instead. @@ -121,18 +137,25 @@ export default class ClassicEditorToolbar extends NoteContextAwareWidget { } async #shouldDisplay() { - if (options.get("textNoteEditorType") !== "ckeditor-classic") { + if (utils.isDesktop() && options.get("textNoteEditorType") !== "ckeditor-classic") { return false; } - if (this.note.type !== "text") { + if (!this.note || this.note.type !== "text") { return false; } - if (await this.noteContext.isReadOnly()) { + if (await this.noteContext?.isReadOnly()) { return false; } return true; } + + async refreshWithNote() { + if (utils.isMobile()) { + this.toggleExt(await this.#shouldDisplay()); + } + } + } diff --git a/src/public/app/widgets/type_widgets/editable_text.js b/src/public/app/widgets/type_widgets/editable_text.js index b22b8cdb2..d3f5f6975 100644 --- a/src/public/app/widgets/type_widgets/editable_text.js +++ b/src/public/app/widgets/type_widgets/editable_text.js @@ -136,7 +136,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget { async initEditor() { await libraryLoader.requireLibrary(libraryLoader.CKEDITOR); - const isClassicEditor = options.get("textNoteEditorType") === "ckeditor-classic"; + const isClassicEditor = utils.isMobile() || options.get("textNoteEditorType") === "ckeditor-classic"; const editorClass = isClassicEditor ? CKEditor.DecoupledEditor : CKEditor.BalloonEditor; const codeBlockLanguages = buildListOfLanguages(); @@ -186,7 +186,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget { const extraOpts = {}; if (isClassicEditor) { extraOpts.toolbar = { - shouldNotGroupWhenFull: options.get("textNoteEditorMultilineToolbar") === "true" + shouldNotGroupWhenFull: utils.isDesktop() && options.get("textNoteEditorMultilineToolbar") === "true" }; } @@ -230,14 +230,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget { $classicToolbarWidget[0].appendChild(editor.ui.view.toolbar.element); if (utils.isMobile()) { - this.$editor.on("focus", (e) => { - $classicToolbarWidget.addClass("visible"); - }); - - // Hide the formatting toolbar - this.$editor.on("focusout", (e) => { - this.$editor[0].focus(); - }); + $classicToolbarWidget.addClass("visible"); } } diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index f2f928ee8..ac1ac6408 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -45,6 +45,8 @@ body { --native-titlebar-foreground: var(--main-text-color); --native-titlebar-darwin-x-offset: 10; --native-titlebar-darwin-y-offset: 12; + --launcher-pane-height: 53px; + --tab-bar-height: 40px; } body.mobile .desktop-only {