fix: Fixes issue where lock screen would not use previously active theme (#2372)

This commit is contained in:
Mo
2023-07-26 15:50:08 -05:00
committed by GitHub
parent 86fc4c684d
commit d268c02ab3
88 changed files with 1118 additions and 716 deletions

View File

@@ -3,13 +3,14 @@ import {
ComponentArea,
ComponentFeatureDescription,
EditorFeatureDescription,
EditorIdentifier,
IframeComponentFeatureDescription,
NativeFeatureIdentifier,
ThemeFeatureDescription,
} from '@standardnotes/features'
import { ActionObserver, ComponentInterface, UIFeature, PermissionDialog, SNNote, SNTag } from '@standardnotes/models'
import { DesktopManagerInterface } from '../Device/DesktopManagerInterface'
import { ComponentViewerInterface } from './ComponentViewerInterface'
import { Uuid } from '@standardnotes/domain-core'
export interface ComponentManagerInterface {
urlForFeature(uiFeature: UIFeature<ComponentFeatureDescription>): string | undefined
@@ -31,12 +32,12 @@ export interface ComponentManagerInterface {
setPermissionDialogUIHandler(handler: (dialog: PermissionDialog) => void): void
editorForNote(note: SNNote): UIFeature<EditorFeatureDescription | IframeComponentFeatureDescription>
getDefaultEditorIdentifier(currentTag?: SNTag): EditorIdentifier
getDefaultEditorIdentifier(currentTag?: SNTag): string
isThemeActive(theme: UIFeature<ThemeFeatureDescription>): boolean
toggleTheme(theme: UIFeature<ThemeFeatureDescription>): Promise<void>
getActiveThemes(): UIFeature<ThemeFeatureDescription>[]
getActiveThemesIdentifiers(): string[]
getActiveThemesIdentifiers(): { features: NativeFeatureIdentifier[]; uuids: Uuid[] }
isComponentActive(component: ComponentInterface): boolean
toggleComponent(component: ComponentInterface): Promise<void>

View File

@@ -1,7 +1,8 @@
import { ActionObserver, ComponentEventObserver, ComponentMessage, UIFeature } from '@standardnotes/models'
import { FeatureStatus } from '../Feature/FeatureStatus'
import { ComponentViewerError } from './ComponentViewerError'
import { IframeComponentFeatureDescription } from '@standardnotes/features'
import { IframeComponentFeatureDescription, NativeFeatureIdentifier } from '@standardnotes/features'
import { Uuid } from '@standardnotes/domain-core'
export interface ComponentViewerInterface {
readonly identifier: string
@@ -9,7 +10,7 @@ export interface ComponentViewerInterface {
readonly sessionKey?: string
get url(): string
get componentUniqueIdentifier(): string
get componentUniqueIdentifier(): NativeFeatureIdentifier | Uuid
getComponentOrFeatureItem(): UIFeature<IframeComponentFeatureDescription>

View File

@@ -1,12 +1,15 @@
import { FeatureIdentifier } from '@standardnotes/features'
import { ComponentInterface, DecryptedItemInterface } from '@standardnotes/models'
import { FeatureStatus } from './FeatureStatus'
import { SetOfflineFeaturesFunctionResponse } from './SetOfflineFeaturesFunctionResponse'
import { NativeFeatureIdentifier } from '@standardnotes/features'
import { Uuid } from '@standardnotes/domain-core'
export interface FeaturesClientInterface {
initializeFromDisk(): void
getFeatureStatus(featureId: FeatureIdentifier, options?: { inContextOfItem?: DecryptedItemInterface }): FeatureStatus
getFeatureStatus(
featureId: NativeFeatureIdentifier | Uuid,
options?: { inContextOfItem?: DecryptedItemInterface },
): FeatureStatus
hasMinimumRole(role: string): boolean
hasFirstPartyOfflineSubscription(): boolean
@@ -16,13 +19,13 @@ export interface FeaturesClientInterface {
isThirdPartyFeature(identifier: string): boolean
toggleExperimentalFeature(identifier: FeatureIdentifier): void
getExperimentalFeatures(): FeatureIdentifier[]
getEnabledExperimentalFeatures(): FeatureIdentifier[]
enableExperimentalFeature(identifier: FeatureIdentifier): void
disableExperimentalFeature(identifier: FeatureIdentifier): void
isExperimentalFeatureEnabled(identifier: FeatureIdentifier): boolean
isExperimentalFeature(identifier: FeatureIdentifier): boolean
toggleExperimentalFeature(identifier: string): void
getExperimentalFeatures(): string[]
getEnabledExperimentalFeatures(): string[]
enableExperimentalFeature(identifier: string): void
disableExperimentalFeature(identifier: string): void
isExperimentalFeatureEnabled(identifier: string): boolean
isExperimentalFeature(identifier: string): boolean
downloadRemoteThirdPartyFeature(urlOrCode: string): Promise<ComponentInterface | undefined>
}

View File

@@ -1,5 +1,5 @@
export enum SessionEvent {
Restored = 'SessionRestored',
Revoked = 'SessionRevoked',
UserKeyPairChanged = 'UserKeyPairChanged',
Restored = 'SessionEvent:SessionRestored',
Revoked = 'SessionEvent:SessionRevoked',
UserKeyPairChanged = 'SessionEvent:UserKeyPairChanged',
}

View File

@@ -18,8 +18,6 @@ export interface SessionsClientInterface {
getWorkspaceDisplayIdentifier(): string
populateSessionFromDemoShareToken(token: Base64String): Promise<void>
initializeFromDisk(): Promise<void>
getUser(): User | undefined
isSignedIn(): boolean
get userUuid(): string

View File

@@ -1,3 +1,6 @@
import { ApplicationStage } from './../Application/ApplicationStage'
import { SessionEvent } from './../Session/SessionEvent'
import { ApplicationEvent } from './../Event/ApplicationEvent'
import { StorageServiceInterface } from './../Storage/StorageServiceInterface'
import { SessionsClientInterface } from './../Session/SessionsClientInterface'
import { SubscriptionApiServiceInterface } from '@standardnotes/api'
@@ -21,11 +24,66 @@ describe('SubscriptionManager', () => {
subscriptionApiService.listInvites = jest.fn()
sessions = {} as jest.Mocked<SessionsClientInterface>
sessions.isSignedIn = jest.fn().mockReturnValue(true)
storage = {} as jest.Mocked<StorageServiceInterface>
internalEventBus = {} as jest.Mocked<InternalEventBusInterface>
internalEventBus.addEventHandler = jest.fn()
internalEventBus.publish = jest.fn()
})
describe('event handling', () => {
it('should fetch subscriptions when the application has launched', async () => {
const manager = createManager()
jest.spyOn(manager, 'fetchOnlineSubscription')
jest.spyOn(manager, 'fetchAvailableSubscriptions')
await manager.handleEvent({ type: ApplicationEvent.Launched, payload: {} })
expect(manager.fetchOnlineSubscription).toHaveBeenCalledTimes(1)
expect(manager.fetchAvailableSubscriptions).toHaveBeenCalledTimes(1)
})
it('should fetch online subscription when user roles have changed', async () => {
const manager = createManager()
jest.spyOn(manager, 'fetchOnlineSubscription')
await manager.handleEvent({ type: ApplicationEvent.UserRolesChanged, payload: {} })
expect(manager.fetchOnlineSubscription).toHaveBeenCalledTimes(1)
})
it('should fetch online subscription when session is restored', async () => {
const manager = createManager()
jest.spyOn(manager, 'fetchOnlineSubscription')
await manager.handleEvent({ type: SessionEvent.Restored, payload: {} })
expect(manager.fetchOnlineSubscription).toHaveBeenCalledTimes(1)
})
it('should fetch online subscription when user has signed in', async () => {
const manager = createManager()
jest.spyOn(manager, 'fetchOnlineSubscription')
await manager.handleEvent({ type: ApplicationEvent.SignedIn, payload: {} })
expect(manager.fetchOnlineSubscription).toHaveBeenCalledTimes(1)
})
it('should handle stage change and notify event', async () => {
const manager = createManager()
jest.spyOn(manager, 'loadSubscriptionFromStorage')
storage.getValue = jest.fn().mockReturnValue({})
await manager.handleEvent({
type: ApplicationEvent.ApplicationStageChanged,
payload: { stage: ApplicationStage.StorageDecrypted_09 },
})
expect(manager.loadSubscriptionFromStorage).toHaveBeenCalled()
})
})
it('should invite user by email to a shared subscription', async () => {

View File

@@ -1,3 +1,4 @@
import { SessionEvent } from './../Session/SessionEvent'
import { StorageKey } from './../Storage/StorageKeys'
import { ApplicationStage } from './../Application/ApplicationStage'
import { StorageServiceInterface } from './../Storage/StorageServiceInterface'
@@ -51,6 +52,7 @@ export class SubscriptionManager
}
case ApplicationEvent.UserRolesChanged:
case SessionEvent.Restored:
case ApplicationEvent.SignedIn:
void this.fetchOnlineSubscription()
break
@@ -58,13 +60,17 @@ export class SubscriptionManager
case ApplicationEvent.ApplicationStageChanged: {
const stage = (event.payload as ApplicationStageChangedEventPayload).stage
if (stage === ApplicationStage.StorageDecrypted_09) {
this.onlineSubscription = this.storage.getValue(StorageKey.Subscription)
void this.notifyEvent(SubscriptionManagerEvent.DidFetchSubscription)
this.loadSubscriptionFromStorage()
}
}
}
}
loadSubscriptionFromStorage(): void {
this.onlineSubscription = this.storage.getValue(StorageKey.Subscription)
void this.notifyEvent(SubscriptionManagerEvent.DidFetchSubscription)
}
hasOnlineSubscription(): boolean {
return this.onlineSubscription != undefined
}
@@ -204,7 +210,7 @@ export class SubscriptionManager
void this.notifyEvent(SubscriptionManagerEvent.DidFetchSubscription)
}
private async fetchAvailableSubscriptions(): Promise<void> {
async fetchAvailableSubscriptions(): Promise<void> {
try {
const response = await this.subscriptionApiService.getAvailableSubscriptions()