-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(playlist-plugin): enhance configuration options for playlist modal
Resolves #16 by introducing new configuration options that allow integrators to specify which buttons should appear in the playlist modal. Also exposes the modal options. - Added `modal` option to configure the modal dialog component. - Exposed `modal.pauseOnOpen` option to control whether the player pauses when the modal is opened. - Added `modal.controls` option to define the order, addition, or removal of the control buttons. ***Other Changes*** - Split the `controls` into individual components that can be registered separately. - Added a test for the playlist plugin UI registration.
- Loading branch information
Showing
14 changed files
with
463 additions
and
265 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
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
52 changes: 52 additions & 0 deletions
52
packages/pillarbox-playlist/src/components/next-item-button.js
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,52 @@ | ||
import videojs from 'video.js'; | ||
|
||
/** | ||
* @ignore | ||
* @type {typeof import('video.js/dist/types/button').default} | ||
*/ | ||
const Button = videojs.getComponent('Button'); | ||
|
||
|
||
/** | ||
* The next item button for the playlist ui. When clicked moves to the | ||
* next item in the playlist. | ||
*/ | ||
class NextItemButton extends Button { | ||
constructor(player, options) { | ||
super(player, options); | ||
this.handleLanguagechange(); | ||
this.setIcon('next-item'); | ||
|
||
this.player().ready(() => { | ||
this.$('.vjs-icon-placeholder').classList.toggle(`vjs-icon-next-item`, true); | ||
}); | ||
} | ||
|
||
/** | ||
* Get the playlist instance associated with the player. | ||
* | ||
* @returns {import('pillarbox-playlist.js').default} The playlist instance. | ||
*/ | ||
playlist() { | ||
return this.player().pillarboxPlaylist(); | ||
} | ||
|
||
/** | ||
* Handles the click event on the button. | ||
* | ||
* @param {Event} event - The click event. | ||
*/ | ||
handleClick(event) { | ||
super.handleClick(event); | ||
this.playlist().next(); | ||
} | ||
|
||
/** | ||
* Handles the language change event to update the control text. | ||
*/ | ||
handleLanguagechange() { | ||
this.controlText(this.localize('Next Item')); | ||
} | ||
} | ||
|
||
videojs.registerComponent('NextItemButton', NextItemButton); |
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
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
138 changes: 138 additions & 0 deletions
138
packages/pillarbox-playlist/src/components/pillarbox-playlist-modal.js
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,138 @@ | ||
import videojs from 'video.js'; | ||
import './pillarbox-playlist-menu-item.js'; | ||
import './playlist-controls.js'; | ||
|
||
/** | ||
* @ignore | ||
* @type {typeof import('./pillarbox-playlist-menu-item.js').default} | ||
*/ | ||
const PillarboxPlaylistMenuItem = videojs.getComponent('PillarboxPlaylistMenuItem'); | ||
/** | ||
* @ignore | ||
* @type {typeof import('video.js/dist/types/component').default} | ||
*/ | ||
const Component = videojs.getComponent('Component'); | ||
/** | ||
* @ignore | ||
* @type {typeof import('video.js/dist/types/modal-dialog').default} | ||
*/ | ||
const ModalDialog = videojs.getComponent('ModalDialog'); | ||
|
||
/** | ||
* PlaylistMenuDialog is a custom dialog that extends the ModalDialog class. | ||
* It is designed to manage and display a playlist with various controls. | ||
*/ | ||
class PlaylistMenuDialog extends ModalDialog { | ||
/** | ||
* Handles the 'statechanged' event when triggered by the playlist. This method | ||
* serves as a proxy to the main `statechanged` handler, ensuring that additional | ||
* logic can be executed or making it easier to detach the event listener later. | ||
* | ||
* @private | ||
*/ | ||
_onPlaylistStateChanged = ({ changes }) => { | ||
if ('items' in changes) { | ||
this.removeItems(); | ||
this.renderItems(); | ||
} | ||
|
||
if ('currentIndex' in changes) { | ||
this.select(changes.currentIndex.to); | ||
} | ||
}; | ||
|
||
/** | ||
* Creates an instance of PlaylistMenuDialog. | ||
* | ||
* @param {import('@srgssr/pillarbox-web').Player} player - The pillarbox player instance. | ||
* @param {Object} options - Options for the dialog. | ||
* @param {boolean} [options.pauseOnOpen=false] - If true, the player will pause when the modal dialog is opened. | ||
* @param {Object} [options.controls={}] - Configuration for the control buttons within the modal. You can define the order of the buttons, remove buttons you don't need, or add new ones. | ||
*/ | ||
constructor(player, options) { | ||
options.temporary = false; | ||
options = videojs.mergeOptions({ pauseOnOpen: false }, options); | ||
|
||
super(player, options); | ||
|
||
this.fill(); | ||
this.addChild('PlaylistControls', options.controls); | ||
this.renderItems(); | ||
this.playlist().on('statechanged', this._onPlaylistStateChanged); | ||
} | ||
|
||
buildCSSClass() { | ||
return `pbw-playlist-dialog ${super.buildCSSClass()}`; | ||
} | ||
|
||
/** | ||
* Dispose of the PlaylistMenuDialog instance. | ||
*/ | ||
dispose() { | ||
this.playlist().off('statechanged', this._onPlaylistStateChanged); | ||
super.dispose(); | ||
} | ||
|
||
/** | ||
* Get the playlist instance associated with the player. | ||
* | ||
* @returns {import('packages/pillarbox-playlist/src/pillarbox-playlist.js').default} The playlist instance. | ||
*/ | ||
playlist() { | ||
return this.player().pillarboxPlaylist(); | ||
} | ||
|
||
/** | ||
* Update the playlist item UI with the selected index. | ||
* | ||
* @param {number} index - The index of the item to select. | ||
*/ | ||
select(index) { | ||
const itemList = this.getChild('PillarboxPlaylistMenuItemsList'); | ||
|
||
itemList.children() | ||
.filter(item => item.name() === 'PillarboxPlaylistMenuItem') | ||
.map(item => item.getChild('PillarboxPlaylistMenuItemButton')) | ||
.forEach(button => button.selected(index === button.options().index)); | ||
} | ||
|
||
/** | ||
* Remove all playlist items from the dialog. | ||
*/ | ||
removeItems() { | ||
this.removeChild(this.getChild('PillarboxPlaylistMenuItemsList')); | ||
} | ||
|
||
/** | ||
* Render the playlist items in the dialog. | ||
*/ | ||
renderItems() { | ||
const itemListEl = new Component(this.player(), { | ||
name: 'PillarboxPlaylistMenuItemsList', | ||
el: videojs.dom.createEl('ol', { | ||
className: 'pbw-playlist-items' | ||
}) | ||
}); | ||
|
||
this.playlist().items.forEach((item, index) => { | ||
const itemEl = new Component(this.player(), { | ||
name: 'PillarboxPlaylistMenuItem', | ||
el: videojs.dom.createEl('li', { | ||
className: 'pbw-playlist-item' | ||
}) | ||
}); | ||
|
||
itemEl.addChild(new PillarboxPlaylistMenuItem(this.player(), { | ||
item, | ||
index, | ||
name: 'PillarboxPlaylistMenuItemButton' | ||
})); | ||
|
||
itemListEl.addChild(itemEl); | ||
}); | ||
|
||
this.addChild(itemListEl); | ||
} | ||
} | ||
|
||
videojs.registerComponent('PlaylistMenuDialog', PlaylistMenuDialog); |
27 changes: 27 additions & 0 deletions
27
packages/pillarbox-playlist/src/components/playlist-controls.js
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,27 @@ | ||
import videojs from 'video.js'; | ||
import './next-item-button.js'; | ||
import './previous-item-button.js'; | ||
import './repeat-button.js'; | ||
import './shuffle-button.js'; | ||
|
||
/** | ||
* @ignore | ||
* @type {typeof import('video.js/dist/types/component').default} | ||
*/ | ||
const Component = videojs.getComponent('Component'); | ||
|
||
class PlaylistControls extends Component { | ||
|
||
} | ||
|
||
PlaylistControls.prototype.options_ = { | ||
className: 'pbw-playlist-controls', | ||
children: [ | ||
'repeatButton', | ||
'shuffleButton', | ||
'previousItemButton', | ||
'nextItemButton' | ||
] | ||
}; | ||
|
||
videojs.registerComponent('PlaylistControls', PlaylistControls); |
51 changes: 51 additions & 0 deletions
51
packages/pillarbox-playlist/src/components/previous-item-button.js
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,51 @@ | ||
import videojs from 'video.js'; | ||
|
||
/** | ||
* @ignore | ||
* @type {typeof import('video.js/dist/types/button').default} | ||
*/ | ||
const Button = videojs.getComponent('Button'); | ||
|
||
/** | ||
* The previous item button for the playlist ui. When clicked moves to the | ||
* previous item in the playlist. | ||
*/ | ||
class PreviousItemButton extends Button { | ||
constructor(player, options) { | ||
super(player, options); | ||
this.handleLanguagechange(); | ||
this.setIcon('previous-item'); | ||
|
||
this.player().ready(() => { | ||
this.$('.vjs-icon-placeholder').classList.toggle(`vjs-icon-previous-item`, true); | ||
}); | ||
} | ||
|
||
/** | ||
* Get the playlist instance associated with the player. | ||
* | ||
* @returns {import('pillarbox-playlist.js').default} The playlist instance. | ||
*/ | ||
playlist() { | ||
return this.player().pillarboxPlaylist(); | ||
} | ||
|
||
/** | ||
* Handles the click event on the button. | ||
* | ||
* @param {Event} event - The click event. | ||
*/ | ||
handleClick(event) { | ||
super.handleClick(event); | ||
this.playlist().previous(); | ||
} | ||
|
||
/** | ||
* Handles the language change event to update the control text. | ||
*/ | ||
handleLanguagechange() { | ||
this.controlText(this.localize('Previous Item')); | ||
} | ||
} | ||
|
||
videojs.registerComponent('PreviousItemButton', PreviousItemButton); |
Oops, something went wrong.