-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
### Description of the Changes save playbackRate in session storage instead of local storage. Solves FEC-13513
- Loading branch information
1 parent
b990ab5
commit 88f1d03
Showing
11 changed files
with
472 additions
and
243 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
// @flow | ||
import StorageWrapper from './storage-wrapper'; | ||
import {Error, Utils, getLogger} from '@playkit-js/playkit-js'; | ||
|
||
export class BaseStorageHelper { | ||
static instance: BaseStorageHelper | null = null; | ||
storageManagers: Array<BaseStorageManager>; | ||
|
||
constructor() { | ||
this.storageManagers = []; | ||
} | ||
|
||
addManager(manager: BaseStorageManager): void { | ||
this.storageManagers.push(manager); | ||
} | ||
|
||
static getInstance(): BaseStorageHelper { | ||
if (this.instance === null) { | ||
this.instance = new BaseStorageHelper(); | ||
} | ||
return this.instance; | ||
} | ||
} | ||
|
||
export class BaseStorageManager { | ||
static _logger: any; | ||
static StorageKeys: {[key: string]: string}; | ||
|
||
/** | ||
* Initializes class. | ||
* @private | ||
* @param {string} className - The manager's class name. | ||
* @returns {void} | ||
*/ | ||
static init(className: string): void { | ||
this._logger = getLogger(className); | ||
//$FlowFixMe | ||
BaseStorageHelper.getInstance().addManager(this); | ||
} | ||
|
||
/** | ||
* Applies cache support if it's supported by the environment. | ||
* @private | ||
* @param {KalturaPlayer} player - The Kaltura player. | ||
* @returns {void} | ||
*/ | ||
static attachAll(player: Player): void { | ||
BaseStorageHelper.getInstance().storageManagers.forEach((manager: BaseStorageManager) => { | ||
//$FlowFixMe | ||
if (manager.isStorageAvailable()) { | ||
//$FlowFixMe | ||
manager.attach(player); | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* Sets the storage config on the player config if certain conditions are met. | ||
* @private | ||
* @param {KPOptionsObject} options - kaltura player options | ||
* @returns {void} | ||
*/ | ||
static setStorageConfig(options: KPOptionsObject): void { | ||
BaseStorageHelper.getInstance().storageManagers.forEach(manager => { | ||
//$FlowFixMe | ||
if (manager.isStorageAvailable() && manager.hasStorage()) { | ||
//$FlowFixMe | ||
Utils.Object.mergeDeep(options, manager.getStorageConfig()); | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* @static | ||
* @private | ||
* @returns {boolean} - Whether the storage is implemented in the current browser. | ||
*/ | ||
static isStorageAvailable(): boolean { | ||
return StorageWrapper.isStorageAvailable(this.getStorageObject()); | ||
} | ||
|
||
/** | ||
* Checks if we have previous storage. | ||
* @private | ||
* @static | ||
* @return {boolean} - Whether we have previous storage. | ||
*/ | ||
static hasStorage(): boolean { | ||
const storageSize = this.getStorageSize(); | ||
const hasStorage = storageSize !== 0; | ||
if (hasStorage) { | ||
this._logger.debug('Storage found with size of ', storageSize); | ||
} else { | ||
this._logger.debug('No storage found'); | ||
} | ||
return hasStorage; | ||
} | ||
|
||
/** | ||
* Sets an item in the storage. | ||
* @private | ||
* @static | ||
* @param {string} key - The key of the item | ||
* @param {any} item - The value of the item | ||
* @returns {void} | ||
*/ | ||
static setItem(key: string, item: any): void { | ||
StorageWrapper.setItem(key, item, this.getStorageObject()); | ||
} | ||
|
||
/** | ||
* Gets an item from the storage. | ||
* @private | ||
* @static | ||
* @param {string} key - The item key | ||
* @returns {any} - The item value | ||
*/ | ||
static getItem(key: string): any { | ||
StorageWrapper.getItem(key, this.getStorageObject()); | ||
} | ||
|
||
/** | ||
* Gets the storage size | ||
* @static | ||
* @private | ||
* @return {number} - The number of keys in the local storage started with wanted prefix. | ||
*/ | ||
static getStorageSize(): number { | ||
return StorageWrapper.getStorageSize(this.getStorageObject()); | ||
} | ||
|
||
/** | ||
* Gets the storage in the structure of the player configuration. | ||
* @private | ||
* @static | ||
* @return {Object} - Partial storageable player configuration. | ||
*/ | ||
static getStorageConfig(): Object { | ||
const values = this._getExistingValues(); | ||
const storageConfig = this._buildStorageConfig(values); | ||
this._logger.debug('Gets storage config', storageConfig); | ||
return storageConfig; | ||
} | ||
|
||
/** | ||
* Gets the current existing values in the storage. | ||
* @private | ||
* @static | ||
* @return {Object} - The values object from the storage. | ||
*/ | ||
static _getExistingValues(): Object { | ||
const obj = {}; | ||
Object.keys(this.StorageKeys).forEach(key => { | ||
const value = this.StorageKeys[key]; | ||
const item = StorageWrapper.getItem(value, this.getStorageObject()); | ||
if (item != null) { | ||
obj[value] = item; | ||
} | ||
}); | ||
return obj; | ||
} | ||
|
||
/** | ||
* Builds the storage configuration object. | ||
* @private | ||
* @static | ||
* @param {Object} values - The values to set to storage configuration | ||
* @return {Object} - The configuration with values from the storage. | ||
*/ | ||
static _buildStorageConfig(values: Object): Object { | ||
const storageConfig = Utils.Object.mergeDeep({}, values); | ||
delete storageConfig.textStyle; | ||
return { | ||
playback: storageConfig | ||
}; | ||
} | ||
|
||
/** | ||
* Gets the storage object to access. | ||
* i.e: sessionStorage, localStorage | ||
* @private | ||
* @static | ||
* @return {Object} - The storage object. | ||
*/ | ||
static getStorageObject(): Object { | ||
throw new Error(Error.Severity.CRITICAL, Error.Category.PLAYER, Error.Code.RUNTIME_ERROR_METHOD_NOT_IMPLEMENTED, 'getStorageObject()'); | ||
} | ||
|
||
/** | ||
* Attaches listeners to the storage manager. | ||
* @private | ||
* @static | ||
* @return {void} | ||
*/ | ||
static attach(): void { | ||
throw new Error(Error.Severity.CRITICAL, Error.Category.PLAYER, Error.Code.RUNTIME_ERROR_METHOD_NOT_IMPLEMENTED, 'attach()'); | ||
} | ||
|
||
/** | ||
* Initialize the storage manager. | ||
* @private | ||
* @static | ||
* @return {void} | ||
*/ | ||
static initialize(): void { | ||
throw new Error(Error.Severity.CRITICAL, Error.Category.PLAYER, Error.Code.RUNTIME_ERROR_METHOD_NOT_IMPLEMENTED, 'initialize()'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// @flow | ||
import {EventManager} from '@playkit-js/playkit-js'; | ||
import {BaseStorageManager} from './base-storage-manager'; | ||
|
||
export default class LocalStorageManager extends BaseStorageManager { | ||
static StorageKeys: {[key: string]: string} = { | ||
MUTED: 'muted', | ||
VOLUME: 'volume', | ||
AUDIO_LANG: 'audioLanguage', | ||
TEXT_LANG: 'textLanguage', | ||
CAPTIONS_DISPLAY: 'captionsDisplay', | ||
TEXT_STYLE: 'textStyle' | ||
}; | ||
|
||
static initialize() { | ||
this.init(this.name); | ||
} | ||
|
||
static getStorageObject() { | ||
return localStorage; | ||
} | ||
|
||
/** | ||
* Attaches the player listeners to the local storage wrapper. | ||
* @private | ||
* @param {Player} player - The player reference. | ||
* @static | ||
* @returns {void} | ||
*/ | ||
static attach(player: Player): void { | ||
this._logger.debug('Attach local storage'); | ||
let eventManager = new EventManager(); | ||
eventManager.listen(player, player.Event.UI.USER_CLICKED_MUTE, () => { | ||
if (!player.isCasting()) { | ||
this.setItem(this.StorageKeys.MUTED, player.muted); | ||
} | ||
}); | ||
eventManager.listen(player, player.Event.UI.USER_CLICKED_UNMUTE, () => { | ||
if (!player.isCasting()) { | ||
this.setItem(this.StorageKeys.MUTED, player.muted); | ||
} | ||
}); | ||
|
||
eventManager.listen(player, player.Event.UI.USER_CHANGED_VOLUME, () => { | ||
if (!player.isCasting()) { | ||
this.setItem(this.StorageKeys.MUTED, !player.volume); | ||
this.setItem(this.StorageKeys.VOLUME, player.volume); | ||
} | ||
}); | ||
|
||
eventManager.listen(player, player.Event.UI.USER_SELECTED_AUDIO_TRACK, event => { | ||
const audioTrack = event.payload.audioTrack; | ||
this.setItem(this.StorageKeys.AUDIO_LANG, audioTrack.language); | ||
}); | ||
|
||
eventManager.listen(player, player.Event.UI.USER_SELECTED_CAPTION_TRACK, event => { | ||
const textTrack = event.payload.captionTrack; | ||
if (textTrack.language !== 'off') { | ||
this.setItem(this.StorageKeys.TEXT_LANG, textTrack.language); | ||
this.setItem(this.StorageKeys.CAPTIONS_DISPLAY, true); | ||
} else { | ||
this.setItem(this.StorageKeys.CAPTIONS_DISPLAY, false); | ||
} | ||
}); | ||
|
||
const onToggleCaptions = () => { | ||
eventManager.listenOnce(player, player.Event.TEXT_TRACK_CHANGED, event => { | ||
const {selectedTextTrack} = event.payload; | ||
if (selectedTextTrack.language !== 'off') { | ||
this.setItem(this.StorageKeys.TEXT_LANG, selectedTextTrack.language); | ||
this.setItem(this.StorageKeys.CAPTIONS_DISPLAY, true); | ||
} else { | ||
this.setItem(this.StorageKeys.CAPTIONS_DISPLAY, false); | ||
} | ||
}); | ||
}; | ||
|
||
eventManager.listen(player, player.Event.UI.USER_SHOWED_CAPTIONS, onToggleCaptions); | ||
eventManager.listen(player, player.Event.UI.USER_HID_CAPTIONS, onToggleCaptions); | ||
|
||
eventManager.listen(player, player.Event.UI.USER_SELECTED_CAPTIONS_STYLE, event => { | ||
try { | ||
const textStyle = JSON.stringify(event.payload.captionsStyle); | ||
this.setItem(this.StorageKeys.TEXT_STYLE, textStyle); | ||
} catch (e) { | ||
this._logger.error(e.message); | ||
} | ||
}); | ||
|
||
eventManager.listen(player, player.Event.PLAYER_DESTROY, () => eventManager.destroy()); | ||
} | ||
|
||
/** | ||
* Gets the player text style from storage. | ||
* @private | ||
* @static | ||
* @returns {?Object} - The stored text style object | ||
*/ | ||
static getPlayerTextStyle(): ?Object { | ||
return this.getItem(this.StorageKeys.TEXT_STYLE); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// @flow | ||
import {EventManager} from '@playkit-js/playkit-js'; | ||
import {BaseStorageManager} from './base-storage-manager'; | ||
|
||
export default class SessionStorageManager extends BaseStorageManager { | ||
static StorageKeys: {[key: string]: string} = { | ||
PLAYBACK_RATE: 'playbackRate' | ||
}; | ||
|
||
static initialize() { | ||
this.init(this.name); | ||
} | ||
|
||
static getStorageObject() { | ||
return sessionStorage; | ||
} | ||
|
||
/** | ||
* Attaches the player listeners to the local storage wrapper. | ||
* @private | ||
* @param {Player} player - The player reference. | ||
* @static | ||
* @returns {void} | ||
*/ | ||
static attach(player: Player): void { | ||
this._logger.debug('Attach session storage'); | ||
let eventManager = new EventManager(); | ||
eventManager.listen(player, player.Event.UI.USER_SELECTED_SPEED, () => { | ||
if (!player.isCasting()) { | ||
this.setItem(this.StorageKeys.PLAYBACK_RATE, player.playbackRate); | ||
} | ||
}); | ||
} | ||
} |
Oops, something went wrong.