feat: select multiple notes in list
This commit is contained in:
@@ -1,8 +0,0 @@
|
|||||||
export { AlertService } from './alertService';
|
|
||||||
export { ArchiveManager } from './archiveManager';
|
|
||||||
export { DesktopManager } from './desktopManager';
|
|
||||||
export { KeyboardManager } from './keyboardManager';
|
|
||||||
export { AutolockService } from './autolock_service';
|
|
||||||
export { NativeExtManager } from './nativeExtManager';
|
|
||||||
export { StatusManager } from './statusManager';
|
|
||||||
export { ThemeManager } from './themeManager';
|
|
||||||
171
app/assets/javascripts/services/ioService.ts
Normal file
171
app/assets/javascripts/services/ioService.ts
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
import { removeFromArray } from '@standardnotes/snjs';
|
||||||
|
export enum KeyboardKey {
|
||||||
|
Tab = 'Tab',
|
||||||
|
Backspace = 'Backspace',
|
||||||
|
Up = 'ArrowUp',
|
||||||
|
Down = 'ArrowDown',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum KeyboardModifier {
|
||||||
|
Shift = 'Shift',
|
||||||
|
Ctrl = 'Control',
|
||||||
|
/** ⌘ key on Mac, ⊞ key on Windows */
|
||||||
|
Meta = 'Meta',
|
||||||
|
Alt = 'Alt',
|
||||||
|
}
|
||||||
|
|
||||||
|
enum KeyboardKeyEvent {
|
||||||
|
Down = 'KeyEventDown',
|
||||||
|
Up = 'KeyEventUp',
|
||||||
|
}
|
||||||
|
|
||||||
|
type KeyboardObserver = {
|
||||||
|
key?: KeyboardKey | string;
|
||||||
|
modifiers?: KeyboardModifier[];
|
||||||
|
onKeyDown?: (event: KeyboardEvent) => void;
|
||||||
|
onKeyUp?: (event: KeyboardEvent) => void;
|
||||||
|
element?: HTMLElement;
|
||||||
|
elements?: HTMLElement[];
|
||||||
|
notElement?: HTMLElement;
|
||||||
|
notElementIds?: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export class IOService {
|
||||||
|
readonly activeModifiers = new Set<KeyboardModifier>();
|
||||||
|
private observers: KeyboardObserver[] = [];
|
||||||
|
|
||||||
|
constructor(private isMac: boolean) {
|
||||||
|
window.addEventListener('keydown', this.handleKeyDown);
|
||||||
|
window.addEventListener('keyup', this.handleKeyUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public deinit() {
|
||||||
|
this.observers.length = 0;
|
||||||
|
window.removeEventListener('keydown', this.handleKeyDown);
|
||||||
|
window.removeEventListener('keyup', this.handleKeyUp);
|
||||||
|
(this.handleKeyDown as unknown) = undefined;
|
||||||
|
(this.handleKeyUp as unknown) = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleKeyDown = (event: KeyboardEvent) => {
|
||||||
|
for (const modifier of this.modifiersForEvent(event)) {
|
||||||
|
switch (modifier) {
|
||||||
|
case KeyboardModifier.Meta: {
|
||||||
|
if (this.isMac) {
|
||||||
|
this.activeModifiers.add(modifier);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case KeyboardModifier.Ctrl: {
|
||||||
|
if (!this.isMac) {
|
||||||
|
this.activeModifiers.add(modifier);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
this.activeModifiers.add(modifier);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.notifyObserver(event, KeyboardKeyEvent.Down);
|
||||||
|
};
|
||||||
|
|
||||||
|
handleKeyUp = (event: KeyboardEvent) => {
|
||||||
|
for (const modifier of this.modifiersForEvent(event)) {
|
||||||
|
this.activeModifiers.delete(modifier);
|
||||||
|
}
|
||||||
|
this.notifyObserver(event, KeyboardKeyEvent.Up);
|
||||||
|
};
|
||||||
|
|
||||||
|
modifiersForEvent(event: KeyboardEvent) {
|
||||||
|
const allModifiers = Object.values(KeyboardModifier);
|
||||||
|
const eventModifiers = allModifiers.filter((modifier) => {
|
||||||
|
// For a modifier like ctrlKey, must check both event.ctrlKey and event.key.
|
||||||
|
// That's because on keyup, event.ctrlKey would be false, but event.key == Control would be true.
|
||||||
|
const matches =
|
||||||
|
((event.ctrlKey || event.key === KeyboardModifier.Ctrl) &&
|
||||||
|
modifier === KeyboardModifier.Ctrl) ||
|
||||||
|
((event.metaKey || event.key === KeyboardModifier.Meta) &&
|
||||||
|
modifier === KeyboardModifier.Meta) ||
|
||||||
|
((event.altKey || event.key === KeyboardModifier.Alt) &&
|
||||||
|
modifier === KeyboardModifier.Alt) ||
|
||||||
|
((event.shiftKey || event.key === KeyboardModifier.Shift) &&
|
||||||
|
modifier === KeyboardModifier.Shift);
|
||||||
|
|
||||||
|
return matches;
|
||||||
|
});
|
||||||
|
|
||||||
|
return eventModifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
eventMatchesKeyAndModifiers(
|
||||||
|
event: KeyboardEvent,
|
||||||
|
key: KeyboardKey | string,
|
||||||
|
modifiers: KeyboardModifier[] = []
|
||||||
|
) {
|
||||||
|
const eventModifiers = this.modifiersForEvent(event);
|
||||||
|
if (eventModifiers.length !== modifiers.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (const modifier of modifiers) {
|
||||||
|
if (!eventModifiers.includes(modifier)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Modifers match, check key
|
||||||
|
if (!key) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// In the browser, shift + f results in key 'f', but in Electron, shift + f results in 'F'
|
||||||
|
// In our case we don't differentiate between the two.
|
||||||
|
return key.toLowerCase() === event.key.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyObserver(event: KeyboardEvent, keyEvent: KeyboardKeyEvent) {
|
||||||
|
const target = event.target as HTMLElement;
|
||||||
|
for (const observer of this.observers) {
|
||||||
|
if (observer.element && event.target !== observer.element) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (observer.elements && !observer.elements.includes(target)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (observer.notElement && observer.notElement === event.target) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
observer.notElementIds &&
|
||||||
|
observer.notElementIds.includes(target.id)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.eventMatchesKeyAndModifiers(
|
||||||
|
event,
|
||||||
|
observer.key!,
|
||||||
|
observer.modifiers
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const callback =
|
||||||
|
keyEvent === KeyboardKeyEvent.Down
|
||||||
|
? observer.onKeyDown
|
||||||
|
: observer.onKeyUp;
|
||||||
|
if (callback) {
|
||||||
|
callback(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addKeyObserver(observer: KeyboardObserver) {
|
||||||
|
this.observers.push(observer);
|
||||||
|
return () => {
|
||||||
|
removeFromArray(this.observers, observer);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
import { removeFromArray } from '@standardnotes/snjs';
|
|
||||||
export enum KeyboardKey {
|
|
||||||
Tab = "Tab",
|
|
||||||
Backspace = "Backspace",
|
|
||||||
Up = "ArrowUp",
|
|
||||||
Down = "ArrowDown",
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum KeyboardModifier {
|
|
||||||
Shift = "Shift",
|
|
||||||
Ctrl = "Control",
|
|
||||||
/** ⌘ key on Mac, ⊞ key on Windows */
|
|
||||||
Meta = "Meta",
|
|
||||||
Alt = "Alt",
|
|
||||||
}
|
|
||||||
|
|
||||||
enum KeyboardKeyEvent {
|
|
||||||
Down = "KeyEventDown",
|
|
||||||
Up = "KeyEventUp"
|
|
||||||
}
|
|
||||||
|
|
||||||
type KeyboardObserver = {
|
|
||||||
key?: KeyboardKey | string
|
|
||||||
modifiers?: KeyboardModifier[]
|
|
||||||
onKeyDown?: (event: KeyboardEvent) => void
|
|
||||||
onKeyUp?: (event: KeyboardEvent) => void
|
|
||||||
element?: HTMLElement
|
|
||||||
elements?: HTMLElement[]
|
|
||||||
notElement?: HTMLElement
|
|
||||||
notElementIds?: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export class KeyboardManager {
|
|
||||||
|
|
||||||
private observers: KeyboardObserver[] = []
|
|
||||||
private handleKeyDown: any
|
|
||||||
private handleKeyUp: any
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.handleKeyDown = (event: KeyboardEvent) => {
|
|
||||||
this.notifyObserver(event, KeyboardKeyEvent.Down);
|
|
||||||
};
|
|
||||||
this.handleKeyUp = (event: KeyboardEvent) => {
|
|
||||||
this.notifyObserver(event, KeyboardKeyEvent.Up);
|
|
||||||
};
|
|
||||||
window.addEventListener('keydown', this.handleKeyDown);
|
|
||||||
window.addEventListener('keyup', this.handleKeyUp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public deinit() {
|
|
||||||
this.observers.length = 0;
|
|
||||||
window.removeEventListener('keydown', this.handleKeyDown);
|
|
||||||
window.removeEventListener('keyup', this.handleKeyUp);
|
|
||||||
this.handleKeyDown = undefined;
|
|
||||||
this.handleKeyUp = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
modifiersForEvent(event: KeyboardEvent) {
|
|
||||||
const allModifiers = Object.values(KeyboardModifier);
|
|
||||||
const eventModifiers = allModifiers.filter((modifier) => {
|
|
||||||
// For a modifier like ctrlKey, must check both event.ctrlKey and event.key.
|
|
||||||
// That's because on keyup, event.ctrlKey would be false, but event.key == Control would be true.
|
|
||||||
const matches = (
|
|
||||||
(
|
|
||||||
(event.ctrlKey || event.key === KeyboardModifier.Ctrl)
|
|
||||||
&& modifier === KeyboardModifier.Ctrl
|
|
||||||
) ||
|
|
||||||
(
|
|
||||||
(event.metaKey || event.key === KeyboardModifier.Meta)
|
|
||||||
&& modifier === KeyboardModifier.Meta
|
|
||||||
) ||
|
|
||||||
(
|
|
||||||
(event.altKey || event.key === KeyboardModifier.Alt)
|
|
||||||
&& modifier === KeyboardModifier.Alt
|
|
||||||
) ||
|
|
||||||
(
|
|
||||||
(event.shiftKey || event.key === KeyboardModifier.Shift)
|
|
||||||
&& modifier === KeyboardModifier.Shift
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return matches;
|
|
||||||
});
|
|
||||||
|
|
||||||
return eventModifiers;
|
|
||||||
}
|
|
||||||
|
|
||||||
eventMatchesKeyAndModifiers(
|
|
||||||
event: KeyboardEvent,
|
|
||||||
key: KeyboardKey | string,
|
|
||||||
modifiers: KeyboardModifier[] = []
|
|
||||||
) {
|
|
||||||
const eventModifiers = this.modifiersForEvent(event);
|
|
||||||
if (eventModifiers.length !== modifiers.length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (const modifier of modifiers) {
|
|
||||||
if (!eventModifiers.includes(modifier)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Modifers match, check key
|
|
||||||
if (!key) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// In the browser, shift + f results in key 'f', but in Electron, shift + f results in 'F'
|
|
||||||
// In our case we don't differentiate between the two.
|
|
||||||
return key.toLowerCase() === event.key.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyObserver(event: KeyboardEvent, keyEvent: KeyboardKeyEvent) {
|
|
||||||
const target = event.target as HTMLElement;
|
|
||||||
for (const observer of this.observers) {
|
|
||||||
if (observer.element && event.target !== observer.element) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (observer.elements && !observer.elements.includes(target)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (observer.notElement && observer.notElement === event.target) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (observer.notElementIds && observer.notElementIds.includes(target.id)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.eventMatchesKeyAndModifiers(event, observer.key!, observer.modifiers)) {
|
|
||||||
const callback = keyEvent === KeyboardKeyEvent.Down
|
|
||||||
? observer.onKeyDown
|
|
||||||
: observer.onKeyUp;
|
|
||||||
if (callback) {
|
|
||||||
callback(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addKeyObserver(observer: KeyboardObserver) {
|
|
||||||
this.observers.push(observer);
|
|
||||||
return () => {
|
|
||||||
removeFromArray(this.observers, observer);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -19,6 +19,7 @@ import { ActionsMenuState } from './actions_menu_state';
|
|||||||
import { NoAccountWarningState } from './no_account_warning_state';
|
import { NoAccountWarningState } from './no_account_warning_state';
|
||||||
import { SyncState } from './sync_state';
|
import { SyncState } from './sync_state';
|
||||||
import { SearchOptionsState } from './search_options_state';
|
import { SearchOptionsState } from './search_options_state';
|
||||||
|
import { NotesState } from './notes_state';
|
||||||
|
|
||||||
export enum AppStateEvent {
|
export enum AppStateEvent {
|
||||||
TagChanged,
|
TagChanged,
|
||||||
@@ -62,7 +63,8 @@ export class AppState {
|
|||||||
readonly actionsMenu = new ActionsMenuState();
|
readonly actionsMenu = new ActionsMenuState();
|
||||||
readonly noAccountWarning: NoAccountWarningState;
|
readonly noAccountWarning: NoAccountWarningState;
|
||||||
readonly sync = new SyncState();
|
readonly sync = new SyncState();
|
||||||
readonly searchOptions;
|
readonly searchOptions: SearchOptionsState;
|
||||||
|
readonly notes: NotesState;
|
||||||
isSessionsModalVisible = false;
|
isSessionsModalVisible = false;
|
||||||
|
|
||||||
private appEventObserverRemovers: (() => void)[] = [];
|
private appEventObserverRemovers: (() => void)[] = [];
|
||||||
@@ -77,6 +79,12 @@ export class AppState {
|
|||||||
this.$timeout = $timeout;
|
this.$timeout = $timeout;
|
||||||
this.$rootScope = $rootScope;
|
this.$rootScope = $rootScope;
|
||||||
this.application = application;
|
this.application = application;
|
||||||
|
this.notes = new NotesState(
|
||||||
|
this.application,
|
||||||
|
async () => {
|
||||||
|
await this.notifyEvent(AppStateEvent.ActiveEditorChanged);
|
||||||
|
}
|
||||||
|
);
|
||||||
this.noAccountWarning = new NoAccountWarningState(
|
this.noAccountWarning = new NoAccountWarningState(
|
||||||
application,
|
application,
|
||||||
this.appEventObserverRemovers
|
this.appEventObserverRemovers
|
||||||
@@ -175,28 +183,6 @@ export class AppState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async openEditor(noteUuid: string): Promise<void> {
|
|
||||||
if (this.getActiveEditor()?.note?.uuid === noteUuid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const note = this.application.findItem(noteUuid) as SNNote;
|
|
||||||
if (!note) {
|
|
||||||
console.warn('Tried accessing a non-existant note of UUID ' + noteUuid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (await this.application.authorizeNoteAccess(note)) {
|
|
||||||
const activeEditor = this.getActiveEditor();
|
|
||||||
if (!activeEditor) {
|
|
||||||
this.application.editorGroup.createEditor(noteUuid);
|
|
||||||
} else {
|
|
||||||
activeEditor.setNote(note);
|
|
||||||
}
|
|
||||||
await this.notifyEvent(AppStateEvent.ActiveEditorChanged);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getActiveEditor() {
|
getActiveEditor() {
|
||||||
return this.application.editorGroup.editors[0];
|
return this.application.editorGroup.editors[0];
|
||||||
}
|
}
|
||||||
|
|||||||
66
app/assets/javascripts/ui_models/app_state/notes_state.ts
Normal file
66
app/assets/javascripts/ui_models/app_state/notes_state.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { KeyboardModifier } from "@/services/ioService";
|
||||||
|
import { UuidString, SNNote } from "@standardnotes/snjs";
|
||||||
|
import { makeObservable, observable, action } from "mobx";
|
||||||
|
import { WebApplication } from "../application";
|
||||||
|
import { Editor } from "../editor";
|
||||||
|
|
||||||
|
export class NotesState {
|
||||||
|
selectedNotes: Record<UuidString, SNNote> = {};
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private application: WebApplication,
|
||||||
|
private onActiveEditorChanged: () => Promise<void>
|
||||||
|
) {
|
||||||
|
makeObservable(this, {
|
||||||
|
selectedNotes: observable,
|
||||||
|
selectNote: action,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get activeEditor(): Editor | undefined {
|
||||||
|
return this.application.editorGroup.editors[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
async selectNote(note: SNNote): Promise<void> {
|
||||||
|
if (
|
||||||
|
this.io.activeModifiers.has(KeyboardModifier.Meta) ||
|
||||||
|
this.io.activeModifiers.has(KeyboardModifier.Ctrl)
|
||||||
|
) {
|
||||||
|
this.selectedNotes[note.uuid] = note;
|
||||||
|
} else {
|
||||||
|
this.selectedNotes = {
|
||||||
|
[note.uuid]: note,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
await this.openEditor(note.uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
async openEditor(noteUuid: string): Promise<void> {
|
||||||
|
if (this.activeEditor?.note?.uuid === noteUuid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const note = this.application.findItem(noteUuid) as SNNote | undefined;
|
||||||
|
if (!note) {
|
||||||
|
console.warn('Tried accessing a non-existant note of UUID ' + noteUuid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await this.application.authorizeNoteAccess(note)) {
|
||||||
|
if (!this.activeEditor) {
|
||||||
|
this.application.editorGroup.createEditor(noteUuid);
|
||||||
|
} else {
|
||||||
|
this.activeEditor.setNote(note);
|
||||||
|
}
|
||||||
|
await this.onActiveEditorChanged();
|
||||||
|
|
||||||
|
if (note.waitingForKey) {
|
||||||
|
this.application.presentKeyRecoveryWizard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private get io() {
|
||||||
|
return this.application.io;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,23 +9,21 @@ import {
|
|||||||
SNComponent,
|
SNComponent,
|
||||||
PermissionDialog,
|
PermissionDialog,
|
||||||
DeinitSource,
|
DeinitSource,
|
||||||
|
Platform,
|
||||||
} from '@standardnotes/snjs';
|
} from '@standardnotes/snjs';
|
||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
import { getPlatform } from '@/utils';
|
|
||||||
import { AlertService } from '@/services/alertService';
|
|
||||||
import { WebDeviceInterface } from '@/web_device_interface';
|
import { WebDeviceInterface } from '@/web_device_interface';
|
||||||
import {
|
|
||||||
DesktopManager,
|
|
||||||
AutolockService,
|
|
||||||
ArchiveManager,
|
|
||||||
NativeExtManager,
|
|
||||||
StatusManager,
|
|
||||||
ThemeManager,
|
|
||||||
KeyboardManager
|
|
||||||
} from '@/services';
|
|
||||||
import { AppState } from '@/ui_models/app_state';
|
import { AppState } from '@/ui_models/app_state';
|
||||||
import { Bridge } from '@/services/bridge';
|
import { Bridge } from '@/services/bridge';
|
||||||
import { WebCrypto } from '@/crypto';
|
import { WebCrypto } from '@/crypto';
|
||||||
|
import { AlertService } from '@/services/alertService';
|
||||||
|
import { AutolockService } from '@/services/autolock_service';
|
||||||
|
import { ArchiveManager } from '@/services/archiveManager';
|
||||||
|
import { DesktopManager } from '@/services/desktopManager';
|
||||||
|
import { IOService } from '@/services/ioService';
|
||||||
|
import { NativeExtManager } from '@/services/nativeExtManager';
|
||||||
|
import { StatusManager } from '@/services/statusManager';
|
||||||
|
import { ThemeManager } from '@/services/themeManager';
|
||||||
|
|
||||||
type WebServices = {
|
type WebServices = {
|
||||||
appState: AppState;
|
appState: AppState;
|
||||||
@@ -35,7 +33,7 @@ type WebServices = {
|
|||||||
nativeExtService: NativeExtManager;
|
nativeExtService: NativeExtManager;
|
||||||
statusManager: StatusManager;
|
statusManager: StatusManager;
|
||||||
themeService: ThemeManager;
|
themeService: ThemeManager;
|
||||||
keyboardService: KeyboardManager;
|
io: IOService;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WebApplication extends SNApplication {
|
export class WebApplication extends SNApplication {
|
||||||
@@ -49,6 +47,7 @@ export class WebApplication extends SNApplication {
|
|||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
constructor(
|
constructor(
|
||||||
deviceInterface: WebDeviceInterface,
|
deviceInterface: WebDeviceInterface,
|
||||||
|
platform: Platform,
|
||||||
identifier: string,
|
identifier: string,
|
||||||
private $compile: angular.ICompileService,
|
private $compile: angular.ICompileService,
|
||||||
scope: angular.IScope,
|
scope: angular.IScope,
|
||||||
@@ -57,7 +56,7 @@ export class WebApplication extends SNApplication {
|
|||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
bridge.environment,
|
bridge.environment,
|
||||||
getPlatform(),
|
platform,
|
||||||
deviceInterface,
|
deviceInterface,
|
||||||
WebCrypto,
|
WebCrypto,
|
||||||
new AlertService(),
|
new AlertService(),
|
||||||
@@ -139,8 +138,8 @@ export class WebApplication extends SNApplication {
|
|||||||
return this.webServices.themeService;
|
return this.webServices.themeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getKeyboardService() {
|
public get io() {
|
||||||
return this.webServices.keyboardService;
|
return this.webServices.io;
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkForSecurityUpdate() {
|
async checkForSecurityUpdate() {
|
||||||
|
|||||||
@@ -1,24 +1,26 @@
|
|||||||
import { WebDeviceInterface } from '@/web_device_interface';
|
import { WebDeviceInterface } from '@/web_device_interface';
|
||||||
import { WebApplication } from './application';
|
import { WebApplication } from './application';
|
||||||
import { ApplicationDescriptor, SNApplicationGroup, DeviceInterface } from '@standardnotes/snjs';
|
|
||||||
import {
|
import {
|
||||||
ArchiveManager,
|
ApplicationDescriptor,
|
||||||
DesktopManager,
|
SNApplicationGroup,
|
||||||
KeyboardManager,
|
DeviceInterface,
|
||||||
AutolockService,
|
Platform,
|
||||||
NativeExtManager,
|
} from '@standardnotes/snjs';
|
||||||
StatusManager,
|
|
||||||
ThemeManager
|
|
||||||
} from '@/services';
|
|
||||||
import { AppState } from '@/ui_models/app_state';
|
import { AppState } from '@/ui_models/app_state';
|
||||||
import { Bridge } from '@/services/bridge';
|
import { Bridge } from '@/services/bridge';
|
||||||
import { isDesktopApplication } from '@/utils';
|
import { getPlatform, isDesktopApplication } from '@/utils';
|
||||||
|
import { ArchiveManager } from '@/services/archiveManager';
|
||||||
|
import { DesktopManager } from '@/services/desktopManager';
|
||||||
|
import { IOService } from '@/services/ioService';
|
||||||
|
import { AutolockService } from '@/services/autolock_service';
|
||||||
|
import { StatusManager } from '@/services/statusManager';
|
||||||
|
import { NativeExtManager } from '@/services/nativeExtManager';
|
||||||
|
import { ThemeManager } from '@/services/themeManager';
|
||||||
|
|
||||||
export class ApplicationGroup extends SNApplicationGroup {
|
export class ApplicationGroup extends SNApplicationGroup {
|
||||||
|
$compile: ng.ICompileService;
|
||||||
$compile: ng.ICompileService
|
$rootScope: ng.IRootScopeService;
|
||||||
$rootScope: ng.IRootScopeService
|
$timeout: ng.ITimeoutService;
|
||||||
$timeout: ng.ITimeoutService
|
|
||||||
|
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
constructor(
|
constructor(
|
||||||
@@ -26,75 +28,72 @@ export class ApplicationGroup extends SNApplicationGroup {
|
|||||||
$rootScope: ng.IRootScopeService,
|
$rootScope: ng.IRootScopeService,
|
||||||
$timeout: ng.ITimeoutService,
|
$timeout: ng.ITimeoutService,
|
||||||
private defaultSyncServerHost: string,
|
private defaultSyncServerHost: string,
|
||||||
private bridge: Bridge,
|
private bridge: Bridge
|
||||||
) {
|
) {
|
||||||
super(new WebDeviceInterface(
|
super(new WebDeviceInterface($timeout, bridge));
|
||||||
$timeout,
|
|
||||||
bridge
|
|
||||||
));
|
|
||||||
this.$compile = $compile;
|
this.$compile = $compile;
|
||||||
this.$timeout = $timeout;
|
this.$timeout = $timeout;
|
||||||
this.$rootScope = $rootScope;
|
this.$rootScope = $rootScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialize(callback?: any) {
|
async initialize(callback?: any): Promise<void> {
|
||||||
await super.initialize({
|
await super.initialize({
|
||||||
applicationCreator: this.createApplication
|
applicationCreator: this.createApplication,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isDesktopApplication()) {
|
if (isDesktopApplication()) {
|
||||||
Object.defineProperty(window, 'desktopManager', {
|
Object.defineProperty(window, 'desktopManager', {
|
||||||
get: () => (this.primaryApplication as WebApplication).getDesktopService()
|
get: () =>
|
||||||
|
(this.primaryApplication as WebApplication).getDesktopService(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private createApplication = (descriptor: ApplicationDescriptor, deviceInterface: DeviceInterface) => {
|
private createApplication = (
|
||||||
|
descriptor: ApplicationDescriptor,
|
||||||
|
deviceInterface: DeviceInterface
|
||||||
|
) => {
|
||||||
const scope = this.$rootScope.$new(true);
|
const scope = this.$rootScope.$new(true);
|
||||||
|
const platform = getPlatform();
|
||||||
const application = new WebApplication(
|
const application = new WebApplication(
|
||||||
deviceInterface as WebDeviceInterface,
|
deviceInterface as WebDeviceInterface,
|
||||||
|
platform,
|
||||||
descriptor.identifier,
|
descriptor.identifier,
|
||||||
this.$compile,
|
this.$compile,
|
||||||
scope,
|
scope,
|
||||||
this.defaultSyncServerHost,
|
this.defaultSyncServerHost,
|
||||||
this.bridge,
|
this.bridge
|
||||||
);
|
);
|
||||||
const appState = new AppState(
|
const appState = new AppState(
|
||||||
this.$rootScope,
|
this.$rootScope,
|
||||||
this.$timeout,
|
this.$timeout,
|
||||||
application,
|
application,
|
||||||
this.bridge,
|
this.bridge
|
||||||
);
|
|
||||||
const archiveService = new ArchiveManager(
|
|
||||||
application
|
|
||||||
);
|
);
|
||||||
|
const archiveService = new ArchiveManager(application);
|
||||||
const desktopService = new DesktopManager(
|
const desktopService = new DesktopManager(
|
||||||
this.$rootScope,
|
this.$rootScope,
|
||||||
this.$timeout,
|
this.$timeout,
|
||||||
application,
|
application,
|
||||||
this.bridge,
|
this.bridge
|
||||||
);
|
);
|
||||||
const keyboardService = new KeyboardManager();
|
const io = new IOService(
|
||||||
const autolockService = new AutolockService(
|
platform === Platform.MacWeb || platform === Platform.MacDesktop
|
||||||
application
|
|
||||||
);
|
|
||||||
const nativeExtService = new NativeExtManager(
|
|
||||||
application
|
|
||||||
);
|
|
||||||
const statusService = new StatusManager();
|
|
||||||
const themeService = new ThemeManager(
|
|
||||||
application,
|
|
||||||
);
|
);
|
||||||
|
const autolockService = new AutolockService(application);
|
||||||
|
const nativeExtService = new NativeExtManager(application);
|
||||||
|
const statusManager = new StatusManager();
|
||||||
|
const themeService = new ThemeManager(application);
|
||||||
application.setWebServices({
|
application.setWebServices({
|
||||||
appState,
|
appState,
|
||||||
archiveService,
|
archiveService,
|
||||||
desktopService,
|
desktopService,
|
||||||
keyboardService,
|
io,
|
||||||
autolockService,
|
autolockService,
|
||||||
nativeExtService,
|
nativeExtService,
|
||||||
statusManager: statusService,
|
statusManager,
|
||||||
themeService
|
themeService,
|
||||||
});
|
});
|
||||||
return application;
|
return application;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { ApplicationEvent } from '@standardnotes/snjs';
|
import { ApplicationEvent } from '@standardnotes/snjs';
|
||||||
import { WebApplication } from '@/ui_models/application';
|
import { WebApplication } from '@/ui_models/application';
|
||||||
|
import { AppState } from '@/ui_models/app_state';
|
||||||
|
import { autorun, IReactionDisposer, IReactionPublic } from 'mobx';
|
||||||
|
|
||||||
export type CtrlState = Partial<Record<string, any>>
|
export type CtrlState = Partial<Record<string, any>>
|
||||||
export type CtrlProps = Partial<Record<string, any>>
|
export type CtrlProps = Partial<Record<string, any>>
|
||||||
@@ -17,6 +19,7 @@ export class PureViewCtrl<P = CtrlProps, S = CtrlState> {
|
|||||||
* no Angular handlebars/syntax render in the UI before display data is ready.
|
* no Angular handlebars/syntax render in the UI before display data is ready.
|
||||||
*/
|
*/
|
||||||
protected templateReady = false
|
protected templateReady = false
|
||||||
|
private reactionDisposers: IReactionDisposer[] = [];
|
||||||
|
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
constructor(
|
constructor(
|
||||||
@@ -26,7 +29,7 @@ export class PureViewCtrl<P = CtrlProps, S = CtrlState> {
|
|||||||
this.$timeout = $timeout;
|
this.$timeout = $timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
$onInit() {
|
$onInit(): void {
|
||||||
this.state = {
|
this.state = {
|
||||||
...this.getInitialState(),
|
...this.getInitialState(),
|
||||||
...this.state,
|
...this.state,
|
||||||
@@ -36,9 +39,13 @@ export class PureViewCtrl<P = CtrlProps, S = CtrlState> {
|
|||||||
this.templateReady = true;
|
this.templateReady = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit() {
|
deinit(): void {
|
||||||
this.unsubApp();
|
this.unsubApp();
|
||||||
this.unsubState();
|
this.unsubState();
|
||||||
|
for (const disposer of this.reactionDisposers) {
|
||||||
|
disposer();
|
||||||
|
}
|
||||||
|
this.reactionDisposers.length = 0;
|
||||||
this.unsubApp = undefined;
|
this.unsubApp = undefined;
|
||||||
this.unsubState = undefined;
|
this.unsubState = undefined;
|
||||||
if (this.stateTimeout) {
|
if (this.stateTimeout) {
|
||||||
@@ -46,16 +53,16 @@ export class PureViewCtrl<P = CtrlProps, S = CtrlState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$onDestroy() {
|
$onDestroy(): void {
|
||||||
this.deinit();
|
this.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get appState() {
|
public get appState(): AppState {
|
||||||
return this.application!.getAppState();
|
return this.application.getAppState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
async resetState() {
|
async resetState(): Promise<void> {
|
||||||
this.state = this.getInitialState();
|
this.state = this.getInitialState();
|
||||||
await this.setState(this.state);
|
await this.setState(this.state);
|
||||||
}
|
}
|
||||||
@@ -65,7 +72,7 @@ export class PureViewCtrl<P = CtrlProps, S = CtrlState> {
|
|||||||
return {} as any;
|
return {} as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
async setState(state: Partial<S>) {
|
async setState(state: Partial<S>): Promise<void> {
|
||||||
if (!this.$timeout) {
|
if (!this.$timeout) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -88,17 +95,21 @@ export class PureViewCtrl<P = CtrlProps, S = CtrlState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @returns a promise that resolves after the UI has been updated. */
|
/** @returns a promise that resolves after the UI has been updated. */
|
||||||
flushUI() {
|
flushUI(): angular.IPromise<void> {
|
||||||
return this.$timeout();
|
return this.$timeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
initProps(props: CtrlProps) {
|
initProps(props: CtrlProps): void {
|
||||||
if (Object.keys(this.props).length > 0) {
|
if (Object.keys(this.props).length > 0) {
|
||||||
throw 'Already init-ed props.';
|
throw 'Already init-ed props.';
|
||||||
}
|
}
|
||||||
this.props = Object.freeze(Object.assign({}, this.props, props));
|
this.props = Object.freeze(Object.assign({}, this.props, props));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
autorun(view: (r: IReactionPublic) => void): void {
|
||||||
|
this.reactionDisposers.push(autorun(view));
|
||||||
|
}
|
||||||
|
|
||||||
addAppStateObserver() {
|
addAppStateObserver() {
|
||||||
this.unsubState = this.application!.getAppState().addObserver(
|
this.unsubState = this.application!.getAppState().addObserver(
|
||||||
async (eventName, data) => {
|
async (eventName, data) => {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import {
|
|||||||
} from '@standardnotes/snjs';
|
} from '@standardnotes/snjs';
|
||||||
import find from 'lodash/find';
|
import find from 'lodash/find';
|
||||||
import { isDesktopApplication } from '@/utils';
|
import { isDesktopApplication } from '@/utils';
|
||||||
import { KeyboardModifier, KeyboardKey } from '@/services/keyboardManager';
|
import { KeyboardModifier, KeyboardKey } from '@/services/ioService';
|
||||||
import template from './editor-view.pug';
|
import template from './editor-view.pug';
|
||||||
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
||||||
import { EventSource } from '@/ui_models/app_state';
|
import { EventSource } from '@/ui_models/app_state';
|
||||||
@@ -1106,7 +1106,7 @@ class EditorViewCtrl extends PureViewCtrl<unknown, EditorState> {
|
|||||||
|
|
||||||
registerKeyboardShortcuts() {
|
registerKeyboardShortcuts() {
|
||||||
this.removeAltKeyObserver = this.application
|
this.removeAltKeyObserver = this.application
|
||||||
.getKeyboardService()
|
.io
|
||||||
.addKeyObserver({
|
.addKeyObserver({
|
||||||
modifiers: [KeyboardModifier.Alt],
|
modifiers: [KeyboardModifier.Alt],
|
||||||
onKeyDown: () => {
|
onKeyDown: () => {
|
||||||
@@ -1122,7 +1122,7 @@ class EditorViewCtrl extends PureViewCtrl<unknown, EditorState> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.removeTrashKeyObserver = this.application
|
this.removeTrashKeyObserver = this.application
|
||||||
.getKeyboardService()
|
.io
|
||||||
.addKeyObserver({
|
.addKeyObserver({
|
||||||
key: KeyboardKey.Backspace,
|
key: KeyboardKey.Backspace,
|
||||||
notElementIds: [ElementIds.NoteTextEditor, ElementIds.NoteTitleEditor],
|
notElementIds: [ElementIds.NoteTextEditor, ElementIds.NoteTitleEditor],
|
||||||
@@ -1147,7 +1147,7 @@ class EditorViewCtrl extends PureViewCtrl<unknown, EditorState> {
|
|||||||
ElementIds.NoteTextEditor
|
ElementIds.NoteTextEditor
|
||||||
)! as HTMLInputElement;
|
)! as HTMLInputElement;
|
||||||
this.removeTabObserver = this.application
|
this.removeTabObserver = this.application
|
||||||
.getKeyboardService()
|
.io
|
||||||
.addKeyObserver({
|
.addKeyObserver({
|
||||||
element: editor,
|
element: editor,
|
||||||
key: KeyboardKey.Tab,
|
key: KeyboardKey.Tab,
|
||||||
|
|||||||
@@ -127,7 +127,7 @@
|
|||||||
)
|
)
|
||||||
.note(
|
.note(
|
||||||
ng-repeat='note in self.state.renderedNotes track by note.uuid'
|
ng-repeat='note in self.state.renderedNotes track by note.uuid'
|
||||||
ng-class="{'selected' : self.activeEditorNote.uuid == note.uuid}"
|
ng-class="{'selected' : self.isNoteSelected(note.uuid) }"
|
||||||
ng-click='self.selectNote(note)'
|
ng-click='self.selectNote(note)'
|
||||||
)
|
)
|
||||||
.note-flags(ng-show='self.noteFlags[note.uuid].length > 0')
|
.note-flags(ng-show='self.noteFlags[note.uuid].length > 0')
|
||||||
|
|||||||
@@ -14,17 +14,17 @@ import {
|
|||||||
} from '@standardnotes/snjs';
|
} from '@standardnotes/snjs';
|
||||||
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
||||||
import { AppStateEvent } from '@/ui_models/app_state';
|
import { AppStateEvent } from '@/ui_models/app_state';
|
||||||
import { KeyboardModifier, KeyboardKey } from '@/services/keyboardManager';
|
import { KeyboardKey, KeyboardModifier } from '@/services/ioService';
|
||||||
import {
|
import {
|
||||||
PANEL_NAME_NOTES
|
PANEL_NAME_NOTES
|
||||||
} from '@/views/constants';
|
} from '@/views/constants';
|
||||||
import { autorun, IReactionDisposer } from 'mobx';
|
|
||||||
|
|
||||||
type NotesState = {
|
type NotesCtrlState = {
|
||||||
panelTitle: string
|
panelTitle: string
|
||||||
notes: SNNote[]
|
notes: SNNote[]
|
||||||
renderedNotes: SNNote[]
|
renderedNotes: SNNote[]
|
||||||
renderedNotesTags: string[],
|
renderedNotesTags: string[],
|
||||||
|
selectedNotes: Record<UuidString, SNNote>,
|
||||||
sortBy?: string
|
sortBy?: string
|
||||||
sortReverse?: boolean
|
sortReverse?: boolean
|
||||||
showArchived?: boolean
|
showArchived?: boolean
|
||||||
@@ -65,7 +65,7 @@ const DEFAULT_LIST_NUM_NOTES = 20;
|
|||||||
const ELEMENT_ID_SEARCH_BAR = 'search-bar';
|
const ELEMENT_ID_SEARCH_BAR = 'search-bar';
|
||||||
const ELEMENT_ID_SCROLL_CONTAINER = 'notes-scrollable';
|
const ELEMENT_ID_SCROLL_CONTAINER = 'notes-scrollable';
|
||||||
|
|
||||||
class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
class NotesViewCtrl extends PureViewCtrl<unknown, NotesCtrlState> {
|
||||||
|
|
||||||
private panelPuppet?: PanelPuppet
|
private panelPuppet?: PanelPuppet
|
||||||
private reloadNotesPromise?: any
|
private reloadNotesPromise?: any
|
||||||
@@ -78,7 +78,6 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
private searchKeyObserver: any
|
private searchKeyObserver: any
|
||||||
private noteFlags: Partial<Record<UuidString, NoteFlag[]>> = {}
|
private noteFlags: Partial<Record<UuidString, NoteFlag[]>> = {}
|
||||||
private removeObservers: Array<() => void> = [];
|
private removeObservers: Array<() => void> = [];
|
||||||
private appStateObserver?: IReactionDisposer;
|
|
||||||
|
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
constructor($timeout: ng.ITimeoutService,) {
|
constructor($timeout: ng.ITimeoutService,) {
|
||||||
@@ -95,7 +94,7 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
this.onPanelResize = this.onPanelResize.bind(this);
|
this.onPanelResize = this.onPanelResize.bind(this);
|
||||||
window.addEventListener('resize', this.onWindowResize, true);
|
window.addEventListener('resize', this.onWindowResize, true);
|
||||||
this.registerKeyboardShortcuts();
|
this.registerKeyboardShortcuts();
|
||||||
this.appStateObserver = autorun(async () => {
|
this.autorun(async () => {
|
||||||
const {
|
const {
|
||||||
includeProtectedContents,
|
includeProtectedContents,
|
||||||
includeArchived,
|
includeArchived,
|
||||||
@@ -113,6 +112,11 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
this.reloadNotes();
|
this.reloadNotes();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.autorun(() => {
|
||||||
|
this.setState({
|
||||||
|
selectedNotes: this.appState.notes.selectedNotes,
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onWindowResize() {
|
onWindowResize() {
|
||||||
@@ -131,7 +135,6 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
this.nextNoteKeyObserver();
|
this.nextNoteKeyObserver();
|
||||||
this.previousNoteKeyObserver();
|
this.previousNoteKeyObserver();
|
||||||
this.searchKeyObserver();
|
this.searchKeyObserver();
|
||||||
this.appStateObserver?.();
|
|
||||||
this.newNoteKeyObserver = undefined;
|
this.newNoteKeyObserver = undefined;
|
||||||
this.nextNoteKeyObserver = undefined;
|
this.nextNoteKeyObserver = undefined;
|
||||||
this.previousNoteKeyObserver = undefined;
|
this.previousNoteKeyObserver = undefined;
|
||||||
@@ -139,15 +142,16 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
super.deinit();
|
super.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
async setNotesState(state: Partial<NotesState>) {
|
async setNotesState(state: Partial<NotesCtrlState>) {
|
||||||
return this.setState(state);
|
return this.setState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
getInitialState(): NotesState {
|
getInitialState(): NotesCtrlState {
|
||||||
return {
|
return {
|
||||||
notes: [],
|
notes: [],
|
||||||
renderedNotes: [],
|
renderedNotes: [],
|
||||||
renderedNotesTags: [],
|
renderedNotesTags: [],
|
||||||
|
selectedNotes: {},
|
||||||
mutable: { showMenu: false },
|
mutable: { showMenu: false },
|
||||||
noteFilter: {
|
noteFilter: {
|
||||||
text: '',
|
text: '',
|
||||||
@@ -180,9 +184,13 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get activeEditorNote() {
|
||||||
|
return this.appState.notes.activeEditor?.note;
|
||||||
|
}
|
||||||
|
|
||||||
/** @template */
|
/** @template */
|
||||||
public get activeEditorNote() {
|
public isNoteSelected(uuid: UuidString) {
|
||||||
return this.appState?.getActiveEditor()?.note;
|
return !!this.state.selectedNotes[uuid];
|
||||||
}
|
}
|
||||||
|
|
||||||
public get editorNotes() {
|
public get editorNotes() {
|
||||||
@@ -288,12 +296,8 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectNote(note: SNNote) {
|
selectNote(note: SNNote): Promise<void> {
|
||||||
await this.appState.openEditor(note.uuid);
|
return this.appState.notes.selectNote(note);
|
||||||
if (note.waitingForKey) {
|
|
||||||
this.application.presentKeyRecoveryWizard();
|
|
||||||
}
|
|
||||||
this.reloadNotes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createNewNote() {
|
async createNewNote() {
|
||||||
@@ -461,7 +465,7 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async reloadPreferences() {
|
async reloadPreferences() {
|
||||||
const viewOptions = {} as NotesState;
|
const viewOptions = {} as NotesCtrlState;
|
||||||
const prevSortValue = this.state.sortBy;
|
const prevSortValue = this.state.sortBy;
|
||||||
let sortBy = this.application.getPreference(
|
let sortBy = this.application.getPreference(
|
||||||
PrefKey.SortNotesBy,
|
PrefKey.SortNotesBy,
|
||||||
@@ -673,7 +677,7 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
selectNextNote() {
|
selectNextNote() {
|
||||||
const displayableNotes = this.state.notes;
|
const displayableNotes = this.state.notes;
|
||||||
const currentIndex = displayableNotes.findIndex((candidate) => {
|
const currentIndex = displayableNotes.findIndex((candidate) => {
|
||||||
return candidate.uuid === this.activeEditorNote.uuid;
|
return candidate.uuid === this.activeEditorNote?.uuid;
|
||||||
});
|
});
|
||||||
if (currentIndex + 1 < displayableNotes.length) {
|
if (currentIndex + 1 < displayableNotes.length) {
|
||||||
this.selectNote(displayableNotes[currentIndex + 1]);
|
this.selectNote(displayableNotes[currentIndex + 1]);
|
||||||
@@ -791,7 +795,7 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
* use Control modifier as well. These rules don't apply to desktop, but
|
* use Control modifier as well. These rules don't apply to desktop, but
|
||||||
* probably better to be consistent.
|
* probably better to be consistent.
|
||||||
*/
|
*/
|
||||||
this.newNoteKeyObserver = this.application.getKeyboardService().addKeyObserver({
|
this.newNoteKeyObserver = this.application.io.addKeyObserver({
|
||||||
key: 'n',
|
key: 'n',
|
||||||
modifiers: [
|
modifiers: [
|
||||||
KeyboardModifier.Meta,
|
KeyboardModifier.Meta,
|
||||||
@@ -803,7 +807,7 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.nextNoteKeyObserver = this.application.getKeyboardService().addKeyObserver({
|
this.nextNoteKeyObserver = this.application.io.addKeyObserver({
|
||||||
key: KeyboardKey.Down,
|
key: KeyboardKey.Down,
|
||||||
elements: [
|
elements: [
|
||||||
document.body,
|
document.body,
|
||||||
@@ -818,7 +822,7 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.previousNoteKeyObserver = this.application.getKeyboardService().addKeyObserver({
|
this.previousNoteKeyObserver = this.application.io.addKeyObserver({
|
||||||
key: KeyboardKey.Up,
|
key: KeyboardKey.Up,
|
||||||
element: document.body,
|
element: document.body,
|
||||||
onKeyDown: () => {
|
onKeyDown: () => {
|
||||||
@@ -826,7 +830,7 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesState> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.searchKeyObserver = this.application.getKeyboardService().addKeyObserver({
|
this.searchKeyObserver = this.application.io.addKeyObserver({
|
||||||
key: "f",
|
key: "f",
|
||||||
modifiers: [
|
modifiers: [
|
||||||
KeyboardModifier.Meta,
|
KeyboardModifier.Meta,
|
||||||
|
|||||||
Reference in New Issue
Block a user