refactor: merge themes into components (#2388)
This commit is contained in:
@@ -12,10 +12,10 @@ import {
|
||||
isThemeFeatureDescription,
|
||||
} from '@standardnotes/features'
|
||||
import { ComponentInterface } from '../../Syncable/Component/ComponentInterface'
|
||||
import { isTheme } from '../../Syncable/Theme'
|
||||
import { isItemBasedFeature, isNativeFeature } from './TypeGuards'
|
||||
import { UIFeatureInterface } from './UIFeatureInterface'
|
||||
import { Uuid } from '@standardnotes/domain-core'
|
||||
import { ThemePackageInfo, isTheme } from '../../Syncable/Component'
|
||||
|
||||
export class UIFeature<F extends UIFeatureDescriptionTypes> implements UIFeatureInterface<F> {
|
||||
constructor(public readonly item: ComponentInterface | F) {}
|
||||
@@ -40,6 +40,14 @@ export class UIFeature<F extends UIFeatureDescriptionTypes> implements UIFeature
|
||||
throw new Error('Cannot cast item to component')
|
||||
}
|
||||
|
||||
get asTheme(): ComponentInterface<ThemePackageInfo> {
|
||||
if (isItemBasedFeature(this.item)) {
|
||||
return this.item
|
||||
}
|
||||
|
||||
throw new Error('Cannot cast item to component')
|
||||
}
|
||||
|
||||
get asFeatureDescription(): F {
|
||||
if (isNativeFeature(this.item)) {
|
||||
return this.item
|
||||
@@ -145,7 +153,7 @@ export class UIFeature<F extends UIFeatureDescriptionTypes> implements UIFeature
|
||||
|
||||
get layerable(): boolean {
|
||||
if (isItemBasedFeature(this.item) && isTheme(this.item)) {
|
||||
return this.item.layerable
|
||||
return this.item.layerableTheme
|
||||
} else if (isThemeFeatureDescription(this.asFeatureDescription)) {
|
||||
return this.asFeatureDescription.layerable ?? false
|
||||
}
|
||||
@@ -155,7 +163,7 @@ export class UIFeature<F extends UIFeatureDescriptionTypes> implements UIFeature
|
||||
|
||||
get dockIcon(): ThemeDockIcon | undefined {
|
||||
if (isItemBasedFeature(this.item) && isTheme(this.item)) {
|
||||
return this.item.package_info.dock_icon
|
||||
return this.asTheme.package_info.dock_icon
|
||||
} else if (isThemeFeatureDescription(this.asFeatureDescription)) {
|
||||
return this.asFeatureDescription.dock_icon
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@ import { PayloadSource } from './../../Abstract/Payload/Types/PayloadSource'
|
||||
import { DecryptedPayload } from './../../Abstract/Payload/Implementations/DecryptedPayload'
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
import { FillItemContent } from '../../Abstract/Content/ItemContent'
|
||||
import { SNComponent } from './Component'
|
||||
import { ComponentItem } from './Component'
|
||||
import { ComponentContent } from './ComponentContent'
|
||||
import { PayloadTimestampDefaults } from '../../Abstract/Payload'
|
||||
import { NoteType } from '@standardnotes/features'
|
||||
|
||||
describe('component model', () => {
|
||||
it('valid hosted url should ignore url', () => {
|
||||
const component = new SNComponent(
|
||||
const component = new ComponentItem(
|
||||
new DecryptedPayload(
|
||||
{
|
||||
uuid: String(Math.random()),
|
||||
@@ -29,7 +29,7 @@ describe('component model', () => {
|
||||
})
|
||||
|
||||
it('invalid hosted url should fallback to url', () => {
|
||||
const component = new SNComponent(
|
||||
const component = new ComponentItem(
|
||||
new DecryptedPayload(
|
||||
{
|
||||
uuid: String(Math.random()),
|
||||
@@ -49,7 +49,7 @@ describe('component model', () => {
|
||||
})
|
||||
|
||||
it('should return noteType as specified in package_info', () => {
|
||||
const component = new SNComponent(
|
||||
const component = new ComponentItem(
|
||||
new DecryptedPayload(
|
||||
{
|
||||
uuid: String(Math.random()),
|
||||
@@ -69,7 +69,7 @@ describe('component model', () => {
|
||||
})
|
||||
|
||||
it('should return unknown as noteType if no note type defined in package_info', () => {
|
||||
const component = new SNComponent(
|
||||
const component = new ComponentItem(
|
||||
new DecryptedPayload(
|
||||
{
|
||||
uuid: String(Math.random()),
|
||||
|
||||
@@ -17,34 +17,16 @@ import { DecryptedPayloadInterface } from '../../Abstract/Payload/Interfaces/Dec
|
||||
import { HistoryEntryInterface } from '../../Runtime/History'
|
||||
import { ItemContent } from '../../Abstract/Content/ItemContent'
|
||||
import { Predicate } from '../../Runtime/Predicate/Predicate'
|
||||
import { ItemInterface } from '../../Abstract/Item/Interfaces/ItemInterface'
|
||||
import { DecryptedItemInterface } from './../../Abstract/Item/Interfaces/DecryptedItem'
|
||||
import { ComponentPackageInfo } from './PackageInfo'
|
||||
import { isDecryptedItem } from '../../Abstract/Item'
|
||||
import { ComponentPackageInfo, ThemePackageInfo } from './PackageInfo'
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
|
||||
export function isComponent(x: ItemInterface): x is ComponentInterface {
|
||||
if (!isDecryptedItem(x as DecryptedItemInterface)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return x.content_type === ContentType.TYPES.Component
|
||||
}
|
||||
|
||||
export function isComponentOrTheme(x: ItemInterface): x is ComponentInterface {
|
||||
if (!isDecryptedItem(x as DecryptedItemInterface)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return x.content_type === ContentType.TYPES.Component || x.content_type === ContentType.TYPES.Theme
|
||||
}
|
||||
|
||||
/**
|
||||
* Components are mostly iframe based extensions that communicate with the SN parent
|
||||
* via the postMessage API. However, a theme can also be a component, which is activated
|
||||
* only by its url.
|
||||
*/
|
||||
export class SNComponent extends DecryptedItem<ComponentContent> implements ComponentInterface {
|
||||
export class ComponentItem extends DecryptedItem<ComponentContent> implements ComponentInterface {
|
||||
public readonly legacyComponentData: Record<string, unknown>
|
||||
/** Items that have requested a component to be disabled in its context */
|
||||
public readonly disassociatedItemIds: string[]
|
||||
@@ -61,7 +43,6 @@ export class SNComponent extends DecryptedItem<ComponentContent> implements Comp
|
||||
public readonly valid_until: Date
|
||||
public readonly legacyActive: boolean
|
||||
public readonly legacy_url?: string
|
||||
public readonly isMobileDefault: boolean
|
||||
|
||||
constructor(payload: DecryptedPayloadInterface<ComponentContent>) {
|
||||
super(payload)
|
||||
@@ -78,13 +59,18 @@ export class SNComponent extends DecryptedItem<ComponentContent> implements Comp
|
||||
this.valid_until = new Date(payload.content.valid_until || 0)
|
||||
this.offlineOnly = payload.content.offlineOnly ?? false
|
||||
this.name = payload.content.name
|
||||
this.area = payload.content.area
|
||||
|
||||
if (this.content_type === ContentType.TYPES.Theme) {
|
||||
this.area = ComponentArea.Themes
|
||||
} else {
|
||||
this.area = payload.content.area
|
||||
}
|
||||
|
||||
this.package_info = payload.content.package_info || {}
|
||||
this.permissions = payload.content.permissions || []
|
||||
this.autoupdateDisabled = payload.content.autoupdateDisabled ?? false
|
||||
this.disassociatedItemIds = payload.content.disassociatedItemIds || []
|
||||
this.associatedItemIds = payload.content.associatedItemIds || []
|
||||
this.isMobileDefault = payload.content.isMobileDefault ?? false
|
||||
|
||||
/**
|
||||
* @legacy
|
||||
@@ -116,15 +102,11 @@ export class SNComponent extends DecryptedItem<ComponentContent> implements Comp
|
||||
return FindNativeFeature(this.identifier)?.name || this.name
|
||||
}
|
||||
|
||||
public override singletonPredicate(): Predicate<SNComponent> {
|
||||
const uniqueIdentifierPredicate = new Predicate<SNComponent>('identifier', '=', this.identifier)
|
||||
public override singletonPredicate(): Predicate<ComponentItem> {
|
||||
const uniqueIdentifierPredicate = new Predicate<ComponentItem>('identifier', '=', this.identifier)
|
||||
return uniqueIdentifierPredicate
|
||||
}
|
||||
|
||||
public isEditor(): boolean {
|
||||
return this.area === ComponentArea.Editor
|
||||
}
|
||||
|
||||
public isTheme(): boolean {
|
||||
return this.content_type === ContentType.TYPES.Theme || this.area === ComponentArea.Themes
|
||||
}
|
||||
@@ -134,10 +116,6 @@ export class SNComponent extends DecryptedItem<ComponentContent> implements Comp
|
||||
return this.getAppDomainValue(AppDataField.DefaultEditor) === true
|
||||
}
|
||||
|
||||
public getLastSize(): unknown {
|
||||
return this.getAppDomainValue(AppDataField.LastSize)
|
||||
}
|
||||
|
||||
public hasValidHostedUrl(): boolean {
|
||||
return (this.hosted_url || this.legacy_url) != undefined
|
||||
}
|
||||
@@ -149,19 +127,6 @@ export class SNComponent extends DecryptedItem<ComponentContent> implements Comp
|
||||
return [...componentKeys, ...superKeys] as (keyof ItemContent)[]
|
||||
}
|
||||
|
||||
/**
|
||||
* An associative component depends on being explicitly activated for a
|
||||
* given item, compared to a dissaciative component, which is enabled by
|
||||
* default in areas unrelated to a certain item.
|
||||
*/
|
||||
public static associativeAreas(): ComponentArea[] {
|
||||
return [ComponentArea.Editor]
|
||||
}
|
||||
|
||||
public isAssociative(): boolean {
|
||||
return SNComponent.associativeAreas().includes(this.area)
|
||||
}
|
||||
|
||||
public isExplicitlyEnabledForItem(uuid: string): boolean {
|
||||
return this.associatedItemIds.indexOf(uuid) !== -1
|
||||
}
|
||||
@@ -199,4 +164,13 @@ export class SNComponent extends DecryptedItem<ComponentContent> implements Comp
|
||||
public get deprecationMessage(): string | undefined {
|
||||
return this.package_info.deprecation_message
|
||||
}
|
||||
|
||||
get layerableTheme(): boolean {
|
||||
if (!this.isTheme()) {
|
||||
return false
|
||||
}
|
||||
|
||||
const themePackageInfo = this.package_info as ThemePackageInfo
|
||||
return themePackageInfo?.layerable ?? false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ export type ComponentContentSpecialized = {
|
||||
valid_until: Date | number
|
||||
|
||||
legacy_url?: string
|
||||
isMobileDefault?: boolean
|
||||
isDeprecated?: boolean
|
||||
|
||||
/** @deprecated */
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { ComponentArea, ComponentPermission, NoteType, ThirdPartyFeatureDescription } from '@standardnotes/features'
|
||||
import { ComponentPackageInfo } from './PackageInfo'
|
||||
import { ComponentPackageInfo, ThemePackageInfo } from './PackageInfo'
|
||||
import { DecryptedItemInterface } from '../../Abstract/Item'
|
||||
import { ComponentContent } from './ComponentContent'
|
||||
|
||||
export interface ComponentInterface extends DecryptedItemInterface<ComponentContent> {
|
||||
export interface ComponentInterface<P extends ComponentPackageInfo | ThemePackageInfo = ComponentPackageInfo>
|
||||
extends DecryptedItemInterface<ComponentContent> {
|
||||
/** Items that have requested a component to be disabled in its context */
|
||||
disassociatedItemIds: string[]
|
||||
|
||||
@@ -16,16 +17,18 @@ export interface ComponentInterface extends DecryptedItemInterface<ComponentCont
|
||||
offlineOnly: boolean
|
||||
name: string
|
||||
autoupdateDisabled: boolean
|
||||
package_info: ComponentPackageInfo
|
||||
package_info: P
|
||||
area: ComponentArea
|
||||
permissions: ComponentPermission[]
|
||||
valid_until: Date
|
||||
isMobileDefault: boolean
|
||||
isDeprecated: boolean
|
||||
|
||||
isExplicitlyEnabledForItem(uuid: string): boolean
|
||||
hasValidHostedUrl(): boolean
|
||||
|
||||
isTheme(): boolean
|
||||
get layerableTheme(): boolean
|
||||
|
||||
isExplicitlyDisabledForItem(uuid: string): boolean
|
||||
legacyIsDefaultEditor(): boolean
|
||||
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import { addIfUnique, removeFromArray } from '@standardnotes/utils'
|
||||
import { ComponentFeatureDescription, ComponentPermission } from '@standardnotes/features'
|
||||
import { AppDataField } from '../../Abstract/Item/Types/AppDataField'
|
||||
import { ComponentContent } from './ComponentContent'
|
||||
import { DecryptedItemMutator } from '../../Abstract/Item/Mutator/DecryptedItemMutator'
|
||||
|
||||
export class ComponentMutator extends DecryptedItemMutator<ComponentContent> {
|
||||
set isMobileDefault(isMobileDefault: boolean) {
|
||||
this.mutableContent.isMobileDefault = isMobileDefault
|
||||
}
|
||||
|
||||
set package_info(package_info: ComponentFeatureDescription) {
|
||||
this.mutableContent.package_info = package_info
|
||||
}
|
||||
@@ -56,8 +51,4 @@ export class ComponentMutator extends DecryptedItemMutator<ComponentContent> {
|
||||
public removeDisassociatedItemId(uuid: string): void {
|
||||
removeFromArray(this.mutableContent.disassociatedItemIds || [], uuid)
|
||||
}
|
||||
|
||||
public setLastSize(size: string): void {
|
||||
this.setAppDataItem(AppDataField.LastSize, size)
|
||||
}
|
||||
}
|
||||
|
||||
29
packages/models/src/Domain/Syncable/Component/TypeGuards.ts
Normal file
29
packages/models/src/Domain/Syncable/Component/TypeGuards.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { ComponentInterface } from './ComponentInterface'
|
||||
import { ItemInterface } from '../../Abstract/Item/Interfaces/ItemInterface'
|
||||
import { DecryptedItemInterface } from '../../Abstract/Item/Interfaces/DecryptedItem'
|
||||
import { isDecryptedItem } from '../../Abstract/Item'
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
|
||||
export function isComponent(x: ItemInterface): x is ComponentInterface {
|
||||
if (!isDecryptedItem(x as DecryptedItemInterface)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return x.content_type === ContentType.TYPES.Component
|
||||
}
|
||||
|
||||
export function isTheme(x: ItemInterface): x is ComponentInterface {
|
||||
if (!isDecryptedItem(x as DecryptedItemInterface)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return x.content_type === ContentType.TYPES.Theme
|
||||
}
|
||||
|
||||
export function isComponentOrTheme(x: ItemInterface): x is ComponentInterface {
|
||||
if (!isDecryptedItem(x as DecryptedItemInterface)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return x.content_type === ContentType.TYPES.Component || x.content_type === ContentType.TYPES.Theme
|
||||
}
|
||||
@@ -2,5 +2,5 @@ export * from './Component'
|
||||
export * from './ComponentMutator'
|
||||
export * from './ComponentContent'
|
||||
export * from './ComponentInterface'
|
||||
export * from '../../Runtime/Feature/UIFeature'
|
||||
export * from './PackageInfo'
|
||||
export * from './TypeGuards'
|
||||
|
||||
@@ -14,7 +14,7 @@ interface EditorContent extends ItemContent {
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Editor objects are depracated in favor of SNComponent objects
|
||||
* Editor objects are depracated in favor of ComponentItem objects
|
||||
*/
|
||||
export class SNEditor extends DecryptedItem<EditorContent> {
|
||||
public readonly notes: SNNote[] = []
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { ComponentArea } from '@standardnotes/features'
|
||||
import { SNComponent } from '../Component/Component'
|
||||
import { ItemInterface } from '../../Abstract/Item'
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
import { useBoolean } from '@standardnotes/utils'
|
||||
import { ThemePackageInfo } from '../Component/PackageInfo'
|
||||
import { ThemeInterface } from './ThemeInterface'
|
||||
|
||||
export const isTheme = (x: ItemInterface): x is ThemeInterface => x.content_type === ContentType.TYPES.Theme
|
||||
|
||||
export class SNTheme extends SNComponent implements ThemeInterface {
|
||||
public override area: ComponentArea = ComponentArea.Themes
|
||||
public declare readonly package_info: ThemePackageInfo
|
||||
|
||||
get layerable(): boolean {
|
||||
return useBoolean(this.package_info && this.package_info.layerable, false)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { ComponentInterface } from '../Component'
|
||||
import { ThemePackageInfo } from '../Component/PackageInfo'
|
||||
|
||||
export interface ThemeInterface extends ComponentInterface {
|
||||
get layerable(): boolean
|
||||
readonly package_info: ThemePackageInfo
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
import { ComponentContent } from '../Component/ComponentContent'
|
||||
import { DecryptedItemMutator } from '../../Abstract/Item/Mutator/DecryptedItemMutator'
|
||||
|
||||
export class ThemeMutator extends DecryptedItemMutator<ComponentContent> {}
|
||||
@@ -1,3 +0,0 @@
|
||||
export * from './Theme'
|
||||
export * from './ThemeMutator'
|
||||
export * from './ThemeInterface'
|
||||
@@ -3,17 +3,15 @@ import { DecryptedPayloadInterface } from '../../Abstract/Payload/Interfaces/Dec
|
||||
import { FileItem } from '../../Syncable/File/File'
|
||||
import { SNFeatureRepo } from '../../Syncable/FeatureRepo/FeatureRepo'
|
||||
import { SNActionsExtension } from '../../Syncable/ActionsExtension/ActionsExtension'
|
||||
import { SNComponent } from '../../Syncable/Component/Component'
|
||||
import { ComponentItem } from '../../Syncable/Component/Component'
|
||||
import { SNEditor } from '../../Syncable/Editor/Editor'
|
||||
import { DecryptedItem } from '../../Abstract/Item/Implementations/DecryptedItem'
|
||||
import { SNNote } from '../../Syncable/Note/Note'
|
||||
import { SmartView } from '../../Syncable/SmartView/SmartView'
|
||||
import { SNTag } from '../../Syncable/Tag/Tag'
|
||||
import { SNTheme } from '../../Syncable/Theme/Theme'
|
||||
import { SNUserPrefs } from '../../Syncable/UserPrefs/UserPrefs'
|
||||
import { FileMutator } from '../../Syncable/File/FileMutator'
|
||||
import { MutationType } from '../../Abstract/Item/Types/MutationType'
|
||||
import { ThemeMutator } from '../../Syncable/Theme/ThemeMutator'
|
||||
import { UserPrefsMutator } from '../../Syncable/UserPrefs/UserPrefsMutator'
|
||||
import { ActionsExtensionMutator } from '../../Syncable/ActionsExtension/ActionsExtensionMutator'
|
||||
import { ComponentMutator } from '../../Syncable/Component/ComponentMutator'
|
||||
@@ -58,7 +56,7 @@ const ContentTypeClassMapping: Partial<Record<string, MappingEntry>> = {
|
||||
itemClass: SNActionsExtension,
|
||||
mutatorClass: ActionsExtensionMutator,
|
||||
},
|
||||
[ContentType.TYPES.Component]: { itemClass: SNComponent, mutatorClass: ComponentMutator },
|
||||
[ContentType.TYPES.Component]: { itemClass: ComponentItem, mutatorClass: ComponentMutator },
|
||||
[ContentType.TYPES.KeySystemRootKey]: { itemClass: KeySystemRootKey, mutatorClass: KeySystemRootKeyMutator },
|
||||
[ContentType.TYPES.TrustedContact]: { itemClass: TrustedContact, mutatorClass: TrustedContactMutator },
|
||||
[ContentType.TYPES.VaultListing]: { itemClass: VaultListing, mutatorClass: VaultListingMutator },
|
||||
@@ -68,7 +66,7 @@ const ContentTypeClassMapping: Partial<Record<string, MappingEntry>> = {
|
||||
[ContentType.TYPES.Note]: { itemClass: SNNote, mutatorClass: NoteMutator },
|
||||
[ContentType.TYPES.SmartView]: { itemClass: SmartView, mutatorClass: SmartViewMutator },
|
||||
[ContentType.TYPES.Tag]: { itemClass: SNTag, mutatorClass: TagMutator },
|
||||
[ContentType.TYPES.Theme]: { itemClass: SNTheme, mutatorClass: ThemeMutator },
|
||||
[ContentType.TYPES.Theme]: { itemClass: ComponentItem, mutatorClass: ComponentMutator },
|
||||
[ContentType.TYPES.UserPrefs]: { itemClass: SNUserPrefs, mutatorClass: UserPrefsMutator },
|
||||
} as unknown as Partial<Record<string, MappingEntry>>
|
||||
|
||||
|
||||
@@ -93,7 +93,6 @@ export * from './Syncable/ItemsKey/ItemsKeyMutatorInterface'
|
||||
export * from './Syncable/Note'
|
||||
export * from './Syncable/SmartView'
|
||||
export * from './Syncable/Tag'
|
||||
export * from './Syncable/Theme'
|
||||
export * from './Syncable/UserPrefs'
|
||||
|
||||
export * from './Syncable/TrustedContact/TrustedContact'
|
||||
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
FileItem,
|
||||
VaultDisplayOptions,
|
||||
NotesAndFilesDisplayControllerOptions,
|
||||
ThemeInterface,
|
||||
ComponentInterface,
|
||||
ItemStream,
|
||||
} from '@standardnotes/models'
|
||||
@@ -123,7 +122,7 @@ export interface ItemManagerInterface extends AbstractService {
|
||||
getTagParent(itemToLookupUuidFor: SNTag): SNTag | undefined
|
||||
isValidTagParent(parentTagToLookUpUuidFor: SNTag, childToLookUpUuidFor: SNTag): boolean
|
||||
isSmartViewTitle(title: string): boolean
|
||||
getDisplayableComponents(): (ComponentInterface | ThemeInterface)[]
|
||||
getDisplayableComponents(): ComponentInterface[]
|
||||
createItemFromPayload<T extends DecryptedItemInterface>(payload: DecryptedPayloadInterface): T
|
||||
createPayloadFromObject(object: DecryptedTransferPayload): DecryptedPayloadInterface
|
||||
getDisplayableFiles(): FileItem[]
|
||||
|
||||
@@ -12,7 +12,7 @@ import { SignInWithRecoveryCodes } from '../../Domain/UseCase/SignInWithRecovery
|
||||
import { ListedService } from '../../Services/Listed/ListedService'
|
||||
import { MigrationService } from '../../Services/Migration/MigrationService'
|
||||
import { MfaService } from '../../Services/Mfa/MfaService'
|
||||
import { SNComponentManager } from '../../Services/ComponentManager/ComponentManager'
|
||||
import { ComponentManager } from '../../Services/ComponentManager/ComponentManager'
|
||||
import { FeaturesService } from '@Lib/Services/Features/FeaturesService'
|
||||
import { SettingsService } from '../../Services/Settings/SNSettingsService'
|
||||
import { PreferencesService } from '../../Services/Preferences/PreferencesService'
|
||||
@@ -1107,7 +1107,7 @@ export class Dependencies {
|
||||
})
|
||||
|
||||
this.factory.set(TYPES.ComponentManager, () => {
|
||||
return new SNComponentManager(
|
||||
return new ComponentManager(
|
||||
this.get<ItemManager>(TYPES.ItemManager),
|
||||
this.get<MutatorService>(TYPES.MutatorService),
|
||||
this.get<SyncService>(TYPES.SyncService),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ApplicationStage } from '@standardnotes/services'
|
||||
import { Migration } from '@Lib/Migrations/Migration'
|
||||
import { ThemeInterface } from '@standardnotes/models'
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
import { ComponentInterface } from '@standardnotes/models'
|
||||
|
||||
const NoDistractionIdentifier = 'org.standardnotes.theme-no-distraction'
|
||||
|
||||
@@ -18,7 +18,7 @@ export class Migration2_42_0 extends Migration {
|
||||
}
|
||||
|
||||
private async deleteNoDistraction(): Promise<void> {
|
||||
const themes = this.services.itemManager.getItems<ThemeInterface>(ContentType.TYPES.Theme).filter((theme) => {
|
||||
const themes = this.services.itemManager.getItems<ComponentInterface>(ContentType.TYPES.Theme).filter((theme) => {
|
||||
return theme.identifier === NoDistractionIdentifier
|
||||
})
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CompoundPredicate, Predicate, SNComponent } from '@standardnotes/models'
|
||||
import { CompoundPredicate, Predicate, ComponentItem } from '@standardnotes/models'
|
||||
import { Migration } from '@Lib/Migrations/Migration'
|
||||
import { ApplicationStage } from '@standardnotes/services'
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
@@ -19,8 +19,8 @@ export class Migration2_7_0 extends Migration {
|
||||
const batchMgrId = 'org.standardnotes.batch-manager'
|
||||
|
||||
const batchMgrPred = new CompoundPredicate('and', [
|
||||
new Predicate<SNComponent>('content_type', '=', ContentType.TYPES.Component),
|
||||
new Predicate<SNComponent>('identifier', '=', batchMgrId),
|
||||
new Predicate<ComponentItem>('content_type', '=', ContentType.TYPES.Component),
|
||||
new Predicate<ComponentItem>('identifier', '=', batchMgrId),
|
||||
])
|
||||
|
||||
const batchMgrSingleton = this.services.singletonManager.findSingleton(ContentType.TYPES.Component, batchMgrPred)
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from '@standardnotes/services'
|
||||
import { ItemManager } from '@Lib/Services/Items/ItemManager'
|
||||
import { FeaturesService } from '@Lib/Services/Features/FeaturesService'
|
||||
import { SNComponentManager } from './ComponentManager'
|
||||
import { ComponentManager } from './ComponentManager'
|
||||
import { SyncService } from '../Sync/SyncService'
|
||||
import { LoggerInterface } from '@standardnotes/utils'
|
||||
|
||||
@@ -27,7 +27,7 @@ describe('featuresService', () => {
|
||||
let logger: LoggerInterface
|
||||
|
||||
const createManager = (environment: Environment, platform: Platform) => {
|
||||
const manager = new SNComponentManager(
|
||||
const manager = new ComponentManager(
|
||||
items,
|
||||
mutator,
|
||||
sync,
|
||||
|
||||
@@ -69,7 +69,7 @@ declare global {
|
||||
* 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
|
||||
export class ComponentManager
|
||||
extends AbstractService<ComponentManagerEvent, ComponentManagerEventData>
|
||||
implements ComponentManagerInterface
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ItemManagerInterface, PreferenceServiceInterface } from '@standardnotes/services'
|
||||
import { GetDefaultEditorIdentifier } from './GetDefaultEditorIdentifier'
|
||||
import { ComponentArea, NativeFeatureIdentifier } from '@standardnotes/features'
|
||||
import { SNComponent, SNTag } from '@standardnotes/models'
|
||||
import { ComponentItem, SNTag } from '@standardnotes/models'
|
||||
|
||||
describe('getDefaultEditorIdentifier', () => {
|
||||
let usecase: GetDefaultEditorIdentifier
|
||||
@@ -49,7 +49,7 @@ describe('getDefaultEditorIdentifier', () => {
|
||||
legacyIsDefaultEditor: jest.fn().mockReturnValue(true),
|
||||
identifier: NativeFeatureIdentifier.TYPES.MarkdownProEditor,
|
||||
area: ComponentArea.Editor,
|
||||
} as unknown as jest.Mocked<SNComponent>
|
||||
} as unknown as jest.Mocked<ComponentItem>
|
||||
|
||||
items.getDisplayableComponents = jest.fn().mockReturnValue([editor])
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
Environment,
|
||||
PayloadTimestampDefaults,
|
||||
Platform,
|
||||
SNComponent,
|
||||
ComponentItem,
|
||||
UIFeature,
|
||||
} from '@standardnotes/models'
|
||||
import { DesktopManagerInterface } from '@standardnotes/services'
|
||||
@@ -26,7 +26,7 @@ const nativeFeatureAsUIFeature = <F extends UIFeatureDescriptionTypes>(identifie
|
||||
}
|
||||
|
||||
const thirdPartyFeature = () => {
|
||||
const component = new SNComponent(
|
||||
const component = new ComponentItem(
|
||||
new DecryptedPayload({
|
||||
uuid: '789',
|
||||
content_type: ContentType.TYPES.Component,
|
||||
@@ -101,7 +101,7 @@ describe('GetFeatureUrl', () => {
|
||||
})
|
||||
|
||||
it('returns hosted url for third party component with no local_url', () => {
|
||||
const component = new SNComponent({
|
||||
const component = new ComponentItem({
|
||||
uuid: '789',
|
||||
content_type: ContentType.TYPES.Component,
|
||||
content: {
|
||||
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
FillItemContent,
|
||||
PayloadEmitSource,
|
||||
ComponentInterface,
|
||||
ThemeInterface,
|
||||
DecryptedItemInterface,
|
||||
} from '@standardnotes/models'
|
||||
import {
|
||||
@@ -191,7 +190,7 @@ export class FeaturesService
|
||||
void this.storage.setValue(StorageKey.ExperimentalFeatures, this.enabledExperimentalFeatures)
|
||||
|
||||
const component = this.items
|
||||
.getItems<ComponentInterface | ThemeInterface>([ContentType.TYPES.Component, ContentType.TYPES.Theme])
|
||||
.getItems<ComponentInterface>([ContentType.TYPES.Component, ContentType.TYPES.Theme])
|
||||
.find((component) => component.identifier === identifier)
|
||||
if (!component) {
|
||||
return
|
||||
|
||||
@@ -37,7 +37,7 @@ export class ItemManager extends Services.AbstractService implements Services.It
|
||||
private tagDisplayController!: Models.ItemDisplayController<Models.SNTag, Models.TagsDisplayOptions>
|
||||
private itemsKeyDisplayController!: Models.ItemDisplayController<SNItemsKey>
|
||||
private componentDisplayController!: Models.ItemDisplayController<Models.ComponentInterface>
|
||||
private themeDisplayController!: Models.ItemDisplayController<Models.ThemeInterface>
|
||||
private themeDisplayController!: Models.ItemDisplayController<Models.ComponentInterface>
|
||||
private fileDisplayController!: Models.ItemDisplayController<Models.FileItem>
|
||||
private smartViewDisplayController!: Models.ItemDisplayController<Models.SmartView>
|
||||
|
||||
@@ -225,7 +225,7 @@ export class ItemManager extends Services.AbstractService implements Services.It
|
||||
return this.itemsKeyDisplayController.items()
|
||||
}
|
||||
|
||||
public getDisplayableComponents(): (Models.ComponentInterface | Models.ThemeInterface)[] {
|
||||
public getDisplayableComponents(): Models.ComponentInterface[] {
|
||||
return [...this.componentDisplayController.items(), ...this.themeDisplayController.items()]
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UIFeature, ThemeInterface } from '@standardnotes/models'
|
||||
import { UIFeature, ComponentInterface } from '@standardnotes/models'
|
||||
import { ItemManagerInterface } from '@standardnotes/services'
|
||||
import { NativeFeatureIdentifier, FindNativeTheme, ThemeFeatureDescription } from '@standardnotes/features'
|
||||
import { Uuid } from '@standardnotes/domain-core'
|
||||
@@ -54,7 +54,7 @@ export class ActiveThemeList {
|
||||
|
||||
for (const entry of this.list) {
|
||||
if (entry instanceof Uuid) {
|
||||
const theme = this.items.findItem<ThemeInterface>(entry.value)
|
||||
const theme = this.items.findItem<ComponentInterface>(entry.value)
|
||||
if (theme) {
|
||||
const uiFeature = new UIFeature<ThemeFeatureDescription>(theme)
|
||||
results.push(uiFeature)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { FindNativeTheme, GetNativeThemes, ThemeFeatureDescription } from '@standardnotes/features'
|
||||
import { UIFeature, ThemeInterface } from '@standardnotes/models'
|
||||
import { ComponentInterface, UIFeature } from '@standardnotes/models'
|
||||
import { ItemManagerInterface } from '@standardnotes/services'
|
||||
|
||||
export class GetAllThemesUseCase {
|
||||
@@ -15,10 +15,10 @@ export class GetAllThemesUseCase {
|
||||
.getDisplayableComponents()
|
||||
.filter(
|
||||
(component) => component.isTheme() && FindNativeTheme(component.identifier) === undefined,
|
||||
) as ThemeInterface[]
|
||||
) as ComponentInterface[]
|
||||
|
||||
const filteredThirdPartyThemes = allThirdPartyThemes.filter((theme) => {
|
||||
return options.excludeLayerable ? !theme.layerable : true
|
||||
return options.excludeLayerable ? !theme.layerableTheme : true
|
||||
})
|
||||
|
||||
return {
|
||||
|
||||
@@ -4,8 +4,8 @@ import {
|
||||
CreateDecryptedLocalStorageContextPayload,
|
||||
LocalStorageDecryptedContextualPayload,
|
||||
PrefKey,
|
||||
ThemeInterface,
|
||||
PrefDefaults,
|
||||
ComponentInterface,
|
||||
} from '@standardnotes/models'
|
||||
import {
|
||||
InternalEventBusInterface,
|
||||
@@ -113,7 +113,7 @@ export class ThemeManager extends AbstractUIServicee {
|
||||
|
||||
for (const uuid of uuids) {
|
||||
if (!this.themesActiveInTheUI.has(uuid)) {
|
||||
const theme = this.application.items.findItem<ThemeInterface>(uuid.value)
|
||||
const theme = this.application.items.findItem<ComponentInterface>(uuid.value)
|
||||
if (theme) {
|
||||
const uiFeature = new UIFeature<ThemeFeatureDescription>(theme)
|
||||
this.activateTheme(uiFeature)
|
||||
@@ -444,7 +444,7 @@ export class ThemeManager extends AbstractUIServicee {
|
||||
for (const cachedTheme of cachedThemes) {
|
||||
if ('uuid' in cachedTheme) {
|
||||
const payload = this.application.items.createPayloadFromObject(cachedTheme)
|
||||
const theme = this.application.items.createItemFromPayload<ThemeInterface>(payload)
|
||||
const theme = this.application.items.createItemFromPayload<ComponentInterface>(payload)
|
||||
features.push(new UIFeature<ThemeFeatureDescription>(theme))
|
||||
} else if ('identifier' in cachedTheme) {
|
||||
const feature = FindNativeTheme((cachedTheme as ThemeFeatureDescription).identifier)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { HeadlessSuperConverter } from '@/Components/SuperEditor/Tools/HeadlessSuperConverter'
|
||||
import {
|
||||
SNComponent,
|
||||
ComponentItem,
|
||||
ComponentMutator,
|
||||
AppDataField,
|
||||
ApplicationService,
|
||||
@@ -26,7 +26,7 @@ export class DesktopManager
|
||||
implements DesktopManagerInterface, DesktopClientRequiresWebMethods
|
||||
{
|
||||
updateObservers: {
|
||||
callback: (component: SNComponent) => void
|
||||
callback: (component: ComponentItem) => void
|
||||
}[] = []
|
||||
|
||||
dataLoaded = false
|
||||
@@ -204,7 +204,7 @@ export class DesktopManager
|
||||
).getValue()
|
||||
|
||||
for (const observer of this.updateObservers) {
|
||||
observer.callback(updatedComponent as SNComponent)
|
||||
observer.callback(updatedComponent as ComponentItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { WebApplication } from '@/Application/WebApplication'
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
import {
|
||||
SNComponentManager,
|
||||
SNComponent,
|
||||
ComponentManager,
|
||||
ComponentItem,
|
||||
SNTag,
|
||||
SNNote,
|
||||
Deferred,
|
||||
@@ -16,7 +16,7 @@ import { NoteViewController } from './NoteViewController'
|
||||
|
||||
describe('note view controller', () => {
|
||||
let application: WebApplication
|
||||
let componentManager: SNComponentManager
|
||||
let componentManager: ComponentManager
|
||||
|
||||
beforeEach(() => {
|
||||
application = {
|
||||
@@ -35,7 +35,7 @@ describe('note view controller', () => {
|
||||
Object.defineProperty(application, 'sync', { value: {} as jest.Mocked<SyncServiceInterface> })
|
||||
application.sync.sync = jest.fn().mockReturnValue(Promise.resolve())
|
||||
|
||||
componentManager = {} as jest.Mocked<SNComponentManager>
|
||||
componentManager = {} as jest.Mocked<ComponentManager>
|
||||
Object.defineProperty(application, 'componentManager', { value: componentManager })
|
||||
})
|
||||
|
||||
@@ -68,7 +68,7 @@ describe('note view controller', () => {
|
||||
application.items.getDisplayableComponents = jest.fn().mockReturnValue([
|
||||
{
|
||||
identifier: NativeFeatureIdentifier.TYPES.MarkdownProEditor,
|
||||
} as SNComponent,
|
||||
} as ComponentItem,
|
||||
])
|
||||
|
||||
application.componentManager.getDefaultEditorIdentifier = jest
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { FunctionComponent, useState } from 'react'
|
||||
import { ComponentInterface, ComponentMutator, SNComponent } from '@standardnotes/snjs'
|
||||
import { ComponentInterface, ComponentMutator, ComponentItem } from '@standardnotes/snjs'
|
||||
import { SubtitleLight } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import Switch from '@/Components/Switch/Switch'
|
||||
import Button from '@/Components/Button/Button'
|
||||
@@ -28,7 +28,7 @@ interface PackageEntryProps {
|
||||
}
|
||||
|
||||
const PackageEntry: FunctionComponent<PackageEntryProps> = ({ application, extension, uninstall }) => {
|
||||
const [offlineOnly, setOfflineOnly] = useState(extension instanceof SNComponent ? extension.offlineOnly : false)
|
||||
const [offlineOnly, setOfflineOnly] = useState(extension instanceof ComponentItem ? extension.offlineOnly : false)
|
||||
const [extensionName, setExtensionName] = useState(extension.displayName)
|
||||
|
||||
const toggleOfflineOnly = () => {
|
||||
|
||||
@@ -45,7 +45,7 @@ const PackagesPreferencesSection: FunctionComponent<Props> = ({
|
||||
application.alerts
|
||||
.confirm(
|
||||
'Are you sure you want to uninstall this plugin? Note that plugins managed by your subscription will automatically be re-installed on application restart.',
|
||||
'Uninstall Extension?',
|
||||
'Uninstall Plugin?',
|
||||
'Uninstall',
|
||||
ButtonType.Danger,
|
||||
'Cancel',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { ComponentInterface, SNActionsExtension, ThemeInterface } from '@standardnotes/snjs'
|
||||
import { ComponentInterface, SNActionsExtension } from '@standardnotes/snjs'
|
||||
|
||||
export type AnyPackageType = ComponentInterface | ThemeInterface | SNActionsExtension
|
||||
export type AnyPackageType = ComponentInterface | SNActionsExtension
|
||||
|
||||
Reference in New Issue
Block a user