},
player: {}, // Holds the Plyr instance
+ playerInitialised: false,
playerOptions: { // Settings used for Plyr instantiation (https://github.com/sampotts/plyr#options)
debug: false,
loadSprite: false, // Custom SVG sprite is already embedded in the page
playerTitle: '',
playerImage: '',
+ /****************\
+ | Initialisation |
+ \****************/
+
+ init() {
+ // Open player if querystring is already set
+ let querystring = new URLSearchParams(location.search);
+ let ID = querystring.get('id');
+ if (ID) {
+ let media = document.querySelector(`#media_${ID}`)
+ if (media) {
+ this.maskContents = true; // Hide page contents while player loads
+ this.initPlayer('#player');
+ this.openPlayer(JSON.parse(media.dataset.player), false);
+ this.maskContents = false;
+ }
+ }
+ },
+
/***********\
| Filtering |
\***********/
initPlayer(selector) {
+ if (this.playerInitialised) {
+ return true; // Don't initialise player more than once
+ }
+
// Get custom controls HTML from the <template> tag
this.playerOptions.controls = document.getElementById('playerControls').innerHTML;
// Reformat the time code every time it changes
this.playerTime = this.formatTime(event.detail.plyr.currentTime);
});
+
+ this.playerInitialised = true;
},
- openPlayer(sourceData) {
+ openPlayer(sourceData, updateQuerystring = true) {
+
+ if (updateQuerystring) {
+ const location = new URL(window.location.href);
+ location.searchParams.set('id', sourceData.ID);
+ history.replaceState(null, document.title, location.toString());
+ }
+
this.playerType = sourceData.player.type;
this.playerTitle = sourceData.title;
this.playerImage = sourceData.image;
closePlayer() {
this.player.stop();
this.playerOpen = false;
+
+ // Update the page URL to remove querystring
+ const location = new URL(window.location.href);
+ location.searchParams.delete('id');
+ history.replaceState(null, document.title, location.toString());
},
formatTime(rawSeconds) {
<div class="media-grid opacity-0 mt-10 -mb-16 -mx-2.5" x-init="initIsotope($el)">
@foreach ($media as $item)
+ @php
+ $player_data = [
+ 'ID' => $item['id'],
+ 'player' => [
+ 'type' => $item['type'], // video / audio
+ 'sources' => [
+ [
+ 'src' => $item['file'],
+ 'type' => $item['mime_type'],
+ ]
+ ]
+ ],
+ 'title' => $item['title'],
+ 'image' => $item['image'],
+ ];
+ @endphp
{{-- TODO: deep-linking - is it actually needed here? Probably won't be linking directly to media... Could use replaceState() to update URL with querystring when opening / closing media. Check this on init / page load so that player can open the overlay already. Since the player needs several details, it's better to store this all in a data attribute and load the player based on the ID of the media / element that contains the data --}}
<div id="media_{{ $item['id'] }}"
- @click="openPlayer({
- player: {
- type: '{{ $item['type'] }}', // video / audio
- sources: [{
- src: '{{ $item['file'] }}',
- type: '{{ $item['mime_type'] }}'
- }]
- },
- title: '{{ $item['title'] }}',
- image: '{{ $item['image'] }}'
- })"
+ @click="openPlayer(JSON.parse($el.dataset.player))"
+ data-player='{{ json_encode($player_data) }}'
class="media-item group cursor-pointer
{{-- Width is 25% minus the gutters (2 * 0.625rem that comes from mx-2.5) --}}
float-left w-[calc(100%/2-1.25rem)] md:w-[calc(100%/3-1.25rem)] lg:w-[calc(100%/4-1.25rem)] mx-2.5 mb-16