summaryrefslogblamecommitdiffstats
path: root/templates/script.js
blob: 428adf3aac7cf8809da670ac0e1db63b009a79a0 (plain) (tree)


































































































































































































































                                                                                                                                                           
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0-or-later
  /*

  SeekToTime - simple script to add video time jump functionality to timestamp links
  Copyright (C) 2020  Grant Shangreaux

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as
  published by the Free Software Foundation, either version 3 of the
  License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License
  along with this program.  If not, see <https://www.gnu.org/licenses/>.

  This script enables wiki editors to create anchor tags with the class "time-link"
  that will be parsed for seeking to specific time stamps in the main video on a page.
  The tag should look like this:

   <a href="#mainVideo" class="time-link">mm:ss</a>

  This could be extended to accept hours in the time stamp as well, but currently does not.
  */
 let timestamps;

  // expects a string like "mm:ss.mmm"
  function parseSeconds(timeString) {
    return timeString.split(":").reduce(function(prev, o) {
      return prev * 60 + parseFloat(o);
    }, 0);
  }

 function handleSubtitleClick(event) {
	 var video = event.target.getAttribute('data-video');
		var start = event.target.getAttribute('data-start');
    var videoElem = document.getElementById(video);
    if (videoElem) {
      videoElem.currentTime = parseSeconds(start);
      videoElem.scrollIntoView();
    }
    if (event.preventDefault) {
	    event.preventDefault();
	  }
  }

  window.onload = function initScript() {
    let subtitles = document.getElementsByClassName('subtitle');
    for (let i = 0; i < subtitles.length; i++) {
      subtitles[i].onclick = handleSubtitleClick;
    }
  }
// @license-end
  // @license magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt txt CC0-1.0
  //  Copyright (C) 2021, 2022 Sacha Chua

  if (document.querySelector('.times')) {
    var dateOptions = {dateStyle: 'short', timeStyle: 'short'};
    var localStart = (new Date(document.querySelector('.times').getAttribute('start'))).toLocaleString([], dateOptions);
    var localEnd = (new Date(document.querySelector('.times').getAttribute('end'))).toLocaleString([], dateOptions);
    var dateElem = document.createElement('div');
    dateElem.appendChild(document.createTextNode('Your local time: ~ ' + localStart +  ' to ~ ' + localEnd));
    document.querySelector('.times').prepend(dateElem);
    if (document.querySelector('.times').querySelector('.others')) {
      document.querySelector('.times').querySelector('.others').style.display = 'none';
    }
  }
	if (document.querySelector('.time-overlay')) {
		document.querySelectorAll('.time-overlay').forEach(function (o) {
			if (o.getAttribute('title')) return;
			var dateOptions = {dateStyle: 'short', timeStyle: 'short'};
			var localStart, localEnd;
			if (o.getAttribute('start') && o.getAttribute('end')) {
				localStart = (new Date(o.getAttribute('start'))).toLocaleString([], dateOptions);
				localEnd = (new Date(o.getAttribute('end'))).toLocaleString([], dateOptions);
				o.setAttribute('title', 'Your local time: ~ ' + localStart +  ' to ~ ' + localEnd);
			} else if (o.getAttribute('start')) {
				localStart = (new Date(o.getAttribute('start'))).toLocaleString([], dateOptions);
				o.setAttribute('title', 'Your local time: ~ ' + localStart);
			}
		});
  }

  if (document.querySelector('a[name=transcript]')) {
    var transcriptLink = document.createElement('a');
    transcriptLink.setAttribute('href', '#transcript');
    transcriptLink.textContent = 'View transcript';
		var video = document.querySelector('.mainVideo video');
		if (video) {
			var resources = document.querySelector('.mainVideo video').closest('.vid').querySelector('.resources');
			var transcriptDiv = document.createElement('div');
			transcriptDiv.appendChild(transcriptLink)
			if (resources) { resources.prepend(transcriptDiv); }
		}
	}
  var chat = document.querySelector('.chat-iframe');
  if (chat) {
    if (chat.getAttribute('data-track')) {
      chat.innerHTML = '<iframe src="https://chat.emacsconf.org?join=emacsconf,emacsconf-' +
        chat.getAttribute('data-track').replace(/[^A-Za-z]/g, '') + '" height="600" width="100%"></iframe>';
    } else {
      chat.innerHTML = '<iframe src="https://chat.emacsconf.org" height="600" width="100%"></iframe>';
    }
  }

// @license-end
 // @license magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt txt CC0-1.0
 // Copyright (c) 2021 Sacha Chua - CC0 Public Domain
 function displayChapters(elem) {
   var i;
   var chapter;
   var list = document.createElement('ol');
   list.setAttribute('class', 'chapters');
   var link;
   var target = elem.getAttribute('data-target');
   var video = document.getElementById(target);
   var track;
   if (video) {
     track = video.addTextTrack('chapters');
     track.mode = 'hidden';
   }
   var chapters = elem.textContent.split(/[ \t]*\n+[ \t]*/).forEach(function(line) {
     var m = (line.match(/^(((?:[0-9]+:)?[0-9]+:[0-9]+)(?:\.[0-9]+))[ \t]+(.*)/));
     if (m) {
       var start = m[1];
       var text = m[3];
       chapter = document.createElement('li');
       link = document.createElement('a');
       link.setAttribute('href', '#');
       link.setAttribute('data-video', target);
       link.setAttribute('data-start', start);
       link.setAttribute('data-start-s', parseSeconds(start));
       link.appendChild(document.createTextNode(m[2] + ' ' + text));
       link.onclick = handleSubtitleClick;
       chapter.appendChild(link);
       list.appendChild(chapter);
       if (track) {
         var time = parseSeconds(start);
         if (track.cues.length > 0) {
           track.cues[track.cues.length - 1].endTime = time - 1;
         }
         track.addCue(new VTTCue(time, time, text));
       }
     }
   })
   if (track && track.cues.length > 0) {
     video.addEventListener('durationchange', function() {
       track.cues[track.cues.length - 1].endTime = video.duration;
     });
     track.addEventListener('cuechange', function() {
       if (!this.activeCues[0]) return;
       if (list.querySelector('.current')) {
         list.querySelector('.current').className = '';
       }
       var chapter;
       if (chapter = list.querySelector('a[data-start-s="' + this.activeCues[0].startTime + '"]')) {
         chapter.parentNode.className = 'current';
       }
     });
   }
   elem.parentNode.replaceChild(list, elem);
 }

 document.querySelectorAll('pre.chapters').forEach(displayChapters);

 var video = document.querySelector('video.reload');
 if (video) {
   var myVar = setInterval(reloadAsNeeded, 1000);
   var oldTime = '';
   function reloadAsNeeded() {
     if ((video.paused != true && (video.currentTime - oldTime) == 0 && video.currentTime != 0)) {
       var source = video.querySelector('source');
       var oldVideo = source.src;
       source.src = '';
       source.src = oldVideo;
       video.load();
       video.play();
     }
     oldTime = video.currentTime;
   };
 }

 /* videoType: mainVideo, qanda */
 function addStickyVideo(videoType) {
	 const transcriptDiv = document.querySelector('.transcript-' + videoType);
	 const video = document.querySelector('.vid.' + videoType + ' video');
	 if (!video || !transcriptDiv) return;
	 if (transcriptDiv.querySelector('.vid'))
		 transcriptDiv.querySelector('.vid').remove();
	 // already has it
	 // TODO: Make a copy of the video and place it at the start of the btranscript div, positioned to the left, and sticky, but only on large screens.
	 const videoCopy = video.cloneNode(true);
	 transcriptDiv.prepend(videoCopy);
	 videoCopy.classList.add('sticky-video');
	 // TODO: fix the ID

 }



 // @license-end
 // @license magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt txt CC0-1.0
 // Copyright (c) 2023 Sacha Chua - CC0 Public Domain
 function highlightTalks() {
	 // highlight any talk mentioned in the highlight URL parameter
	 var params = new URLSearchParams(window.location.search);
	 if (!params.get('highlight')) return;
	 var talks = params.get('highlight').split(',').filter(function(o) { return o.match(/^[-a-z0-9]+$/); });
	 var regexp = new RegExp('/talks/(' + talks.join('|') + ')/?$');
	 document.querySelectorAll('a[href]').forEach(function(link) {
		 console.debug(link.getAttribute('href'), link.getAttribute('href').match(regexp));
		 if (link.getAttribute('href').match(regexp)) {
			 console.debug(link);
			 link.classList.add('highlight');
		 }
	 });
 }

 addEventListener('DOMContentLoaded', highlightTalks);
 addEventListener('DOMContentLoaded', function() {
	 addStickyVideo('mainVideo');
	 addStickyVideo('qanda');
 });
 // @license-end