diff --git a/src/public/app/components/tab_manager.js b/src/public/app/components/tab_manager.js index e5ca32c45..53c3ccbbd 100644 --- a/src/public/app/components/tab_manager.js +++ b/src/public/app/components/tab_manager.js @@ -451,16 +451,23 @@ export default class TabManager extends Component { this.tabsUpdate.scheduleUpdate(); } - noteContextReorderEvent({ntxIdsInOrder}) { - const order = {}; - let i = 0; - - for (const ntxId of ntxIdsInOrder) { - order[ntxId] = i++; - } + noteContextReorderEvent({ntxIdsInOrder, oldMainNtxId, newMainNtxId}) { + const order = Object.fromEntries(ntxIdsInOrder.map((v, i) => [v, i])); this.children.sort((a, b) => order[a.ntxId] < order[b.ntxId] ? -1 : 1); + if (oldMainNtxId && newMainNtxId) { + this.children.forEach(c => { + if (c.ntxId === newMainNtxId) { + // new main context has null mainNtxId + c.mainNtxId = null; + } else if (c.ntxId === oldMainNtxId || c.mainNtxId === oldMainNtxId) { + // old main context or subcontexts all have the new mainNtxId + c.mainNtxId = newMainNtxId; + } + }); + } + this.tabsUpdate.scheduleUpdate(); } diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index 17dcc99a7..62e6b3ed1 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -75,6 +75,7 @@ import CodeButtonsWidget from "../widgets/floating_buttons/code_buttons.js"; import ApiLogWidget from "../widgets/api_log.js"; import HideFloatingButtonsButton from "../widgets/floating_buttons/hide_floating_buttons_button.js"; import ScriptExecutorWidget from "../widgets/ribbon_widgets/script_executor.js"; +import MovePaneButton from "../widgets/buttons/move_pane_button.js"; export default class DesktopLayout { constructor(customWidgets) { @@ -123,6 +124,8 @@ export default class DesktopLayout { .child(new NoteIconWidget()) .child(new NoteTitleWidget()) .child(new SpacerWidget(0, 1)) + .child(new MovePaneButton(true)) + .child(new MovePaneButton(false)) .child(new ClosePaneButton()) .child(new CreatePaneButton()) ) diff --git a/src/public/app/widgets/buttons/close_pane_button.js b/src/public/app/widgets/buttons/close_pane_button.js index 690dcac6f..220fd2cca 100644 --- a/src/public/app/widgets/buttons/close_pane_button.js +++ b/src/public/app/widgets/buttons/close_pane_button.js @@ -7,6 +7,10 @@ export default class ClosePaneButton extends OnClickButtonWidget { && this.noteContext && !!this.noteContext.mainNtxId; } + async noteContextReorderEvent({ntxIdsInOrder}) { + this.refresh(); + } + constructor() { super(); diff --git a/src/public/app/widgets/buttons/move_pane_button.js b/src/public/app/widgets/buttons/move_pane_button.js new file mode 100644 index 000000000..632651ca5 --- /dev/null +++ b/src/public/app/widgets/buttons/move_pane_button.js @@ -0,0 +1,47 @@ +import OnClickButtonWidget from "./onclick_button.js"; +import appContext from "../../components/app_context.js"; + +export default class MovePaneButton extends OnClickButtonWidget { + constructor(isMovingLeft) { + super(); + + this.isMovingLeft = isMovingLeft; + + this.icon(isMovingLeft ? "bx-chevron-left" : "bx-chevron-right") + .title(isMovingLeft ? "Move left" : "Move right") + .titlePlacement("bottom") + .onClick(async (widget, e) => { + e.stopPropagation(); + widget.triggerCommand("moveThisNoteSplit", {ntxId: widget.getClosestNtxId(), isMovingLeft: this.isMovingLeft}); + }) + .class("icon-action"); + } + + isEnabled() { + if (!super.isEnabled()) { + return false; + } + + if (this.isMovingLeft) { + // movable if the current context is not a main context, i.e. non-null mainNtxId + return !!this.noteContext?.mainNtxId; + } else { + const currentIndex = appContext.tabManager.noteContexts.findIndex(c => c.ntxId === this.ntxId); + const nextContext = appContext.tabManager.noteContexts[currentIndex + 1]; + // movable if the next context is not null and not a main context, i.e. non-null mainNtxId + return !!nextContext?.mainNtxId; + } + } + + async noteContextRemovedEvent() { + this.refresh(); + } + + async newNoteContextCreatedEvent() { + this.refresh(); + } + + async noteContextReorderEvent() { + this.refresh(); + } +} diff --git a/src/public/app/widgets/containers/split_note_container.js b/src/public/app/widgets/containers/split_note_container.js index 66356164d..0188add6d 100644 --- a/src/public/app/widgets/containers/split_note_container.js +++ b/src/public/app/widgets/containers/split_note_container.js @@ -74,6 +74,50 @@ export default class SplitNoteContainer extends FlexContainer { appContext.tabManager.removeNoteContext(ntxId); } + async moveThisNoteSplitCommand({ntxId, isMovingLeft}) { + if (!ntxId) { + logError("empty ntxId!"); + return; + } + + const contexts = appContext.tabManager.noteContexts; + + const currentIndex = contexts.findIndex(c => c.ntxId === ntxId); + const leftIndex = isMovingLeft ? currentIndex - 1 : currentIndex; + + if (currentIndex === -1 || leftIndex < 0 || leftIndex + 1 >= contexts.length) { + logError(`invalid context! currentIndex: ${currentIndex}, leftIndex: ${leftIndex}, contexts.length: ${contexts.length}`); + return; + } + + if (contexts[leftIndex].isEmpty() && contexts[leftIndex + 1].isEmpty()) { + // no op + return; + } + + const ntxIds = contexts.map(c => c.ntxId); + const newNtxIds = [ + ...ntxIds.slice(0, leftIndex), + ntxIds[leftIndex + 1], + ntxIds[leftIndex], + ...ntxIds.slice(leftIndex + 2), + ]; + const isChangingMainContext = !contexts[leftIndex].mainNtxId; + + this.triggerCommand("noteContextReorder", { + ntxIdsInOrder: newNtxIds, + oldMainNtxId: isChangingMainContext ? ntxIds[leftIndex] : null, + newMainNtxId: isChangingMainContext ? ntxIds[leftIndex + 1]: null, + }); + + // reorder the note context widgets + this.$widget.find(`[data-ntx-id="${ntxIds[leftIndex]}"]`) + .insertAfter(this.$widget.find(`[data-ntx-id="${ntxIds[leftIndex + 1]}"]`)); + + // activate context that now contains the original note + await appContext.tabManager.activateNoteContext(isMovingLeft ? ntxIds[leftIndex + 1] : ntxIds[leftIndex]); + } + activeContextChangedEvent() { this.refresh(); } diff --git a/src/public/app/widgets/tab_row.js b/src/public/app/widgets/tab_row.js index 55a5da24c..9081ed9e1 100644 --- a/src/public/app/widgets/tab_row.js +++ b/src/public/app/widgets/tab_row.js @@ -609,6 +609,17 @@ export default class TabRowWidget extends BasicWidget { this.updateTabById(noteContext.mainNtxId || noteContext.ntxId); } + noteContextReorderEvent({oldMainNtxId, newMainNtxId}) { + if (!oldMainNtxId || !newMainNtxId) { + // no need to update tab row + return; + } + + // update tab id for the new main context + this.getTabById(oldMainNtxId).attr("data-ntx-id", newMainNtxId); + this.updateTabById(newMainNtxId); + } + updateTabById(ntxId) { const $tab = this.getTabById(ntxId);