feat: use panel width event instead of ResizeObserver
This commit is contained in:
100
app/assets/javascripts/ui_models/app_state/active_note_state.ts
Normal file
100
app/assets/javascripts/ui_models/app_state/active_note_state.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import {
|
||||
SNNote,
|
||||
ContentType,
|
||||
SNTag,
|
||||
} from '@standardnotes/snjs';
|
||||
import {
|
||||
action,
|
||||
makeObservable,
|
||||
observable,
|
||||
} from 'mobx';
|
||||
import { WebApplication } from '../application';
|
||||
import { AppState } from './app_state';
|
||||
|
||||
export class ActiveNoteState {
|
||||
tags: SNTag[] = [];
|
||||
tagsContainerPosition? = 0;
|
||||
tagsContainerMaxWidth: number | 'auto' = 'auto';
|
||||
|
||||
constructor(
|
||||
private application: WebApplication,
|
||||
private appState: AppState,
|
||||
appEventListeners: (() => void)[]
|
||||
) {
|
||||
makeObservable(this, {
|
||||
tags: observable,
|
||||
tagsContainerPosition: observable,
|
||||
tagsContainerMaxWidth: observable,
|
||||
|
||||
setTagsContainerPosition: action,
|
||||
setTagsContainerMaxWidth: action,
|
||||
reloadTags: action,
|
||||
});
|
||||
|
||||
this.tagsContainerPosition = document
|
||||
.getElementById('editor-column')
|
||||
?.getBoundingClientRect().left;
|
||||
|
||||
appEventListeners.push(
|
||||
application.streamItems(
|
||||
ContentType.Tag,
|
||||
() => {
|
||||
this.reloadTags();
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
get activeNote(): SNNote | undefined {
|
||||
return this.appState.notes.activeEditor?.note;
|
||||
}
|
||||
|
||||
setTagsContainerPosition(position: number): void {
|
||||
this.tagsContainerPosition = position;
|
||||
}
|
||||
|
||||
setTagsContainerMaxWidth(width: number): void {
|
||||
this.tagsContainerMaxWidth = width;
|
||||
}
|
||||
|
||||
reloadTags(): void {
|
||||
const { activeNote } = this;
|
||||
if (activeNote) {
|
||||
this.tags = this.application.getSortedTagsForNote(activeNote);
|
||||
}
|
||||
}
|
||||
|
||||
reloadTagsContainerLayout(): void {
|
||||
const editorElementId = 'editor-column';
|
||||
const { clientWidth } = document.documentElement;
|
||||
const editorPosition =
|
||||
document.getElementById(editorElementId)?.getBoundingClientRect()
|
||||
.left ?? 0;
|
||||
this.appState.activeNote.setTagsContainerPosition(editorPosition);
|
||||
this.appState.activeNote.setTagsContainerMaxWidth(
|
||||
clientWidth - editorPosition
|
||||
);
|
||||
}
|
||||
|
||||
async addTagToActiveNote(tag: SNTag): Promise<void> {
|
||||
const { activeNote } = this;
|
||||
if (activeNote) {
|
||||
await this.application.changeItem(tag.uuid, (mutator) => {
|
||||
mutator.addItemAsRelationship(activeNote);
|
||||
});
|
||||
this.application.sync();
|
||||
this.reloadTags();
|
||||
}
|
||||
}
|
||||
|
||||
async removeTagFromActiveNote(tag: SNTag): Promise<void> {
|
||||
const { activeNote } = this;
|
||||
if (activeNote) {
|
||||
await this.application.changeItem(tag.uuid, (mutator) => {
|
||||
mutator.removeItemAsRelationship(activeNote);
|
||||
});
|
||||
this.application.sync();
|
||||
this.reloadTags();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import { Bridge } from '@/services/bridge';
|
||||
import { storage, StorageKey } from '@/services/localStorage';
|
||||
import { AccountMenuState } from './account_menu_state';
|
||||
import { ActionsMenuState } from './actions_menu_state';
|
||||
import { ActiveNoteState } from './active_note_state';
|
||||
import { NoAccountWarningState } from './no_account_warning_state';
|
||||
import { SyncState } from './sync_state';
|
||||
import { SearchOptionsState } from './search_options_state';
|
||||
@@ -62,6 +63,7 @@ export class AppState {
|
||||
showBetaWarning: boolean;
|
||||
readonly accountMenu = new AccountMenuState();
|
||||
readonly actionsMenu = new ActionsMenuState();
|
||||
readonly activeNote: ActiveNoteState;
|
||||
readonly noAccountWarning: NoAccountWarningState;
|
||||
readonly sync = new SyncState();
|
||||
readonly searchOptions: SearchOptionsState;
|
||||
@@ -81,8 +83,14 @@ export class AppState {
|
||||
this.$timeout = $timeout;
|
||||
this.$rootScope = $rootScope;
|
||||
this.application = application;
|
||||
this.activeNote = new ActiveNoteState(
|
||||
application,
|
||||
this,
|
||||
this.appEventObserverRemovers
|
||||
);
|
||||
this.notes = new NotesState(
|
||||
this.application,
|
||||
application,
|
||||
this,
|
||||
async () => {
|
||||
await this.notifyEvent(AppStateEvent.ActiveEditorChanged);
|
||||
},
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
} from 'mobx';
|
||||
import { WebApplication } from '../application';
|
||||
import { Editor } from '../editor';
|
||||
import { AppState } from './app_state';
|
||||
|
||||
export class NotesState {
|
||||
lastSelectedNote: SNNote | undefined;
|
||||
@@ -29,10 +30,10 @@ export class NotesState {
|
||||
};
|
||||
contextMenuMaxHeight: number | 'auto' = 'auto';
|
||||
showProtectedWarning = false;
|
||||
activeNoteTags: SNTag[] = [];
|
||||
|
||||
constructor(
|
||||
private application: WebApplication,
|
||||
private appState: AppState,
|
||||
private onActiveEditorChanged: () => Promise<void>,
|
||||
appEventListeners: (() => void)[]
|
||||
) {
|
||||
@@ -41,12 +42,10 @@ export class NotesState {
|
||||
contextMenuOpen: observable,
|
||||
contextMenuPosition: observable,
|
||||
showProtectedWarning: observable,
|
||||
activeNoteTags: observable,
|
||||
|
||||
selectedNotesCount: computed,
|
||||
trashedNotesCount: computed,
|
||||
|
||||
reloadActiveNoteTags: action,
|
||||
setContextMenuOpen: action,
|
||||
setContextMenuPosition: action,
|
||||
setContextMenuMaxHeight: action,
|
||||
@@ -65,24 +64,12 @@ export class NotesState {
|
||||
});
|
||||
})
|
||||
);
|
||||
appEventListeners.push(
|
||||
application.streamItems(
|
||||
ContentType.Tag,
|
||||
() => {
|
||||
this.reloadActiveNoteTags();
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
get activeEditor(): Editor | undefined {
|
||||
return this.application.editorGroup.editors[0];
|
||||
}
|
||||
|
||||
get activeNote(): SNNote | undefined {
|
||||
return this.activeEditor?.note;
|
||||
}
|
||||
|
||||
get selectedNotesCount(): number {
|
||||
return Object.keys(this.selectedNotes).length;
|
||||
}
|
||||
@@ -163,13 +150,6 @@ export class NotesState {
|
||||
}
|
||||
}
|
||||
|
||||
reloadActiveNoteTags(): void {
|
||||
const { activeNote } = this;
|
||||
if (activeNote) {
|
||||
this.activeNoteTags = this.application.getSortedTagsForNote(activeNote);
|
||||
}
|
||||
}
|
||||
|
||||
private async openEditor(noteUuid: string): Promise<void> {
|
||||
if (this.activeEditor?.note?.uuid === noteUuid) {
|
||||
return;
|
||||
@@ -187,7 +167,7 @@ export class NotesState {
|
||||
this.activeEditor.setNote(note);
|
||||
}
|
||||
|
||||
this.reloadActiveNoteTags();
|
||||
this.appState.activeNote.reloadTags();
|
||||
await this.onActiveEditorChanged();
|
||||
|
||||
if (note.waitingForKey) {
|
||||
@@ -368,36 +348,12 @@ export class NotesState {
|
||||
isTagInSelectedNotes(tag: SNTag): boolean {
|
||||
const selectedNotes = Object.values(this.selectedNotes);
|
||||
return selectedNotes.every((note) =>
|
||||
this.application
|
||||
.getAppState()
|
||||
this.appState
|
||||
.getNoteTags(note)
|
||||
.find((noteTag) => noteTag.uuid === tag.uuid)
|
||||
);
|
||||
}
|
||||
|
||||
async addTagToActiveNote(tag: SNTag): Promise<void> {
|
||||
const { activeNote } = this;
|
||||
if (activeNote) {
|
||||
await this.application.changeItem(tag.uuid, (mutator) => {
|
||||
mutator.addItemAsRelationship(activeNote);
|
||||
});
|
||||
this.application.sync();
|
||||
this.reloadActiveNoteTags();
|
||||
}
|
||||
}
|
||||
|
||||
async removeTagFromActiveNote(tag: SNTag): Promise<void> {
|
||||
const { activeNote } = this;
|
||||
if (activeNote) {
|
||||
await this.application.changeItem(tag.uuid, (mutator) => {
|
||||
mutator.removeItemAsRelationship(activeNote);
|
||||
});
|
||||
this.application.sync();
|
||||
this.reloadActiveNoteTags();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setShowProtectedWarning(show: boolean): void {
|
||||
this.showProtectedWarning = show;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user