import {StorageUtils} from '../../storageutils'; import {Component, ComponentConfig} from '../component'; import {EventDispatcher, Event} from '../../eventdispatcher'; interface SubtitleSettings { fontColor?: string; fontOpacity?: string; fontFamily?: string; fontSize?: string; characterEdge?: string; backgroundColor?: string; backgroundOpacity?: string; windowColor?: string; windowOpacity?: string; } interface Properties { [name: string]: SubtitleSettingsProperty; } export class SubtitleSettingsManager { private userSettings: SubtitleSettings; private localStorageKey: string; private _properties: Properties = { fontColor: new SubtitleSettingsProperty(this), fontOpacity: new SubtitleSettingsProperty(this), fontFamily: new SubtitleSettingsProperty(this), fontSize: new SubtitleSettingsProperty(this), characterEdge: new SubtitleSettingsProperty(this), backgroundColor: new SubtitleSettingsProperty(this), backgroundOpacity: new SubtitleSettingsProperty(this), windowColor: new SubtitleSettingsProperty(this), windowOpacity: new SubtitleSettingsProperty(this), }; constructor() { this.userSettings = {}; this.localStorageKey = DummyComponent.instance().prefixCss('subtitlesettings'); for (let propertyName in this._properties) { this._properties[propertyName].onChanged.subscribe((sender, property) => { if (property.isSet()) { (this.userSettings)[propertyName] = property.value; } else { // Delete the property from the settings object if unset to avoid serialization of null values delete (this.userSettings)[propertyName]; } // Save the settings object when a property has changed this.save(); }); } this.load(); } public reset(): void { for (let propertyName in this._properties) { this._properties[propertyName].clear(); } } public get fontColor(): SubtitleSettingsProperty { return this._properties.fontColor; } public get fontOpacity(): SubtitleSettingsProperty { return this._properties.fontOpacity; } public get fontFamily(): SubtitleSettingsProperty { return this._properties.fontFamily; } public get fontSize(): SubtitleSettingsProperty { return this._properties.fontSize; } public get characterEdge(): SubtitleSettingsProperty { return this._properties.characterEdge; } public get backgroundColor(): SubtitleSettingsProperty { return this._properties.backgroundColor; } public get backgroundOpacity(): SubtitleSettingsProperty { return this._properties.backgroundOpacity; } public get windowColor(): SubtitleSettingsProperty { return this._properties.windowColor; } public get windowOpacity(): SubtitleSettingsProperty { return this._properties.windowOpacity; } /** * Saves the settings to local storage. */ public save(): void { StorageUtils.setObject(this.localStorageKey, this.userSettings); } /** * Loads the settings from local storage */ public load(): void { this.userSettings = StorageUtils.getObject(this.localStorageKey) || {}; // Apply the loaded settings for (let property in this.userSettings) { this._properties[property].value = (this.userSettings)[property]; } } } /** * A dummy component whose sole purpose is to expose the {@link #prefixCss} method to the * {@link SubtitleSettingsManager}. */ class DummyComponent extends Component { private static _instance: DummyComponent; public static instance(): DummyComponent { if (!DummyComponent._instance) { DummyComponent._instance = new DummyComponent(); } return DummyComponent._instance; } public prefixCss(cssClassOrId: string): string { return super.prefixCss(cssClassOrId); } } export class SubtitleSettingsProperty { private _manager: SubtitleSettingsManager; private _onChanged: EventDispatcher>; private _value: T; constructor(manager: SubtitleSettingsManager) { this._manager = manager; this._onChanged = new EventDispatcher>(); } public isSet(): boolean { return this._value != null; } public clear(): void { this._value = null; this.onChangedEvent(null); } public get value(): T { return this._value; } public set value(value: T) { if (typeof value === 'string' && value === 'null') { value = null; } this._value = value; this.onChangedEvent(value); } protected onChangedEvent(value: T) { this._onChanged.dispatch(this._manager, this); } public get onChanged(): Event> { return this._onChanged.getEvent(); } }