standardnotes-app/app/assets/javascripts/ui_models/component_group.ts
Gorjan Petrovski 1294b94117
feat: integrate two factor authentication (#626)
* feat: integrate SNJS MFA with web

* fix: create rudimentary typings file for qrcode.react

* chore: lint fixes

* fix: address PR feedback

* fix: address PR feedback

* fix: address PR feedback 2

* fix: replace spread props on TwoFactorAuthWrapper component

* chore: change null check to undefined check
2021-09-06 17:15:34 +02:00

100 lines
2.8 KiB
TypeScript

import { SNComponent, ComponentArea, removeFromArray, addIfUnique , UuidString } from '@standardnotes/snjs';
import { WebApplication } from './application';
/** Areas that only allow a single component to be active */
const SingleComponentAreas = [
ComponentArea.Editor,
ComponentArea.NoteTags,
ComponentArea.TagsList
];
export class ComponentGroup {
private application: WebApplication
changeObservers: any[] = []
activeComponents: UuidString[] = []
constructor(application: WebApplication) {
this.application = application;
}
get componentManager() {
return this.application.componentManager!;
}
public deinit() {
(this.application as any) = undefined;
}
async activateComponent(component: SNComponent) {
if (this.activeComponents.includes(component.uuid)) {
return;
}
if (SingleComponentAreas.includes(component.area)) {
const currentActive = this.activeComponentForArea(component.area);
if (currentActive) {
await this.deactivateComponent(currentActive, false);
}
}
addIfUnique(this.activeComponents, component.uuid);
await this.componentManager.activateComponent(component.uuid);
this.notifyObservers();
}
async deactivateComponent(component: SNComponent, notify = true) {
if (!this.activeComponents.includes(component.uuid)) {
return;
}
removeFromArray(this.activeComponents, component.uuid);
/** If this function is called as part of global application deinit (locking),
* componentManager can be destroyed. In this case, it's harmless to not take any
* action since the componentManager will be destroyed, and the component will
* essentially be deregistered. */
if(this.componentManager) {
await this.componentManager.deactivateComponent(component.uuid);
if(notify) {
this.notifyObservers();
}
}
}
async deactivateComponentForArea(area: ComponentArea) {
const component = this.activeComponentForArea(area);
if (component) {
return this.deactivateComponent(component);
}
}
activeComponentForArea(area: ComponentArea) {
return this.activeComponentsForArea(area)[0];
}
activeComponentsForArea(area: ComponentArea) {
return this.allActiveComponents().filter((c) => c.area === area);
}
allComponentsForArea(area: ComponentArea) {
return this.componentManager.componentsForArea(area);
}
private allActiveComponents() {
return this.application.getAll(this.activeComponents) as SNComponent[];
}
/**
* Notifies observer when the active editor has changed.
*/
public addChangeObserver(callback: () => void) {
this.changeObservers.push(callback);
callback();
return () => {
removeFromArray(this.changeObservers, callback);
};
}
private notifyObservers() {
for (const observer of this.changeObservers) {
observer();
}
}
}