packages/core: added AppThemeSelector

This commit is contained in:
Patrik Oldsberg
2020-05-15 00:46:59 +02:00
parent b8e3f9736e
commit 05ac0bef26
5 changed files with 126 additions and 1 deletions
@@ -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.
@@ -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<AppTheme>();
const selector = new AppThemeSelector(themes);
expect(selector.getInstalledThemes()).toEqual(themes);
expect(selector.getInstalledThemes()).not.toBe(themes);
});
});
@@ -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<string | undefined>;
private readonly subscribers = new Set<
ZenObservable.SubscriptionObserver<string | undefined>
>();
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<string | undefined> {
return this.observable;
}
getActiveThemeId(): string | undefined {
return this.activeThemeId;
}
setActiveThemeId(themeId?: string): void {
this.activeThemeId = themeId;
this.subscribers.forEach((subscriber) => subscriber.next(themeId));
}
}
@@ -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';
@@ -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';