-
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 `pillarboxPlaylistMenuDialog` option to configure the modal dialog component. - Exposed `pillarboxPlaylistMenuDialog.pauseOnOpen` option to control whetherWQ the player pauses when the modal is opened. - Added `pillarboxPlaylistMenuDialog.pillarboxPlaylistControls` option to define the order, addition, or remova 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. - Added suffix `pillarboxPlaylist` to all components to avoid naming clashes.
- Loading branch information
Showing
17 changed files
with
741 additions
and
415 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
27 changes: 27 additions & 0 deletions
27
packages/pillarbox-playlist/src/components/modal/pillarbox-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 './pillarbox-playlist-next-item-button.js'; | ||
import './pillarbox-previous-item-button.js'; | ||
import './pillarbox-playlist-repeat-button.js'; | ||
import './pillarbox-playlist-shuffle-button.js'; | ||
|
||
/** | ||
* @ignore | ||
* @type {typeof import('video.js/dist/types/component').default} | ||
*/ | ||
const Component = videojs.getComponent('Component'); | ||
|
||
class PillarboxPlaylistControls extends Component { | ||
|
||
} | ||
|
||
PillarboxPlaylistControls.prototype.options_ = { | ||
className: 'pbw-playlist-controls', | ||
children: [ | ||
'pillarboxPlaylistRepeatButton', | ||
'pillarboxPlaylistShuffleButton', | ||
'pillarboxPlaylistPreviousItemButton', | ||
'pillarboxPlaylistNextItemButton' | ||
] | ||
}; | ||
|
||
videojs.registerComponent('PillarboxPlaylistControls', PillarboxPlaylistControls); |
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
129 changes: 129 additions & 0 deletions
129
packages/pillarbox-playlist/src/components/modal/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,129 @@ | ||
import videojs from 'video.js'; | ||
import './pillarbox-playlist-menu-item.js'; | ||
import './pillarbox-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('../pillarbox-playlist-base.js').PillarboxPlaylistBaseModal} | ||
*/ | ||
const ModalDialog = videojs.getComponent('PillarboxPlaylistBaseModal'); | ||
|
||
/** | ||
* 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.pillarboxPlaylistControls={}] - 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('PillarboxPlaylistControls', options.pillarboxPlaylistControls); | ||
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(); | ||
} | ||
|
||
/** | ||
* 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('PillarboxPlaylistMenuDialog', PlaylistMenuDialog); |
35 changes: 35 additions & 0 deletions
35
packages/pillarbox-playlist/src/components/modal/pillarbox-playlist-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,35 @@ | ||
import videojs from 'video.js'; | ||
|
||
/** | ||
* @ignore | ||
* @type {typeof import('../pillarbox-playlist-base.js').PillarboxPlaylistBaseButton} | ||
*/ | ||
const Button = videojs.getComponent('PillarboxPlaylistBaseButton'); | ||
|
||
/** | ||
* The next item button for the playlist ui. When clicked moves to the | ||
* next item in the playlist. | ||
*/ | ||
class PillarboxPlaylistNextItemButton extends Button { | ||
constructor(player, options) { | ||
options = videojs.mergeOptions({ controlText: 'Next Item' }, options); | ||
super(player, options); | ||
this.setIcon('next-item'); | ||
} | ||
|
||
ready() { | ||
this.$('.vjs-icon-placeholder').classList.toggle(`vjs-icon-next-item`, true); | ||
} | ||
|
||
/** | ||
* Handles the click event on the button. | ||
* | ||
* @param {Event} event - The click event. | ||
*/ | ||
handleClick(event) { | ||
super.handleClick(event); | ||
this.playlist().next(); | ||
} | ||
} | ||
|
||
videojs.registerComponent('PillarboxPlaylistNextItemButton', PillarboxPlaylistNextItemButton); |
45 changes: 45 additions & 0 deletions
45
packages/pillarbox-playlist/src/components/modal/pillarbox-playlist-repeat-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,45 @@ | ||
import videojs from 'video.js'; | ||
|
||
/** | ||
* @ignore | ||
* @type {typeof import('../pillarbox-playlist-base.js').PillarboxPlaylistBaseButton} | ||
*/ | ||
const Button = videojs.getComponent('PillarboxPlaylistBaseButton'); | ||
|
||
/** | ||
* The repeat button for the playlist ui. When clicked toggles the repeat mode | ||
* of the playlist. | ||
*/ | ||
class PillarboxPlaylistRepeatButton extends Button { | ||
constructor(player, options) { | ||
options = videojs.mergeOptions({ controlText: 'Repeat' }, options); | ||
super(player, options); | ||
this.setIcon('repeat'); | ||
} | ||
|
||
ready() { | ||
this.$('.vjs-icon-placeholder').classList.toggle(`vjs-icon-repeat`, true); | ||
} | ||
|
||
/** | ||
* Builds the CSS class string for the button. | ||
* | ||
* @returns {string} The CSS class string. | ||
*/ | ||
buildCSSClass() { | ||
return `${this.playlist().repeat ? 'vjs-selected' : ''} ${super.buildCSSClass()}`; | ||
} | ||
|
||
/** | ||
* Handles the click event on the button. | ||
* | ||
* @param {Event} event - The click event. | ||
*/ | ||
handleClick(event) { | ||
super.handleClick(event); | ||
this.playlist().toggleRepeat(); | ||
this.toggleClass('vjs-selected', this.playlist().repeat); | ||
} | ||
} | ||
|
||
videojs.registerComponent('PillarboxPlaylistRepeatButton', PillarboxPlaylistRepeatButton); |
35 changes: 35 additions & 0 deletions
35
packages/pillarbox-playlist/src/components/modal/pillarbox-playlist-shuffle-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,35 @@ | ||
import videojs from 'video.js'; | ||
|
||
/** | ||
* @ignore | ||
* @type {typeof import('../pillarbox-playlist-base.js').PillarboxPlaylistBaseButton} | ||
*/ | ||
const Button = videojs.getComponent('PillarboxPlaylistBaseButton'); | ||
|
||
/** | ||
* The shuffle button for the playlist ui. When clicked shuffles the items | ||
* in the playlist. | ||
*/ | ||
class PillarboxPlaylistShuffleButton extends Button { | ||
constructor(player, options) { | ||
options = videojs.mergeOptions({ controlText: 'Shuffle' }, options); | ||
super(player, options); | ||
this.setIcon('shuffle'); | ||
} | ||
|
||
ready() { | ||
this.$('.vjs-icon-placeholder').classList.toggle(`vjs-icon-shuffle`, true); | ||
} | ||
|
||
/** | ||
* Handles the click event on the button. | ||
* | ||
* @param {Event} event - The click event. | ||
*/ | ||
handleClick(event) { | ||
super.handleClick(event); | ||
this.playlist().shuffle(); | ||
} | ||
} | ||
|
||
videojs.registerComponent('PillarboxPlaylistShuffleButton', PillarboxPlaylistShuffleButton); |
Oops, something went wrong.