161 lines
4.4 KiB
TypeScript
161 lines
4.4 KiB
TypeScript
import { removeFromArray } from '@standardnotes/utils'
|
|
import {
|
|
AlertService,
|
|
ComponentManagerInterface,
|
|
FileItem,
|
|
ItemManagerInterface,
|
|
MutatorClientInterface,
|
|
PreferenceServiceInterface,
|
|
SNNote,
|
|
SessionsClientInterface,
|
|
SyncServiceInterface,
|
|
} from '@standardnotes/snjs'
|
|
import { NoteViewController } from './NoteViewController'
|
|
import { FileViewController } from './FileViewController'
|
|
import { TemplateNoteViewControllerOptions } from './TemplateNoteViewControllerOptions'
|
|
import { IsNativeMobileWeb } from '@standardnotes/ui-services'
|
|
|
|
type ItemControllerGroupChangeCallback = (activeController: NoteViewController | FileViewController | undefined) => void
|
|
|
|
export class ItemGroupController {
|
|
public itemControllers: (NoteViewController | FileViewController)[] = []
|
|
changeObservers: ItemControllerGroupChangeCallback[] = []
|
|
eventObservers: (() => void)[] = []
|
|
|
|
constructor(
|
|
private items: ItemManagerInterface,
|
|
private mutator: MutatorClientInterface,
|
|
private sync: SyncServiceInterface,
|
|
private sessions: SessionsClientInterface,
|
|
private preferences: PreferenceServiceInterface,
|
|
private components: ComponentManagerInterface,
|
|
private alerts: AlertService,
|
|
private _isNativeMobileWeb: IsNativeMobileWeb,
|
|
) {}
|
|
|
|
public deinit(): void {
|
|
;(this.items as unknown) = undefined
|
|
|
|
this.eventObservers.forEach((removeObserver) => {
|
|
removeObserver()
|
|
})
|
|
|
|
this.changeObservers.length = 0
|
|
|
|
for (const controller of this.itemControllers) {
|
|
this.closeItemController(controller, { notify: false })
|
|
}
|
|
|
|
this.itemControllers.length = 0
|
|
}
|
|
|
|
async createItemController(context: {
|
|
file?: FileItem
|
|
note?: SNNote
|
|
templateOptions?: TemplateNoteViewControllerOptions
|
|
}): Promise<NoteViewController | FileViewController> {
|
|
if (this.activeItemViewController) {
|
|
this.closeItemController(this.activeItemViewController, { notify: false })
|
|
}
|
|
|
|
let controller!: NoteViewController | FileViewController
|
|
|
|
if (context.file) {
|
|
controller = new FileViewController(context.file, this.items)
|
|
} else if (context.note) {
|
|
controller = new NoteViewController(
|
|
context.note,
|
|
this.items,
|
|
this.mutator,
|
|
this.sync,
|
|
this.sessions,
|
|
this.preferences,
|
|
this.components,
|
|
this.alerts,
|
|
this._isNativeMobileWeb,
|
|
)
|
|
} else if (context.templateOptions) {
|
|
controller = new NoteViewController(
|
|
undefined,
|
|
this.items,
|
|
this.mutator,
|
|
this.sync,
|
|
this.sessions,
|
|
this.preferences,
|
|
this.components,
|
|
this.alerts,
|
|
this._isNativeMobileWeb,
|
|
context.templateOptions,
|
|
)
|
|
} else {
|
|
throw Error('Invalid input to createItemController')
|
|
}
|
|
|
|
this.itemControllers.push(controller)
|
|
|
|
await controller.initialize()
|
|
|
|
this.notifyObservers()
|
|
|
|
return controller
|
|
}
|
|
|
|
public closeItemController(
|
|
controller: NoteViewController | FileViewController,
|
|
{ notify = true }: { notify: boolean } = { notify: true },
|
|
): void {
|
|
if (controller instanceof NoteViewController) {
|
|
controller.syncOnlyIfLargeNote()
|
|
}
|
|
controller.deinit()
|
|
|
|
removeFromArray(this.itemControllers, controller)
|
|
|
|
if (notify) {
|
|
this.notifyObservers()
|
|
}
|
|
}
|
|
|
|
closeActiveItemController(): void {
|
|
const activeController = this.activeItemViewController
|
|
|
|
if (activeController) {
|
|
this.closeItemController(activeController, { notify: true })
|
|
}
|
|
}
|
|
|
|
closeAllItemControllers(): void {
|
|
for (const controller of this.itemControllers) {
|
|
this.closeItemController(controller, { notify: false })
|
|
}
|
|
|
|
this.notifyObservers()
|
|
}
|
|
|
|
get activeItemViewController(): NoteViewController | FileViewController | undefined {
|
|
return this.itemControllers[0]
|
|
}
|
|
|
|
/**
|
|
* Notifies observer when the active controller has changed.
|
|
*/
|
|
public addActiveControllerChangeObserver(callback: ItemControllerGroupChangeCallback): () => void {
|
|
this.changeObservers.push(callback)
|
|
|
|
if (this.activeItemViewController) {
|
|
callback(this.activeItemViewController)
|
|
}
|
|
|
|
const thislessChangeObservers = this.changeObservers
|
|
return () => {
|
|
removeFromArray(thislessChangeObservers, callback)
|
|
}
|
|
}
|
|
|
|
private notifyObservers(): void {
|
|
for (const observer of this.changeObservers) {
|
|
observer(this.activeItemViewController)
|
|
}
|
|
}
|
|
}
|