diff --git a/.yarn/cache/@standardnotes-common-npm-1.30.0-a603c54867-833b6e7f3e.zip b/.yarn/cache/@standardnotes-common-npm-1.30.0-a603c54867-833b6e7f3e.zip new file mode 100644 index 000000000..b2fcc1f63 Binary files /dev/null and b/.yarn/cache/@standardnotes-common-npm-1.30.0-a603c54867-833b6e7f3e.zip differ diff --git a/package.json b/package.json index 93ded1b26..8050a131d 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "build:desktop": "yarn workspaces foreach -pt --verbose -R --from @standardnotes/desktop --exclude @standardnotes/components-meta run build", "build:mobile": "yarn workspaces foreach -pt --verbose -R --from @standardnotes/mobile --exclude @standardnotes/components-meta run build", "build:snjs": "yarn workspaces foreach -pt --verbose -R --from @standardnotes/snjs --exclude @standardnotes/components-meta run build", + "build:services": "yarn workspaces foreach -pt --verbose -R --from @standardnotes/services --exclude @standardnotes/components-meta run build", "start:server:web": "lerna run start --scope=@standardnotes/web", "start:server:e2e": "lerna run start:test-server --scope=@standardnotes/snjs", "prepare": "husky install", diff --git a/packages/encryption/src/Domain/Backups/BackupFile.ts b/packages/encryption/src/Domain/Backups/BackupFile.ts deleted file mode 100644 index 115cd01a5..000000000 --- a/packages/encryption/src/Domain/Backups/BackupFile.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { AnyKeyParamsContent, ProtocolVersion } from '@standardnotes/common' -import { BackupFileDecryptedContextualPayload, BackupFileEncryptedContextualPayload } from '@standardnotes/models' - -export type BackupFile = { - version?: ProtocolVersion - keyParams?: AnyKeyParamsContent - auth_params?: AnyKeyParamsContent - items: (BackupFileDecryptedContextualPayload | BackupFileEncryptedContextualPayload)[] -} diff --git a/packages/encryption/src/Domain/Backups/BackupFileDecryptor.ts b/packages/encryption/src/Domain/Backups/BackupFileDecryptor.ts index 3a0f41ae8..920699c78 100644 --- a/packages/encryption/src/Domain/Backups/BackupFileDecryptor.ts +++ b/packages/encryption/src/Domain/Backups/BackupFileDecryptor.ts @@ -6,6 +6,7 @@ import { ProtocolVersion, } from '@standardnotes/common' import { + BackupFile, CreateDecryptedItemFromPayload, CreatePayloadSplit, DecryptedPayload, @@ -28,7 +29,6 @@ import { CreateAnyKeyParams } from '../Keys/RootKey/KeyParamsFunctions' import { SNRootKey } from '../Keys/RootKey/RootKey' import { SNRootKeyParams } from '../Keys/RootKey/RootKeyParams' import { EncryptionService } from '../Service/Encryption/EncryptionService' -import { BackupFile } from './BackupFile' import { BackupFileType } from './BackupFileType' export async function DecryptBackupFile( diff --git a/packages/encryption/src/Domain/Service/Encryption/EncryptionProvider.ts b/packages/encryption/src/Domain/Service/Encryption/EncryptionProvider.ts index 32f0c81d6..9cca1a5d5 100644 --- a/packages/encryption/src/Domain/Service/Encryption/EncryptionProvider.ts +++ b/packages/encryption/src/Domain/Service/Encryption/EncryptionProvider.ts @@ -1,12 +1,12 @@ import { ProtocolVersion } from '@standardnotes/common' import { + BackupFile, DecryptedPayloadInterface, EncryptedPayloadInterface, ItemContent, RootKeyInterface, } from '@standardnotes/models' import { ClientDisplayableError } from '@standardnotes/responses' -import { BackupFile } from '../../Backups/BackupFile' import { SNRootKeyParams } from '../../Keys/RootKey/RootKeyParams' import { KeyedDecryptionSplit } from '../../Split/KeyedDecryptionSplit' import { KeyedEncryptionSplit } from '../../Split/KeyedEncryptionSplit' diff --git a/packages/encryption/src/Domain/Service/Encryption/EncryptionService.ts b/packages/encryption/src/Domain/Service/Encryption/EncryptionService.ts index 423a4a153..6df4dc899 100644 --- a/packages/encryption/src/Domain/Service/Encryption/EncryptionService.ts +++ b/packages/encryption/src/Domain/Service/Encryption/EncryptionService.ts @@ -1,6 +1,7 @@ import * as Common from '@standardnotes/common' import * as Models from '@standardnotes/models' import { + BackupFile, CreateDecryptedBackupFileContextPayload, CreateEncryptedBackupFileContextPayload, EncryptedPayload, @@ -15,7 +16,6 @@ import { PureCryptoInterface } from '@standardnotes/sncrypto-common' import * as Utils from '@standardnotes/utils' import { isNotUndefined } from '@standardnotes/utils' import { V001Algorithm, V002Algorithm } from '../../Algorithm' -import { BackupFile } from '../../Backups/BackupFile' import { DecryptBackupFile } from '../../Backups/BackupFileDecryptor' import { CreateAnyKeyParams } from '../../Keys/RootKey/KeyParamsFunctions' import { SNRootKey } from '../../Keys/RootKey/RootKey' diff --git a/packages/encryption/src/Domain/index.ts b/packages/encryption/src/Domain/index.ts index d6e087691..93adda627 100644 --- a/packages/encryption/src/Domain/index.ts +++ b/packages/encryption/src/Domain/index.ts @@ -1,5 +1,4 @@ export * from './Algorithm' -export * from './Backups/BackupFile' export * from './Backups/BackupFileDecryptor' export * from './Backups/BackupFileType' export * from './Keys/ItemsKey/ItemsKey' diff --git a/packages/models/src/Domain/Abstract/Component/ActionObserver.ts b/packages/models/src/Domain/Abstract/Component/ActionObserver.ts new file mode 100644 index 000000000..4627cc770 --- /dev/null +++ b/packages/models/src/Domain/Abstract/Component/ActionObserver.ts @@ -0,0 +1,4 @@ +import { ComponentAction } from '@standardnotes/features' +import { MessageData } from './MessageData' + +export type ActionObserver = (action: ComponentAction, messageData: MessageData) => void diff --git a/packages/models/src/Domain/Abstract/Component/ComponentEventObserver.ts b/packages/models/src/Domain/Abstract/Component/ComponentEventObserver.ts new file mode 100644 index 000000000..4eef6f3a3 --- /dev/null +++ b/packages/models/src/Domain/Abstract/Component/ComponentEventObserver.ts @@ -0,0 +1,3 @@ +import { ComponentViewerEvent } from './ComponentViewerEvent' + +export type ComponentEventObserver = (event: ComponentViewerEvent) => void diff --git a/packages/models/src/Domain/Abstract/Component/ComponentMessage.ts b/packages/models/src/Domain/Abstract/Component/ComponentMessage.ts new file mode 100644 index 000000000..fb818071d --- /dev/null +++ b/packages/models/src/Domain/Abstract/Component/ComponentMessage.ts @@ -0,0 +1,9 @@ +import { ComponentAction } from '@standardnotes/features' +import { MessageData } from './MessageData' + +export type ComponentMessage = { + action: ComponentAction + sessionKey?: string + componentData?: Record + data: MessageData +} diff --git a/packages/models/src/Domain/Abstract/Component/ComponentViewerEvent.ts b/packages/models/src/Domain/Abstract/Component/ComponentViewerEvent.ts new file mode 100644 index 000000000..b4ec5529c --- /dev/null +++ b/packages/models/src/Domain/Abstract/Component/ComponentViewerEvent.ts @@ -0,0 +1,3 @@ +export enum ComponentViewerEvent { + FeatureStatusUpdated = 'FeatureStatusUpdated', +} diff --git a/packages/models/src/Domain/Abstract/Component/IncomingComponentItemPayload.ts b/packages/models/src/Domain/Abstract/Component/IncomingComponentItemPayload.ts new file mode 100644 index 000000000..ec57a94e0 --- /dev/null +++ b/packages/models/src/Domain/Abstract/Component/IncomingComponentItemPayload.ts @@ -0,0 +1,5 @@ +import { DecryptedTransferPayload } from '../TransferPayload/Interfaces/DecryptedTransferPayload' + +export type IncomingComponentItemPayload = DecryptedTransferPayload & { + clientData: Record +} diff --git a/packages/models/src/Domain/Abstract/Component/KeyboardModifier.ts b/packages/models/src/Domain/Abstract/Component/KeyboardModifier.ts new file mode 100644 index 000000000..3160b4b6e --- /dev/null +++ b/packages/models/src/Domain/Abstract/Component/KeyboardModifier.ts @@ -0,0 +1,5 @@ +export enum KeyboardModifier { + Shift = 'Shift', + Ctrl = 'Control', + Meta = 'Meta', +} diff --git a/packages/models/src/Domain/Abstract/Component/MessageData.ts b/packages/models/src/Domain/Abstract/Component/MessageData.ts new file mode 100644 index 000000000..e18ef5782 --- /dev/null +++ b/packages/models/src/Domain/Abstract/Component/MessageData.ts @@ -0,0 +1,31 @@ +import { ContentType, Uuid } from '@standardnotes/common' +import { ComponentPermission } from '@standardnotes/features' + +import { IncomingComponentItemPayload } from './IncomingComponentItemPayload' +import { KeyboardModifier } from './KeyboardModifier' + +export type MessageData = Partial<{ + /** Related to the stream-item-context action */ + item?: IncomingComponentItemPayload + /** Related to the stream-items action */ + content_types?: ContentType[] + items?: IncomingComponentItemPayload[] + /** Related to the request-permission action */ + permissions?: ComponentPermission[] + /** Related to the component-registered action */ + componentData?: Record + uuid?: Uuid + environment?: string + platform?: string + activeThemeUrls?: string[] + /** Related to set-size action */ + width?: string | number + height?: string | number + type?: string + /** Related to themes action */ + themes?: string[] + /** Related to clear-selection action */ + content_type?: ContentType + /** Related to key-pressed action */ + keyboardModifier?: KeyboardModifier +}> diff --git a/packages/models/src/Domain/Abstract/Component/PermissionDialog.ts b/packages/models/src/Domain/Abstract/Component/PermissionDialog.ts new file mode 100644 index 000000000..e9bedea0e --- /dev/null +++ b/packages/models/src/Domain/Abstract/Component/PermissionDialog.ts @@ -0,0 +1,10 @@ +import { ComponentPermission } from '@standardnotes/features' +import { SNComponent } from '../../Syncable/Component' + +export type PermissionDialog = { + component: SNComponent + permissions: ComponentPermission[] + permissionsString: string + actionBlock: (approved: boolean) => void + callback: (approved: boolean) => void +} diff --git a/packages/models/src/Domain/Abstract/Contextual/BackupFile.ts b/packages/models/src/Domain/Abstract/Contextual/BackupFile.ts index 87b4bc6be..bcf7110dd 100644 --- a/packages/models/src/Domain/Abstract/Contextual/BackupFile.ts +++ b/packages/models/src/Domain/Abstract/Contextual/BackupFile.ts @@ -1,60 +1,10 @@ -import { Uuid } from '@standardnotes/common' -import { ContextPayload } from './ContextPayload' -import { ItemContent } from '../Content/ItemContent' -import { DecryptedTransferPayload, EncryptedTransferPayload } from '../TransferPayload' +import { AnyKeyParamsContent, ProtocolVersion } from '@standardnotes/common' +import { BackupFileDecryptedContextualPayload } from './BackupFileDecryptedContextualPayload' +import { BackupFileEncryptedContextualPayload } from './BackupFileEncryptedContextualPayload' -export interface BackupFileEncryptedContextualPayload extends ContextPayload { - auth_hash?: string - content: string - created_at_timestamp: number - created_at: Date - duplicate_of?: Uuid - enc_item_key: string - items_key_id: string | undefined - updated_at: Date - updated_at_timestamp: number -} - -export interface BackupFileDecryptedContextualPayload extends ContextPayload { - content: C - created_at_timestamp: number - created_at: Date - duplicate_of?: Uuid - updated_at: Date - updated_at_timestamp: number -} - -export function CreateEncryptedBackupFileContextPayload( - fromPayload: EncryptedTransferPayload, -): BackupFileEncryptedContextualPayload { - return { - auth_hash: fromPayload.auth_hash, - content_type: fromPayload.content_type, - content: fromPayload.content, - created_at_timestamp: fromPayload.created_at_timestamp, - created_at: fromPayload.created_at, - deleted: false, - duplicate_of: fromPayload.duplicate_of, - enc_item_key: fromPayload.enc_item_key, - items_key_id: fromPayload.items_key_id, - updated_at_timestamp: fromPayload.updated_at_timestamp, - updated_at: fromPayload.updated_at, - uuid: fromPayload.uuid, - } -} - -export function CreateDecryptedBackupFileContextPayload( - fromPayload: DecryptedTransferPayload, -): BackupFileDecryptedContextualPayload { - return { - content_type: fromPayload.content_type, - content: fromPayload.content, - created_at_timestamp: fromPayload.created_at_timestamp, - created_at: fromPayload.created_at, - deleted: false, - duplicate_of: fromPayload.duplicate_of, - updated_at_timestamp: fromPayload.updated_at_timestamp, - updated_at: fromPayload.updated_at, - uuid: fromPayload.uuid, - } +export type BackupFile = { + version?: ProtocolVersion + keyParams?: AnyKeyParamsContent + auth_params?: AnyKeyParamsContent + items: (BackupFileDecryptedContextualPayload | BackupFileEncryptedContextualPayload)[] } diff --git a/packages/models/src/Domain/Abstract/Contextual/BackupFileDecryptedContextualPayload.ts b/packages/models/src/Domain/Abstract/Contextual/BackupFileDecryptedContextualPayload.ts new file mode 100644 index 000000000..9de4eadde --- /dev/null +++ b/packages/models/src/Domain/Abstract/Contextual/BackupFileDecryptedContextualPayload.ts @@ -0,0 +1,12 @@ +import { Uuid } from '@standardnotes/common' +import { ItemContent } from '../Content/ItemContent' +import { ContextPayload } from './ContextPayload' + +export interface BackupFileDecryptedContextualPayload extends ContextPayload { + content: C + created_at_timestamp: number + created_at: Date + duplicate_of?: Uuid + updated_at: Date + updated_at_timestamp: number +} diff --git a/packages/models/src/Domain/Abstract/Contextual/BackupFileEncryptedContextualPayload.ts b/packages/models/src/Domain/Abstract/Contextual/BackupFileEncryptedContextualPayload.ts new file mode 100644 index 000000000..28ea876f2 --- /dev/null +++ b/packages/models/src/Domain/Abstract/Contextual/BackupFileEncryptedContextualPayload.ts @@ -0,0 +1,14 @@ +import { Uuid } from '@standardnotes/common' +import { ContextPayload } from './ContextPayload' + +export interface BackupFileEncryptedContextualPayload extends ContextPayload { + auth_hash?: string + content: string + created_at_timestamp: number + created_at: Date + duplicate_of?: Uuid + enc_item_key: string + items_key_id: string | undefined + updated_at: Date + updated_at_timestamp: number +} diff --git a/packages/models/src/Domain/Abstract/Contextual/Functions.ts b/packages/models/src/Domain/Abstract/Contextual/Functions.ts new file mode 100644 index 000000000..3fd55da51 --- /dev/null +++ b/packages/models/src/Domain/Abstract/Contextual/Functions.ts @@ -0,0 +1,39 @@ +import { DecryptedTransferPayload, EncryptedTransferPayload } from '../TransferPayload' + +import { BackupFileDecryptedContextualPayload } from './BackupFileDecryptedContextualPayload' +import { BackupFileEncryptedContextualPayload } from './BackupFileEncryptedContextualPayload' + +export function CreateEncryptedBackupFileContextPayload( + fromPayload: EncryptedTransferPayload, +): BackupFileEncryptedContextualPayload { + return { + auth_hash: fromPayload.auth_hash, + content_type: fromPayload.content_type, + content: fromPayload.content, + created_at_timestamp: fromPayload.created_at_timestamp, + created_at: fromPayload.created_at, + deleted: false, + duplicate_of: fromPayload.duplicate_of, + enc_item_key: fromPayload.enc_item_key, + items_key_id: fromPayload.items_key_id, + updated_at_timestamp: fromPayload.updated_at_timestamp, + updated_at: fromPayload.updated_at, + uuid: fromPayload.uuid, + } +} + +export function CreateDecryptedBackupFileContextPayload( + fromPayload: DecryptedTransferPayload, +): BackupFileDecryptedContextualPayload { + return { + content_type: fromPayload.content_type, + content: fromPayload.content, + created_at_timestamp: fromPayload.created_at_timestamp, + created_at: fromPayload.created_at, + deleted: false, + duplicate_of: fromPayload.duplicate_of, + updated_at_timestamp: fromPayload.updated_at_timestamp, + updated_at: fromPayload.updated_at, + uuid: fromPayload.uuid, + } +} diff --git a/packages/models/src/Domain/Abstract/Contextual/index.ts b/packages/models/src/Domain/Abstract/Contextual/index.ts deleted file mode 100644 index b6a0ab3e6..000000000 --- a/packages/models/src/Domain/Abstract/Contextual/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './ComponentCreate' -export * from './ComponentRetrieved' -export * from './BackupFile' -export * from './LocalStorage' -export * from './OfflineSyncPush' -export * from './OfflineSyncSaved' -export * from './ServerSyncPush' -export * from './SessionHistory' -export * from './ServerSyncSaved' -export * from './FilteredServerItem' diff --git a/packages/models/src/Domain/Abstract/Item/Mutator/TransactionalMutation.ts b/packages/models/src/Domain/Abstract/Item/Mutator/TransactionalMutation.ts new file mode 100644 index 000000000..c484fb0bd --- /dev/null +++ b/packages/models/src/Domain/Abstract/Item/Mutator/TransactionalMutation.ts @@ -0,0 +1,11 @@ +import { Uuid } from '@standardnotes/common' + +import { MutationType } from '../Types/MutationType' + +import { ItemMutator } from './ItemMutator' + +export type TransactionalMutation = { + itemUuid: Uuid + mutate: (mutator: ItemMutator) => void + mutationType?: MutationType +} diff --git a/packages/models/src/Domain/Abstract/Item/Types/ItemStream.ts b/packages/models/src/Domain/Abstract/Item/Types/ItemStream.ts new file mode 100644 index 000000000..730f8263d --- /dev/null +++ b/packages/models/src/Domain/Abstract/Item/Types/ItemStream.ts @@ -0,0 +1,11 @@ +import { PayloadEmitSource } from '../../Payload' +import { DecryptedItemInterface } from '../Interfaces/DecryptedItem' +import { DeletedItemInterface } from '../Interfaces/DeletedItem' +import { EncryptedItemInterface } from '../Interfaces/EncryptedItem' + +export type ItemStream = (data: { + changed: I[] + inserted: I[] + removed: (DeletedItemInterface | EncryptedItemInterface)[] + source: PayloadEmitSource +}) => void diff --git a/packages/models/src/Domain/Abstract/Item/index.ts b/packages/models/src/Domain/Abstract/Item/index.ts index 99509324b..68ceeacf8 100644 --- a/packages/models/src/Domain/Abstract/Item/index.ts +++ b/packages/models/src/Domain/Abstract/Item/index.ts @@ -20,10 +20,10 @@ export * from './Interfaces/TypeCheck' export * from './Mutator/DecryptedItemMutator' export * from './Mutator/DeleteMutator' export * from './Mutator/ItemMutator' -export * from './Types/AppDataField' +export * from './Mutator/TransactionalMutation' export * from './Types/AppDataField' export * from './Types/ConflictStrategy' export * from './Types/DefaultAppDomain' -export * from './Types/DefaultAppDomain' +export * from './Types/ItemStream' export * from './Types/MutationType' export * from './Types/SingletonStrategy' diff --git a/packages/models/src/Domain/index.ts b/packages/models/src/Domain/index.ts index a11b7ce49..1b1f49f76 100644 --- a/packages/models/src/Domain/index.ts +++ b/packages/models/src/Domain/index.ts @@ -1,5 +1,26 @@ +export * from './Abstract/Component/ActionObserver' +export * from './Abstract/Component/ComponentViewerEvent' +export * from './Abstract/Component/ComponentMessage' +export * from './Abstract/Component/ComponentEventObserver' +export * from './Abstract/Component/IncomingComponentItemPayload' +export * from './Abstract/Component/KeyboardModifier' +export * from './Abstract/Component/MessageData' +export * from './Abstract/Component/PermissionDialog' export * from './Abstract/Content/ItemContent' -export * from './Abstract/Contextual' +export * from './Abstract/Contextual/BackupFile' +export * from './Abstract/Contextual/BackupFileDecryptedContextualPayload' +export * from './Abstract/Contextual/BackupFileEncryptedContextualPayload' +export * from './Abstract/Contextual/ComponentCreate' +export * from './Abstract/Contextual/ComponentRetrieved' +export * from './Abstract/Contextual/ContextPayload' +export * from './Abstract/Contextual/FilteredServerItem' +export * from './Abstract/Contextual/Functions' +export * from './Abstract/Contextual/LocalStorage' +export * from './Abstract/Contextual/OfflineSyncPush' +export * from './Abstract/Contextual/OfflineSyncSaved' +export * from './Abstract/Contextual/ServerSyncPush' +export * from './Abstract/Contextual/ServerSyncSaved' +export * from './Abstract/Contextual/SessionHistory' export * from './Abstract/Item' export * from './Abstract/Payload' export * from './Abstract/TransferPayload' diff --git a/packages/services/package.json b/packages/services/package.json index 5521fc055..48eb9ec5b 100644 --- a/packages/services/package.json +++ b/packages/services/package.json @@ -24,8 +24,8 @@ }, "dependencies": { "@standardnotes/auth": "^3.19.4", - "@standardnotes/common": "^1.23.1", - "@standardnotes/models": "workspace:*", + "@standardnotes/common": "^1.30.0", + "@standardnotes/models": "workspace:^", "@standardnotes/responses": "workspace:*", "@standardnotes/security": "^1.2.0", "@standardnotes/utils": "workspace:*", diff --git a/packages/services/src/Domain/Application/AppGroupManagedApplication.ts b/packages/services/src/Domain/Application/AppGroupManagedApplication.ts new file mode 100644 index 000000000..6d3167774 --- /dev/null +++ b/packages/services/src/Domain/Application/AppGroupManagedApplication.ts @@ -0,0 +1,7 @@ +import { ApplicationInterface } from './ApplicationInterface' +import { DeinitCallback } from './DeinitCallback' + +export interface AppGroupManagedApplication extends ApplicationInterface { + onDeinit: DeinitCallback + setOnDeinit(onDeinit: DeinitCallback): void +} diff --git a/packages/services/src/Domain/Application/ApplicationInterface.ts b/packages/services/src/Domain/Application/ApplicationInterface.ts index 6f7875484..848173b30 100644 --- a/packages/services/src/Domain/Application/ApplicationInterface.ts +++ b/packages/services/src/Domain/Application/ApplicationInterface.ts @@ -1,22 +1,44 @@ -import { ApplicationIdentifier } from '@standardnotes/common' +import { ApplicationIdentifier, ContentType } from '@standardnotes/common' +import { BackupFile, DecryptedItemInterface, ItemStream, PrefKey, PrefValue } from '@standardnotes/models' + +import { ComponentManagerInterface } from '../Component/ComponentManagerInterface' +import { ApplicationEvent } from '../Event/ApplicationEvent' +import { ApplicationEventCallback } from '../Event/ApplicationEventCallback' +import { FeaturesClientInterface } from '../Feature/FeaturesClientInterface' +import { ItemsClientInterface } from '../Item/ItemsClientInterface' +import { MutatorClientInterface } from '../Mutator/MutatorClientInterface' +import { StorageValueModes } from '../Storage/StorageTypes' -import { DeinitCallback } from './DeinitCallback' import { DeinitMode } from './DeinitMode' import { DeinitSource } from './DeinitSource' import { UserClientInterface } from './UserClientInterface' export interface ApplicationInterface { deinit(mode: DeinitMode, source: DeinitSource): void - getDeinitMode(): DeinitMode - + isStarted(): boolean + isLaunched(): boolean + addEventObserver(callback: ApplicationEventCallback, singleEvent?: ApplicationEvent): () => void + hasProtectionSources(): boolean + createEncryptedBackupFileForAutomatedDesktopBackups(): Promise + createDecryptedBackupFile(): Promise + hasPasscode(): boolean + lock(): Promise + setValue(key: string, value: unknown, mode?: StorageValueModes): void + getValue(key: string, mode?: StorageValueModes): unknown + removeValue(key: string, mode?: StorageValueModes): Promise + isLocked(): Promise + getPreference(key: K): PrefValue[K] | undefined + getPreference(key: K, defaultValue: PrefValue[K]): PrefValue[K] + getPreference(key: K, defaultValue?: PrefValue[K]): PrefValue[K] | undefined + streamItems( + contentType: ContentType | ContentType[], + stream: ItemStream, + ): () => void + get features(): FeaturesClientInterface + get componentManager(): ComponentManagerInterface + get items(): ItemsClientInterface + get mutator(): MutatorClientInterface get user(): UserClientInterface - readonly identifier: ApplicationIdentifier } - -export interface AppGroupManagedApplication extends ApplicationInterface { - onDeinit: DeinitCallback - - setOnDeinit(onDeinit: DeinitCallback): void -} diff --git a/packages/services/src/Domain/Application/DeinitCallback.ts b/packages/services/src/Domain/Application/DeinitCallback.ts index b7a72abc0..82810771e 100644 --- a/packages/services/src/Domain/Application/DeinitCallback.ts +++ b/packages/services/src/Domain/Application/DeinitCallback.ts @@ -1,5 +1,5 @@ import { DeinitSource } from './DeinitSource' import { DeinitMode } from './DeinitMode' -import { AppGroupManagedApplication } from './ApplicationInterface' +import { AppGroupManagedApplication } from './AppGroupManagedApplication' export type DeinitCallback = (application: AppGroupManagedApplication, mode: DeinitMode, source: DeinitSource) => void diff --git a/packages/services/src/Domain/Application/WebApplicationInterface.ts b/packages/services/src/Domain/Application/WebApplicationInterface.ts new file mode 100644 index 000000000..7d2512a72 --- /dev/null +++ b/packages/services/src/Domain/Application/WebApplicationInterface.ts @@ -0,0 +1,8 @@ +import { DesktopManagerInterface } from '../Device/DesktopManagerInterface' +import { WebAppEvent } from '../Event/WebAppEvent' +import { ApplicationInterface } from './ApplicationInterface' + +export interface WebApplicationInterface extends ApplicationInterface { + notifyWebEvent(event: WebAppEvent, data?: unknown): void + getDesktopService(): DesktopManagerInterface | undefined +} diff --git a/packages/services/src/Domain/Component/ComponentManagerInterface.ts b/packages/services/src/Domain/Component/ComponentManagerInterface.ts new file mode 100644 index 000000000..cc6e91b15 --- /dev/null +++ b/packages/services/src/Domain/Component/ComponentManagerInterface.ts @@ -0,0 +1,23 @@ +import { Uuid } from '@standardnotes/common' +import { ComponentArea } from '@standardnotes/features' +import { ActionObserver, PermissionDialog, SNComponent, SNNote } from '@standardnotes/models' + +import { DesktopManagerInterface } from '../Device/DesktopManagerInterface' +import { ComponentViewerInterface } from './ComponentViewerInterface' + +export interface ComponentManagerInterface { + urlForComponent(component: SNComponent): string | undefined + setDesktopManager(desktopManager: DesktopManagerInterface): void + componentsForArea(area: ComponentArea): SNComponent[] + editorForNote(note: SNNote): SNComponent | undefined + doesEditorChangeRequireAlert(from: SNComponent | undefined, to: SNComponent | undefined): boolean + showEditorChangeAlert(): Promise + destroyComponentViewer(viewer: ComponentViewerInterface): void + createComponentViewer( + component: SNComponent, + contextItem?: Uuid, + actionObserver?: ActionObserver, + urlOverride?: string, + ): ComponentViewerInterface + presentPermissionsDialog(_dialog: PermissionDialog): void +} diff --git a/packages/services/src/Domain/Component/ComponentViewerError.ts b/packages/services/src/Domain/Component/ComponentViewerError.ts new file mode 100644 index 000000000..43a03fb61 --- /dev/null +++ b/packages/services/src/Domain/Component/ComponentViewerError.ts @@ -0,0 +1,4 @@ +export enum ComponentViewerError { + OfflineRestricted = 'OfflineRestricted', + MissingUrl = 'MissingUrl', +} diff --git a/packages/services/src/Domain/Component/ComponentViewerInterface.ts b/packages/services/src/Domain/Component/ComponentViewerInterface.ts new file mode 100644 index 000000000..acaee599e --- /dev/null +++ b/packages/services/src/Domain/Component/ComponentViewerInterface.ts @@ -0,0 +1,29 @@ +import { + ActionObserver, + ComponentEventObserver, + ComponentMessage, + DecryptedItemInterface, + SNComponent, +} from '@standardnotes/models' +import { FeatureStatus } from '../Feature/FeatureStatus' +import { ComponentViewerError } from './ComponentViewerError' + +export interface ComponentViewerInterface { + readonly component: SNComponent + readonly url?: string + identifier: string + lockReadonly: boolean + sessionKey?: string + overrideContextItem?: DecryptedItemInterface + get componentUuid(): string + destroy(): void + setReadonly(readonly: boolean): void + getFeatureStatus(): FeatureStatus + shouldRender(): boolean + getError(): ComponentViewerError | undefined + setWindow(window: Window): void + addEventObserver(observer: ComponentEventObserver): () => void + addActionObserver(observer: ActionObserver): () => void + postActiveThemes(): void + handleMessage(message: ComponentMessage): void +} diff --git a/packages/services/src/Domain/Device/DesktopManagerInterface.ts b/packages/services/src/Domain/Device/DesktopManagerInterface.ts new file mode 100644 index 000000000..aa3c81ad8 --- /dev/null +++ b/packages/services/src/Domain/Device/DesktopManagerInterface.ts @@ -0,0 +1,7 @@ +import { SNComponent } from '@standardnotes/models' + +export interface DesktopManagerInterface { + syncComponentsInstallation(components: SNComponent[]): void + registerUpdateObserver(callback: (component: SNComponent) => void): () => void + getExtServerHost(): string +} diff --git a/packages/services/src/Domain/Event/ApplicationEvent.ts b/packages/services/src/Domain/Event/ApplicationEvent.ts new file mode 100644 index 000000000..0c814fe21 --- /dev/null +++ b/packages/services/src/Domain/Event/ApplicationEvent.ts @@ -0,0 +1,65 @@ +export enum ApplicationEvent { + SignedIn = 2, + SignedOut = 3, + + /** When a full, potentially multi-page sync completes */ + CompletedFullSync = 5, + + FailedSync = 6, + HighLatencySync = 7, + EnteredOutOfSync = 8, + ExitedOutOfSync = 9, + + /** + * The application has finished it `prepareForLaunch` state and is now ready for unlock + * Called when the application has initialized and is ready for launch, but before + * the application has been unlocked, if applicable. Use this to do pre-launch + * configuration, but do not attempt to access user data like notes or tags. + */ + Started = 10, + + /** + * The applicaiton is fully unlocked and ready for i/o + * Called when the application has been fully decrypted and unlocked. Use this to + * to begin streaming data like notes and tags. + */ + Launched = 11, + LocalDataLoaded = 12, + + /** + * When the root key or root key wrapper changes. Includes events like account state + * changes (registering, signing in, changing pw, logging out) and passcode state + * changes (adding, removing, changing). + */ + KeyStatusChanged = 13, + + MajorDataChange = 14, + CompletedRestart = 15, + LocalDataIncrementalLoad = 16, + SyncStatusChanged = 17, + WillSync = 18, + InvalidSyncSession = 19, + LocalDatabaseReadError = 20, + LocalDatabaseWriteError = 21, + + /** When a single roundtrip completes with sync, in a potentially multi-page sync request. + * If just a single roundtrip, this event will be triggered, along with CompletedFullSync */ + CompletedIncrementalSync = 22, + + /** + * The application has loaded all pending migrations (but not run any, except for the base one), + * and consumers may now call `hasPendingMigrations` + */ + MigrationsLoaded = 23, + + /** When StorageService is ready to start servicing read/write requests */ + StorageReady = 24, + + PreferencesChanged = 25, + UnprotectedSessionBegan = 26, + UserRolesChanged = 27, + FeaturesUpdated = 28, + UnprotectedSessionExpired = 29, + /** Called when the app first launches and after first sync request made after sign in */ + CompletedInitialSync = 30, +} diff --git a/packages/services/src/Domain/Event/ApplicationEventCallback.ts b/packages/services/src/Domain/Event/ApplicationEventCallback.ts new file mode 100644 index 000000000..eba7e5fdf --- /dev/null +++ b/packages/services/src/Domain/Event/ApplicationEventCallback.ts @@ -0,0 +1,3 @@ +import { ApplicationEvent } from './ApplicationEvent' + +export type ApplicationEventCallback = (event: ApplicationEvent, data?: unknown) => Promise diff --git a/packages/web/src/javascripts/Application/WebAppEvent.ts b/packages/services/src/Domain/Event/WebAppEvent.ts similarity index 100% rename from packages/web/src/javascripts/Application/WebAppEvent.ts rename to packages/services/src/Domain/Event/WebAppEvent.ts diff --git a/packages/services/src/Domain/Feature/FeatureStatus.ts b/packages/services/src/Domain/Feature/FeatureStatus.ts new file mode 100644 index 000000000..5b276d5d0 --- /dev/null +++ b/packages/services/src/Domain/Feature/FeatureStatus.ts @@ -0,0 +1,6 @@ +export enum FeatureStatus { + NoUserSubscription = 'NoUserSubscription', + NotInCurrentPlan = 'NotInCurrentPlan', + InCurrentPlanButExpired = 'InCurrentPlanButExpired', + Entitled = 'Entitled', +} diff --git a/packages/snjs/lib/Services/Features/ClientInterface.ts b/packages/services/src/Domain/Feature/FeaturesClientInterface.ts similarity index 89% rename from packages/snjs/lib/Services/Features/ClientInterface.ts rename to packages/services/src/Domain/Feature/FeaturesClientInterface.ts index 82f223da0..39ddd8bdc 100644 --- a/packages/snjs/lib/Services/Features/ClientInterface.ts +++ b/packages/services/src/Domain/Feature/FeaturesClientInterface.ts @@ -1,8 +1,10 @@ -import { FeatureStatus, SetOfflineFeaturesFunctionResponse } from './Types' import { FeatureDescription, FeatureIdentifier } from '@standardnotes/features' import { SNComponent } from '@standardnotes/models' import { RoleName } from '@standardnotes/common' +import { FeatureStatus } from './FeatureStatus' +import { SetOfflineFeaturesFunctionResponse } from './SetOfflineFeaturesFunctionResponse' + export interface FeaturesClientInterface { downloadExternalFeature(urlOrCode: string): Promise diff --git a/packages/services/src/Domain/Feature/FeaturesEvent.ts b/packages/services/src/Domain/Feature/FeaturesEvent.ts new file mode 100644 index 000000000..75595699a --- /dev/null +++ b/packages/services/src/Domain/Feature/FeaturesEvent.ts @@ -0,0 +1,4 @@ +export enum FeaturesEvent { + UserRolesChanged = 'UserRolesChanged', + FeaturesUpdated = 'FeaturesUpdated', +} diff --git a/packages/services/src/Domain/Feature/OfflineSubscriptionEntitlements.ts b/packages/services/src/Domain/Feature/OfflineSubscriptionEntitlements.ts new file mode 100644 index 000000000..a2ce448e1 --- /dev/null +++ b/packages/services/src/Domain/Feature/OfflineSubscriptionEntitlements.ts @@ -0,0 +1,4 @@ +export type OfflineSubscriptionEntitlements = { + featuresUrl: string + extensionKey: string +} diff --git a/packages/services/src/Domain/Feature/SetOfflineFeaturesFunctionResponse.ts b/packages/services/src/Domain/Feature/SetOfflineFeaturesFunctionResponse.ts new file mode 100644 index 000000000..1dab8a477 --- /dev/null +++ b/packages/services/src/Domain/Feature/SetOfflineFeaturesFunctionResponse.ts @@ -0,0 +1,3 @@ +import { ClientDisplayableError } from '@standardnotes/responses' + +export type SetOfflineFeaturesFunctionResponse = ClientDisplayableError | undefined diff --git a/packages/snjs/lib/Services/Items/ItemsClientInterface.ts b/packages/services/src/Domain/Item/ItemsClientInterface.ts similarity index 92% rename from packages/snjs/lib/Services/Items/ItemsClientInterface.ts rename to packages/services/src/Domain/Item/ItemsClientInterface.ts index b6324f593..c137d6519 100644 --- a/packages/snjs/lib/Services/Items/ItemsClientInterface.ts +++ b/packages/services/src/Domain/Item/ItemsClientInterface.ts @@ -1,5 +1,4 @@ -import { SNItemsKey } from '@standardnotes/encryption' -import { ContentType } from '@standardnotes/common' +import { ContentType, Uuid } from '@standardnotes/common' import { SNNote, FileItem, @@ -14,8 +13,8 @@ import { SNComponent, SNTheme, DisplayOptions, + ItemsKeyInterface, } from '@standardnotes/models' -import { UuidString } from '@Lib/Types' export interface ItemsClientInterface { get invalidItems(): EncryptedItemInterface[] @@ -43,7 +42,7 @@ export interface ItemsClientInterface { getDisplayableTags(): SNTag[] - getDisplayableItemsKeys(): SNItemsKey[] + getDisplayableItemsKeys(): ItemsKeyInterface[] getDisplayableFiles(): FileItem[] @@ -116,14 +115,14 @@ export interface ItemsClientInterface { /** * Finds an item by UUID. */ - findItem(uuid: UuidString): T | undefined + findItem(uuid: Uuid): T | undefined /** * Finds an item by predicate. */ - findItems(uuids: UuidString[]): T[] + findItems(uuids: Uuid[]): T[] - findSureItem(uuid: UuidString): T + findSureItem(uuid: Uuid): T /** * Finds an item by predicate. diff --git a/packages/services/src/Domain/Mutator/MutatorClientInterface.ts b/packages/services/src/Domain/Mutator/MutatorClientInterface.ts new file mode 100644 index 000000000..0a9ebb5be --- /dev/null +++ b/packages/services/src/Domain/Mutator/MutatorClientInterface.ts @@ -0,0 +1,184 @@ +import { ContentType } from '@standardnotes/common' +import { + BackupFile, + DecryptedItemInterface, + DecryptedItemMutator, + EncryptedItemInterface, + FileItem, + ItemContent, + PayloadEmitSource, + SmartView, + SNComponent, + SNNote, + SNTag, + TransactionalMutation, +} from '@standardnotes/models' +import { ClientDisplayableError } from '@standardnotes/responses' + +import { ChallengeReason } from '../Challenge/Types/ChallengeReason' +import { SyncOptions } from '../Sync/SyncOptions' + +export interface MutatorClientInterface { + /** + * Inserts the input item by its payload properties, and marks the item as dirty. + * A sync is not performed after an item is inserted. This must be handled by the caller. + */ + insertItem(item: DecryptedItemInterface): Promise + + /** + * Mutates a pre-existing item, marks it as dirty, and syncs it + */ + changeAndSaveItem( + itemToLookupUuidFor: DecryptedItemInterface, + mutate: (mutator: M) => void, + updateTimestamps?: boolean, + emitSource?: PayloadEmitSource, + syncOptions?: SyncOptions, + ): Promise + + /** + * Mutates pre-existing items, marks them as dirty, and syncs + */ + changeAndSaveItems( + itemsToLookupUuidsFor: DecryptedItemInterface[], + mutate: (mutator: M) => void, + updateTimestamps?: boolean, + emitSource?: PayloadEmitSource, + syncOptions?: SyncOptions, + ): Promise + + /** + * Mutates a pre-existing item and marks it as dirty. Does not sync changes. + */ + changeItem( + itemToLookupUuidFor: DecryptedItemInterface, + mutate: (mutator: M) => void, + updateTimestamps?: boolean, + ): Promise + + /** + * Mutates a pre-existing items and marks them as dirty. Does not sync changes. + */ + changeItems( + itemsToLookupUuidsFor: DecryptedItemInterface[], + mutate: (mutator: M) => void, + updateTimestamps?: boolean, + ): Promise<(DecryptedItemInterface | undefined)[]> + + /** + * Run unique mutations per each item in the array, then only propagate all changes + * once all mutations have been run. This differs from `changeItems` in that changeItems + * runs the same mutation on all items. + */ + runTransactionalMutations( + transactions: TransactionalMutation[], + emitSource?: PayloadEmitSource, + payloadSourceKey?: string, + ): Promise<(DecryptedItemInterface | undefined)[]> + + runTransactionalMutation( + transaction: TransactionalMutation, + emitSource?: PayloadEmitSource, + payloadSourceKey?: string, + ): Promise + + protectItems<_M extends DecryptedItemMutator, I extends DecryptedItemInterface>( + items: I[], + ): Promise + + unprotectItems<_M extends DecryptedItemMutator, I extends DecryptedItemInterface>( + items: I[], + reason: ChallengeReason, + ): Promise + + protectNote(note: SNNote): Promise + + unprotectNote(note: SNNote): Promise + + protectNotes(notes: SNNote[]): Promise + + unprotectNotes(notes: SNNote[]): Promise + + protectFile(file: FileItem): Promise + + unprotectFile(file: FileItem): Promise + + /** + * Takes the values of the input item and emits it onto global state. + */ + mergeItem(item: DecryptedItemInterface, source: PayloadEmitSource): Promise + + /** + * Creates an unmanaged item that can be added later. + */ + createTemplateItem< + C extends ItemContent = ItemContent, + I extends DecryptedItemInterface = DecryptedItemInterface, + >( + contentType: ContentType, + content?: C, + ): I + + /** + * @param isUserModified Whether to change the modified date the user + * sees of the item. + */ + setItemNeedsSync(item: DecryptedItemInterface, isUserModified?: boolean): Promise + + setItemsNeedsSync(items: DecryptedItemInterface[]): Promise<(DecryptedItemInterface | undefined)[]> + + deleteItem(item: DecryptedItemInterface | EncryptedItemInterface): Promise + + deleteItems(items: (DecryptedItemInterface | EncryptedItemInterface)[]): Promise + + emptyTrash(): Promise + + duplicateItem(item: T, additionalContent?: Partial): Promise + + /** + * Migrates any tags containing a '.' character to sa chema-based heirarchy, removing + * the dot from the tag's title. + */ + migrateTagsToFolders(): Promise + + /** + * Establishes a hierarchical relationship between two tags. + */ + setTagParent(parentTag: SNTag, childTag: SNTag): Promise + + /** + * Remove the tag parent. + */ + unsetTagParent(childTag: SNTag): Promise + + findOrCreateTag(title: string): Promise + + /** Creates and returns the tag but does not run sync. Callers must perform sync. */ + createTagOrSmartView(title: string): Promise + + /** + * Activates or deactivates a component, depending on its + * current state, and syncs. + */ + toggleComponent(component: SNComponent): Promise + + toggleTheme(theme: SNComponent): Promise + + /** + * @returns + * .affectedItems: Items that were either created or dirtied by this import + * .errorCount: The number of items that were not imported due to failure to decrypt. + */ + importData( + data: BackupFile, + awaitSync?: boolean, + ): Promise< + | { + affectedItems: DecryptedItemInterface[] + errorCount: number + } + | { + error: ClientDisplayableError + } + > +} diff --git a/packages/services/src/Domain/index.ts b/packages/services/src/Domain/index.ts index 241e7624d..7fe53f1a5 100644 --- a/packages/services/src/Domain/index.ts +++ b/packages/services/src/Domain/index.ts @@ -1,13 +1,19 @@ export * from './Alert/AlertService' export * from './Api/ApiServiceInterface' +export * from './Application/AppGroupManagedApplication' +export * from './Application/ApplicationInterface' export * from './Application/ApplicationStage' export * from './Application/DeinitCallback' export * from './Application/DeinitSource' export * from './Application/DeinitMode' export * from './Application/UserClientInterface' -export * from './Application/ApplicationInterface' +export * from './Application/WebApplicationInterface' export * from './Challenge' +export * from './Component/ComponentManagerInterface' +export * from './Component/ComponentViewerError' +export * from './Component/ComponentViewerInterface' export * from './Device/DesktopDeviceInterface' +export * from './Device/DesktopManagerInterface' export * from './Device/DesktopWebCommunication' export * from './Device/DeviceInterface' export * from './Device/Environments' @@ -16,9 +22,17 @@ export * from './Device/MobileDeviceInterface' export * from './Device/TypeCheck' export * from './Device/WebOrDesktopDeviceInterface' export * from './Diagnostics/ServiceDiagnostics' +export * from './Event/ApplicationEvent' +export * from './Event/ApplicationEventCallback' export * from './Event/EventObserver' export * from './Event/SyncEvent' export * from './Event/SyncEventReceiver' +export * from './Event/WebAppEvent' +export * from './Feature/FeatureStatus' +export * from './Feature/FeaturesClientInterface' +export * from './Feature/FeaturesEvent' +export * from './Feature/OfflineSubscriptionEntitlements' +export * from './Feature/SetOfflineFeaturesFunctionResponse' export * from './Files/FilesApiInterface' export * from './FileSystem/FileSystemApi' export * from './Integrity/IntegrityApiInterface' @@ -32,7 +46,9 @@ export * from './Internal/InternalEventInterface' export * from './Internal/InternalEventPublishStrategy' export * from './Internal/InternalEventType' export * from './Item/ItemManagerInterface' +export * from './Item/ItemsClientInterface' export * from './Item/ItemsServerInterface' +export * from './Mutator/MutatorClientInterface' export * from './Payloads/PayloadManagerInterface' export * from './Preferences/PreferenceServiceInterface' export * from './Service/AbstractService' diff --git a/packages/snjs/lib/Application/Application.ts b/packages/snjs/lib/Application/Application.ts index 5219343a9..1f438f957 100644 --- a/packages/snjs/lib/Application/Application.ts +++ b/packages/snjs/lib/Application/Application.ts @@ -19,9 +19,12 @@ import * as Settings from '@standardnotes/settings' import * as Files from '@standardnotes/files' import { Subscription } from '@standardnotes/security' import { UuidString, ApplicationEventPayload } from '../Types' -import { ApplicationEvent, applicationEventForSyncEvent } from '@Lib/Application/Event' +import { applicationEventForSyncEvent } from '@Lib/Application/Event' import { + ApplicationEvent, + ApplicationEventCallback, ChallengeValidation, + ComponentManagerInterface, DiagnosticInfo, Environment, isDesktopDevice, @@ -36,7 +39,7 @@ import { } from '@standardnotes/services' import { SNLog } from '../Log' import { useBoolean } from '@standardnotes/utils' -import { DecryptedItemInterface, EncryptedItemInterface } from '@standardnotes/models' +import { BackupFile, DecryptedItemInterface, EncryptedItemInterface, ItemStream } from '@standardnotes/models' import { ClientDisplayableError } from '@standardnotes/responses' import { Challenge, ChallengeResponse } from '../Services' import { ApplicationConstructorOptions, FullyResolvedApplicationOptions } from './Options/ApplicationOptions' @@ -49,20 +52,11 @@ type LaunchCallback = { receiveChallenge: (challenge: Challenge) => void } -type ApplicationEventCallback = (event: ApplicationEvent, data?: unknown) => Promise - type ApplicationObserver = { singleEvent?: ApplicationEvent callback: ApplicationEventCallback } -type ItemStream = (data: { - changed: I[] - inserted: I[] - removed: (Models.DeletedItemInterface | Models.EncryptedItemInterface)[] - source: Models.PayloadEmitSource -}) => void - type ObserverRemover = () => void export class SNApplication @@ -97,7 +91,7 @@ export class SNApplication private syncService!: InternalServices.SNSyncService private challengeService!: InternalServices.ChallengeService public singletonManager!: InternalServices.SNSingletonManager - public componentManager!: InternalServices.SNComponentManager + public componentManagerService!: InternalServices.SNComponentManager public protectionService!: InternalServices.SNProtectionService public actionsManager!: InternalServices.SNActionsService public historyManager!: InternalServices.SNHistoryManager @@ -192,11 +186,11 @@ export class SNApplication return this.fileService } - public get features(): InternalServices.FeaturesClientInterface { + public get features(): ExternalServices.FeaturesClientInterface { return this.featuresService } - public get items(): InternalServices.ItemsClientInterface { + public get items(): ExternalServices.ItemsClientInterface { return this.itemManager } @@ -216,7 +210,7 @@ export class SNApplication return this.settingsService } - public get mutator(): InternalServices.MutatorClientInterface { + public get mutator(): ExternalServices.MutatorClientInterface { return this.mutatorService } @@ -232,6 +226,10 @@ export class SNApplication return this.filesBackupService } + public get componentManager(): ComponentManagerInterface { + return this.componentManagerService + } + public computePrivateWorkspaceIdentifier(userphrase: string, name: string): Promise { return Encryption.ComputePrivateWorkspaceIdentifier(this.options.crypto, userphrase, name) } @@ -659,11 +657,11 @@ export class SNApplication return this.listedService.getListedAccountInfo(account, inContextOfItem) } - public async createEncryptedBackupFileForAutomatedDesktopBackups(): Promise { + public async createEncryptedBackupFileForAutomatedDesktopBackups(): Promise { return this.protocolService.createEncryptedBackupFile() } - public async createEncryptedBackupFile(): Promise { + public async createEncryptedBackupFile(): Promise { if (!(await this.protectionService.authorizeBackupCreation())) { return } @@ -671,7 +669,7 @@ export class SNApplication return this.protocolService.createEncryptedBackupFile() } - public async createDecryptedBackupFile(): Promise { + public async createDecryptedBackupFile(): Promise { if (!(await this.protectionService.authorizeBackupCreation())) { return } @@ -1070,7 +1068,7 @@ export class SNApplication ;(this.syncService as unknown) = undefined ;(this.challengeService as unknown) = undefined ;(this.singletonManager as unknown) = undefined - ;(this.componentManager as unknown) = undefined + ;(this.componentManagerService as unknown) = undefined ;(this.protectionService as unknown) = undefined ;(this.actionsManager as unknown) = undefined ;(this.historyManager as unknown) = undefined @@ -1161,11 +1159,11 @@ export class SNApplication this.serviceObservers.push( this.featuresService.addEventObserver((event) => { switch (event) { - case InternalServices.FeaturesEvent.UserRolesChanged: { + case ExternalServices.FeaturesEvent.UserRolesChanged: { void this.notifyEvent(ApplicationEvent.UserRolesChanged) break } - case InternalServices.FeaturesEvent.FeaturesUpdated: { + case ExternalServices.FeaturesEvent.FeaturesUpdated: { void this.notifyEvent(ApplicationEvent.FeaturesUpdated) break } @@ -1268,7 +1266,7 @@ export class SNApplication const MaybeSwappedComponentManager = this.getClass( InternalServices.SNComponentManager, ) - this.componentManager = new MaybeSwappedComponentManager( + this.componentManagerService = new MaybeSwappedComponentManager( this.itemManager, this.syncService, this.featuresService, @@ -1278,7 +1276,7 @@ export class SNApplication this.platform, this.internalEventBus, ) - this.services.push(this.componentManager) + this.services.push(this.componentManagerService) } private createHttpManager() { @@ -1533,7 +1531,7 @@ export class SNApplication this.protocolService, this.payloadManager, this.challengeService, - this.componentManager, + this.componentManagerService, this.historyManager, this.internalEventBus, ) diff --git a/packages/snjs/lib/Application/Event.ts b/packages/snjs/lib/Application/Event.ts index 51ad3da19..91ba03516 100644 --- a/packages/snjs/lib/Application/Event.ts +++ b/packages/snjs/lib/Application/Event.ts @@ -1,72 +1,6 @@ -import { SyncEvent } from '@standardnotes/services' +import { ApplicationEvent, SyncEvent } from '@standardnotes/services' export { SyncEvent } -export enum ApplicationEvent { - SignedIn = 2, - SignedOut = 3, - - /** When a full, potentially multi-page sync completes */ - CompletedFullSync = 5, - - FailedSync = 6, - HighLatencySync = 7, - EnteredOutOfSync = 8, - ExitedOutOfSync = 9, - - /** - * The application has finished it `prepareForLaunch` state and is now ready for unlock - * Called when the application has initialized and is ready for launch, but before - * the application has been unlocked, if applicable. Use this to do pre-launch - * configuration, but do not attempt to access user data like notes or tags. - */ - Started = 10, - - /** - * The applicaiton is fully unlocked and ready for i/o - * Called when the application has been fully decrypted and unlocked. Use this to - * to begin streaming data like notes and tags. - */ - Launched = 11, - LocalDataLoaded = 12, - - /** - * When the root key or root key wrapper changes. Includes events like account state - * changes (registering, signing in, changing pw, logging out) and passcode state - * changes (adding, removing, changing). - */ - KeyStatusChanged = 13, - - MajorDataChange = 14, - CompletedRestart = 15, - LocalDataIncrementalLoad = 16, - SyncStatusChanged = 17, - WillSync = 18, - InvalidSyncSession = 19, - LocalDatabaseReadError = 20, - LocalDatabaseWriteError = 21, - - /** When a single roundtrip completes with sync, in a potentially multi-page sync request. - * If just a single roundtrip, this event will be triggered, along with CompletedFullSync */ - CompletedIncrementalSync = 22, - - /** - * The application has loaded all pending migrations (but not run any, except for the base one), - * and consumers may now call `hasPendingMigrations` - */ - MigrationsLoaded = 23, - - /** When StorageService is ready to start servicing read/write requests */ - StorageReady = 24, - - PreferencesChanged = 25, - UnprotectedSessionBegan = 26, - UserRolesChanged = 27, - FeaturesUpdated = 28, - UnprotectedSessionExpired = 29, - /** Called when the app first launches and after first sync request made after sign in */ - CompletedInitialSync = 30, -} - export function applicationEventForSyncEvent(syncEvent: SyncEvent) { return ( { diff --git a/packages/snjs/lib/Client/ItemGroupController.ts b/packages/snjs/lib/Client/ItemGroupController.ts index c97ee80d7..bf382d6ba 100644 --- a/packages/snjs/lib/Client/ItemGroupController.ts +++ b/packages/snjs/lib/Client/ItemGroupController.ts @@ -1,7 +1,9 @@ -import { ApplicationEvent } from '../Application/Event' import { FileItem, PrefKey, SNNote } from '@standardnotes/models' import { removeFromArray } from '@standardnotes/utils' +import { ApplicationEvent } from '@standardnotes/services' + import { SNApplication } from '../Application/Application' + import { NoteViewController } from './NoteViewController' import { FileViewController } from './FileViewController' import { TemplateNoteViewControllerOptions } from './TemplateNoteViewControllerOptions' diff --git a/packages/snjs/lib/Services/AppService/ApplicationService.ts b/packages/snjs/lib/Services/AppService/ApplicationService.ts index d11dd51db..2127f691a 100644 --- a/packages/snjs/lib/Services/AppService/ApplicationService.ts +++ b/packages/snjs/lib/Services/AppService/ApplicationService.ts @@ -1,11 +1,17 @@ -import { ApplicationEvent } from '@Lib/Application/Event' -import { AbstractService, InternalEventBusInterface } from '@standardnotes/services' -import { SNApplication } from '../../Application/Application' +import { + AbstractService, + ApplicationEvent, + ApplicationInterface, + InternalEventBusInterface, +} from '@standardnotes/services' export class ApplicationService extends AbstractService { private unsubApp!: () => void - constructor(protected application: SNApplication, protected override internalEventBus: InternalEventBusInterface) { + constructor( + protected application: ApplicationInterface, + protected override internalEventBus: InternalEventBusInterface, + ) { super(internalEventBus) this.addAppEventObserverAfterSubclassesFinishConstructing() } diff --git a/packages/snjs/lib/Services/ComponentManager/ComponentManager.spec.ts b/packages/snjs/lib/Services/ComponentManager/ComponentManager.spec.ts index faf597bf4..5b134508d 100644 --- a/packages/snjs/lib/Services/ComponentManager/ComponentManager.spec.ts +++ b/packages/snjs/lib/Services/ComponentManager/ComponentManager.spec.ts @@ -10,10 +10,15 @@ import { FindNativeFeature, FeatureIdentifier, } from '@standardnotes/features' -import { DesktopManagerInterface } from '@Lib/Services/ComponentManager/Types' import { ContentType } from '@standardnotes/common' import { GenericItem, SNComponent } from '@standardnotes/models' -import { InternalEventBusInterface, Environment, Platform, AlertService } from '@standardnotes/services' +import { + DesktopManagerInterface, + InternalEventBusInterface, + Environment, + Platform, + AlertService, +} from '@standardnotes/services' import { ItemManager } from '@Lib/Services/Items/ItemManager' import { SNFeaturesService } from '@Lib/Services/Features/FeaturesService' import { SNComponentManager } from './ComponentManager' @@ -34,7 +39,10 @@ describe('featuresService', () => { // eslint-disable-next-line @typescript-eslint/no-empty-function syncComponentsInstallation() {}, // eslint-disable-next-line @typescript-eslint/no-empty-function - registerUpdateObserver() {}, + registerUpdateObserver(_callback: (component: SNComponent) => void) { + // eslint-disable-next-line @typescript-eslint/no-empty-function + return () => {} + }, getExtServerHost() { return desktopExtHost }, diff --git a/packages/snjs/lib/Services/ComponentManager/ComponentManager.ts b/packages/snjs/lib/Services/ComponentManager/ComponentManager.ts index e95e4d084..39d5229fe 100644 --- a/packages/snjs/lib/Services/ComponentManager/ComponentManager.ts +++ b/packages/snjs/lib/Services/ComponentManager/ComponentManager.ts @@ -3,21 +3,28 @@ import { SNPreferencesService } from '../Preferences/PreferencesService' import { SNFeaturesService } from '@Lib/Services/Features/FeaturesService' import { ContentType, DisplayStringForContentType } from '@standardnotes/common' import { ItemManager } from '@Lib/Services/Items/ItemManager' -import { SNNote, SNTheme, SNComponent, ComponentMutator, PayloadEmitSource } from '@standardnotes/models' +import { + ActionObserver, + SNNote, + SNTheme, + SNComponent, + ComponentMutator, + PayloadEmitSource, + PermissionDialog, +} from '@standardnotes/models' import { SNSyncService } from '@Lib/Services/Sync/SyncService' import find from 'lodash/find' import uniq from 'lodash/uniq' import { ComponentArea, ComponentAction, ComponentPermission, FindNativeFeature } from '@standardnotes/features' import { Copy, filterFromArray, removeFromArray, sleep, assert } from '@standardnotes/utils' import { UuidString } from '@Lib/Types/UuidString' -import { - PermissionDialog, - DesktopManagerInterface, - AllowedBatchContentTypes, -} from '@Lib/Services/ComponentManager/Types' -import { ActionObserver, ComponentViewer } from '@Lib/Services/ComponentManager/ComponentViewer' +import { AllowedBatchContentTypes } from '@Lib/Services/ComponentManager/Types' +import { ComponentViewer } from '@Lib/Services/ComponentManager/ComponentViewer' import { AbstractService, + ComponentManagerInterface, + ComponentViewerInterface, + DesktopManagerInterface, InternalEventBusInterface, Environment, Platform, @@ -42,7 +49,7 @@ export enum ComponentManagerEvent { } export type EventData = { - componentViewer?: ComponentViewer + componentViewer?: ComponentViewerInterface } /** @@ -50,9 +57,12 @@ export type EventData = { * and other components. The component manager primarily deals with iframes, and orchestrates * sending and receiving messages to and from frames via the postMessage API. */ -export class SNComponentManager extends AbstractService { +export class SNComponentManager + extends AbstractService + implements ComponentManagerInterface +{ private desktopManager?: DesktopManagerInterface - private viewers: ComponentViewer[] = [] + private viewers: ComponentViewerInterface[] = [] private removeItemObserver!: () => void private permissionDialogs: PermissionDialog[] = [] @@ -137,7 +147,7 @@ export class SNComponentManager extends AbstractService(uuid) } - findComponentViewer(identifier: string): ComponentViewer | undefined { + findComponentViewer(identifier: string): ComponentViewerInterface | undefined { return this.viewers.find((viewer) => viewer.identifier === identifier) } - componentViewerForSessionKey(key: string): ComponentViewer | undefined { + componentViewerForSessionKey(key: string): ComponentViewerInterface | undefined { return this.viewers.find((viewer) => viewer.sessionKey === key) } diff --git a/packages/snjs/lib/Services/ComponentManager/ComponentViewer.ts b/packages/snjs/lib/Services/ComponentManager/ComponentViewer.ts index 0a7a1ad98..637c296b9 100644 --- a/packages/snjs/lib/Services/ComponentManager/ComponentViewer.ts +++ b/packages/snjs/lib/Services/ComponentManager/ComponentViewer.ts @@ -1,8 +1,19 @@ import { SNPreferencesService } from '../Preferences/PreferencesService' -import { FeatureStatus, FeaturesEvent } from '@Lib/Services/Features' -import { Environment, Platform, AlertService } from '@standardnotes/services' +import { + ComponentViewerInterface, + ComponentViewerError, + Environment, + FeatureStatus, + FeaturesEvent, + Platform, + AlertService, +} from '@standardnotes/services' import { SNFeaturesService } from '@Lib/Services' import { + ActionObserver, + ComponentEventObserver, + ComponentViewerEvent, + ComponentMessage, SNComponent, PrefKey, NoteContent, @@ -21,6 +32,8 @@ import { ComponentDataDomain, PayloadEmitSource, PayloadTimestampDefaults, + IncomingComponentItemPayload, + MessageData, } from '@standardnotes/models' import find from 'lodash/find' import uniq from 'lodash/uniq' @@ -28,12 +41,10 @@ import remove from 'lodash/remove' import { SNSyncService } from '@Lib/Services/Sync/SyncService' import { environmentToString, platformToString } from '@Lib/Application/Platforms' import { - ComponentMessage, OutgoingItemMessagePayload, MessageReply, StreamItemsMessageData, AllowedBatchContentTypes, - IncomingComponentItemPayload, DeleteItemsMessageData, MessageReplyData, } from './Types' @@ -53,7 +64,6 @@ import { sureSearchArray, isNotUndefined, } from '@standardnotes/utils' -import { MessageData } from '..' type RunWithPermissionsCallback = ( componentUuid: UuidString, @@ -76,21 +86,9 @@ const ReadwriteActions = [ ComponentAction.SetComponentData, ] -export type ActionObserver = (action: ComponentAction, messageData: MessageData) => void - -export enum ComponentViewerEvent { - FeatureStatusUpdated = 'FeatureStatusUpdated', -} -type EventObserver = (event: ComponentViewerEvent) => void - -export enum ComponentViewerError { - OfflineRestricted = 'OfflineRestricted', - MissingUrl = 'MissingUrl', -} - type Writeable = { -readonly [P in keyof T]: T[P] } -export class ComponentViewer { +export class ComponentViewer implements ComponentViewerInterface { private streamItems?: ContentType[] private streamContextItemOriginalMessage?: ComponentMessage private streamItemsOriginalMessage?: ComponentMessage @@ -101,7 +99,7 @@ export class ComponentViewer { public overrideContextItem?: DecryptedItemInterface private featureStatus: FeatureStatus private removeFeaturesObserver: () => void - private eventObservers: EventObserver[] = [] + private eventObservers: ComponentEventObserver[] = [] private dealloced = false private window?: Window @@ -189,7 +187,7 @@ export class ComponentViewer { ;(this.removeItemObserver as unknown) = undefined } - public addEventObserver(observer: EventObserver): () => void { + public addEventObserver(observer: ComponentEventObserver): () => void { this.eventObservers.push(observer) const thislessChangeObservers = this.eventObservers diff --git a/packages/snjs/lib/Services/ComponentManager/Types.ts b/packages/snjs/lib/Services/ComponentManager/Types.ts index 5a4858310..c0b5f25fa 100644 --- a/packages/snjs/lib/Services/ComponentManager/Types.ts +++ b/packages/snjs/lib/Services/ComponentManager/Types.ts @@ -1,24 +1,8 @@ -import { - ComponentArea, - ComponentAction, - ComponentPermission, - FeatureIdentifier, - LegacyFileSafeIdentifier, -} from '@standardnotes/features' -import { ItemContent, SNComponent, DecryptedTransferPayload } from '@standardnotes/models' +import { ComponentArea, ComponentAction, FeatureIdentifier, LegacyFileSafeIdentifier } from '@standardnotes/features' +import { ComponentMessage, ItemContent, MessageData } from '@standardnotes/models' import { UuidString } from '@Lib/Types/UuidString' import { ContentType } from '@standardnotes/common' -export interface DesktopManagerInterface { - syncComponentsInstallation(components: SNComponent[]): void - registerUpdateObserver(callback: (component: SNComponent) => void): void - getExtServerHost(): string -} - -export type IncomingComponentItemPayload = DecryptedTransferPayload & { - clientData: Record -} - export type OutgoingItemMessagePayload = { uuid: string content_type: ContentType @@ -63,46 +47,6 @@ export type StreamObserver = { contentTypes?: ContentType[] } -export type PermissionDialog = { - component: SNComponent - permissions: ComponentPermission[] - permissionsString: string - actionBlock: (approved: boolean) => void - callback: (approved: boolean) => void -} - -export enum KeyboardModifier { - Shift = 'Shift', - Ctrl = 'Control', - Meta = 'Meta', -} - -export type MessageData = Partial<{ - /** Related to the stream-item-context action */ - item?: IncomingComponentItemPayload - /** Related to the stream-items action */ - content_types?: ContentType[] - items?: IncomingComponentItemPayload[] - /** Related to the request-permission action */ - permissions?: ComponentPermission[] - /** Related to the component-registered action */ - componentData?: Record - uuid?: UuidString - environment?: string - platform?: string - activeThemeUrls?: string[] - /** Related to set-size action */ - width?: string | number - height?: string | number - type?: string - /** Related to themes action */ - themes?: string[] - /** Related to clear-selection action */ - content_type?: ContentType - /** Related to key-pressed action */ - keyboardModifier?: KeyboardModifier -}> - export type MessageReplyData = { approved?: boolean deleted?: boolean @@ -120,13 +64,6 @@ export type DeleteItemsMessageData = MessageData & { items: OutgoingItemMessagePayload[] } -export type ComponentMessage = { - action: ComponentAction - sessionKey?: string - componentData?: Record - data: MessageData -} - export type MessageReply = { action: ComponentAction original: ComponentMessage diff --git a/packages/snjs/lib/Services/Features/FeaturesService.spec.ts b/packages/snjs/lib/Services/Features/FeaturesService.spec.ts index 0d6487b68..844700b0d 100644 --- a/packages/snjs/lib/Services/Features/FeaturesService.spec.ts +++ b/packages/snjs/lib/Services/Features/FeaturesService.spec.ts @@ -10,14 +10,14 @@ import { DiskStorageService, StorageKey, } from '@Lib/index' -import { FeatureStatus, SNFeaturesService } from '@Lib/Services/Features' +import { SNFeaturesService } from '@Lib/Services/Features' import { ContentType, RoleName } from '@standardnotes/common' import { FeatureDescription, FeatureIdentifier, GetFeatures } from '@standardnotes/features' import { SNWebSocketsService } from '../Api/WebsocketsService' import { SNSettingsService } from '../Settings' import { PureCryptoInterface } from '@standardnotes/sncrypto-common' import { convertTimestampToMilliseconds } from '@standardnotes/utils' -import { InternalEventBusInterface } from '@standardnotes/services' +import { FeatureStatus, InternalEventBusInterface } from '@standardnotes/services' describe('featuresService', () => { let storageService: DiskStorageService diff --git a/packages/snjs/lib/Services/Features/FeaturesService.ts b/packages/snjs/lib/Services/Features/FeaturesService.ts index 52e325567..0851538d7 100644 --- a/packages/snjs/lib/Services/Features/FeaturesService.ts +++ b/packages/snjs/lib/Services/Features/FeaturesService.ts @@ -10,7 +10,6 @@ import { } from '@standardnotes/utils' import { ClientDisplayableError, UserFeaturesResponse } from '@standardnotes/responses' import { ContentType, RoleName } from '@standardnotes/common' -import { FeaturesClientInterface } from './ClientInterface' import { FillItemContent, PayloadEmitSource } from '@standardnotes/models' import { ItemManager } from '../Items/ItemManager' import { LEGACY_PROD_EXT_ORIGIN, PROD_OFFLINE_FEATURES_URL } from '../../Hosts' @@ -27,20 +26,30 @@ import { UuidString } from '@Lib/Types/UuidString' import * as FeaturesImports from '@standardnotes/features' import * as Messages from '@Lib/Services/Api/Messages' import * as Models from '@standardnotes/models' -import * as Services from '@standardnotes/services' import { + AbstractService, + AlertService, + ApiServiceEvent, + ApplicationStage, + ButtonType, + DiagnosticInfo, + FeaturesClientInterface, FeaturesEvent, FeatureStatus, + InternalEventBusInterface, + InternalEventHandlerInterface, + InternalEventInterface, + MetaReceivedData, OfflineSubscriptionEntitlements, SetOfflineFeaturesFunctionResponse, -} from './Types' -import { DiagnosticInfo } from '@standardnotes/services' + StorageKey, +} from '@standardnotes/services' type GetOfflineSubscriptionDetailsResponse = OfflineSubscriptionEntitlements | ClientDisplayableError export class SNFeaturesService - extends Services.AbstractService - implements FeaturesClientInterface, Services.InternalEventHandlerInterface + extends AbstractService + implements FeaturesClientInterface, InternalEventHandlerInterface { private deinited = false private roles: RoleName[] = [] @@ -60,10 +69,10 @@ export class SNFeaturesService private settingsService: SNSettingsService, private userService: UserService, private syncService: SNSyncService, - private alertService: Services.AlertService, + private alertService: AlertService, private sessionManager: SNSessionManager, private crypto: PureCryptoInterface, - protected override internalEventBus: Services.InternalEventBusInterface, + protected override internalEventBus: InternalEventBusInterface, ) { super(internalEventBus) @@ -109,8 +118,8 @@ export class SNFeaturesService }) } - async handleEvent(event: Services.InternalEventInterface): Promise { - if (event.type === Services.ApiServiceEvent.MetaReceived) { + async handleEvent(event: InternalEventInterface): Promise { + if (event.type === ApiServiceEvent.MetaReceived) { if (!this.syncService) { this.log('[Features Service] Handling events interrupted. Sync service is not yet initialized.', event) @@ -126,7 +135,7 @@ export class SNFeaturesService return } - const { userUuid, userRoles } = event.payload as Services.MetaReceivedData + const { userUuid, userRoles } = event.payload as MetaReceivedData await this.updateRolesAndFetchFeatures( userUuid, userRoles.map((role) => role.name), @@ -134,9 +143,9 @@ export class SNFeaturesService } } - override async handleApplicationStage(stage: Services.ApplicationStage): Promise { + override async handleApplicationStage(stage: ApplicationStage): Promise { await super.handleApplicationStage(stage) - if (stage === Services.ApplicationStage.FullSyncCompleted_13) { + if (stage === ApplicationStage.FullSyncCompleted_13) { if (!this.hasOnlineSubscription()) { const offlineRepo = this.getOfflineRepo() if (offlineRepo) { @@ -154,7 +163,7 @@ export class SNFeaturesService this.enabledExperimentalFeatures.push(identifier) - void this.storageService.setValue(Services.StorageKey.ExperimentalFeatures, this.enabledExperimentalFeatures) + void this.storageService.setValue(StorageKey.ExperimentalFeatures, this.enabledExperimentalFeatures) void this.mapRemoteNativeFeaturesToItems([feature]) void this.notifyEvent(FeaturesEvent.FeaturesUpdated) @@ -168,7 +177,7 @@ export class SNFeaturesService removeFromArray(this.enabledExperimentalFeatures, identifier) - void this.storageService.setValue(Services.StorageKey.ExperimentalFeatures, this.enabledExperimentalFeatures) + void this.storageService.setValue(StorageKey.ExperimentalFeatures, this.enabledExperimentalFeatures) const component = this.itemManager .getItems([ContentType.Component, ContentType.Theme]) @@ -248,7 +257,7 @@ export class SNFeaturesService await this.itemManager.setItemToBeDeleted(repo) void this.syncService.sync() } - await this.storageService.removeValue(Services.StorageKey.UserFeatures) + await this.storageService.removeValue(StorageKey.UserFeatures) } private parseOfflineEntitlementsCode(code: string): GetOfflineSubscriptionDetailsResponse | ClientDisplayableError { @@ -322,15 +331,11 @@ export class SNFeaturesService } public initializeFromDisk(): void { - this.roles = this.storageService.getValue(Services.StorageKey.UserRoles, undefined, []) + this.roles = this.storageService.getValue(StorageKey.UserRoles, undefined, []) - this.features = this.storageService.getValue(Services.StorageKey.UserFeatures, undefined, []) + this.features = this.storageService.getValue(StorageKey.UserFeatures, undefined, []) - this.enabledExperimentalFeatures = this.storageService.getValue( - Services.StorageKey.ExperimentalFeatures, - undefined, - [], - ) + this.enabledExperimentalFeatures = this.storageService.getValue(StorageKey.ExperimentalFeatures, undefined, []) } public async updateRolesAndFetchFeatures(userUuid: UuidString, roles: RoleName[]): Promise { @@ -361,7 +366,7 @@ export class SNFeaturesService if (!arraysEqual(this.roles, roles)) { void this.notifyEvent(FeaturesEvent.UserRolesChanged) } - await this.storageService.setValue(Services.StorageKey.UserRoles, this.roles) + await this.storageService.setValue(StorageKey.UserRoles, this.roles) } public async didDownloadFeatures(features: FeaturesImports.FeatureDescription[]): Promise { @@ -372,7 +377,7 @@ export class SNFeaturesService this.features = features this.completedSuccessfulFeaturesRetrieval = true void this.notifyEvent(FeaturesEvent.FeaturesUpdated) - void this.storageService.setValue(Services.StorageKey.UserFeatures, this.features) + void this.storageService.setValue(StorageKey.UserFeatures, this.features) await this.mapRemoteNativeFeaturesToItems(features) } @@ -607,7 +612,7 @@ export class SNFeaturesService Messages.API_MESSAGE_UNTRUSTED_EXTENSIONS_WARNING, 'Install extension from an untrusted source?', 'Proceed to install', - Services.ButtonType.Danger, + ButtonType.Danger, 'Cancel', ) if (didConfirm) { diff --git a/packages/snjs/lib/Services/Features/Types.ts b/packages/snjs/lib/Services/Features/Types.ts deleted file mode 100644 index f455af7c3..000000000 --- a/packages/snjs/lib/Services/Features/Types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ClientDisplayableError } from '@standardnotes/responses' - -export type SetOfflineFeaturesFunctionResponse = ClientDisplayableError | undefined - -export type OfflineSubscriptionEntitlements = { - featuresUrl: string - extensionKey: string -} - -export enum FeaturesEvent { - UserRolesChanged = 'UserRolesChanged', - FeaturesUpdated = 'FeaturesUpdated', -} - -export enum FeatureStatus { - NoUserSubscription = 'NoUserSubscription', - NotInCurrentPlan = 'NotInCurrentPlan', - InCurrentPlanButExpired = 'InCurrentPlanButExpired', - Entitled = 'Entitled', -} diff --git a/packages/snjs/lib/Services/Features/index.ts b/packages/snjs/lib/Services/Features/index.ts index a2c4fe199..8027f7d29 100644 --- a/packages/snjs/lib/Services/Features/index.ts +++ b/packages/snjs/lib/Services/Features/index.ts @@ -1,3 +1 @@ -export * from './ClientInterface' export * from './FeaturesService' -export * from './Types' diff --git a/packages/snjs/lib/Services/Items/ItemManager.ts b/packages/snjs/lib/Services/Items/ItemManager.ts index 656aa8946..67244d619 100644 --- a/packages/snjs/lib/Services/Items/ItemManager.ts +++ b/packages/snjs/lib/Services/Items/ItemManager.ts @@ -3,13 +3,11 @@ import { assert, naturalSort, removeFromArray, UuidGenerator, Uuids } from '@sta import { ItemsKeyMutator, SNItemsKey } from '@standardnotes/encryption' import { PayloadManager } from '../Payloads/PayloadManager' import { TagsToFoldersMigrationApplicator } from '../../Migrations/Applicators/TagsToFolders' -import { TransactionalMutation } from './TransactionalMutation' import { UuidString } from '../../Types/UuidString' import * as Models from '@standardnotes/models' import * as Services from '@standardnotes/services' -import { ItemsClientInterface } from './ItemsClientInterface' import { PayloadManagerChangeData } from '../Payloads' -import { DiagnosticInfo } from '@standardnotes/services' +import { DiagnosticInfo, ItemsClientInterface } from '@standardnotes/services' import { ApplicationDisplayOptions } from '@Lib/Application/Options/OptionalOptions' import { CollectionSort } from '@standardnotes/models' @@ -578,7 +576,7 @@ export class ItemManager * runs the same mutation on all items. */ public async runTransactionalMutations( - transactions: TransactionalMutation[], + transactions: Models.TransactionalMutation[], emitSource = Models.PayloadEmitSource.LocalChanged, payloadSourceKey?: string, ): Promise<(Models.DecryptedItemInterface | undefined)[]> { @@ -607,7 +605,7 @@ export class ItemManager } public async runTransactionalMutation( - transaction: TransactionalMutation, + transaction: Models.TransactionalMutation, emitSource = Models.PayloadEmitSource.LocalChanged, payloadSourceKey?: string, ): Promise { diff --git a/packages/snjs/lib/Services/Items/TransactionalMutation.ts b/packages/snjs/lib/Services/Items/TransactionalMutation.ts deleted file mode 100644 index a4e2eb2dc..000000000 --- a/packages/snjs/lib/Services/Items/TransactionalMutation.ts +++ /dev/null @@ -1,8 +0,0 @@ -import * as Models from '@standardnotes/models' -import { UuidString } from '../../Types/UuidString' - -export type TransactionalMutation = { - itemUuid: UuidString - mutate: (mutator: Models.ItemMutator) => void - mutationType?: Models.MutationType -} diff --git a/packages/snjs/lib/Services/Items/index.ts b/packages/snjs/lib/Services/Items/index.ts index c708e0351..a49df0481 100644 --- a/packages/snjs/lib/Services/Items/index.ts +++ b/packages/snjs/lib/Services/Items/index.ts @@ -1,3 +1 @@ -export * from './ItemsClientInterface' export * from './ItemManager' -export * from './TransactionalMutation' diff --git a/packages/snjs/lib/Services/Migration/MigrationService.ts b/packages/snjs/lib/Services/Migration/MigrationService.ts index 5f680ca5e..a6d5381a3 100644 --- a/packages/snjs/lib/Services/Migration/MigrationService.ts +++ b/packages/snjs/lib/Services/Migration/MigrationService.ts @@ -1,4 +1,3 @@ -import { ApplicationEvent } from '../../Application/Event' import { BaseMigration } from '@Lib/Migrations/Base' import { compareSemVersions } from '@Lib/Version' import { lastElement } from '@standardnotes/utils' @@ -7,6 +6,7 @@ import { MigrationServices } from '../../Migrations/MigrationServices' import { RawStorageKey, namespacedKey, + ApplicationEvent, ApplicationStage, AbstractService, DiagnosticInfo, diff --git a/packages/snjs/lib/Services/Mutator/MutatorClientInterface.ts b/packages/snjs/lib/Services/Mutator/MutatorClientInterface.ts deleted file mode 100644 index e099405ff..000000000 --- a/packages/snjs/lib/Services/Mutator/MutatorClientInterface.ts +++ /dev/null @@ -1,183 +0,0 @@ -import { ContentType } from '@standardnotes/common' -import { ChallengeReason, SyncOptions } from '@standardnotes/services' -import { TransactionalMutation } from '../Items' -import * as Models from '@standardnotes/models' -import { ClientDisplayableError } from '@standardnotes/responses' -import { BackupFile } from '@standardnotes/encryption' - -export interface MutatorClientInterface { - /** - * Inserts the input item by its payload properties, and marks the item as dirty. - * A sync is not performed after an item is inserted. This must be handled by the caller. - */ - insertItem(item: Models.DecryptedItemInterface): Promise - - /** - * Mutates a pre-existing item, marks it as dirty, and syncs it - */ - changeAndSaveItem( - itemToLookupUuidFor: Models.DecryptedItemInterface, - mutate: (mutator: M) => void, - updateTimestamps?: boolean, - emitSource?: Models.PayloadEmitSource, - syncOptions?: SyncOptions, - ): Promise - - /** - * Mutates pre-existing items, marks them as dirty, and syncs - */ - changeAndSaveItems( - itemsToLookupUuidsFor: Models.DecryptedItemInterface[], - mutate: (mutator: M) => void, - updateTimestamps?: boolean, - emitSource?: Models.PayloadEmitSource, - syncOptions?: SyncOptions, - ): Promise - - /** - * Mutates a pre-existing item and marks it as dirty. Does not sync changes. - */ - changeItem( - itemToLookupUuidFor: Models.DecryptedItemInterface, - mutate: (mutator: M) => void, - updateTimestamps?: boolean, - ): Promise - - /** - * Mutates a pre-existing items and marks them as dirty. Does not sync changes. - */ - changeItems( - itemsToLookupUuidsFor: Models.DecryptedItemInterface[], - mutate: (mutator: M) => void, - updateTimestamps?: boolean, - ): Promise<(Models.DecryptedItemInterface | undefined)[]> - - /** - * Run unique mutations per each item in the array, then only propagate all changes - * once all mutations have been run. This differs from `changeItems` in that changeItems - * runs the same mutation on all items. - */ - runTransactionalMutations( - transactions: TransactionalMutation[], - emitSource?: Models.PayloadEmitSource, - payloadSourceKey?: string, - ): Promise<(Models.DecryptedItemInterface | undefined)[]> - - runTransactionalMutation( - transaction: TransactionalMutation, - emitSource?: Models.PayloadEmitSource, - payloadSourceKey?: string, - ): Promise - - protectItems< - _M extends Models.DecryptedItemMutator, - I extends Models.DecryptedItemInterface, - >( - items: I[], - ): Promise - - unprotectItems< - _M extends Models.DecryptedItemMutator, - I extends Models.DecryptedItemInterface, - >( - items: I[], - reason: ChallengeReason, - ): Promise - - protectNote(note: Models.SNNote): Promise - - unprotectNote(note: Models.SNNote): Promise - - protectNotes(notes: Models.SNNote[]): Promise - - unprotectNotes(notes: Models.SNNote[]): Promise - - protectFile(file: Models.FileItem): Promise - - unprotectFile(file: Models.FileItem): Promise - - /** - * Takes the values of the input item and emits it onto global state. - */ - mergeItem( - item: Models.DecryptedItemInterface, - source: Models.PayloadEmitSource, - ): Promise - - /** - * Creates an unmanaged item that can be added later. - */ - createTemplateItem< - C extends Models.ItemContent = Models.ItemContent, - I extends Models.DecryptedItemInterface = Models.DecryptedItemInterface, - >( - contentType: ContentType, - content?: C, - ): I - - /** - * @param isUserModified Whether to change the modified date the user - * sees of the item. - */ - setItemNeedsSync( - item: Models.DecryptedItemInterface, - isUserModified?: boolean, - ): Promise - - setItemsNeedsSync(items: Models.DecryptedItemInterface[]): Promise<(Models.DecryptedItemInterface | undefined)[]> - - deleteItem(item: Models.DecryptedItemInterface | Models.EncryptedItemInterface): Promise - - deleteItems(items: (Models.DecryptedItemInterface | Models.EncryptedItemInterface)[]): Promise - - emptyTrash(): Promise - - duplicateItem(item: T, additionalContent?: Partial): Promise - - /** - * Migrates any tags containing a '.' character to sa chema-based heirarchy, removing - * the dot from the tag's title. - */ - migrateTagsToFolders(): Promise - - /** - * Establishes a hierarchical relationship between two tags. - */ - setTagParent(parentTag: Models.SNTag, childTag: Models.SNTag): Promise - - /** - * Remove the tag parent. - */ - unsetTagParent(childTag: Models.SNTag): Promise - - findOrCreateTag(title: string): Promise - - /** Creates and returns the tag but does not run sync. Callers must perform sync. */ - createTagOrSmartView(title: string): Promise - - /** - * Activates or deactivates a component, depending on its - * current state, and syncs. - */ - toggleComponent(component: Models.SNComponent): Promise - - toggleTheme(theme: Models.SNComponent): Promise - - /** - * @returns - * .affectedItems: Items that were either created or dirtied by this import - * .errorCount: The number of items that were not imported due to failure to decrypt. - */ - importData( - data: BackupFile, - awaitSync?: boolean, - ): Promise< - | { - affectedItems: Models.DecryptedItemInterface[] - errorCount: number - } - | { - error: ClientDisplayableError - } - > -} diff --git a/packages/snjs/lib/Services/Mutator/MutatorService.ts b/packages/snjs/lib/Services/Mutator/MutatorService.ts index 55ba1c274..2153df6bb 100644 --- a/packages/snjs/lib/Services/Mutator/MutatorService.ts +++ b/packages/snjs/lib/Services/Mutator/MutatorService.ts @@ -6,25 +6,42 @@ import { ChallengeValidation, ChallengePrompt, ChallengeReason, + MutatorClientInterface, } from '@standardnotes/services' -import { BackupFile, EncryptionProvider } from '@standardnotes/encryption' +import { EncryptionProvider } from '@standardnotes/encryption' import { ClientDisplayableError } from '@standardnotes/responses' import { ContentType, ProtocolVersion, compareVersions } from '@standardnotes/common' -import { ItemManager, TransactionalMutation } from '../Items' -import { MutatorClientInterface } from './MutatorClientInterface' +import { ItemManager } from '../Items' import { PayloadManager } from '../Payloads/PayloadManager' import { SNComponentManager } from '../ComponentManager/ComponentManager' import { SNProtectionService } from '../Protection/ProtectionService' import { SNSyncService } from '../Sync' import { Strings } from '../../Strings' import { TagsToFoldersMigrationApplicator } from '@Lib/Migrations/Applicators/TagsToFolders' -import * as Models from '@standardnotes/models' import { Challenge, ChallengeService } from '../Challenge' import { + BackupFile, + BackupFileDecryptedContextualPayload, + ComponentContent, + CopyPayloadWithContentOverride, CreateDecryptedBackupFileContextPayload, + CreateDecryptedMutatorForItem, CreateEncryptedBackupFileContextPayload, + DecryptedItemInterface, + DecryptedItemMutator, + DecryptedPayloadInterface, + EncryptedItemInterface, + FileItem, isDecryptedPayload, isEncryptedTransferPayload, + ItemContent, + MutationType, + PayloadEmitSource, + SmartView, + SNComponent, + SNNote, + SNTag, + TransactionalMutation, } from '@standardnotes/models' export class MutatorService extends AbstractService implements MutatorClientInterface { @@ -54,106 +71,101 @@ export class MutatorService extends AbstractService implements MutatorClientInte ;(this.historyService as unknown) = undefined } - public async insertItem(item: Models.DecryptedItemInterface): Promise { - const mutator = Models.CreateDecryptedMutatorForItem(item, Models.MutationType.UpdateUserTimestamps) + public async insertItem(item: DecryptedItemInterface): Promise { + const mutator = CreateDecryptedMutatorForItem(item, MutationType.UpdateUserTimestamps) const dirtiedPayload = mutator.getResult() - const insertedItem = await this.itemManager.emitItemFromPayload( - dirtiedPayload, - Models.PayloadEmitSource.LocalInserted, - ) + const insertedItem = await this.itemManager.emitItemFromPayload(dirtiedPayload, PayloadEmitSource.LocalInserted) return insertedItem } - public async changeAndSaveItem( - itemToLookupUuidFor: Models.DecryptedItemInterface, + public async changeAndSaveItem( + itemToLookupUuidFor: DecryptedItemInterface, mutate: (mutator: M) => void, updateTimestamps = true, - emitSource?: Models.PayloadEmitSource, + emitSource?: PayloadEmitSource, syncOptions?: SyncOptions, - ): Promise { + ): Promise { await this.itemManager.changeItems( [itemToLookupUuidFor], mutate, - updateTimestamps ? Models.MutationType.UpdateUserTimestamps : Models.MutationType.NoUpdateUserTimestamps, + updateTimestamps ? MutationType.UpdateUserTimestamps : MutationType.NoUpdateUserTimestamps, emitSource, ) await this.syncService.sync(syncOptions) return this.itemManager.findItem(itemToLookupUuidFor.uuid) } - public async changeAndSaveItems( - itemsToLookupUuidsFor: Models.DecryptedItemInterface[], + public async changeAndSaveItems( + itemsToLookupUuidsFor: DecryptedItemInterface[], mutate: (mutator: M) => void, updateTimestamps = true, - emitSource?: Models.PayloadEmitSource, + emitSource?: PayloadEmitSource, syncOptions?: SyncOptions, ): Promise { await this.itemManager.changeItems( itemsToLookupUuidsFor, mutate, - updateTimestamps ? Models.MutationType.UpdateUserTimestamps : Models.MutationType.NoUpdateUserTimestamps, + updateTimestamps ? MutationType.UpdateUserTimestamps : MutationType.NoUpdateUserTimestamps, emitSource, ) await this.syncService.sync(syncOptions) } - public async changeItem( - itemToLookupUuidFor: Models.DecryptedItemInterface, + public async changeItem( + itemToLookupUuidFor: DecryptedItemInterface, mutate: (mutator: M) => void, updateTimestamps = true, - ): Promise { + ): Promise { await this.itemManager.changeItems( [itemToLookupUuidFor], mutate, - updateTimestamps ? Models.MutationType.UpdateUserTimestamps : Models.MutationType.NoUpdateUserTimestamps, + updateTimestamps ? MutationType.UpdateUserTimestamps : MutationType.NoUpdateUserTimestamps, ) return this.itemManager.findItem(itemToLookupUuidFor.uuid) } - public async changeItems( - itemsToLookupUuidsFor: Models.DecryptedItemInterface[], + public async changeItems( + itemsToLookupUuidsFor: DecryptedItemInterface[], mutate: (mutator: M) => void, updateTimestamps = true, - ): Promise<(Models.DecryptedItemInterface | undefined)[]> { + ): Promise<(DecryptedItemInterface | undefined)[]> { return this.itemManager.changeItems( itemsToLookupUuidsFor, mutate, - updateTimestamps ? Models.MutationType.UpdateUserTimestamps : Models.MutationType.NoUpdateUserTimestamps, + updateTimestamps ? MutationType.UpdateUserTimestamps : MutationType.NoUpdateUserTimestamps, ) } public async runTransactionalMutations( transactions: TransactionalMutation[], - emitSource = Models.PayloadEmitSource.LocalChanged, + emitSource = PayloadEmitSource.LocalChanged, payloadSourceKey?: string, - ): Promise<(Models.DecryptedItemInterface | undefined)[]> { + ): Promise<(DecryptedItemInterface | undefined)[]> { return this.itemManager.runTransactionalMutations(transactions, emitSource, payloadSourceKey) } public async runTransactionalMutation( transaction: TransactionalMutation, - emitSource = Models.PayloadEmitSource.LocalChanged, + emitSource = PayloadEmitSource.LocalChanged, payloadSourceKey?: string, - ): Promise { + ): Promise { return this.itemManager.runTransactionalMutation(transaction, emitSource, payloadSourceKey) } - async protectItems( - items: I[], - ): Promise { + async protectItems(items: I[]): Promise { const protectedItems = await this.itemManager.changeItems( items, (mutator) => { mutator.protected = true }, - Models.MutationType.NoUpdateUserTimestamps, + MutationType.NoUpdateUserTimestamps, ) void this.syncService.sync() return protectedItems } - async unprotectItems( + async unprotectItems( items: I[], reason: ChallengeReason, ): Promise { @@ -166,74 +178,69 @@ export class MutatorService extends AbstractService implements MutatorClientInte (mutator) => { mutator.protected = false }, - Models.MutationType.NoUpdateUserTimestamps, + MutationType.NoUpdateUserTimestamps, ) void this.syncService.sync() return unprotectedItems } - public async protectNote(note: Models.SNNote): Promise { + public async protectNote(note: SNNote): Promise { const result = await this.protectItems([note]) return result[0] } - public async unprotectNote(note: Models.SNNote): Promise { + public async unprotectNote(note: SNNote): Promise { const result = await this.unprotectItems([note], ChallengeReason.UnprotectNote) return result ? result[0] : undefined } - public async protectNotes(notes: Models.SNNote[]): Promise { + public async protectNotes(notes: SNNote[]): Promise { return this.protectItems(notes) } - public async unprotectNotes(notes: Models.SNNote[]): Promise { + public async unprotectNotes(notes: SNNote[]): Promise { const results = await this.unprotectItems(notes, ChallengeReason.UnprotectNote) return results || [] } - async protectFile(file: Models.FileItem): Promise { + async protectFile(file: FileItem): Promise { const result = await this.protectItems([file]) return result[0] } - async unprotectFile(file: Models.FileItem): Promise { + async unprotectFile(file: FileItem): Promise { const result = await this.unprotectItems([file], ChallengeReason.UnprotectFile) return result ? result[0] : undefined } - public async mergeItem( - item: Models.DecryptedItemInterface, - source: Models.PayloadEmitSource, - ): Promise { + public async mergeItem(item: DecryptedItemInterface, source: PayloadEmitSource): Promise { return this.itemManager.emitItemFromPayload(item.payloadRepresentation(), source) } public createTemplateItem< - C extends Models.ItemContent = Models.ItemContent, - I extends Models.DecryptedItemInterface = Models.DecryptedItemInterface, + C extends ItemContent = ItemContent, + I extends DecryptedItemInterface = DecryptedItemInterface, >(contentType: ContentType, content?: C): I { return this.itemManager.createTemplateItem(contentType, content) } public async setItemNeedsSync( - item: Models.DecryptedItemInterface, + item: DecryptedItemInterface, updateTimestamps = false, - ): Promise { + ): Promise { return this.itemManager.setItemDirty(item, updateTimestamps) } - public async setItemsNeedsSync( - items: Models.DecryptedItemInterface[], - ): Promise<(Models.DecryptedItemInterface | undefined)[]> { + public async setItemsNeedsSync(items: DecryptedItemInterface[]): Promise<(DecryptedItemInterface | undefined)[]> { return this.itemManager.setItemsDirty(items) } - public async deleteItem(item: Models.DecryptedItemInterface | Models.EncryptedItemInterface): Promise { + public async deleteItem(item: DecryptedItemInterface | EncryptedItemInterface): Promise { return this.deleteItems([item]) } - public async deleteItems(items: (Models.DecryptedItemInterface | Models.EncryptedItemInterface)[]): Promise { + public async deleteItems(items: (DecryptedItemInterface | EncryptedItemInterface)[]): Promise { await this.itemManager.setItemsToBeDeleted(items) await this.syncService.sync() } @@ -243,7 +250,7 @@ export class MutatorService extends AbstractService implements MutatorClientInte await this.syncService.sync() } - public duplicateItem( + public duplicateItem( item: T, additionalContent?: Partial, ): Promise { @@ -257,29 +264,29 @@ export class MutatorService extends AbstractService implements MutatorClientInte return this.syncService.sync() } - public async setTagParent(parentTag: Models.SNTag, childTag: Models.SNTag): Promise { + public async setTagParent(parentTag: SNTag, childTag: SNTag): Promise { await this.itemManager.setTagParent(parentTag, childTag) } - public async unsetTagParent(childTag: Models.SNTag): Promise { + public async unsetTagParent(childTag: SNTag): Promise { await this.itemManager.unsetTagParent(childTag) } - public async findOrCreateTag(title: string): Promise { + public async findOrCreateTag(title: string): Promise { return this.itemManager.findOrCreateTagByTitle(title) } /** Creates and returns the tag but does not run sync. Callers must perform sync. */ - public async createTagOrSmartView(title: string): Promise { + public async createTagOrSmartView(title: string): Promise { return this.itemManager.createTagOrSmartView(title) } - public async toggleComponent(component: Models.SNComponent): Promise { + public async toggleComponent(component: SNComponent): Promise { await this.componentManager.toggleComponent(component.uuid) await this.syncService.sync() } - public async toggleTheme(theme: Models.SNComponent): Promise { + public async toggleTheme(theme: SNComponent): Promise { await this.componentManager.toggleTheme(theme.uuid) await this.syncService.sync() } @@ -289,7 +296,7 @@ export class MutatorService extends AbstractService implements MutatorClientInte awaitSync = false, ): Promise< | { - affectedItems: Models.DecryptedItemInterface[] + affectedItems: DecryptedItemInterface[] errorCount: number } | { @@ -342,7 +349,7 @@ export class MutatorService extends AbstractService implements MutatorClientInte if (isEncryptedTransferPayload(item)) { return CreateEncryptedBackupFileContextPayload(item) } else { - return CreateDecryptedBackupFileContextPayload(item as Models.BackupFileDecryptedContextualPayload) + return CreateDecryptedBackupFileContextPayload(item as BackupFileDecryptedContextualPayload) } }) @@ -355,9 +362,9 @@ export class MutatorService extends AbstractService implements MutatorClientInte const validPayloads = decryptedPayloadsOrError.filter(isDecryptedPayload).map((payload) => { /* Don't want to activate any components during import process in * case of exceptions breaking up the import proccess */ - if (payload.content_type === ContentType.Component && (payload.content as Models.ComponentContent).active) { - const typedContent = payload as Models.DecryptedPayloadInterface - return Models.CopyPayloadWithContentOverride(typedContent, { + if (payload.content_type === ContentType.Component && (payload.content as ComponentContent).active) { + const typedContent = payload as DecryptedPayloadInterface + return CopyPayloadWithContentOverride(typedContent, { active: false, }) } else { @@ -376,7 +383,7 @@ export class MutatorService extends AbstractService implements MutatorClientInte await promise } - const affectedItems = this.itemManager.findItems(affectedUuids) as Models.DecryptedItemInterface[] + const affectedItems = this.itemManager.findItems(affectedUuids) as DecryptedItemInterface[] return { affectedItems: affectedItems, diff --git a/packages/snjs/lib/Services/Mutator/index.ts b/packages/snjs/lib/Services/Mutator/index.ts index ae73aaa1c..0ed275311 100644 --- a/packages/snjs/lib/Services/Mutator/index.ts +++ b/packages/snjs/lib/Services/Mutator/index.ts @@ -1,2 +1 @@ -export * from './MutatorClientInterface' export * from './MutatorService' diff --git a/packages/ui-services/.eslintignore b/packages/ui-services/.eslintignore new file mode 100644 index 000000000..5a19e8ace --- /dev/null +++ b/packages/ui-services/.eslintignore @@ -0,0 +1,3 @@ +node_modules +dist +coverage \ No newline at end of file diff --git a/packages/ui-services/.eslintrc b/packages/ui-services/.eslintrc new file mode 100644 index 000000000..42e723b15 --- /dev/null +++ b/packages/ui-services/.eslintrc @@ -0,0 +1,9 @@ +{ + "extends": "../../.eslintrc", + "parserOptions": { + "project": "./linter.tsconfig.json" + }, + "rules": { + "@typescript-eslint/no-explicit-any": ["warn", { "ignoreRestArgs": true }] + } +} diff --git a/packages/ui-services/.gitignore b/packages/ui-services/.gitignore new file mode 100644 index 000000000..1521c8b76 --- /dev/null +++ b/packages/ui-services/.gitignore @@ -0,0 +1 @@ +dist diff --git a/packages/ui-services/jest.config.js b/packages/ui-services/jest.config.js new file mode 100644 index 000000000..ad1ceabb0 --- /dev/null +++ b/packages/ui-services/jest.config.js @@ -0,0 +1,11 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const base = require('../../node_modules/@standardnotes/config/src/jest.json'); + +module.exports = { + ...base, + globals: { + 'ts-jest': { + tsconfig: 'tsconfig.json', + }, + } +}; diff --git a/packages/ui-services/linter.tsconfig.json b/packages/ui-services/linter.tsconfig.json new file mode 100644 index 000000000..c1a7d22c5 --- /dev/null +++ b/packages/ui-services/linter.tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["dist"] +} diff --git a/packages/ui-services/package.json b/packages/ui-services/package.json new file mode 100644 index 000000000..4fae95890 --- /dev/null +++ b/packages/ui-services/package.json @@ -0,0 +1,41 @@ +{ + "name": "@standardnotes/ui-services", + "version": "1.0.0", + "engines": { + "node": ">=16.0.0 <17.0.0" + }, + "description": "UI Services for Standard Notes clients", + "main": "dist/index.js", + "author": "Standard Notes", + "types": "dist/index.d.ts", + "files": [ + "dist" + ], + "private": true, + "license": "AGPL-3.0-or-later", + "scripts": { + "clean": "rm -fr dist", + "prestart": "yarn clean", + "start": "tsc -p tsconfig.json --watch", + "prebuild": "yarn clean", + "build": "tsc -p tsconfig.json", + "lint": "eslint . --ext .ts", + "test:unit": "jest spec --coverage" + }, + "dependencies": { + "@standardnotes/filepicker": "workspace:^", + "@standardnotes/services": "workspace:^", + "@standardnotes/snjs": "workspace:^", + "@standardnotes/styles": "workspace:^", + "@standardnotes/toast": "workspace:^", + "@standardnotes/utils": "workspace:^" + }, + "devDependencies": { + "@types/jest": "^28.1.5", + "@typescript-eslint/eslint-plugin": "^5.30.0", + "@typescript-eslint/parser": "^5.12.1", + "eslint-plugin-prettier": "*", + "jest": "^28.1.2", + "ts-jest": "^28.0.5" + } +} diff --git a/packages/web/src/javascripts/Services/AlertService.ts b/packages/ui-services/src/Alert/Functions.ts similarity index 62% rename from packages/web/src/javascripts/Services/AlertService.ts rename to packages/ui-services/src/Alert/Functions.ts index 8b06672b2..81c4c2bf7 100644 --- a/packages/web/src/javascripts/Services/AlertService.ts +++ b/packages/ui-services/src/Alert/Functions.ts @@ -1,4 +1,3 @@ -import { AlertService, ButtonType } from '@standardnotes/services' import { sanitizeHtmlString } from '@standardnotes/utils' import { SKAlert } from '@standardnotes/styles' @@ -65,37 +64,3 @@ export function alertDialog({ alert.present() }) } - -export class WebAlertService extends AlertService { - alert(text: string, title?: string, closeButtonText?: string) { - return alertDialog({ text, title, closeButtonText }) - } - - confirm( - text: string, - title?: string, - confirmButtonText?: string, - confirmButtonType?: ButtonType, - cancelButtonText?: string, - ): Promise { - return confirmDialog({ - text, - title, - confirmButtonText, - cancelButtonText, - confirmButtonStyle: confirmButtonType === ButtonType.Danger ? 'danger' : 'info', - }) - } - - blockingDialog(text: string, title?: string) { - const alert = new SKAlert({ - title: title && sanitizeHtmlString(title), - text: sanitizeHtmlString(text), - buttons: [], - }) - alert.present() - return () => { - alert.dismiss() - } - } -} diff --git a/packages/ui-services/src/Alert/WebAlertService.ts b/packages/ui-services/src/Alert/WebAlertService.ts new file mode 100644 index 000000000..0483efc1a --- /dev/null +++ b/packages/ui-services/src/Alert/WebAlertService.ts @@ -0,0 +1,38 @@ +import { AlertService, ButtonType } from '@standardnotes/services' +import { sanitizeHtmlString } from '@standardnotes/utils' +import { SKAlert } from '@standardnotes/styles' +import { alertDialog, confirmDialog } from './Functions' + +export class WebAlertService extends AlertService { + alert(text: string, title?: string, closeButtonText?: string) { + return alertDialog({ text, title, closeButtonText }) + } + + confirm( + text: string, + title?: string, + confirmButtonText?: string, + confirmButtonType?: ButtonType, + cancelButtonText?: string, + ): Promise { + return confirmDialog({ + text, + title, + confirmButtonText, + cancelButtonText, + confirmButtonStyle: confirmButtonType === ButtonType.Danger ? 'danger' : 'info', + }) + } + + blockingDialog(text: string, title?: string) { + const alert = new SKAlert({ + title: title && sanitizeHtmlString(title), + text: sanitizeHtmlString(text), + buttons: [], + }) + alert.present() + return () => { + alert.dismiss() + } + } +} diff --git a/packages/web/src/javascripts/Services/ArchiveManager.ts b/packages/ui-services/src/Archive/ArchiveManager.ts similarity index 97% rename from packages/web/src/javascripts/Services/ArchiveManager.ts rename to packages/ui-services/src/Archive/ArchiveManager.ts index 4f4976498..305dfadd1 100644 --- a/packages/web/src/javascripts/Services/ArchiveManager.ts +++ b/packages/ui-services/src/Archive/ArchiveManager.ts @@ -1,4 +1,3 @@ -import { WebApplication } from '@/Application/Application' import { parseFileName } from '@standardnotes/filepicker' import { BackupFile, @@ -6,6 +5,7 @@ import { BackupFileDecryptedContextualPayload, NoteContent, EncryptedItemInterface, + SNApplication, } from '@standardnotes/snjs' function sanitizeFileName(name: string): string { @@ -27,10 +27,10 @@ type ZippableData = { type ObjectURL = string export class ArchiveManager { - private readonly application: WebApplication + private readonly application: SNApplication private textFile?: string - constructor(application: WebApplication) { + constructor(application: SNApplication) { this.application = application } diff --git a/packages/web/src/javascripts/Services/IOService.ts b/packages/ui-services/src/IO/IOService.ts similarity index 100% rename from packages/web/src/javascripts/Services/IOService.ts rename to packages/ui-services/src/IO/IOService.ts diff --git a/packages/web/src/javascripts/Services/AutolockService.ts b/packages/ui-services/src/Security/AutolockService.ts similarity index 100% rename from packages/web/src/javascripts/Services/AutolockService.ts rename to packages/ui-services/src/Security/AutolockService.ts diff --git a/packages/web/src/javascripts/Services/LocalStorage.ts b/packages/ui-services/src/Storage/LocalStorage.ts similarity index 61% rename from packages/web/src/javascripts/Services/LocalStorage.ts rename to packages/ui-services/src/Storage/LocalStorage.ts index bf7859cf3..d905bc8a0 100644 --- a/packages/web/src/javascripts/Services/LocalStorage.ts +++ b/packages/ui-services/src/Storage/LocalStorage.ts @@ -1,5 +1,3 @@ -import { useCallback, useState } from 'react' - export enum StorageKey { AnonymousUserId = 'AnonymousUserId', ShowBetaWarning = 'ShowBetaWarning', @@ -26,19 +24,3 @@ export const storage = { localStorage.removeItem(key) }, } - -type LocalStorageHookReturnType = [StorageValue[Key] | null, (value: StorageValue[Key]) => void] - -export const useLocalStorageItem = (key: Key): LocalStorageHookReturnType => { - const [value, setValue] = useState(() => storage.get(key)) - - const set = useCallback( - (value: StorageValue[Key]) => { - storage.set(key, value) - setValue(value) - }, - [key], - ) - - return [value, set] -} diff --git a/packages/web/src/javascripts/Services/ThemeManager.ts b/packages/ui-services/src/Theme/ThemeManager.ts similarity index 98% rename from packages/web/src/javascripts/Services/ThemeManager.ts rename to packages/ui-services/src/Theme/ThemeManager.ts index 4002b64d0..bdc2049ff 100644 --- a/packages/web/src/javascripts/Services/ThemeManager.ts +++ b/packages/ui-services/src/Theme/ThemeManager.ts @@ -1,4 +1,3 @@ -import { WebApplication } from '@/Application/Application' import { StorageValueModes, ApplicationService, @@ -13,6 +12,7 @@ import { InternalEventBus, PayloadEmitSource, LocalStorageDecryptedContextualPayload, + WebApplicationInterface, } from '@standardnotes/snjs' import { dismissToast, ToastType, addTimedToast } from '@standardnotes/toast' @@ -26,7 +26,7 @@ export class ThemeManager extends ApplicationService { private unregisterStream!: () => void private lastUseDeviceThemeSettings = false - constructor(application: WebApplication) { + constructor(application: WebApplicationInterface) { super(application, new InternalEventBus()) this.colorSchemeEventHandler = this.colorSchemeEventHandler.bind(this) } @@ -80,7 +80,7 @@ export class ThemeManager extends ApplicationService { } get webApplication() { - return this.application as WebApplication + return this.application as WebApplicationInterface } override deinit() { diff --git a/packages/ui-services/src/index.ts b/packages/ui-services/src/index.ts new file mode 100644 index 000000000..10a482bde --- /dev/null +++ b/packages/ui-services/src/index.ts @@ -0,0 +1,7 @@ +export * from './Alert/Functions' +export * from './Alert/WebAlertService' +export * from './Archive/ArchiveManager' +export * from './IO/IOService' +export * from './Security/AutolockService' +export * from './Storage/LocalStorage' +export * from './Theme/ThemeManager' diff --git a/packages/ui-services/tsconfig.json b/packages/ui-services/tsconfig.json new file mode 100644 index 000000000..e2096ea2c --- /dev/null +++ b/packages/ui-services/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../node_modules/@standardnotes/config/src/tsconfig.json", + "compilerOptions": { + "skipLibCheck": true, + "rootDir": "./src", + "outDir": "./dist", + "jsx": "react-jsx", + }, + "include": [ + "src/**/*" + ], + "references": [], + "exclude": ["**/*.spec.ts", "dist", "node_modules"] +} diff --git a/packages/web/package.json b/packages/web/package.json index f491e22d0..cd2e212cf 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -82,6 +82,7 @@ "@standardnotes/snjs": "workspace:*", "@standardnotes/styles": "workspace:*", "@standardnotes/toast": "workspace:*", + "@standardnotes/ui-services": "workspace:^", "@zip.js/zip.js": "^2.4.10", "mobx": "^6.5.0", "mobx-react-lite": "^3.3.0", diff --git a/packages/web/src/javascripts/Application/Application.ts b/packages/web/src/javascripts/Application/Application.ts index 1de3a3dba..699df2c37 100644 --- a/packages/web/src/javascripts/Application/Application.ts +++ b/packages/web/src/javascripts/Application/Application.ts @@ -1,11 +1,5 @@ import { WebCrypto } from '@/Application/Crypto' -import { WebAlertService } from '@/Services/AlertService' -import { ArchiveManager } from '@/Services/ArchiveManager' -import { AutolockService } from '@/Services/AutolockService' -import { DesktopManager } from '@/Services/DesktopManager' -import { IOService } from '@/Services/IOService' -import { ThemeManager } from '@/Services/ThemeManager' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { WebOrDesktopDevice } from '@/Application/Device/WebOrDesktopDevice' import { DeinitSource, @@ -21,11 +15,14 @@ import { SNTag, ContentType, DecryptedItemInterface, + WebAppEvent, + WebApplicationInterface, } from '@standardnotes/snjs' import { makeObservable, observable } from 'mobx' import { PanelResizedData } from '@/Types/PanelResizedData' -import { WebAppEvent } from './WebAppEvent' import { isDesktopApplication } from '@/Utils' +import { DesktopManager } from './Device/DesktopManager' +import { ArchiveManager, AutolockService, IOService, ThemeManager, WebAlertService } from '@standardnotes/ui-services' type WebServices = { viewControllerManager: ViewControllerManager @@ -38,7 +35,7 @@ type WebServices = { export type WebEventObserver = (event: WebAppEvent, data?: unknown) => void -export class WebApplication extends SNApplication { +export class WebApplication extends SNApplication implements WebApplicationInterface { private webServices!: WebServices private webEventObservers: WebEventObserver[] = [] public itemControllerGroup: ItemGroupController diff --git a/packages/web/src/javascripts/Application/ApplicationGroup.ts b/packages/web/src/javascripts/Application/ApplicationGroup.ts index a5fbca58e..c21569ed1 100644 --- a/packages/web/src/javascripts/Application/ApplicationGroup.ts +++ b/packages/web/src/javascripts/Application/ApplicationGroup.ts @@ -6,14 +6,12 @@ import { InternalEventBus, isDesktopDevice, } from '@standardnotes/snjs' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ArchiveManager, IOService, AutolockService, ThemeManager } from '@standardnotes/ui-services' + +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { getPlatform, isDesktopApplication } from '@/Utils' -import { ArchiveManager } from '@/Services/ArchiveManager' -import { DesktopManager } from '@/Services/DesktopManager' -import { IOService } from '@/Services/IOService' -import { AutolockService } from '@/Services/AutolockService' -import { ThemeManager } from '@/Services/ThemeManager' import { WebOrDesktopDevice } from '@/Application/Device/WebOrDesktopDevice' +import { DesktopManager } from './Device/DesktopManager' const createApplication = ( descriptor: ApplicationDescriptor, diff --git a/packages/web/src/javascripts/Services/DesktopManager.ts b/packages/web/src/javascripts/Application/Device/DesktopManager.ts similarity index 94% rename from packages/web/src/javascripts/Services/DesktopManager.ts rename to packages/web/src/javascripts/Application/Device/DesktopManager.ts index ba0512e5a..2f08f1366 100644 --- a/packages/web/src/javascripts/Services/DesktopManager.ts +++ b/packages/web/src/javascripts/Application/Device/DesktopManager.ts @@ -12,9 +12,9 @@ import { assert, DesktopClientRequiresWebMethods, DesktopDeviceInterface, + WebApplicationInterface, + WebAppEvent, } from '@standardnotes/snjs' -import { WebApplication } from '@/Application/Application' -import { WebAppEvent } from '@/Application/WebAppEvent' export class DesktopManager extends ApplicationService @@ -27,12 +27,12 @@ export class DesktopManager dataLoaded = false lastSearchedText?: string - constructor(application: WebApplication, private device: DesktopDeviceInterface) { + constructor(application: WebApplicationInterface, private device: DesktopDeviceInterface) { super(application, new InternalEventBus()) } get webApplication() { - return this.application as WebApplication + return this.application as WebApplicationInterface } override deinit() { @@ -80,7 +80,7 @@ export class DesktopManager .catch(console.error) } - registerUpdateObserver(callback: (component: SNComponent) => void) { + registerUpdateObserver(callback: (component: SNComponent) => void): () => void { const observer = { callback: callback, } diff --git a/packages/web/src/javascripts/Components/Abstract/PureComponent.tsx b/packages/web/src/javascripts/Components/Abstract/PureComponent.tsx index cddb98807..e9d8fb0bb 100644 --- a/packages/web/src/javascripts/Components/Abstract/PureComponent.tsx +++ b/packages/web/src/javascripts/Components/Abstract/PureComponent.tsx @@ -1,6 +1,6 @@ import { ApplicationEvent } from '@standardnotes/snjs' import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { autorun, IReactionDisposer, IReactionPublic } from 'mobx' import { Component } from 'react' diff --git a/packages/web/src/javascripts/Components/AccountMenu/AccountMenu.tsx b/packages/web/src/javascripts/Components/AccountMenu/AccountMenu.tsx index ce43a1ffb..4f44a9659 100644 --- a/packages/web/src/javascripts/Components/AccountMenu/AccountMenu.tsx +++ b/packages/web/src/javascripts/Components/AccountMenu/AccountMenu.tsx @@ -1,5 +1,5 @@ import { observer } from 'mobx-react-lite' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { WebApplication } from '@/Application/Application' import { useCallback, FunctionComponent, KeyboardEventHandler } from 'react' import { ApplicationGroup } from '@/Application/ApplicationGroup' diff --git a/packages/web/src/javascripts/Components/AccountMenu/AdvancedOptions.tsx b/packages/web/src/javascripts/Components/AccountMenu/AdvancedOptions.tsx index ec062f624..c1668f3d3 100644 --- a/packages/web/src/javascripts/Components/AccountMenu/AdvancedOptions.tsx +++ b/packages/web/src/javascripts/Components/AccountMenu/AdvancedOptions.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { ChangeEventHandler, FunctionComponent, useCallback, useEffect, useState } from 'react' import Checkbox from '@/Components/Checkbox/Checkbox' diff --git a/packages/web/src/javascripts/Components/AccountMenu/ConfirmPassword.tsx b/packages/web/src/javascripts/Components/AccountMenu/ConfirmPassword.tsx index 45043ab1b..ac966c431 100644 --- a/packages/web/src/javascripts/Components/AccountMenu/ConfirmPassword.tsx +++ b/packages/web/src/javascripts/Components/AccountMenu/ConfirmPassword.tsx @@ -1,6 +1,6 @@ import { STRING_NON_MATCHING_PASSWORDS } from '@/Constants/Strings' import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent, KeyboardEventHandler, useCallback, useEffect, useRef, useState } from 'react' import { AccountMenuPane } from './AccountMenuPane' diff --git a/packages/web/src/javascripts/Components/AccountMenu/CreateAccount.tsx b/packages/web/src/javascripts/Components/AccountMenu/CreateAccount.tsx index f3509965c..f0278bfbb 100644 --- a/packages/web/src/javascripts/Components/AccountMenu/CreateAccount.tsx +++ b/packages/web/src/javascripts/Components/AccountMenu/CreateAccount.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent, KeyboardEventHandler, useCallback, useEffect, useRef, useState } from 'react' import { AccountMenuPane } from './AccountMenuPane' diff --git a/packages/web/src/javascripts/Components/AccountMenu/GeneralAccountMenu.tsx b/packages/web/src/javascripts/Components/AccountMenu/GeneralAccountMenu.tsx index 93df5edf8..fd966798b 100644 --- a/packages/web/src/javascripts/Components/AccountMenu/GeneralAccountMenu.tsx +++ b/packages/web/src/javascripts/Components/AccountMenu/GeneralAccountMenu.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import Icon from '@/Components/Icon/Icon' import { SyncQueueStrategy } from '@standardnotes/snjs' diff --git a/packages/web/src/javascripts/Components/AccountMenu/MenuPaneSelector.tsx b/packages/web/src/javascripts/Components/AccountMenu/MenuPaneSelector.tsx index 4544ac6e2..4f05dd120 100644 --- a/packages/web/src/javascripts/Components/AccountMenu/MenuPaneSelector.tsx +++ b/packages/web/src/javascripts/Components/AccountMenu/MenuPaneSelector.tsx @@ -1,6 +1,6 @@ import { WebApplication } from '@/Application/Application' import { ApplicationGroup } from '@/Application/ApplicationGroup' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent, useState } from 'react' import { AccountMenuPane } from './AccountMenuPane' diff --git a/packages/web/src/javascripts/Components/AccountMenu/SignIn.tsx b/packages/web/src/javascripts/Components/AccountMenu/SignIn.tsx index df51d3eac..240bfd3f4 100644 --- a/packages/web/src/javascripts/Components/AccountMenu/SignIn.tsx +++ b/packages/web/src/javascripts/Components/AccountMenu/SignIn.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { isDev } from '@/Utils' import { observer } from 'mobx-react-lite' import React, { FunctionComponent, KeyboardEventHandler, useCallback, useEffect, useRef, useState } from 'react' diff --git a/packages/web/src/javascripts/Components/AccountMenu/User.tsx b/packages/web/src/javascripts/Components/AccountMenu/User.tsx index ac7d4b338..0b8a27e90 100644 --- a/packages/web/src/javascripts/Components/AccountMenu/User.tsx +++ b/packages/web/src/javascripts/Components/AccountMenu/User.tsx @@ -1,5 +1,5 @@ import { observer } from 'mobx-react-lite' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { WebApplication } from '@/Application/Application' import { User as UserType } from '@standardnotes/snjs' diff --git a/packages/web/src/javascripts/Components/AccountMenu/WorkspaceSwitcher/WorkspaceMenuItem.tsx b/packages/web/src/javascripts/Components/AccountMenu/WorkspaceSwitcher/WorkspaceMenuItem.tsx index cad6d9a8b..99c950674 100644 --- a/packages/web/src/javascripts/Components/AccountMenu/WorkspaceSwitcher/WorkspaceMenuItem.tsx +++ b/packages/web/src/javascripts/Components/AccountMenu/WorkspaceSwitcher/WorkspaceMenuItem.tsx @@ -1,7 +1,7 @@ import Icon from '@/Components/Icon/Icon' import MenuItem from '@/Components/Menu/MenuItem' import { MenuItemType } from '@/Components/Menu/MenuItemType' -import { KeyboardKey } from '@/Services/IOService' +import { KeyboardKey } from '@standardnotes/ui-services' import { ApplicationDescriptor } from '@standardnotes/snjs' import { ChangeEventHandler, diff --git a/packages/web/src/javascripts/Components/AccountMenu/WorkspaceSwitcher/WorkspaceSwitcherMenu.tsx b/packages/web/src/javascripts/Components/AccountMenu/WorkspaceSwitcher/WorkspaceSwitcherMenu.tsx index e060d4113..574604dd5 100644 --- a/packages/web/src/javascripts/Components/AccountMenu/WorkspaceSwitcher/WorkspaceSwitcherMenu.tsx +++ b/packages/web/src/javascripts/Components/AccountMenu/WorkspaceSwitcher/WorkspaceSwitcherMenu.tsx @@ -1,5 +1,5 @@ import { ApplicationGroup } from '@/Application/ApplicationGroup' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { ApplicationDescriptor, ApplicationGroupEvent, ButtonType } from '@standardnotes/snjs' import { observer } from 'mobx-react-lite' import { FunctionComponent, useCallback, useEffect, useState } from 'react' diff --git a/packages/web/src/javascripts/Components/AccountMenu/WorkspaceSwitcher/WorkspaceSwitcherOption.tsx b/packages/web/src/javascripts/Components/AccountMenu/WorkspaceSwitcher/WorkspaceSwitcherOption.tsx index 0e89ed3fd..80bea1e7d 100644 --- a/packages/web/src/javascripts/Components/AccountMenu/WorkspaceSwitcher/WorkspaceSwitcherOption.tsx +++ b/packages/web/src/javascripts/Components/AccountMenu/WorkspaceSwitcher/WorkspaceSwitcherOption.tsx @@ -1,6 +1,6 @@ import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants/Constants' import { ApplicationGroup } from '@/Application/ApplicationGroup' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent, useCallback, useRef, useState } from 'react' import Icon from '@/Components/Icon/Icon' diff --git a/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx b/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx index 42a49c447..43f1e2fb5 100644 --- a/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx +++ b/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx @@ -1,10 +1,9 @@ import { ApplicationGroup } from '@/Application/ApplicationGroup' import { getPlatformString, getWindowUrlParams } from '@/Utils' -import { ApplicationEvent, Challenge, removeFromArray } from '@standardnotes/snjs' +import { ApplicationEvent, Challenge, removeFromArray, WebAppEvent } from '@standardnotes/snjs' import { PANEL_NAME_NOTES, PANEL_NAME_NAVIGATION } from '@/Constants/Constants' -import { alertDialog } from '@/Services/AlertService' +import { alertDialog } from '@standardnotes/ui-services' import { WebApplication } from '@/Application/Application' -import { WebAppEvent } from '@/Application/WebAppEvent' import Navigation from '@/Components/Navigation/Navigation' import NoteGroupView from '@/Components/NoteGroupView/NoteGroupView' import Footer from '@/Components/Footer/Footer' diff --git a/packages/web/src/javascripts/Components/AttachedFilesPopover/PopoverFileItem.tsx b/packages/web/src/javascripts/Components/AttachedFilesPopover/PopoverFileItem.tsx index 03d28ca47..65f9eaf04 100644 --- a/packages/web/src/javascripts/Components/AttachedFilesPopover/PopoverFileItem.tsx +++ b/packages/web/src/javascripts/Components/AttachedFilesPopover/PopoverFileItem.tsx @@ -1,5 +1,5 @@ import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants/Constants' -import { KeyboardKey } from '@/Services/IOService' +import { KeyboardKey } from '@standardnotes/ui-services' import { formatSizeToReadableString } from '@standardnotes/filepicker' import { FileItem } from '@standardnotes/snjs' import { diff --git a/packages/web/src/javascripts/Components/ChallengeModal/ChallengeModal.tsx b/packages/web/src/javascripts/Components/ChallengeModal/ChallengeModal.tsx index 20105446c..e8b3356c3 100644 --- a/packages/web/src/javascripts/Components/ChallengeModal/ChallengeModal.tsx +++ b/packages/web/src/javascripts/Components/ChallengeModal/ChallengeModal.tsx @@ -15,7 +15,7 @@ import Icon from '@/Components/Icon/Icon' import ChallengeModalPrompt from './ChallengePrompt' import LockscreenWorkspaceSwitcher from './LockscreenWorkspaceSwitcher' import { ApplicationGroup } from '@/Application/ApplicationGroup' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { ChallengeModalValues } from './ChallengeModalValues' type Props = { diff --git a/packages/web/src/javascripts/Components/ChallengeModal/LockscreenWorkspaceSwitcher.tsx b/packages/web/src/javascripts/Components/ChallengeModal/LockscreenWorkspaceSwitcher.tsx index ff1664291..efd7e0a5e 100644 --- a/packages/web/src/javascripts/Components/ChallengeModal/LockscreenWorkspaceSwitcher.tsx +++ b/packages/web/src/javascripts/Components/ChallengeModal/LockscreenWorkspaceSwitcher.tsx @@ -1,5 +1,5 @@ import { ApplicationGroup } from '@/Application/ApplicationGroup' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { FunctionComponent, useCallback, useRef, useState } from 'react' import WorkspaceSwitcherMenu from '@/Components/AccountMenu/WorkspaceSwitcher/WorkspaceSwitcherMenu' import Button from '@/Components/Button/Button' diff --git a/packages/web/src/javascripts/Components/ChangeEditor/ChangeEditorButton.tsx b/packages/web/src/javascripts/Components/ChangeEditor/ChangeEditorButton.tsx index 3ad137d03..46ad10a52 100644 --- a/packages/web/src/javascripts/Components/ChangeEditor/ChangeEditorButton.tsx +++ b/packages/web/src/javascripts/Components/ChangeEditor/ChangeEditorButton.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent, useCallback, useRef, useState } from 'react' import Icon from '@/Components/Icon/Icon' diff --git a/packages/web/src/javascripts/Components/ComponentView/ComponentView.tsx b/packages/web/src/javascripts/Components/ComponentView/ComponentView.tsx index 40df6f36d..7407c01dd 100644 --- a/packages/web/src/javascripts/Components/ComponentView/ComponentView.tsx +++ b/packages/web/src/javascripts/Components/ComponentView/ComponentView.tsx @@ -3,7 +3,7 @@ import { FeatureStatus, SNComponent, dateToLocalizedString, - ComponentViewer, + ComponentViewerInterface, ComponentViewerEvent, ComponentViewerError, } from '@standardnotes/snjs' @@ -19,8 +19,8 @@ import { openSubscriptionDashboard } from '@/Utils/ManageSubscription' interface IProps { application: WebApplication - componentViewer: ComponentViewer - requestReload?: (viewer: ComponentViewer, force?: boolean) => void + componentViewer: ComponentViewerInterface + requestReload?: (viewer: ComponentViewerInterface, force?: boolean) => void onLoad?: (component: SNComponent) => void } diff --git a/packages/web/src/javascripts/Components/ConfirmSignoutModal/ConfirmSignoutModal.tsx b/packages/web/src/javascripts/Components/ConfirmSignoutModal/ConfirmSignoutModal.tsx index 50b8ace93..9ba529753 100644 --- a/packages/web/src/javascripts/Components/ConfirmSignoutModal/ConfirmSignoutModal.tsx +++ b/packages/web/src/javascripts/Components/ConfirmSignoutModal/ConfirmSignoutModal.tsx @@ -2,7 +2,7 @@ import { FunctionComponent, useEffect, useRef, useState } from 'react' import { AlertDialog, AlertDialogDescription, AlertDialogLabel } from '@reach/alert-dialog' import { STRING_SIGN_OUT_CONFIRMATION } from '@/Constants/Strings' import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { ApplicationGroup } from '@/Application/ApplicationGroup' import { isDesktopApplication } from '@/Utils' diff --git a/packages/web/src/javascripts/Components/ContentListView/ContentList.tsx b/packages/web/src/javascripts/Components/ContentListView/ContentList.tsx index 044964fea..2e4106930 100644 --- a/packages/web/src/javascripts/Components/ContentListView/ContentList.tsx +++ b/packages/web/src/javascripts/Components/ContentListView/ContentList.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { KeyboardKey } from '@/Services/IOService' +import { KeyboardKey } from '@standardnotes/ui-services' import { UuidString } from '@standardnotes/snjs' import { observer } from 'mobx-react-lite' import { FunctionComponent, KeyboardEventHandler, UIEventHandler, useCallback } from 'react' diff --git a/packages/web/src/javascripts/Components/ContentListView/ContentListView.tsx b/packages/web/src/javascripts/Components/ContentListView/ContentListView.tsx index 7af98b13c..febe12a7b 100644 --- a/packages/web/src/javascripts/Components/ContentListView/ContentListView.tsx +++ b/packages/web/src/javascripts/Components/ContentListView/ContentListView.tsx @@ -1,4 +1,4 @@ -import { KeyboardKey, KeyboardModifier } from '@/Services/IOService' +import { KeyboardKey, KeyboardModifier } from '@standardnotes/ui-services' import { WebApplication } from '@/Application/Application' import { PANEL_NAME_NOTES } from '@/Constants/Constants' import { PrefKey, SystemViewId } from '@standardnotes/snjs' diff --git a/packages/web/src/javascripts/Components/FilePreview/FilePreviewModal.tsx b/packages/web/src/javascripts/Components/FilePreview/FilePreviewModal.tsx index 093e09237..cc84b9a6e 100644 --- a/packages/web/src/javascripts/Components/FilePreview/FilePreviewModal.tsx +++ b/packages/web/src/javascripts/Components/FilePreview/FilePreviewModal.tsx @@ -5,8 +5,8 @@ import { getFileIconComponent } from '@/Components/AttachedFilesPopover/getFileI import Icon from '@/Components/Icon/Icon' import FilePreviewInfoPanel from './FilePreviewInfoPanel' import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants/Constants' -import { KeyboardKey } from '@/Services/IOService' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { KeyboardKey } from '@standardnotes/ui-services' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import FilePreview from './FilePreview' diff --git a/packages/web/src/javascripts/Components/FileView/FileViewProps.tsx b/packages/web/src/javascripts/Components/FileView/FileViewProps.tsx index 0cb9a4fb1..9becc9ab3 100644 --- a/packages/web/src/javascripts/Components/FileView/FileViewProps.tsx +++ b/packages/web/src/javascripts/Components/FileView/FileViewProps.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { FileItem } from '@standardnotes/snjs/dist/@types' export type FileViewProps = { diff --git a/packages/web/src/javascripts/Components/Footer/Footer.tsx b/packages/web/src/javascripts/Components/Footer/Footer.tsx index eeddf9ea0..17f38b597 100644 --- a/packages/web/src/javascripts/Components/Footer/Footer.tsx +++ b/packages/web/src/javascripts/Components/Footer/Footer.tsx @@ -1,9 +1,8 @@ import { WebApplication } from '@/Application/Application' -import { WebAppEvent } from '@/Application/WebAppEvent' import { ApplicationGroup } from '@/Application/ApplicationGroup' import { PureComponent } from '@/Components/Abstract/PureComponent' import { destroyAllObjectProperties, preventRefreshing } from '@/Utils' -import { ApplicationEvent, ApplicationDescriptor } from '@standardnotes/snjs' +import { ApplicationEvent, ApplicationDescriptor, WebAppEvent } from '@standardnotes/snjs' import { STRING_NEW_UPDATE_READY, STRING_CONFIRM_APP_QUIT_DURING_UPGRADE, @@ -11,7 +10,7 @@ import { STRING_UPGRADE_ACCOUNT_CONFIRM_TITLE, STRING_UPGRADE_ACCOUNT_CONFIRM_BUTTON, } from '@/Constants/Strings' -import { alertDialog, confirmDialog } from '@/Services/AlertService' +import { alertDialog, confirmDialog } from '@standardnotes/ui-services' import Icon from '@/Components/Icon/Icon' import SyncResolutionMenu from '@/Components/SyncResolutionMenu/SyncResolutionMenu' import { Fragment } from 'react' diff --git a/packages/web/src/javascripts/Components/Menu/Menu.tsx b/packages/web/src/javascripts/Components/Menu/Menu.tsx index e88783c27..cd9606ab6 100644 --- a/packages/web/src/javascripts/Components/Menu/Menu.tsx +++ b/packages/web/src/javascripts/Components/Menu/Menu.tsx @@ -7,7 +7,7 @@ import { useEffect, useRef, } from 'react' -import { KeyboardKey } from '@/Services/IOService' +import { KeyboardKey } from '@standardnotes/ui-services' import { useListKeyboardNavigation } from '@/Hooks/useListKeyboardNavigation' type MenuProps = { diff --git a/packages/web/src/javascripts/Components/NoteTags/NoteTag.tsx b/packages/web/src/javascripts/Components/NoteTags/NoteTag.tsx index 3c791fc12..27d89f864 100644 --- a/packages/web/src/javascripts/Components/NoteTags/NoteTag.tsx +++ b/packages/web/src/javascripts/Components/NoteTags/NoteTag.tsx @@ -8,7 +8,7 @@ import { useRef, useState, } from 'react' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { SNTag } from '@standardnotes/snjs' import { observer } from 'mobx-react-lite' diff --git a/packages/web/src/javascripts/Components/NoteTags/NoteTagsContainer.tsx b/packages/web/src/javascripts/Components/NoteTags/NoteTagsContainer.tsx index dba5d5f6d..a7c8ded1f 100644 --- a/packages/web/src/javascripts/Components/NoteTags/NoteTagsContainer.tsx +++ b/packages/web/src/javascripts/Components/NoteTags/NoteTagsContainer.tsx @@ -1,4 +1,4 @@ -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import AutocompleteTagInput from '@/Components/TagAutocomplete/AutocompleteTagInput' import NoteTag from './NoteTag' diff --git a/packages/web/src/javascripts/Components/NoteView/NoteView.test.ts b/packages/web/src/javascripts/Components/NoteView/NoteView.test.ts index c3819bc5a..544200089 100644 --- a/packages/web/src/javascripts/Components/NoteView/NoteView.test.ts +++ b/packages/web/src/javascripts/Components/NoteView/NoteView.test.ts @@ -3,7 +3,7 @@ */ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { NotesController } from '@/Controllers/NotesController' import { ApplicationEvent, diff --git a/packages/web/src/javascripts/Components/NoteView/NoteView.tsx b/packages/web/src/javascripts/Components/NoteView/NoteView.tsx index a26f4b9c1..fa6e3f0c4 100644 --- a/packages/web/src/javascripts/Components/NoteView/NoteView.tsx +++ b/packages/web/src/javascripts/Components/NoteView/NoteView.tsx @@ -8,16 +8,16 @@ import { SNNote, ComponentArea, PrefKey, - ComponentViewer, + ComponentViewerInterface, ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction, NoteViewController, PayloadEmitSource, + WebAppEvent, } from '@standardnotes/snjs' import { debounce, isDesktopApplication } from '@/Utils' import { EditorEventSource } from '../../Types/EditorEventSource' -import { KeyboardModifier, KeyboardKey } from '@/Services/IOService' +import { confirmDialog, KeyboardModifier, KeyboardKey } from '@standardnotes/ui-services' import { STRING_DELETE_PLACEHOLDER_ATTEMPT, STRING_DELETE_LOCKED_ATTEMPT, StringDeleteNote } from '@/Constants/Strings' -import { confirmDialog } from '@/Services/AlertService' import { PureComponent } from '@/Components/Abstract/PureComponent' import ProtectedItemOverlay from '@/Components/ProtectedItemOverlay/ProtectedItemOverlay' import PinNoteButton from '@/Components/PinNoteButton/PinNoteButton' @@ -35,7 +35,6 @@ import { } from './TransactionFunctions' import { reloadFont } from './FontFunctions' import { NoteViewProps } from './NoteViewProps' -import { WebAppEvent } from '@/Application/WebAppEvent' import IndicatorCircle from '../IndicatorCircle/IndicatorCircle' const MINIMUM_STATUS_DURATION = 400 @@ -53,7 +52,7 @@ function sortAlphabetically(array: SNComponent[]): SNComponent[] { type State = { availableStackComponents: SNComponent[] - editorComponentViewer?: ComponentViewer + editorComponentViewer?: ComponentViewerInterface editorComponentViewerDidAlreadyReload?: boolean editorStateDidLoad: boolean editorTitle: string @@ -68,7 +67,7 @@ type State = { showLockedIcon: boolean showProtectedWarning: boolean spellcheck: boolean - stackComponentViewers: ComponentViewer[] + stackComponentViewers: ComponentViewerInterface[] syncTakingTooLong: boolean /** Setting to true then false will allow the main content textarea to be destroyed * then re-initialized. Used when reloading spellcheck status. */ @@ -404,7 +403,10 @@ class NoteView extends PureComponent { return viewer } - public editorComponentViewerRequestsReload = async (viewer: ComponentViewer, force?: boolean): Promise => { + public editorComponentViewerRequestsReload = async ( + viewer: ComponentViewerInterface, + force?: boolean, + ): Promise => { if (this.state.editorComponentViewerDidAlreadyReload && !force) { return } @@ -726,7 +728,7 @@ class NoteView extends PureComponent { return !viewerComponentExistsInEnabledComponents }) - const newViewers: ComponentViewer[] = [] + const newViewers: ComponentViewerInterface[] = [] for (const component of needsNewViewer) { newViewers.push(this.application.componentManager.createComponentViewer(component, this.note.uuid)) } diff --git a/packages/web/src/javascripts/Components/NotesOptions/AddTagOption.tsx b/packages/web/src/javascripts/Components/NotesOptions/AddTagOption.tsx index eff32d6c0..264903255 100644 --- a/packages/web/src/javascripts/Components/NotesOptions/AddTagOption.tsx +++ b/packages/web/src/javascripts/Components/NotesOptions/AddTagOption.tsx @@ -4,7 +4,7 @@ import Icon from '@/Components/Icon/Icon' import { NavigationController } from '@/Controllers/Navigation/NavigationController' import { NotesController } from '@/Controllers/NotesController' import { NoteTagsController } from '@/Controllers/NoteTagsController' -import { KeyboardKey } from '@/Services/IOService' +import { KeyboardKey } from '@standardnotes/ui-services' import Popover from '../Popover/Popover' type Props = { diff --git a/packages/web/src/javascripts/Components/NotesOptions/ChangeEditorOption.tsx b/packages/web/src/javascripts/Components/NotesOptions/ChangeEditorOption.tsx index 8fdfbff64..9ed3b0a51 100644 --- a/packages/web/src/javascripts/Components/NotesOptions/ChangeEditorOption.tsx +++ b/packages/web/src/javascripts/Components/NotesOptions/ChangeEditorOption.tsx @@ -1,4 +1,4 @@ -import { KeyboardKey } from '@/Services/IOService' +import { KeyboardKey } from '@standardnotes/ui-services' import { WebApplication } from '@/Application/Application' import { SNNote } from '@standardnotes/snjs' import { FunctionComponent, useCallback, useRef, useState } from 'react' diff --git a/packages/web/src/javascripts/Components/NotesOptions/ListedActionsOption.tsx b/packages/web/src/javascripts/Components/NotesOptions/ListedActionsOption.tsx index 0bceef05a..89814d1f0 100644 --- a/packages/web/src/javascripts/Components/NotesOptions/ListedActionsOption.tsx +++ b/packages/web/src/javascripts/Components/NotesOptions/ListedActionsOption.tsx @@ -3,7 +3,7 @@ import { SNNote } from '@standardnotes/snjs' import { FunctionComponent, useCallback, useRef, useState } from 'react' import Icon from '@/Components/Icon/Icon' import ListedActionsMenu from './ListedActionsMenu' -import { KeyboardKey } from '@/Services/IOService' +import { KeyboardKey } from '@standardnotes/ui-services' import Popover from '../Popover/Popover' type Props = { diff --git a/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx b/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx index 5e39547c0..263ba395e 100644 --- a/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx +++ b/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx @@ -3,7 +3,7 @@ import Switch from '@/Components/Switch/Switch' import { observer } from 'mobx-react-lite' import { useState, useEffect, useMemo, useCallback, FunctionComponent } from 'react' import { SNApplication, SNComponent, SNNote } from '@standardnotes/snjs' -import { KeyboardModifier } from '@/Services/IOService' +import { KeyboardModifier } from '@standardnotes/ui-services' import ChangeEditorOption from './ChangeEditorOption' import { BYTES_IN_ONE_MEGABYTE } from '@/Constants/Constants' import ListedActionsOption from './ListedActionsOption' diff --git a/packages/web/src/javascripts/Components/OtherSessionsSignOut/OtherSessionsSignOut.tsx b/packages/web/src/javascripts/Components/OtherSessionsSignOut/OtherSessionsSignOut.tsx index e8efb6a68..92a0df490 100644 --- a/packages/web/src/javascripts/Components/OtherSessionsSignOut/OtherSessionsSignOut.tsx +++ b/packages/web/src/javascripts/Components/OtherSessionsSignOut/OtherSessionsSignOut.tsx @@ -1,7 +1,7 @@ import { useCallback, useRef } from 'react' import { AlertDialog, AlertDialogDescription, AlertDialogLabel } from '@reach/alert-dialog' import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import Button from '@/Components/Button/Button' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Account/AccountPreferences.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Account/AccountPreferences.tsx index 05236cb13..efdfbf2b7 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Account/AccountPreferences.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Account/AccountPreferences.tsx @@ -1,6 +1,6 @@ import { observer } from 'mobx-react-lite' import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import Authentication from './Authentication' import Credentials from './Credentials' import Sync from './Sync' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Account/Authentication.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Account/Authentication.tsx index f4dd3788c..7318018e2 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Account/Authentication.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Account/Authentication.tsx @@ -1,7 +1,7 @@ import Button from '@/Components/Button/Button' import { Text, Title } from '@/Components/Preferences/PreferencesComponents/Content' import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent } from 'react' import { AccountIllustration } from '@standardnotes/icons' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Account/ClearSessionDataView.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Account/ClearSessionDataView.tsx index 1af25f80b..0de8e3167 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Account/ClearSessionDataView.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Account/ClearSessionDataView.tsx @@ -1,5 +1,5 @@ import Button from '@/Components/Button/Button' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent } from 'react' import { Title, Text } from '../../PreferencesComponents/Content' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Account/Credentials.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Account/Credentials.tsx index 0388915bc..a3f7a9322 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Account/Credentials.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Account/Credentials.tsx @@ -6,7 +6,7 @@ import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator' import { dateToLocalizedString } from '@standardnotes/snjs' import { useCallback, useState, FunctionComponent } from 'react' import ChangeEmail from '@/Components/Preferences/Panes/Account/ChangeEmail/ChangeEmail' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import PasswordWizard from '@/Components/PasswordWizard/PasswordWizard' import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup' import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Account/SignOutView.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Account/SignOutView.tsx index f2eeaa904..dcba67bf8 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Account/SignOutView.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Account/SignOutView.tsx @@ -2,7 +2,7 @@ import Button from '@/Components/Button/Button' import OtherSessionsSignOutContainer from '@/Components/OtherSessionsSignOut/OtherSessionsSignOut' import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator' import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent } from 'react' import { Subtitle, Title, Text } from '../../PreferencesComponents/Content' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Account/Subscription/Subscription.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Account/Subscription/Subscription.tsx index 1ff1c6173..6d7ffdf67 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Account/Subscription/Subscription.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Account/Subscription/Subscription.tsx @@ -4,7 +4,7 @@ import SubscriptionInformation from './SubscriptionInformation' import NoSubscription from './NoSubscription' import { observer } from 'mobx-react-lite' import { FunctionComponent } from 'react' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup' import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Backups/Backups.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Backups/Backups.tsx index 96faa910c..d494c826f 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Backups/Backups.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Backups/Backups.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { FunctionComponent } from 'react' import PreferencesPane from '@/Components/Preferences/PreferencesComponents/PreferencesPane' import CloudLink from './CloudBackups/CloudBackups' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Backups/CloudBackups/CloudBackupProvider.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Backups/CloudBackups/CloudBackupProvider.tsx index 3cd83c8bb..6d7eec50c 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Backups/CloudBackups/CloudBackupProvider.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Backups/CloudBackups/CloudBackupProvider.tsx @@ -19,7 +19,7 @@ import { WebApplication } from '@/Application/Application' import Button from '@/Components/Button/Button' import { isDev, openInNewTab } from '@/Utils' import { Subtitle } from '@/Components/Preferences/PreferencesComponents/Content' -import { KeyboardKey } from '@/Services/IOService' +import { KeyboardKey } from '@standardnotes/ui-services' type Props = { application: WebApplication diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Backups/DataBackups.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Backups/DataBackups.tsx index a387b2562..6b0f2356c 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Backups/DataBackups.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Backups/DataBackups.tsx @@ -1,5 +1,5 @@ import { isDesktopApplication } from '@/Utils' -import { alertDialog } from '@/Services/AlertService' +import { alertDialog } from '@standardnotes/ui-services' import { STRING_IMPORT_SUCCESS, STRING_INVALID_IMPORT_FILE, @@ -13,7 +13,7 @@ import { import { BackupFile } from '@standardnotes/snjs' import { ChangeEventHandler, MouseEventHandler, useCallback, useEffect, useRef, useState } from 'react' import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { Title, Text, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content' import Button from '@/Components/Button/Button' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/General/Advanced/AdvancedSection.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/General/Advanced/AdvancedSection.tsx index ed9ff7836..042e75227 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/General/Advanced/AdvancedSection.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/General/Advanced/AdvancedSection.tsx @@ -2,7 +2,7 @@ import { FunctionComponent } from 'react' import OfflineSubscription from '@/Components/Preferences/Panes/General/Advanced/OfflineSubscription' import { WebApplication } from '@/Application/Application' import { observer } from 'mobx-react-lite' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import PackagesPreferencesSection from '@/Components/Preferences/Panes/General/Advanced/Packages/Section' import { PackageProvider } from '@/Components/Preferences/Panes/General/Advanced/Packages/Provider/PackageProvider' import AccordionItem from '@/Components/Shared/AccordionItem' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/General/Advanced/OfflineSubscription.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/General/Advanced/OfflineSubscription.tsx index 5ec34156f..4c967475b 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/General/Advanced/OfflineSubscription.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/General/Advanced/OfflineSubscription.tsx @@ -3,7 +3,7 @@ import { Subtitle } from '@/Components/Preferences/PreferencesComponents/Content import DecoratedInput from '@/Components/Input/DecoratedInput' import Button from '@/Components/Button/Button' import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { STRING_REMOVE_OFFLINE_KEY_CONFIRMATION } from '@/Constants/Strings' import { ButtonType, ClientDisplayableError } from '@standardnotes/snjs' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/General/General.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/General/General.tsx index a06824b6e..db3e8a94a 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/General/General.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/General/General.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { FunctionComponent } from 'react' import { PackageProvider } from '@/Components/Preferences/Panes/General/Advanced/Packages/Provider/PackageProvider' import { observer } from 'mobx-react-lite' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/Encryption.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Security/Encryption.tsx index e9b1799e2..c4afb78f2 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/Encryption.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Security/Encryption.tsx @@ -1,5 +1,5 @@ import { STRING_E2E_ENABLED, STRING_ENC_NOT_ENABLED, STRING_LOCAL_ENC_ENABLED } from '@/Constants/Strings' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent } from 'react' import { Title, Text } from '../../PreferencesComponents/Content' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/EncryptionEnabled.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Security/EncryptionEnabled.tsx index efc3ca991..76c333b8f 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/EncryptionEnabled.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Security/EncryptionEnabled.tsx @@ -1,5 +1,5 @@ import Icon from '@/Components/Icon/Icon' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent } from 'react' import EncryptionStatusItem from './EncryptionStatusItem' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/ErroredItems.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Security/ErroredItems.tsx index 595a2e5ef..84665d7c4 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/ErroredItems.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Security/ErroredItems.tsx @@ -1,4 +1,4 @@ -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { Fragment, FunctionComponent, useState } from 'react' import { Text, Title, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/PasscodeLock.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Security/PasscodeLock.tsx index d6dff012f..06ff37bac 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/PasscodeLock.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Security/PasscodeLock.tsx @@ -10,11 +10,11 @@ import { } from '@/Constants/Strings' import { WebApplication } from '@/Application/Application' import { preventRefreshing } from '@/Utils' -import { alertDialog } from '@/Services/AlertService' +import { alertDialog } from '@standardnotes/ui-services' import { FormEvent, useCallback, useEffect, useRef, useState } from 'react' import { ApplicationEvent } from '@standardnotes/snjs' import { observer } from 'mobx-react-lite' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { Title, Text } from '@/Components/Preferences/PreferencesComponents/Content' import Button from '@/Components/Button/Button' import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup' diff --git a/packages/web/src/javascripts/Components/Preferences/Panes/Security/Security.tsx b/packages/web/src/javascripts/Components/Preferences/Panes/Security/Security.tsx index 0b01c8d23..ca37da458 100644 --- a/packages/web/src/javascripts/Components/Preferences/Panes/Security/Security.tsx +++ b/packages/web/src/javascripts/Components/Preferences/Panes/Security/Security.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { FunctionComponent } from 'react' import TwoFactorAuthWrapper from './TwoFactorAuth/TwoFactorAuthWrapper' import { MfaProps } from './TwoFactorAuth/MfaProps' diff --git a/packages/web/src/javascripts/Components/Preferences/PreferencesProps.tsx b/packages/web/src/javascripts/Components/Preferences/PreferencesProps.tsx index 856b8e933..432b06992 100644 --- a/packages/web/src/javascripts/Components/Preferences/PreferencesProps.tsx +++ b/packages/web/src/javascripts/Components/Preferences/PreferencesProps.tsx @@ -1,6 +1,6 @@ import { WebApplication } from '@/Application/Application' import { MfaProps } from './Panes/Security/TwoFactorAuth/MfaProps' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' export interface PreferencesProps extends MfaProps { application: WebApplication diff --git a/packages/web/src/javascripts/Components/Preferences/PreferencesViewWrapperProps.tsx b/packages/web/src/javascripts/Components/Preferences/PreferencesViewWrapperProps.tsx index a7dd58638..7d9c44f77 100644 --- a/packages/web/src/javascripts/Components/Preferences/PreferencesViewWrapperProps.tsx +++ b/packages/web/src/javascripts/Components/Preferences/PreferencesViewWrapperProps.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' export interface PreferencesViewWrapperProps { viewControllerManager: ViewControllerManager diff --git a/packages/web/src/javascripts/Components/ProtectedItemOverlay/ProtectedItemOverlay.tsx b/packages/web/src/javascripts/Components/ProtectedItemOverlay/ProtectedItemOverlay.tsx index 63216aeaf..3e4cd564d 100644 --- a/packages/web/src/javascripts/Components/ProtectedItemOverlay/ProtectedItemOverlay.tsx +++ b/packages/web/src/javascripts/Components/ProtectedItemOverlay/ProtectedItemOverlay.tsx @@ -1,4 +1,4 @@ -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import Button from '@/Components/Button/Button' type Props = { diff --git a/packages/web/src/javascripts/Components/PurchaseFlow/Panes/CreateAccount.tsx b/packages/web/src/javascripts/Components/PurchaseFlow/Panes/CreateAccount.tsx index 8ff3356f4..b545673d8 100644 --- a/packages/web/src/javascripts/Components/PurchaseFlow/Panes/CreateAccount.tsx +++ b/packages/web/src/javascripts/Components/PurchaseFlow/Panes/CreateAccount.tsx @@ -1,6 +1,6 @@ import Button from '@/Components/Button/Button' import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { PurchaseFlowPane } from '@/Controllers/PurchaseFlow/PurchaseFlowPane' import { observer } from 'mobx-react-lite' import { ChangeEventHandler, FunctionComponent, useEffect, useRef, useState } from 'react' diff --git a/packages/web/src/javascripts/Components/PurchaseFlow/Panes/SignIn.tsx b/packages/web/src/javascripts/Components/PurchaseFlow/Panes/SignIn.tsx index d263be3fa..6fb8ff0c6 100644 --- a/packages/web/src/javascripts/Components/PurchaseFlow/Panes/SignIn.tsx +++ b/packages/web/src/javascripts/Components/PurchaseFlow/Panes/SignIn.tsx @@ -1,6 +1,6 @@ import Button from '@/Components/Button/Button' import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { PurchaseFlowPane } from '@/Controllers/PurchaseFlow/PurchaseFlowPane' import { observer } from 'mobx-react-lite' import { ChangeEventHandler, FunctionComponent, useEffect, useRef, useState } from 'react' diff --git a/packages/web/src/javascripts/Components/PurchaseFlow/PurchaseFlowView.tsx b/packages/web/src/javascripts/Components/PurchaseFlow/PurchaseFlowView.tsx index 46fcd3ed1..fccf16066 100644 --- a/packages/web/src/javascripts/Components/PurchaseFlow/PurchaseFlowView.tsx +++ b/packages/web/src/javascripts/Components/PurchaseFlow/PurchaseFlowView.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { PurchaseFlowPane } from '@/Controllers/PurchaseFlow/PurchaseFlowPane' import { observer } from 'mobx-react-lite' import { FunctionComponent } from 'react' diff --git a/packages/web/src/javascripts/Components/PurchaseFlow/PurchaseFlowWrapperProps.tsx b/packages/web/src/javascripts/Components/PurchaseFlow/PurchaseFlowWrapperProps.tsx index 08330e0f5..9947bc014 100644 --- a/packages/web/src/javascripts/Components/PurchaseFlow/PurchaseFlowWrapperProps.tsx +++ b/packages/web/src/javascripts/Components/PurchaseFlow/PurchaseFlowWrapperProps.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' export type PurchaseFlowWrapperProps = { viewControllerManager: ViewControllerManager diff --git a/packages/web/src/javascripts/Components/SearchBar/SearchBar.tsx b/packages/web/src/javascripts/Components/SearchBar/SearchBar.tsx index 0ecd8f853..04a9ee035 100644 --- a/packages/web/src/javascripts/Components/SearchBar/SearchBar.tsx +++ b/packages/web/src/javascripts/Components/SearchBar/SearchBar.tsx @@ -1,5 +1,5 @@ import { ItemListController } from '@/Controllers/ItemList/ItemListController' -import { KeyboardKey } from '@/Services/IOService' +import { KeyboardKey } from '@standardnotes/ui-services' import { useState, useCallback, KeyboardEventHandler, useRef } from 'react' import SearchOptions from '@/Components/SearchOptions/SearchOptions' import { SearchOptionsController } from '@/Controllers/SearchOptionsController' diff --git a/packages/web/src/javascripts/Components/SessionsModal/SessionsModal.tsx b/packages/web/src/javascripts/Components/SessionsModal/SessionsModal.tsx index 47218f9f8..ee7d12228 100644 --- a/packages/web/src/javascripts/Components/SessionsModal/SessionsModal.tsx +++ b/packages/web/src/javascripts/Components/SessionsModal/SessionsModal.tsx @@ -1,4 +1,4 @@ -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { SNApplication, SessionStrings, UuidString, isNullOrUndefined, RemoteSession } from '@standardnotes/snjs' import { FunctionComponent, useState, useEffect, useRef, useMemo } from 'react' import { Alert } from '@reach/alert' diff --git a/packages/web/src/javascripts/Components/TagAutocomplete/AutocompleteTagHint.tsx b/packages/web/src/javascripts/Components/TagAutocomplete/AutocompleteTagHint.tsx index 7e9ca8c68..dae670cbd 100644 --- a/packages/web/src/javascripts/Components/TagAutocomplete/AutocompleteTagHint.tsx +++ b/packages/web/src/javascripts/Components/TagAutocomplete/AutocompleteTagHint.tsx @@ -1,4 +1,4 @@ -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { useRef, useEffect, useCallback, FocusEventHandler, KeyboardEventHandler } from 'react' import Icon from '@/Components/Icon/Icon' diff --git a/packages/web/src/javascripts/Components/TagAutocomplete/AutocompleteTagInput.tsx b/packages/web/src/javascripts/Components/TagAutocomplete/AutocompleteTagInput.tsx index d0cd43c94..23864de41 100644 --- a/packages/web/src/javascripts/Components/TagAutocomplete/AutocompleteTagInput.tsx +++ b/packages/web/src/javascripts/Components/TagAutocomplete/AutocompleteTagInput.tsx @@ -9,7 +9,7 @@ import { } from 'react' import { Disclosure, DisclosurePanel } from '@reach/disclosure' import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import AutocompleteTagResult from './AutocompleteTagResult' import AutocompleteTagHint from './AutocompleteTagHint' import { observer } from 'mobx-react-lite' diff --git a/packages/web/src/javascripts/Components/TagAutocomplete/AutocompleteTagResult.tsx b/packages/web/src/javascripts/Components/TagAutocomplete/AutocompleteTagResult.tsx index e9d1c4618..8f1cc3405 100644 --- a/packages/web/src/javascripts/Components/TagAutocomplete/AutocompleteTagResult.tsx +++ b/packages/web/src/javascripts/Components/TagAutocomplete/AutocompleteTagResult.tsx @@ -1,4 +1,4 @@ -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { splitQueryInString } from '@/Utils/StringUtils' import { SNTag } from '@standardnotes/snjs' import { observer } from 'mobx-react-lite' diff --git a/packages/web/src/javascripts/Components/Tags/SmartViewsList.tsx b/packages/web/src/javascripts/Components/Tags/SmartViewsList.tsx index d5a13fa26..71454537f 100644 --- a/packages/web/src/javascripts/Components/Tags/SmartViewsList.tsx +++ b/packages/web/src/javascripts/Components/Tags/SmartViewsList.tsx @@ -1,4 +1,4 @@ -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent } from 'react' import SmartViewsListItem from './SmartViewsListItem' diff --git a/packages/web/src/javascripts/Components/Tags/SmartViewsSection.tsx b/packages/web/src/javascripts/Components/Tags/SmartViewsSection.tsx index 2ac055c7e..f2f48399b 100644 --- a/packages/web/src/javascripts/Components/Tags/SmartViewsSection.tsx +++ b/packages/web/src/javascripts/Components/Tags/SmartViewsSection.tsx @@ -1,4 +1,4 @@ -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent } from 'react' import SmartViewsList from './SmartViewsList' diff --git a/packages/web/src/javascripts/Components/Tags/TagsList.tsx b/packages/web/src/javascripts/Components/Tags/TagsList.tsx index 704a066e7..74e72159f 100644 --- a/packages/web/src/javascripts/Components/Tags/TagsList.tsx +++ b/packages/web/src/javascripts/Components/Tags/TagsList.tsx @@ -1,4 +1,4 @@ -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { SNTag } from '@standardnotes/snjs' import { observer } from 'mobx-react-lite' import { FunctionComponent, useCallback } from 'react' diff --git a/packages/web/src/javascripts/Components/Tags/TagsListItem.tsx b/packages/web/src/javascripts/Components/Tags/TagsListItem.tsx index 6df65b0c0..811d270a6 100644 --- a/packages/web/src/javascripts/Components/Tags/TagsListItem.tsx +++ b/packages/web/src/javascripts/Components/Tags/TagsListItem.tsx @@ -1,7 +1,7 @@ import Icon from '@/Components/Icon/Icon' import { TAG_FOLDERS_FEATURE_NAME } from '@/Constants/Constants' import { usePremiumModal } from '@/Hooks/usePremiumModal' -import { KeyboardKey } from '@/Services/IOService' +import { KeyboardKey } from '@standardnotes/ui-services' import { FeaturesController } from '@/Controllers/FeaturesController' import { NavigationController } from '@/Controllers/Navigation/NavigationController' import '@reach/tooltip/styles.css' diff --git a/packages/web/src/javascripts/Components/Tags/TagsSection.tsx b/packages/web/src/javascripts/Components/Tags/TagsSection.tsx index 916daade1..f804afd00 100644 --- a/packages/web/src/javascripts/Components/Tags/TagsSection.tsx +++ b/packages/web/src/javascripts/Components/Tags/TagsSection.tsx @@ -1,5 +1,5 @@ import TagsList from '@/Components/Tags/TagsList' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { ApplicationEvent } from '@/__mocks__/@standardnotes/snjs' import { observer } from 'mobx-react-lite' import { FunctionComponent, useCallback, useEffect, useState } from 'react' diff --git a/packages/web/src/javascripts/Controllers/FilesController.ts b/packages/web/src/javascripts/Controllers/FilesController.ts index 4c3a3636b..cf989e1ff 100644 --- a/packages/web/src/javascripts/Controllers/FilesController.ts +++ b/packages/web/src/javascripts/Controllers/FilesController.ts @@ -4,7 +4,7 @@ import { PopoverFileItemActionType, } from '@/Components/AttachedFilesPopover/PopoverFileItemAction' import { BYTES_IN_ONE_MEGABYTE } from '@/Constants/Constants' -import { confirmDialog } from '@/Services/AlertService' +import { confirmDialog } from '@standardnotes/ui-services' import { Strings, StringUtils } from '@/Constants/Strings' import { concatenateUint8Arrays } from '@/Utils/ConcatenateUint8Arrays' import { diff --git a/packages/web/src/javascripts/Controllers/ItemList/ItemListController.ts b/packages/web/src/javascripts/Controllers/ItemList/ItemListController.ts index 10128b4a1..f24cf88e5 100644 --- a/packages/web/src/javascripts/Controllers/ItemList/ItemListController.ts +++ b/packages/web/src/javascripts/Controllers/ItemList/ItemListController.ts @@ -17,6 +17,7 @@ import { InternalEventInterface, FileViewController, FileItem, + WebAppEvent, } from '@standardnotes/snjs' import { action, computed, makeObservable, observable, reaction, runInAction } from 'mobx' import { WebApplication } from '../../Application/Application' @@ -28,7 +29,6 @@ import { SearchOptionsController } from '../SearchOptionsController' import { SelectedItemsController } from '../SelectedItemsController' import { NotesController } from '../NotesController' import { NoteTagsController } from '../NoteTagsController' -import { WebAppEvent } from '@/Application/WebAppEvent' const MinNoteCellHeight = 51.0 const DefaultListNumNotes = 20 diff --git a/packages/web/src/javascripts/Controllers/Navigation/NavigationController.ts b/packages/web/src/javascripts/Controllers/Navigation/NavigationController.ts index da46bd307..793f5266e 100644 --- a/packages/web/src/javascripts/Controllers/Navigation/NavigationController.ts +++ b/packages/web/src/javascripts/Controllers/Navigation/NavigationController.ts @@ -1,4 +1,4 @@ -import { confirmDialog } from '@/Services/AlertService' +import { confirmDialog } from '@standardnotes/ui-services' import { STRING_DELETE_TAG } from '@/Constants/Strings' import { MAX_MENU_SIZE_MULTIPLIER, MENU_MARGIN_FROM_APP_BORDER, SMART_TAGS_FEATURE_NAME } from '@/Constants/Constants' import { diff --git a/packages/web/src/javascripts/Controllers/NoAccountWarningController.ts b/packages/web/src/javascripts/Controllers/NoAccountWarningController.ts index 03559f580..f3a5a9ce0 100644 --- a/packages/web/src/javascripts/Controllers/NoAccountWarningController.ts +++ b/packages/web/src/javascripts/Controllers/NoAccountWarningController.ts @@ -1,4 +1,4 @@ -import { storage, StorageKey } from '@/Services/LocalStorage' +import { storage, StorageKey } from '@standardnotes/ui-services' import { ApplicationEvent, InternalEventBus } from '@standardnotes/snjs' import { runInAction, makeObservable, observable, action } from 'mobx' import { WebApplication } from '../Application/Application' diff --git a/packages/web/src/javascripts/Controllers/NoteHistory/NoteHistoryController.ts b/packages/web/src/javascripts/Controllers/NoteHistory/NoteHistoryController.ts index 227fd0298..b4dbf1214 100644 --- a/packages/web/src/javascripts/Controllers/NoteHistory/NoteHistoryController.ts +++ b/packages/web/src/javascripts/Controllers/NoteHistory/NoteHistoryController.ts @@ -7,7 +7,7 @@ import { sortRevisionListIntoGroups, } from '@/Components/RevisionHistoryModal/utils' import { STRING_RESTORE_LOCKED_ATTEMPT } from '@/Constants/Strings' -import { confirmDialog } from '@/Services/AlertService' +import { confirmDialog } from '@standardnotes/ui-services' import { Action, ActionVerb, diff --git a/packages/web/src/javascripts/Controllers/NotesController.ts b/packages/web/src/javascripts/Controllers/NotesController.ts index c62e92d62..cff4109f5 100644 --- a/packages/web/src/javascripts/Controllers/NotesController.ts +++ b/packages/web/src/javascripts/Controllers/NotesController.ts @@ -1,5 +1,5 @@ import { destroyAllObjectProperties } from '@/Utils' -import { confirmDialog } from '@/Services/AlertService' +import { confirmDialog } from '@standardnotes/ui-services' import { StringEmptyTrash, Strings, StringUtils } from '@/Constants/Strings' import { MENU_MARGIN_FROM_APP_BORDER } from '@/Constants/Constants' import { SNNote, NoteMutator, ContentType, SNTag, TagMutator, InternalEventBus } from '@standardnotes/snjs' diff --git a/packages/web/src/javascripts/Services/ViewControllerManager.ts b/packages/web/src/javascripts/Controllers/ViewControllerManager.ts similarity index 82% rename from packages/web/src/javascripts/Services/ViewControllerManager.ts rename to packages/web/src/javascripts/Controllers/ViewControllerManager.ts index 02788692d..cfda20dac 100644 --- a/packages/web/src/javascripts/Services/ViewControllerManager.ts +++ b/packages/web/src/javascripts/Controllers/ViewControllerManager.ts @@ -1,26 +1,26 @@ -import { storage, StorageKey } from '@/Services/LocalStorage' +import { storage, StorageKey } from '@standardnotes/ui-services' import { WebApplication } from '@/Application/Application' import { AccountMenuController } from '@/Controllers/AccountMenu/AccountMenuController' import { destroyAllObjectProperties } from '@/Utils' import { ApplicationEvent, DeinitSource, WebOrDesktopDeviceInterface, InternalEventBus } from '@standardnotes/snjs' import { action, makeObservable, observable } from 'mobx' -import { ActionsMenuController } from '../Controllers/ActionsMenuController' -import { FeaturesController } from '../Controllers/FeaturesController' -import { FilesController } from '../Controllers/FilesController' -import { NotesController } from '../Controllers/NotesController' -import { ItemListController } from '../Controllers/ItemList/ItemListController' -import { NoteTagsController } from '../Controllers/NoteTagsController' -import { NoAccountWarningController } from '../Controllers/NoAccountWarningController' -import { PreferencesController } from '../Controllers/PreferencesController' -import { PurchaseFlowController } from '../Controllers/PurchaseFlow/PurchaseFlowController' -import { QuickSettingsController } from '../Controllers/QuickSettingsController' -import { SearchOptionsController } from '../Controllers/SearchOptionsController' -import { SubscriptionController } from '../Controllers/Subscription/SubscriptionController' -import { SyncStatusController } from '../Controllers/SyncStatusController' -import { NavigationController } from '../Controllers/Navigation/NavigationController' -import { FilePreviewModalController } from '../Controllers/FilePreviewModalController' -import { SelectedItemsController } from '../Controllers/SelectedItemsController' -import { HistoryModalController } from '../Controllers/NoteHistory/HistoryModalController' +import { ActionsMenuController } from './ActionsMenuController' +import { FeaturesController } from './FeaturesController' +import { FilesController } from './FilesController' +import { NotesController } from './NotesController' +import { ItemListController } from './ItemList/ItemListController' +import { NoteTagsController } from './NoteTagsController' +import { NoAccountWarningController } from './NoAccountWarningController' +import { PreferencesController } from './PreferencesController' +import { PurchaseFlowController } from './PurchaseFlow/PurchaseFlowController' +import { QuickSettingsController } from './QuickSettingsController' +import { SearchOptionsController } from './SearchOptionsController' +import { SubscriptionController } from './Subscription/SubscriptionController' +import { SyncStatusController } from './SyncStatusController' +import { NavigationController } from './Navigation/NavigationController' +import { FilePreviewModalController } from './FilePreviewModalController' +import { SelectedItemsController } from './SelectedItemsController' +import { HistoryModalController } from './NoteHistory/HistoryModalController' export class ViewControllerManager { readonly enableUnfinishedFeatures: boolean = window?.enabledUnfinishedFeatures diff --git a/packages/web/src/javascripts/Hooks/useListKeyboardNavigation.ts b/packages/web/src/javascripts/Hooks/useListKeyboardNavigation.ts index 8ad795cb3..ccf40f5f8 100644 --- a/packages/web/src/javascripts/Hooks/useListKeyboardNavigation.ts +++ b/packages/web/src/javascripts/Hooks/useListKeyboardNavigation.ts @@ -1,4 +1,4 @@ -import { KeyboardKey } from '@/Services/IOService' +import { KeyboardKey } from '@standardnotes/ui-services' import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants/Constants' import { useCallback, useState, useEffect, RefObject } from 'react' diff --git a/packages/web/src/javascripts/Hooks/usePremiumModal.tsx b/packages/web/src/javascripts/Hooks/usePremiumModal.tsx index c304a9254..2ba419d80 100644 --- a/packages/web/src/javascripts/Hooks/usePremiumModal.tsx +++ b/packages/web/src/javascripts/Hooks/usePremiumModal.tsx @@ -1,5 +1,5 @@ import { WebApplication } from '@/Application/Application' -import { ViewControllerManager } from '@/Services/ViewControllerManager' +import { ViewControllerManager } from '@/Controllers/ViewControllerManager' import { observer } from 'mobx-react-lite' import { FunctionComponent, createContext, useCallback, useContext, ReactNode } from 'react' import PremiumFeaturesModal from '@/Components/PremiumFeaturesModal/PremiumFeaturesModal' diff --git a/packages/web/tsconfig.json b/packages/web/tsconfig.json index f61c886c0..acde4c547 100644 --- a/packages/web/tsconfig.json +++ b/packages/web/tsconfig.json @@ -19,8 +19,7 @@ "typeRoots": ["./src/javascripts/Types/External", "../../node_modules/@types", "node_modules/@types"], "paths": { "@/*": ["./src/javascripts/*"], - "@Controllers/*": ["src/javascripts/Controllers/*"], - "@Services/*": ["src/javascripts/Services/*"] + "@Controllers/*": ["src/javascripts/Controllers/*"] } }, "exclude": ["node_modules", "dist", "coverage"] diff --git a/yarn.lock b/yarn.lock index 05accc694..41337a1a9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6388,6 +6388,15 @@ __metadata: languageName: node linkType: hard +"@standardnotes/common@npm:^1.30.0": + version: 1.30.0 + resolution: "@standardnotes/common@npm:1.30.0" + dependencies: + reflect-metadata: ^0.1.13 + checksum: 833b6e7f3ee4cfbf306769d7387073073204a3dd5cd9adaf11bb10914338a4b16420e5ef196d28974427b491d7630d887a7a9e3dcbfb070f30c491437213b329 + languageName: node + linkType: hard + "@standardnotes/component-relay@npm:2.2.0": version: 2.2.0 resolution: "@standardnotes/component-relay@npm:2.2.0" @@ -6626,7 +6635,7 @@ __metadata: languageName: unknown linkType: soft -"@standardnotes/filepicker@workspace:*, @standardnotes/filepicker@workspace:packages/filepicker": +"@standardnotes/filepicker@workspace:*, @standardnotes/filepicker@workspace:^, @standardnotes/filepicker@workspace:packages/filepicker": version: 0.0.0-use.local resolution: "@standardnotes/filepicker@workspace:packages/filepicker" dependencies: @@ -7033,7 +7042,7 @@ __metadata: languageName: unknown linkType: soft -"@standardnotes/models@workspace:*, @standardnotes/models@workspace:packages/models": +"@standardnotes/models@workspace:*, @standardnotes/models@workspace:^, @standardnotes/models@workspace:packages/models": version: 0.0.0-use.local resolution: "@standardnotes/models@workspace:packages/models" dependencies: @@ -7167,13 +7176,13 @@ __metadata: languageName: node linkType: hard -"@standardnotes/services@workspace:*, @standardnotes/services@workspace:packages/services": +"@standardnotes/services@workspace:*, @standardnotes/services@workspace:^, @standardnotes/services@workspace:packages/services": version: 0.0.0-use.local resolution: "@standardnotes/services@workspace:packages/services" dependencies: "@standardnotes/auth": ^3.19.4 - "@standardnotes/common": ^1.23.1 - "@standardnotes/models": "workspace:*" + "@standardnotes/common": ^1.30.0 + "@standardnotes/models": "workspace:^" "@standardnotes/responses": "workspace:*" "@standardnotes/security": ^1.2.0 "@standardnotes/utils": "workspace:*" @@ -7273,7 +7282,7 @@ __metadata: languageName: unknown linkType: soft -"@standardnotes/snjs@^2.41.1, @standardnotes/snjs@workspace:*, @standardnotes/snjs@workspace:packages/snjs": +"@standardnotes/snjs@^2.41.1, @standardnotes/snjs@workspace:*, @standardnotes/snjs@workspace:^, @standardnotes/snjs@workspace:packages/snjs": version: 0.0.0-use.local resolution: "@standardnotes/snjs@workspace:packages/snjs" dependencies: @@ -7406,7 +7415,7 @@ __metadata: languageName: node linkType: hard -"@standardnotes/styles@workspace:*, @standardnotes/styles@workspace:packages/styles": +"@standardnotes/styles@workspace:*, @standardnotes/styles@workspace:^, @standardnotes/styles@workspace:packages/styles": version: 0.0.0-use.local resolution: "@standardnotes/styles@workspace:packages/styles" dependencies: @@ -7428,7 +7437,7 @@ __metadata: languageName: unknown linkType: soft -"@standardnotes/toast@workspace:*, @standardnotes/toast@workspace:packages/toast": +"@standardnotes/toast@workspace:*, @standardnotes/toast@workspace:^, @standardnotes/toast@workspace:packages/toast": version: 0.0.0-use.local resolution: "@standardnotes/toast@workspace:packages/toast" dependencies: @@ -7446,7 +7455,26 @@ __metadata: languageName: unknown linkType: soft -"@standardnotes/utils@workspace:*, @standardnotes/utils@workspace:packages/utils": +"@standardnotes/ui-services@workspace:^, @standardnotes/ui-services@workspace:packages/ui-services": + version: 0.0.0-use.local + resolution: "@standardnotes/ui-services@workspace:packages/ui-services" + dependencies: + "@standardnotes/filepicker": "workspace:^" + "@standardnotes/services": "workspace:^" + "@standardnotes/snjs": "workspace:^" + "@standardnotes/styles": "workspace:^" + "@standardnotes/toast": "workspace:^" + "@standardnotes/utils": "workspace:^" + "@types/jest": ^28.1.5 + "@typescript-eslint/eslint-plugin": ^5.30.0 + "@typescript-eslint/parser": ^5.12.1 + eslint-plugin-prettier: "*" + jest: ^28.1.2 + ts-jest: ^28.0.5 + languageName: unknown + linkType: soft + +"@standardnotes/utils@workspace:*, @standardnotes/utils@workspace:^, @standardnotes/utils@workspace:packages/utils": version: 0.0.0-use.local resolution: "@standardnotes/utils@workspace:packages/utils" dependencies: @@ -7492,6 +7520,7 @@ __metadata: "@standardnotes/snjs": "workspace:*" "@standardnotes/styles": "workspace:*" "@standardnotes/toast": "workspace:*" + "@standardnotes/ui-services": "workspace:^" "@types/jest": ^28.1.5 "@types/react": ^17.0.42 "@types/react-dom": ^18.0.5