Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

MediaWiki:Common-votd.js

MediaWiki interface page
Revision as of 03:16, 13 April 2026 by Joe Beaudoin Jr. (talk | contribs) (Joe Beaudoin Jr. moved page MediaWiki:Common.votd.js to MediaWiki:Common-votd.js without leaving a redirect)

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.

/* Any JavaScript here will be loaded for all users on every page load. */ /**

* BattlestarWiki — Video of the Day loader
* Append to MediaWiki:Common.js (after the main page JS block)
*
* Fetches from battlestarpegasus.com MediaCMS API.
* Selects a video deterministically by date.
* Supports manual override via Battlestar_Wiki:Video_of_the_Day/YYYY-MM-DD subpage.
*/

( function () {

   'use strict';
   var PEGASUS   = 'https://battlestarpegasus.com';
   var PAGE_SIZE = 50;
   function esc( s ) {
       return String( s ||  )
           .replace( /&/g, '&' ).replace( /</g, '<' )
           .replace( />/g, '>' ).replace( /"/g, '"' );
   }
   function dailySeed() {
       var now = new Date();
       return Math.floor( Date.UTC(
           now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()
       ) / 86400000 );
   }
   function fmtDuration( secs ) {
       secs = Math.round( secs || 0 );
       var m = Math.floor( secs / 60 ), s = secs % 60;
       return m + ':' + ( s < 10 ? '0' :  ) + s;
   }
   function pegasusGet( path ) {
       return fetch( PEGASUS + path, { headers: { Accept: 'application/json' } } )
           .then( function ( r ) {
               if ( !r.ok ) throw new Error( 'HTTP ' + r.status );
               return r.json();
           } );
   }
   function fetchAllVideos() {
       return pegasusGet( '/api/v1/media/?media_type=video&ordering=add_date&page_size=' + PAGE_SIZE )
           .then( function ( data ) {
               var results = data.results || [];
               if ( data.next ) {
                   return pegasusGet( '/api/v1/media/?media_type=video&ordering=add_date&page_size=' + PAGE_SIZE + '&page=2' )
                       .then( function ( d2 ) { return results.concat( d2.results || [] ); } );
               }
               return results;
           } );
   }
   function fetchVideoDetail( token ) {
       return pegasusGet( '/api/v1/media/' + token );
   }
   function renderVotd( container, media ) {
       var token    = media.friendly_token;
       var watchUrl = media.url || ( PEGASUS + '/view?m=' + token );
       var thumb    = media.thumbnail_url ? PEGASUS + media.thumbnail_url : ;
       var poster   = media.poster_url   ? PEGASUS + media.poster_url   : thumb;
       /* ── Build video URLs from API response ── */
       var hlsSrc = ;
       var mp4Src = ;
       if ( media.hls_info && media.hls_info.master_file ) {
           hlsSrc = PEGASUS + media.hls_info.master_file;
       }
       /* Prefer 720p MP4 fallback, cascade down */
       var enc = media.encodings_info || {};
       var mp4Res = [ '720', '480', '360', '1080', '240' ];
       for ( var i = 0; i < mp4Res.length; i++ ) {
           var r = enc[ mp4Res[i] ];
           if ( r && r.h264 && r.h264.url && r.h264.status === 'success' ) {
               mp4Src = PEGASUS + r.h264.url;
               break;
           }
       }
       /* ── Player HTML: <video> with poster ── */
       var videoId  = 'bsw-votd-video';
       var playerHtml =
           '<video id="' + videoId + '" ' +
           'style="width:100%;aspect-ratio:16/9;display:block;background:#000" ' +
           'controls playsinline preload="none" ' +
           ( poster ? 'poster="' + esc( poster ) + '"' :  ) + '>' +
           ( mp4Src ? '<source src="' + esc( mp4Src ) + '" type="video/mp4">' :  ) +
           '</video>';
       /* ── Description sidebar ── */
       var tags = ( media.tags || [] ).slice( 0, 8 ).map( function ( t ) {
           var label = typeof t === 'string' ? t : ( t.title || t.name ||  );
           return label ? '' + esc( label ) + '' : ;
       } ).join(  );
       var stats = [];
       if ( media.duration ) stats.push( '\u23f1 ' + fmtDuration( media.duration ) );
       if ( media.views )    stats.push( '\ud83d\udc41 ' + media.views.toLocaleString() );
       if ( media.size )     stats.push( media.size );
       var desc = media.description || ;
       var infoHtml =

'

' + esc( media.title || 'Untitled' ) + '

' + ( stats.length ? '

' + stats.join( '  \u00b7  ' ) + '

' : ) + ( desc ? '

' + desc + '

' : ) + ( tags ? '

' + tags + '

' : ) + '

' +
           '<a class="bsw-votd-watch" href="' + esc( watchUrl ) + '" target="_blank" rel="noopener">Watch on Battlestar Pegasus \u2197</a>' +
           '<a class="bsw-votd-archive" href="/Battlestar_Wiki:Video_of_the_Day">Video archive</a>' +
'

';

       /* Inject into DOM */
       var playerEl = container.querySelector( '.bsw-votd-player' );
       var infoEl   = document.getElementById( 'bsw-votd-info' );
       if ( playerEl ) {
           playerEl.innerHTML = playerHtml;
           /* Wire HLS.js if HLS src available and browser needs it */
           if ( hlsSrc ) {
               var videoEl = document.getElementById( videoId );
               if ( videoEl ) {
                   if ( videoEl.canPlayType( 'application/vnd.apple.mpegurl' ) ) {
                       /* Native HLS (Safari) */
                       videoEl.src = hlsSrc;
                   } else {
                       /* Load hls.js dynamically from cdnjs */
                       var script = document.createElement( 'script' );
                       script.src = 'https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.4.12/hls.min.js';
                       script.onload = function () {
                           if ( window.Hls && Hls.isSupported() ) {
                               var hls = new Hls( { startLevel: 3 } ); /* start at 720p */
                               hls.loadSource( hlsSrc );
                               hls.attachMedia( videoEl );
                           }
                       };
                       document.head.appendChild( script );
                   }
               }
           }
       }
       if ( infoEl ) {
           infoEl.innerHTML = infoHtml;
           infoEl.style.display = ;
       }
   }
   function showVotdError( container, msg ) {
       var playerEl = container.querySelector( '.bsw-votd-player' );
       if ( playerEl ) {
           playerEl.innerHTML =

'

' +
               'Could not load video. ' +
               '<a href="' + esc( PEGASUS ) + '" target="_blank" rel="noopener">Visit Battlestar Pegasus \u2197</a>' +
'

';

       }
   }
   mw.hook( 'wikipage.content' ).add( function () {
       var container = document.getElementById( 'bsw-votd-container' );
       if ( !container ) return;
       var dateStr      = container.dataset.date || ;
       var overrideEl   = document.getElementById( 'bsw-votd-override' );
       var override     = overrideEl ? overrideEl.textContent.trim() : ;
       var seed = ( function () {
           if ( dateStr ) {
               var p = dateStr.split( '-' );
               return Math.floor( Date.UTC( +p[0], +p[1] - 1, +p[2] ) / 86400000 );
           }
           return dailySeed();
       }() );
       if ( override ) {
           fetchVideoDetail( override )
               .then( function ( media ) { renderVotd( container, media ); } )
               .catch( function ( e ) { showVotdError( container, e.message ); } );
       } else {
           fetchAllVideos()
               .then( function ( items ) {
                   if ( !items.length ) throw new Error( 'No videos available.' );
                   var pick = items[ seed % items.length ];
                   return fetchVideoDetail( pick.friendly_token );
               } )
               .then( function ( media ) { renderVotd( container, media ); } )
               .catch( function ( e ) { showVotdError( container, e.message ); } );
       }
   } );

}() );