feat: shift-click to select range of notes
This commit is contained in:
@@ -19,9 +19,10 @@ import { WebApplication } from '../application';
|
|||||||
import { Editor } from '../editor';
|
import { Editor } from '../editor';
|
||||||
|
|
||||||
export class NotesState {
|
export class NotesState {
|
||||||
|
lastSelectedNote: SNNote | undefined;
|
||||||
selectedNotes: Record<UuidString, SNNote> = {};
|
selectedNotes: Record<UuidString, SNNote> = {};
|
||||||
contextMenuOpen = false;
|
contextMenuOpen = false;
|
||||||
contextMenuPosition: { top: number, left: number } = { top: 0, left: 0 };
|
contextMenuPosition: { top: number; left: number } = { top: 0, left: 0 };
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private application: WebApplication,
|
private application: WebApplication,
|
||||||
@@ -70,18 +71,32 @@ export class NotesState {
|
|||||||
async selectNote(uuid: UuidString): Promise<void> {
|
async selectNote(uuid: UuidString): Promise<void> {
|
||||||
const note = this.application.findItem(uuid) as SNNote;
|
const note = this.application.findItem(uuid) as SNNote;
|
||||||
if (
|
if (
|
||||||
this.io.activeModifiers.has(KeyboardModifier.Meta) ||
|
this.io.activeModifiers.has(
|
||||||
this.io.activeModifiers.has(KeyboardModifier.Ctrl)
|
KeyboardModifier.Meta || KeyboardModifier.Ctrl
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
if (this.selectedNotes[uuid]) {
|
if (this.selectedNotes[uuid]) {
|
||||||
delete this.selectedNotes[uuid];
|
delete this.selectedNotes[uuid];
|
||||||
} else {
|
} else {
|
||||||
this.selectedNotes[uuid] = note;
|
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 {
|
} else {
|
||||||
this.selectedNotes = {
|
this.selectedNotes = {
|
||||||
[uuid]: note,
|
[uuid]: note,
|
||||||
};
|
};
|
||||||
|
this.lastSelectedNote = note;
|
||||||
await this.openEditor(uuid);
|
await this.openEditor(uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,7 +130,7 @@ export class NotesState {
|
|||||||
this.contextMenuOpen = open;
|
this.contextMenuOpen = open;
|
||||||
}
|
}
|
||||||
|
|
||||||
setContextMenuPosition(position: { top: number, left: number }): void {
|
setContextMenuPosition(position: { top: number; left: number }): void {
|
||||||
this.contextMenuPosition = position;
|
this.contextMenuPosition = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +154,10 @@ export class NotesState {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setTrashSelectedNotes(trashed: boolean, trashButtonRef: RefObject<HTMLButtonElement>): Promise<void> {
|
async setTrashSelectedNotes(
|
||||||
|
trashed: boolean,
|
||||||
|
trashButtonRef: RefObject<HTMLButtonElement>
|
||||||
|
): Promise<void> {
|
||||||
if (
|
if (
|
||||||
await confirmDialog({
|
await confirmDialog({
|
||||||
title: Strings.trashNotesTitle,
|
title: Strings.trashNotesTitle,
|
||||||
|
|||||||
@@ -307,7 +307,10 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesCtrlState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private removeAllContextMenuListeners = () => {
|
private removeAllContextMenuListeners = () => {
|
||||||
const { selectedNotes, selectedNotesCount } = this.application.getAppState().notes;
|
const {
|
||||||
|
selectedNotes,
|
||||||
|
selectedNotesCount,
|
||||||
|
} = this.application.getAppState().notes;
|
||||||
if (selectedNotesCount > 0) {
|
if (selectedNotesCount > 0) {
|
||||||
Object.values(selectedNotes).forEach(({ uuid }) => {
|
Object.values(selectedNotes).forEach(({ uuid }) => {
|
||||||
document
|
document
|
||||||
@@ -315,27 +318,26 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesCtrlState> {
|
|||||||
?.removeEventListener('contextmenu', this.openNotesContextMenu);
|
?.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<void> {
|
async selectNote(note: SNNote): Promise<void> {
|
||||||
const noteElement = document.getElementById(`note-${note.uuid}`);
|
this.removeAllContextMenuListeners();
|
||||||
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);
|
|
||||||
}
|
|
||||||
await this.appState.notes.selectNote(note.uuid);
|
await this.appState.notes.selectNote(note.uuid);
|
||||||
|
this.addContextMenuListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
async createNewNote() {
|
async createNewNote() {
|
||||||
|
|||||||
Reference in New Issue
Block a user