Actions

MediaWiki

MediaWiki:Gadget-VideoGallery.js

From Dune Awakening DB

Revision as of 23:26, 1 June 2025 by Operator (talk | contribs) (Created page with "Video Gallery – Common.js / Gadget Loads only when .video-gallery-main-container exists: mw.loader.using( [ 'jquery', 'mediawiki.util' ] ).then( function () { 'use strict'; // Avoid double-init if RL bundles it twice if ( window.DuneVideoGalleryLoaded ) { return; } window.DuneVideoGalleryLoaded = true; // Bail out on pages without a gallery if ( !$( '.video-gallery-main-container' ).length ) { return; } /* -------------------------------------------...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* Video Gallery – Common.js / Gadget
   Loads only when .video-gallery-main-container exists  */

mw.loader.using( [ 'jquery', 'mediawiki.util' ] ).then( function () {
	'use strict';

	// Avoid double-init if RL bundles it twice
	if ( window.DuneVideoGalleryLoaded ) { return; }
	window.DuneVideoGalleryLoaded = true;

	// Bail out on pages without a gallery
	if ( !$( '.video-gallery-main-container' ).length ) { return; }

	/* -------------------------------------------------
	   DuneVideoGallery object (your original code)
	--------------------------------------------------*/
	window.DuneVideoGallery = {
		videoData: {},
		currentVideo: null,

		init: function () {
			this.parseVideoData();
			this.setupEventListeners();
			this.checkUrlParams();
		},

		parseVideoData: function () {
			var dataElement = $( '#video-gallery-data' );
			if ( dataElement.length ) {
				try {
					this.videoData = JSON.parse( dataElement.text() );
				} catch ( e ) {
					console.error( 'Failed to parse video data:', e );
				}
			}
		},

		setupEventListeners: function () {
			var self = this;

			$( document )
				.on( 'click', '.video-tab', function ( e ) {
					e.preventDefault();
					self.switchTab( $( this ).data( 'tab' ) );
				} )
				.on( 'click', '.video-card', function ( e ) {
					e.preventDefault();
					self.loadVideo( $( this ).data( 'video-id' ) );
				} )
				.on( 'input', '.video-search-input', function () {
					self.searchVideos( $( this ).val() );
				} )
				.on( 'click', '.video-search-button', function ( e ) {
					e.preventDefault();
					self.searchVideos( $( '.video-search-input' ).val() );
				} );
		},

		switchTab: function ( tabName ) {
			$( '.video-tab, .video-tab-content' ).removeClass( 'active' );
			$( '.video-tab[data-tab="' + tabName + '"]' ).addClass( 'active' );
			$( '.video-tab-content[data-content="' + tabName + '"]' ).addClass( 'active' );

			var url = new URL( window.location );
			url.searchParams.set( 'tab', tabName );
			window.history.pushState( {}, '', url );
		},

		loadVideo: function ( videoId ) {
			var video = this.videoData[ videoId ];
			if ( !video ) { console.error( 'Video not found:', videoId ); return; }

			$( '.video-card' ).removeClass( 'active' )
				.filter( '[data-video-id="' + videoId + '"]' ).addClass( 'active' );

			this.currentVideo = video;
			$( '#videoPlayerPanel' ).html( this.buildPlayerHTML( video ) );

			var url = new URL( window.location );
			url.searchParams.set( 'video', videoId );
			window.history.pushState( {}, '', url );

			if ( window.innerWidth <= 1200 ) {
				document.getElementById( 'videoPlayerPanel' )
					.scrollIntoView( { behavior: 'smooth', block: 'start' } );
			}
		},

		buildPlayerHTML: function ( v ) {
			var published = v.published_at ? v.published_at.slice( 0, 10 ) : '';
			return (
				'<div class="video-embed-container">' +
					'<iframe src="https://www.youtube.com/embed/' + v.youtube_id +
					'?rel=0&modestbranding=1" frameborder="0" allow="accelerometer; autoplay; ' +
					'clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>' +
				'</div>' +
				'<div class="video-details-header">' +
					'<h2 class="video-main-title">' + this.escapeHtml( v.title ) + '</h2>' +
					'<div class="video-meta">' +
						'<span class="video-author">👤 ' + this.escapeHtml( v.author || v.channel_title ) + '</span>' +
						'<span class="video-date">📅 ' + published + '</span>' +
					'</div>' +
				'</div>' +
				'<div class="video-notes-section">' +
					'<div class="notes-header">Video Notes</div>' +
					'<div class="notes-content">' +
						( v.video_notes || '<p>No notes available for this video.</p>' ) +
					'</div>' +
				'</div>'
			);
		},

		escapeHtml: function ( txt ) {
			return txt.replace( /[&<>"']/g, function ( ch ) {
				return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' }[ ch ];
			} );
		},

		checkUrlParams: function () {
			var params   = new URLSearchParams( window.location.search );
			var tab      = params.get( 'tab' );
			var videoId  = params.get( 'video' );

			if ( tab && $( '.video-tab[data-tab="' + tab + '"]' ).length ) {
				this.switchTab( tab );
			}
			if ( videoId && this.videoData[ videoId ] ) {
				var self = this;
				setTimeout( function () { self.loadVideo( videoId ); }, 100 );
			}
		},

		searchVideos: function ( q ) {
			q = ( q || '' ).toLowerCase();
			if ( !q ) {
				$( '.video-card, .video-section' ).show();
				return;
			}

			var self = this;
			$( '.video-card' ).each( function () {
				var id   = $( this ).data( 'video-id' );
				var v    = self.videoData[ id ] || {};
				var blob = ( v.title + ' ' + v.channel_title + ' ' + ( v.description || '' ) +
					' ' + ( ( v.tags || [] ).join( ' ' ) ) ).toLowerCase();

				$( this ).toggle( blob.includes( q ) );
			} );

			$( '.video-section' ).each( function () {
				$( this ).toggle( $( this ).find( '.video-card:visible' ).length > 0 );
			} );
		}
	};

	// Boot once DOM ready
	$( function () {
		window.DuneVideoGallery.init();
	} );
} );