]> _ Git - odl.git/commitdiff
Allow deep-linking to media items. WIP #4973 @2
authorStephen Cameron <stephen@cubedesigners.com>
Mon, 20 Dec 2021 19:40:51 +0000 (20:40 +0100)
committerStephen Cameron <stephen@cubedesigners.com>
Mon, 20 Dec 2021 19:40:51 +0000 (20:40 +0100)
resources/js/media-library.js
resources/views/components/media-library/index.blade.php
resources/views/layouts/app.blade.php

index 313442eb5d68c6b2a5e9d4b24725082b6f28d394..3317a15bbff8873f0fc91250257255a62359df4f 100644 (file)
@@ -13,6 +13,7 @@ export default (options = {}) => ({
     },
 
     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
@@ -23,6 +24,25 @@ export default (options = {}) => ({
     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 |
     \***********/
@@ -93,6 +113,10 @@ export default (options = {}) => ({
 
     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;
 
@@ -108,9 +132,18 @@ export default (options = {}) => ({
             // 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;
@@ -122,6 +155,11 @@ export default (options = {}) => ({
     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) {
index 820e27f9aa79900c3784c85743f3fd97f50eaea8..79a332fb4a66c5509ddef843df4ecf66aaa5b32d 100644 (file)
     <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
index 721b3930a84945be323ffb540e9c212ef2f51701..3d4f524426382872f18329befe5359f5eba64b27 100644 (file)
@@ -4,6 +4,7 @@
     <script>
         function app() {
             return {
+                maskContents: false,
                 menuOpen: false,
                 searchOpen: false,
                 PDFOpen: false, // Resources PDF overlay
@@ -67,7 +68,7 @@
     <div style="width: var(--content-width)">
         <x-header main="true" />
 
-        <div class="min-h-content flex flex-col mx-22 pt-22">
+        <div class="min-h-content flex flex-col mx-22 pt-22 opacity-0" :class="{ 'opacity-0': maskContents }">
             @yield('content')
         </div>
     </div>