From 9bf9cc37da83280a59739ddaf9394ec8c19ed700 Mon Sep 17 00:00:00 2001 From: Antonella Sgarlatta Date: Fri, 30 Apr 2021 14:58:49 -0300 Subject: [PATCH] feat: shift-click to select range of notes --- .../ui_models/app_state/notes_state.ts | 28 +++++++++++--- .../javascripts/views/notes/notes_view.ts | 38 ++++++++++--------- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/app/assets/javascripts/ui_models/app_state/notes_state.ts b/app/assets/javascripts/ui_models/app_state/notes_state.ts index 22014aa44..8a321f7f1 100644 --- a/app/assets/javascripts/ui_models/app_state/notes_state.ts +++ b/app/assets/javascripts/ui_models/app_state/notes_state.ts @@ -19,9 +19,10 @@ import { WebApplication } from '../application'; import { Editor } from '../editor'; export class NotesState { + lastSelectedNote: SNNote | undefined; selectedNotes: Record = {}; contextMenuOpen = false; - contextMenuPosition: { top: number, left: number } = { top: 0, left: 0 }; + contextMenuPosition: { top: number; left: number } = { top: 0, left: 0 }; constructor( private application: WebApplication, @@ -70,18 +71,32 @@ export class NotesState { async selectNote(uuid: UuidString): Promise { const note = this.application.findItem(uuid) as SNNote; if ( - this.io.activeModifiers.has(KeyboardModifier.Meta) || - this.io.activeModifiers.has(KeyboardModifier.Ctrl) + this.io.activeModifiers.has( + KeyboardModifier.Meta || KeyboardModifier.Ctrl + ) ) { if (this.selectedNotes[uuid]) { delete this.selectedNotes[uuid]; } else { this.selectedNotes[uuid] = note; + this.lastSelectedNote = note; } + } else if (this.io.activeModifiers.has(KeyboardModifier.Shift)) { + const notes = this.application.getDisplayableItems( + ContentType.Note + ) as SNNote[]; + const lastSelectedNoteIndex = notes.findIndex( + (note) => note.uuid == this.lastSelectedNote?.uuid + ); + const selectedNoteIndex = notes.findIndex((note) => note.uuid == uuid); + notes + .slice(lastSelectedNoteIndex, selectedNoteIndex + 1) + .forEach((note) => (this.selectedNotes[note.uuid] = note)); } else { this.selectedNotes = { [uuid]: note, }; + this.lastSelectedNote = note; await this.openEditor(uuid); } } @@ -115,7 +130,7 @@ export class NotesState { this.contextMenuOpen = open; } - setContextMenuPosition(position: { top: number, left: number }): void { + setContextMenuPosition(position: { top: number; left: number }): void { this.contextMenuPosition = position; } @@ -139,7 +154,10 @@ export class NotesState { ); } - async setTrashSelectedNotes(trashed: boolean, trashButtonRef: RefObject): Promise { + async setTrashSelectedNotes( + trashed: boolean, + trashButtonRef: RefObject + ): Promise { if ( await confirmDialog({ title: Strings.trashNotesTitle, diff --git a/app/assets/javascripts/views/notes/notes_view.ts b/app/assets/javascripts/views/notes/notes_view.ts index fc7be7755..4f3b49cf8 100644 --- a/app/assets/javascripts/views/notes/notes_view.ts +++ b/app/assets/javascripts/views/notes/notes_view.ts @@ -307,7 +307,10 @@ class NotesViewCtrl extends PureViewCtrl { } private removeAllContextMenuListeners = () => { - const { selectedNotes, selectedNotesCount } = this.application.getAppState().notes; + const { + selectedNotes, + selectedNotesCount, + } = this.application.getAppState().notes; if (selectedNotesCount > 0) { Object.values(selectedNotes).forEach(({ uuid }) => { document @@ -315,27 +318,26 @@ class NotesViewCtrl extends PureViewCtrl { ?.removeEventListener('contextmenu', this.openNotesContextMenu); }); } + }; + + private addContextMenuListeners = () => { + const { + selectedNotes, + selectedNotesCount, + } = this.application.getAppState().notes; + if (selectedNotesCount > 0) { + Object.values(selectedNotes).forEach(({ uuid }) => { + document + .getElementById(`note-${uuid}`) + ?.addEventListener('contextmenu', this.openNotesContextMenu); + }); + } } async selectNote(note: SNNote): Promise { - const noteElement = document.getElementById(`note-${note.uuid}`); - if ( - this.application.io.activeModifiers.has(KeyboardModifier.Meta) || - this.application.io.activeModifiers.has(KeyboardModifier.Ctrl) - ) { - if (this.application.getAppState().notes.selectedNotes[note.uuid]) { - noteElement?.removeEventListener( - 'contextmenu', - this.openNotesContextMenu - ); - } else { - noteElement?.addEventListener('contextmenu', this.openNotesContextMenu); - } - } else { - this.removeAllContextMenuListeners(); - noteElement?.addEventListener('contextmenu', this.openNotesContextMenu); - } + this.removeAllContextMenuListeners(); await this.appState.notes.selectNote(note.uuid); + this.addContextMenuListeners(); } async createNewNote() {