From 05ac0bef26d88a73d6c0dbde38f0737e7c6cf1db Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 15 May 2020 00:46:59 +0200 Subject: [PATCH] packages/core: added AppThemeSelector --- .../src/api/apis/definitions/AppThemeApi.ts | 2 +- .../AppThemeSelector/AppThemeSelector.test.ts | 48 +++++++++++++++ .../AppThemeSelector/AppThemeSelector.ts | 59 +++++++++++++++++++ .../implementations/AppThemeSelector/index.ts | 17 ++++++ .../src/api/apis/implementations/index.ts | 1 + 5 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 packages/core/src/api/apis/implementations/AppThemeSelector/AppThemeSelector.test.ts create mode 100644 packages/core/src/api/apis/implementations/AppThemeSelector/AppThemeSelector.ts create mode 100644 packages/core/src/api/apis/implementations/AppThemeSelector/index.ts diff --git a/packages/core/src/api/apis/definitions/AppThemeApi.ts b/packages/core/src/api/apis/definitions/AppThemeApi.ts index 801210de0a..738bae8a9f 100644 --- a/packages/core/src/api/apis/definitions/AppThemeApi.ts +++ b/packages/core/src/api/apis/definitions/AppThemeApi.ts @@ -51,7 +51,7 @@ export type AppThemeApi = { /** * Get a list of available themes. */ - getThemeOptions(): AppTheme[]; + getInstalledThemes(): AppTheme[]; /** * Observe the currently selected theme. A value of undefined means no specific theme has been selected. diff --git a/packages/core/src/api/apis/implementations/AppThemeSelector/AppThemeSelector.test.ts b/packages/core/src/api/apis/implementations/AppThemeSelector/AppThemeSelector.test.ts new file mode 100644 index 0000000000..6c6c9774bd --- /dev/null +++ b/packages/core/src/api/apis/implementations/AppThemeSelector/AppThemeSelector.test.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AppTheme } from '../../definitions'; +import { AppThemeSelector } from './AppThemeSelector'; + +describe('AppThemeSelector', () => { + it('should should select new themes', async () => { + const selector = new AppThemeSelector([]); + + expect(selector.getInstalledThemes()).toEqual([]); + + const subFn = jest.fn(); + selector.activeThemeId$().subscribe(subFn); + expect(selector.getActiveThemeId()).toBe(undefined); + await 'wait a tick'; + expect(subFn).toHaveBeenLastCalledWith(undefined); + + selector.setActiveThemeId('x'); + expect(subFn).toHaveBeenLastCalledWith('x'); + expect(selector.getActiveThemeId()).toBe('x'); + + selector.setActiveThemeId(undefined); + expect(subFn).toHaveBeenLastCalledWith(undefined); + expect(selector.getActiveThemeId()).toBe(undefined); + }); + + it('should return a new array of themes', () => { + const themes = new Array(); + const selector = new AppThemeSelector(themes); + + expect(selector.getInstalledThemes()).toEqual(themes); + expect(selector.getInstalledThemes()).not.toBe(themes); + }); +}); diff --git a/packages/core/src/api/apis/implementations/AppThemeSelector/AppThemeSelector.ts b/packages/core/src/api/apis/implementations/AppThemeSelector/AppThemeSelector.ts new file mode 100644 index 0000000000..97343f8d1b --- /dev/null +++ b/packages/core/src/api/apis/implementations/AppThemeSelector/AppThemeSelector.ts @@ -0,0 +1,59 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Observable from 'zen-observable'; +import { AppThemeApi, AppTheme } from '../../definitions'; + +export class AppThemeSelector implements AppThemeApi { + private readonly themes: AppTheme[]; + + private activeThemeId: string | undefined; + + private readonly observable: Observable; + private readonly subscribers = new Set< + ZenObservable.SubscriptionObserver + >(); + + constructor(themes: AppTheme[]) { + this.themes = themes; + + this.observable = new Observable((subscriber) => { + subscriber.next(this.activeThemeId); + + this.subscribers.add(subscriber); + return () => { + this.subscribers.delete(subscriber); + }; + }); + } + + getInstalledThemes(): AppTheme[] { + return this.themes.slice(); + } + + activeThemeId$(): Observable { + return this.observable; + } + + getActiveThemeId(): string | undefined { + return this.activeThemeId; + } + + setActiveThemeId(themeId?: string): void { + this.activeThemeId = themeId; + this.subscribers.forEach((subscriber) => subscriber.next(themeId)); + } +} diff --git a/packages/core/src/api/apis/implementations/AppThemeSelector/index.ts b/packages/core/src/api/apis/implementations/AppThemeSelector/index.ts new file mode 100644 index 0000000000..cb42c0f875 --- /dev/null +++ b/packages/core/src/api/apis/implementations/AppThemeSelector/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './AppThemeSelector'; diff --git a/packages/core/src/api/apis/implementations/index.ts b/packages/core/src/api/apis/implementations/index.ts index ebd89b54c6..8334b068fc 100644 --- a/packages/core/src/api/apis/implementations/index.ts +++ b/packages/core/src/api/apis/implementations/index.ts @@ -18,6 +18,7 @@ // // Plugins should rely on these APIs for functionality as much as possible. +export * from './AppThemeSelector'; export * from './AlertApiForwarder'; export * from './ErrorApiForwarder'; export * from './OAuthRequestManager';