refactor(web): dependency management (#2386)

This commit is contained in:
Mo
2023-08-05 12:48:39 -05:00
committed by GitHub
parent b07da5b663
commit d8d4052a52
274 changed files with 4065 additions and 3873 deletions

View File

@@ -1,7 +1,7 @@
import { FileItem } from '@standardnotes/models'
import { ContentType } from '@standardnotes/domain-core'
import { SNApplication } from '@standardnotes/snjs'
import { ItemViewControllerInterface } from './ItemViewControllerInterface'
import { ItemManagerInterface } from '@standardnotes/snjs'
export class FileViewController implements ItemViewControllerInterface {
public dealloced = false
@@ -9,15 +9,14 @@ export class FileViewController implements ItemViewControllerInterface {
public runtimeId = `${Math.random()}`
constructor(
private application: SNApplication,
public item: FileItem,
private items: ItemManagerInterface,
) {}
deinit() {
this.dealloced = true
this.removeStreamObserver?.()
;(this.removeStreamObserver as unknown) = undefined
;(this.application as unknown) = undefined
;(this.item as unknown) = undefined
}
@@ -26,23 +25,20 @@ export class FileViewController implements ItemViewControllerInterface {
}
private streamItems() {
this.removeStreamObserver = this.application.streamItems<FileItem>(
ContentType.TYPES.File,
({ changed, inserted }) => {
if (this.dealloced) {
return
}
this.removeStreamObserver = this.items.streamItems<FileItem>(ContentType.TYPES.File, ({ changed, inserted }) => {
if (this.dealloced) {
return
}
const files = changed.concat(inserted)
const files = changed.concat(inserted)
const matchingFile = files.find((item) => {
return item.uuid === this.item.uuid
})
const matchingFile = files.find((item) => {
return item.uuid === this.item.uuid
})
if (matchingFile) {
this.item = matchingFile
}
},
)
if (matchingFile) {
this.item = matchingFile
}
})
}
}

View File

@@ -1,9 +1,19 @@
import { WebApplication } from '@/Application/WebApplication'
import { removeFromArray } from '@standardnotes/utils'
import { FileItem, SNNote } from '@standardnotes/snjs'
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
@@ -12,10 +22,19 @@ export class ItemGroupController {
changeObservers: ItemControllerGroupChangeCallback[] = []
eventObservers: (() => void)[] = []
constructor(private application: WebApplication) {}
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.application as unknown) = undefined
;(this.items as unknown) = undefined
this.eventObservers.forEach((removeObserver) => {
removeObserver()
@@ -42,11 +61,32 @@ export class ItemGroupController {
let controller!: NoteViewController | FileViewController
if (context.file) {
controller = new FileViewController(this.application, context.file)
controller = new FileViewController(context.file, this.items)
} else if (context.note) {
controller = new NoteViewController(this.application, 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(this.application, undefined, 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')
}

View File

@@ -9,6 +9,7 @@ import {
SyncServiceInterface,
ItemManagerInterface,
MutatorClientInterface,
PreferenceServiceInterface,
} from '@standardnotes/snjs'
import { NativeFeatureIdentifier, NoteType } from '@standardnotes/features'
import { NoteViewController } from './NoteViewController'
@@ -18,24 +19,24 @@ describe('note view controller', () => {
let componentManager: SNComponentManager
beforeEach(() => {
application = {} as jest.Mocked<WebApplication>
application.streamItems = jest.fn().mockReturnValue(() => {})
application.getPreference = jest.fn().mockReturnValue(true)
application.noAccount = jest.fn().mockReturnValue(false)
application.isNativeMobileWeb = jest.fn().mockReturnValue(false)
application = {
preferences: {
getValue: jest.fn().mockReturnValue(true),
} as unknown as jest.Mocked<PreferenceServiceInterface>,
items: {
streamItems: jest.fn().mockReturnValue(() => {}),
createTemplateItem: jest.fn().mockReturnValue({} as SNNote),
} as unknown as jest.Mocked<ItemManagerInterface>,
mutator: {} as jest.Mocked<MutatorClientInterface>,
} as unknown as jest.Mocked<WebApplication>
const items = {} as jest.Mocked<ItemManagerInterface>
items.createTemplateItem = jest.fn().mockReturnValue({} as SNNote)
Object.defineProperty(application, 'items', { value: items })
application.isNativeMobileWeb = jest.fn().mockReturnValue(false)
Object.defineProperty(application, 'sync', { value: {} as jest.Mocked<SyncServiceInterface> })
application.sync.sync = jest.fn().mockReturnValue(Promise.resolve())
componentManager = {} as jest.Mocked<SNComponentManager>
Object.defineProperty(application, 'componentManager', { value: componentManager })
const mutator = {} as jest.Mocked<MutatorClientInterface>
Object.defineProperty(application, 'mutator', { value: mutator })
})
it('should create notes with plaintext note type', async () => {
@@ -43,7 +44,17 @@ describe('note view controller', () => {
.fn()
.mockReturnValue(NativeFeatureIdentifier.TYPES.PlainEditor)
const controller = new NoteViewController(application)
const controller = new NoteViewController(
undefined,
application.items,
application.mutator,
application.sync,
application.sessions,
application.preferences,
application.componentManager,
application.alerts,
application.isNativeMobileWebUseCase,
)
await controller.initialize()
expect(application.items.createTemplateItem).toHaveBeenCalledWith(
@@ -64,7 +75,17 @@ describe('note view controller', () => {
.fn()
.mockReturnValue(NativeFeatureIdentifier.TYPES.MarkdownProEditor)
const controller = new NoteViewController(application)
const controller = new NoteViewController(
undefined,
application.items,
application.mutator,
application.sync,
application.sessions,
application.preferences,
application.componentManager,
application.alerts,
application.isNativeMobileWebUseCase,
)
await controller.initialize()
expect(application.items.createTemplateItem).toHaveBeenCalledWith(
@@ -86,7 +107,18 @@ describe('note view controller', () => {
application.items.findItem = jest.fn().mockReturnValue(tag)
application.mutator.addTagToNote = jest.fn()
const controller = new NoteViewController(application, undefined, { tag: tag.uuid })
const controller = new NoteViewController(
undefined,
application.items,
application.mutator,
application.sync,
application.sessions,
application.preferences,
application.componentManager,
application.alerts,
application.isNativeMobileWebUseCase,
{ tag: tag.uuid },
)
await controller.initialize()
expect(controller['defaultTag']).toEqual(tag)
@@ -100,7 +132,17 @@ describe('note view controller', () => {
application.items.findItem = jest.fn().mockReturnValue(note)
const controller = new NoteViewController(application, note)
const controller = new NoteViewController(
note,
application.items,
application.mutator,
application.sync,
application.sessions,
application.preferences,
application.componentManager,
application.alerts,
application.isNativeMobileWebUseCase,
)
await controller.initialize()
const changePromise = Deferred()

View File

@@ -1,4 +1,3 @@
import { WebApplication } from '@/Application/WebApplication'
import { noteTypeForEditorIdentifier } from '@standardnotes/features'
import {
SNNote,
@@ -9,13 +8,23 @@ import {
PrefKey,
PayloadVaultOverrides,
} from '@standardnotes/models'
import { UuidString } from '@standardnotes/snjs'
import {
AlertService,
ComponentManagerInterface,
ItemManagerInterface,
MutatorClientInterface,
PreferenceServiceInterface,
SessionsClientInterface,
SyncServiceInterface,
UuidString,
} from '@standardnotes/snjs'
import { removeFromArray } from '@standardnotes/utils'
import { ContentType } from '@standardnotes/domain-core'
import { ItemViewControllerInterface } from './ItemViewControllerInterface'
import { TemplateNoteViewControllerOptions } from './TemplateNoteViewControllerOptions'
import { log, LoggingDomain } from '@/Logging'
import { NoteSaveFunctionParams, NoteSyncController } from '../../../Controllers/NoteSyncController'
import { IsNativeMobileWeb } from '@standardnotes/ui-services'
export type EditorValues = {
title: string
@@ -37,8 +46,15 @@ export class NoteViewController implements ItemViewControllerInterface {
private syncController!: NoteSyncController
constructor(
private application: WebApplication,
item?: SNNote,
item: SNNote | undefined,
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 templateNoteOptions?: TemplateNoteViewControllerOptions,
) {
if (item) {
@@ -50,10 +66,18 @@ export class NoteViewController implements ItemViewControllerInterface {
}
if (this.defaultTagUuid) {
this.defaultTag = this.application.items.findItem(this.defaultTagUuid) as SNTag
this.defaultTag = this.items.findItem(this.defaultTagUuid) as SNTag
}
this.syncController = new NoteSyncController(this.application, this.item)
this.syncController = new NoteSyncController(
this.item,
this.items,
this.mutator,
this.sessions,
this.sync,
this.alerts,
this._isNativeMobileWeb,
)
}
deinit(): void {
@@ -74,9 +98,6 @@ export class NoteViewController implements ItemViewControllerInterface {
disposer()
}
this.disposers.length = 0
;(this.application as unknown) = undefined
;(this.item as unknown) = undefined
this.innerValueChangeObservers.length = 0
}
@@ -89,16 +110,16 @@ export class NoteViewController implements ItemViewControllerInterface {
this.needsInit = false
const addTagHierarchy = this.application.getPreference(PrefKey.NoteAddToParentFolders, true)
const addTagHierarchy = this.preferences.getValue(PrefKey.NoteAddToParentFolders, true)
if (!this.item) {
log(LoggingDomain.NoteView, 'Initializing as template note')
const editorIdentifier = this.application.componentManager.getDefaultEditorIdentifier(this.defaultTag)
const editorIdentifier = this.components.getDefaultEditorIdentifier(this.defaultTag)
const noteType = noteTypeForEditorIdentifier(editorIdentifier)
const note = this.application.items.createTemplateItem<NoteContent, SNNote>(
const note = this.items.createTemplateItem<NoteContent, SNNote>(
ContentType.TYPES.Note,
{
text: '',
@@ -118,8 +139,8 @@ export class NoteViewController implements ItemViewControllerInterface {
this.syncController.setItem(this.item)
if (this.defaultTagUuid) {
const tag = this.application.items.findItem(this.defaultTagUuid) as SNTag
await this.application.mutator.addTagToNote(note, tag, addTagHierarchy)
const tag = this.items.findItem(this.defaultTagUuid) as SNTag
await this.mutator.addTagToNote(note, tag, addTagHierarchy)
}
this.notifyObservers(this.item, PayloadEmitSource.InitialObserverRegistrationPush)
@@ -140,7 +161,7 @@ export class NoteViewController implements ItemViewControllerInterface {
}
this.disposers.push(
this.application.streamItems<SNNote>(ContentType.TYPES.Note, ({ changed, inserted, source }) => {
this.items.streamItems<SNNote>(ContentType.TYPES.Note, ({ changed, inserted, source }) => {
if (this.dealloced) {
return
}
@@ -163,7 +184,7 @@ export class NoteViewController implements ItemViewControllerInterface {
public insertTemplatedNote(): Promise<DecryptedItemInterface> {
log(LoggingDomain.NoteView, 'Inserting template note')
this.isTemplateNote = false
return this.application.mutator.insertItem(this.item)
return this.mutator.insertItem(this.item)
}
/**