fixed showing speaker's view with timings/pacing while serving the presentation from the file system
This commit is contained in:
parent
325162692e
commit
8468d82433
3 changed files with 141 additions and 77 deletions
16
js/reveal.js
16
js/reveal.js
|
@ -3901,6 +3901,20 @@
|
|||
|
||||
}
|
||||
|
||||
function getSlidesMetaInfo() {
|
||||
|
||||
var slides = getSlides();
|
||||
return slides.map( function (slide) {
|
||||
var meta = {};
|
||||
for( var i = 0; i < slide.attributes.length; i++ ) {
|
||||
var attribute = slide.attributes[ i ];
|
||||
meta[ attribute.name ] = attribute.value;
|
||||
}
|
||||
return meta;
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the total number of slides in this presentation.
|
||||
*
|
||||
|
@ -5252,6 +5266,8 @@
|
|||
// Returns an Array of all slides
|
||||
getSlides: getSlides,
|
||||
|
||||
getSlidesMetaInfo: getSlidesMetaInfo,
|
||||
|
||||
// Returns the total number of slides
|
||||
getTotalSlides: getTotalSlides,
|
||||
|
||||
|
|
|
@ -329,6 +329,8 @@
|
|||
upcomingSlide,
|
||||
layoutLabel,
|
||||
layoutDropdown,
|
||||
pendingCalls = {},
|
||||
lastRevealApiCallId = 0,
|
||||
connected = false;
|
||||
|
||||
var SPEAKER_LAYOUTS = {
|
||||
|
@ -356,6 +358,10 @@
|
|||
else if( data.type === 'state' ) {
|
||||
handleStateMessage( data );
|
||||
}
|
||||
else if( data.type === 'return' ) {
|
||||
pendingCalls[data.callId](data.result);
|
||||
delete pendingCalls[data.callId];
|
||||
}
|
||||
}
|
||||
// Messages sent by the reveal.js inside of the current slide preview
|
||||
else if( data && data.namespace === 'reveal' ) {
|
||||
|
@ -372,6 +378,18 @@
|
|||
|
||||
} );
|
||||
|
||||
function callRevealApi( methodName, methodArguments, callback ) {
|
||||
var callId = ++lastRevealApiCallId;
|
||||
pendingCalls[callId] = callback;
|
||||
window.opener.postMessage( JSON.stringify( {
|
||||
namespace: 'reveal-notes',
|
||||
type: 'call',
|
||||
callId: callId,
|
||||
methodName: methodName,
|
||||
arguments: methodArguments
|
||||
} ), '*' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the main window is trying to establish a
|
||||
* connection.
|
||||
|
@ -486,28 +504,34 @@
|
|||
|
||||
}
|
||||
|
||||
function getTimings() {
|
||||
function getTimings( callback ) {
|
||||
|
||||
var slides = Reveal.getSlides();
|
||||
var defaultTiming = Reveal.getConfig().defaultTiming;
|
||||
if (defaultTiming == null) {
|
||||
return null;
|
||||
}
|
||||
var timings = [];
|
||||
for ( var i in slides ) {
|
||||
var slide = slides[i];
|
||||
var timing = defaultTiming;
|
||||
if( slide.hasAttribute( 'data-timing' )) {
|
||||
var t = slide.getAttribute( 'data-timing' );
|
||||
timing = parseInt(t);
|
||||
if( isNaN(timing) ) {
|
||||
console.warn("Could not parse timing '" + t + "' of slide " + i + "; using default of " + defaultTiming);
|
||||
timing = defaultTiming;
|
||||
callRevealApi( 'getSlidesMetaInfo', [], function ( slides ) {
|
||||
callRevealApi( 'getConfig', [], function ( config ) {
|
||||
var defaultTiming = config.defaultTiming;
|
||||
if (defaultTiming == null) {
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
timings.push(timing);
|
||||
}
|
||||
return timings;
|
||||
|
||||
var timings = [];
|
||||
for ( var i in slides ) {
|
||||
var slide = slides[ i ];
|
||||
var timing = defaultTiming;
|
||||
if( slide.hasOwnProperty( 'data-timing' )) {
|
||||
var t = slide[ 'data-timing' ];
|
||||
timing = parseInt(t);
|
||||
if( isNaN(timing) ) {
|
||||
console.warn("Could not parse timing '" + t + "' of slide " + i + "; using default of " + defaultTiming);
|
||||
timing = defaultTiming;
|
||||
}
|
||||
}
|
||||
timings.push(timing);
|
||||
}
|
||||
|
||||
callback( timings );
|
||||
} );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
@ -515,15 +539,15 @@
|
|||
* Return the number of seconds allocated for presenting
|
||||
* all slides up to and including this one.
|
||||
*/
|
||||
function getTimeAllocated(timings) {
|
||||
function getTimeAllocated( timings, callback ) {
|
||||
|
||||
var slides = Reveal.getSlides();
|
||||
var allocated = 0;
|
||||
var currentSlide = Reveal.getSlidePastCount();
|
||||
for (var i in slides.slice(0, currentSlide + 1)) {
|
||||
allocated += timings[i];
|
||||
}
|
||||
return allocated;
|
||||
callRevealApi( 'getSlidePastCount', [], function ( currentSlide ) {
|
||||
var allocated = 0;
|
||||
for (var i in timings.slice(0, currentSlide + 1)) {
|
||||
allocated += timings[i];
|
||||
}
|
||||
callback( allocated );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
@ -545,12 +569,51 @@
|
|||
pacingMinutesEl = pacingEl.querySelector( '.minutes-value' ),
|
||||
pacingSecondsEl = pacingEl.querySelector( '.seconds-value' );
|
||||
|
||||
var timings = getTimings();
|
||||
if (timings !== null) {
|
||||
pacingTitleEl.style.removeProperty('display');
|
||||
pacingEl.style.removeProperty('display');
|
||||
var timings = null;
|
||||
getTimings( function ( _timings ) {
|
||||
|
||||
timings = _timings;
|
||||
if (_timings !== null) {
|
||||
pacingTitleEl.style.removeProperty('display');
|
||||
pacingEl.style.removeProperty('display');
|
||||
}
|
||||
|
||||
// Update once directly
|
||||
_updateTimer();
|
||||
|
||||
// Then update every second
|
||||
setInterval( _updateTimer, 1000 );
|
||||
|
||||
} );
|
||||
|
||||
|
||||
function _resetTimer() {
|
||||
|
||||
if (timings == null) {
|
||||
start = new Date();
|
||||
_updateTimer();
|
||||
}
|
||||
else {
|
||||
// Reset timer to beginning of current slide
|
||||
getTimeAllocated( timings, function ( slideEndTimingSeconds ) {
|
||||
var slideEndTiming = slideEndTimingSeconds * 1000;
|
||||
callRevealApi( 'getSlidePastCount', [], function ( currentSlide ) {
|
||||
var currentSlideTiming = timings[currentSlide] * 1000;
|
||||
var previousSlidesTiming = slideEndTiming - currentSlideTiming;
|
||||
var now = new Date();
|
||||
start = new Date(now.getTime() - previousSlidesTiming);
|
||||
_updateTimer();
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
timeEl.addEventListener( 'click', function() {
|
||||
_resetTimer();
|
||||
return false;
|
||||
} );
|
||||
|
||||
function _displayTime( hrEl, minEl, secEl, time) {
|
||||
|
||||
var sign = Math.sign(time) == -1 ? "-" : "";
|
||||
|
@ -592,52 +655,26 @@
|
|||
|
||||
function _updatePacing(diff) {
|
||||
|
||||
var slideEndTiming = getTimeAllocated(timings) * 1000;
|
||||
var currentSlide = Reveal.getSlidePastCount();
|
||||
var currentSlideTiming = timings[currentSlide] * 1000;
|
||||
var timeLeftCurrentSlide = slideEndTiming - diff;
|
||||
if (timeLeftCurrentSlide < 0) {
|
||||
pacingEl.className = 'pacing behind';
|
||||
}
|
||||
else if (timeLeftCurrentSlide < currentSlideTiming) {
|
||||
pacingEl.className = 'pacing on-track';
|
||||
}
|
||||
else {
|
||||
pacingEl.className = 'pacing ahead';
|
||||
}
|
||||
_displayTime( pacingHoursEl, pacingMinutesEl, pacingSecondsEl, timeLeftCurrentSlide );
|
||||
getTimeAllocated( timings, function ( slideEndTimingSeconds ) {
|
||||
var slideEndTiming = slideEndTimingSeconds * 1000;
|
||||
|
||||
callRevealApi( 'getSlidePastCount', [], function ( currentSlide ) {
|
||||
var currentSlideTiming = timings[currentSlide] * 1000;
|
||||
var timeLeftCurrentSlide = slideEndTiming - diff;
|
||||
if (timeLeftCurrentSlide < 0) {
|
||||
pacingEl.className = 'pacing behind';
|
||||
}
|
||||
else if (timeLeftCurrentSlide < currentSlideTiming) {
|
||||
pacingEl.className = 'pacing on-track';
|
||||
}
|
||||
else {
|
||||
pacingEl.className = 'pacing ahead';
|
||||
}
|
||||
_displayTime( pacingHoursEl, pacingMinutesEl, pacingSecondsEl, timeLeftCurrentSlide );
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
// Update once directly
|
||||
_updateTimer();
|
||||
|
||||
// Then update every second
|
||||
setInterval( _updateTimer, 1000 );
|
||||
|
||||
function _resetTimer() {
|
||||
|
||||
if (timings == null) {
|
||||
start = new Date();
|
||||
}
|
||||
else {
|
||||
// Reset timer to beginning of current slide
|
||||
var slideEndTiming = getTimeAllocated(timings) * 1000;
|
||||
var currentSlide = Reveal.getSlidePastCount();
|
||||
var currentSlideTiming = timings[currentSlide] * 1000;
|
||||
var previousSlidesTiming = slideEndTiming - currentSlideTiming;
|
||||
var now = new Date();
|
||||
start = new Date(now.getTime() - previousSlidesTiming);
|
||||
}
|
||||
_updateTimer();
|
||||
|
||||
}
|
||||
|
||||
timeEl.addEventListener( 'click', function() {
|
||||
_resetTimer();
|
||||
return false;
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,8 +21,6 @@ var RevealNotes = (function() {
|
|||
|
||||
var notesPopup = window.open( notesFilePath, 'reveal.js - Notes', 'width=1100,height=700' );
|
||||
|
||||
// Allow popup window access to Reveal API
|
||||
notesPopup.Reveal = this.Reveal;
|
||||
|
||||
/**
|
||||
* Connect to the notes window through a postmessage handshake.
|
||||
|
@ -47,9 +45,22 @@ var RevealNotes = (function() {
|
|||
clearInterval( connectInterval );
|
||||
onConnected();
|
||||
}
|
||||
if( data && data.namespace === 'reveal-notes' && data.type === 'call' ) {
|
||||
callRevealApi( data.methodName, data.arguments, data.callId );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
function callRevealApi( methodName, methodArguments, callId ) {
|
||||
var result = Reveal[methodName].call(Reveal, methodArguments);
|
||||
notesPopup.postMessage( JSON.stringify( {
|
||||
namespace: 'reveal-notes',
|
||||
type: 'return',
|
||||
result: result,
|
||||
callId: callId
|
||||
} ), '*' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts the current slide data to the notes window
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue