diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index 76a05b7e2..1706077f8 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -78,6 +78,7 @@ import HideFloatingButtonsButton from "../widgets/floating_buttons/hide_floating import ScriptExecutorWidget from "../widgets/ribbon_widgets/script_executor.js"; import MovePaneButton from "../widgets/buttons/move_pane_button.js"; import UploadAttachmentsDialog from "../widgets/dialogs/upload_attachments.js"; +import ScrollPaddingWidget from "../widgets/scroll_padding.js"; export default class DesktopLayout { constructor(customWidgets) { @@ -173,6 +174,7 @@ export default class DesktopLayout { .child(new NoteListWidget()) .child(new SearchResultWidget()) .child(new SqlResultWidget()) + .child(new ScrollPaddingWidget()) ) .child(new ApiLogWidget()) .child(new FindWidget()) diff --git a/src/public/app/widgets/note_detail.js b/src/public/app/widgets/note_detail.js index 3b0fdbbf7..0bd8246f7 100644 --- a/src/public/app/widgets/note_detail.js +++ b/src/public/app/widgets/note_detail.js @@ -142,7 +142,7 @@ export default class NoteDetailWidget extends NoteContextAwareWidget { this.$widget.toggleClass("full-height", ( !this.noteContext.hasNoteList() - && ['editableText', 'editableCode', 'canvas', 'webView', 'noteMap'].includes(this.type) + && ['canvas', 'webView', 'noteMap'].includes(this.type) && this.mime !== 'text/x-sqlite;schema=trilium' ) || this.noteContext.viewScope.viewMode === 'attachments' @@ -191,12 +191,27 @@ export default class NoteDetailWidget extends NoteContextAwareWidget { } async focusOnDetailEvent({ntxId}) { - if (this.noteContext.ntxId === ntxId) { - await this.refresh(); + if (this.noteContext.ntxId !== ntxId) { + return; + } - const widget = this.getTypeWidget(); - await widget.initialized; - widget.focus(); + await this.refresh(); + const widget = this.getTypeWidget(); + await widget.initialized; + widget.focus(); + } + + async scrollToEndEvent({ntxId}) { + if (this.noteContext.ntxId !== ntxId) { + return; + } + + await this.refresh(); + const widget = this.getTypeWidget(); + await widget.initialized; + + if (widget.scrollToEnd) { + widget.scrollToEnd(); } } diff --git a/src/public/app/widgets/note_map.js b/src/public/app/widgets/note_map.js index bfeee265e..ab7d2c0e0 100644 --- a/src/public/app/widgets/note_map.js +++ b/src/public/app/widgets/note_map.js @@ -55,7 +55,7 @@ export default class NoteMapWidget extends NoteContextAwareWidget { this.$container = this.$widget.find(".note-map-container"); this.$styleResolver = this.$widget.find('.style-resolver'); - new ResizeObserver(() => this.setDimensions()).observe(this.$container[0]) + new ResizeObserver(() => this.setDimensions()).observe(this.$container[0]); this.$widget.find(".map-type-switcher button").on("click", async e => { const type = $(e.target).closest("button").attr("data-type"); diff --git a/src/public/app/widgets/ribbon_widgets/note_map.js b/src/public/app/widgets/ribbon_widgets/note_map.js index 5b1348827..9dd4de961 100644 --- a/src/public/app/widgets/ribbon_widgets/note_map.js +++ b/src/public/app/widgets/ribbon_widgets/note_map.js @@ -100,7 +100,7 @@ export default class NoteMapRibbonWidget extends NoteContextAwareWidget { } } - new ResizeObserver(handleResize).observe(this.$widget[0]) + new ResizeObserver(handleResize).observe(this.$widget[0]); } setSmallSize() { diff --git a/src/public/app/widgets/scroll_padding.js b/src/public/app/widgets/scroll_padding.js new file mode 100644 index 000000000..1ccea4d1a --- /dev/null +++ b/src/public/app/widgets/scroll_padding.js @@ -0,0 +1,27 @@ +import NoteContextAwareWidget from "./note_context_aware_widget.js"; + +const TPL = `
`; + +export default class ScrollPaddingWidget extends NoteContextAwareWidget { + doRender() { + this.$widget = $(TPL); + this.contentSized(); + + this.$widget.on("click", () => + this.triggerCommand('scrollToEnd', {ntxId: this.ntxId})); + } + + initialRenderCompleteEvent() { + this.$scrollingContainer = this.$widget.closest(".scrolling-container"); + + new ResizeObserver(() => this.refreshHeight()).observe(this.$scrollingContainer[0]); + + this.refreshHeight(); + } + + refreshHeight() { + const containerHeight = this.$scrollingContainer.height(); + + this.$widget.css("height", Math.round(containerHeight / 2)); + } +} diff --git a/src/public/app/widgets/type_widgets/editable_code.js b/src/public/app/widgets/type_widgets/editable_code.js index 9674e7b25..16b6f93ed 100644 --- a/src/public/app/widgets/type_widgets/editable_code.js +++ b/src/public/app/widgets/type_widgets/editable_code.js @@ -110,6 +110,11 @@ export default class EditableCodeTypeWidget extends TypeWidget { this.codeEditor.focus(); } + scrollToEnd() { + this.codeEditor.setCursor(this.codeEditor.lineCount(), 0); + this.codeEditor.focus(); + } + cleanup() { if (this.codeEditor) { this.spacedUpdate.allowUpdateWithoutChange(() => { diff --git a/src/public/app/widgets/type_widgets/editable_text.js b/src/public/app/widgets/type_widgets/editable_text.js index 0b013fd27..36cdc170f 100644 --- a/src/public/app/widgets/type_widgets/editable_text.js +++ b/src/public/app/widgets/type_widgets/editable_text.js @@ -203,6 +203,14 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget { this.$editor.trigger('focus'); } + scrollToEnd() { + this.watchdog?.editor.model.change(writer => { + writer.setSelection(writer.createPositionAt(this.watchdog?.editor.model.document.getRoot(), 'end')); + }); + + this.watchdog?.editor.editing.view.focus(); + } + show() {} getEditor() {