Hakim El Hattab
12 years ago
9 changed files with 241 additions and 10 deletions
File diff suppressed because one or more lines are too long
@ -0,0 +1,13 @@ |
|||
(function() { |
|||
var multiplex = window.globals.multiplex; |
|||
var socketId = multiplex.id; |
|||
var socket = io.connect(multiplex.url); |
|||
|
|||
socket.on(multiplex.id, function(data) { |
|||
// ignore data from sockets that aren't ours
|
|||
if (data.socketId !== socketId) { return; } |
|||
if( window.location.host === 'localhost:1947' ) return; |
|||
|
|||
Reveal.slide(data.indexh, data.indexv, null, 'remote'); |
|||
}); |
|||
}()); |
@ -0,0 +1,48 @@ |
|||
var express = require('express'); |
|||
var fs = require('fs'); |
|||
var io = require('socket.io'); |
|||
var crypto = require('crypto'); |
|||
|
|||
var app = express.createServer(); |
|||
var staticDir = express.static; |
|||
|
|||
io = io.listen(app); |
|||
|
|||
var opts = { |
|||
port: 1948, |
|||
baseDir : __dirname + '/../../' |
|||
}; |
|||
|
|||
io.sockets.on('connection', function(socket) { |
|||
socket.on('slidechanged', function(slideData) { |
|||
if (createHash(slideData.secret) === slideData.socketId) { |
|||
slideData.secret = null; |
|||
socket.broadcast.emit(slideData.socketId, slideData); |
|||
}; |
|||
}); |
|||
}); |
|||
|
|||
app.configure(function() { |
|||
[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) { |
|||
app.use('/' + dir, staticDir(opts.baseDir + dir)); |
|||
}); |
|||
}); |
|||
|
|||
app.get("/", function(req, res) { |
|||
fs.createReadStream(opts.baseDir + '/index.html').pipe(res); |
|||
}); |
|||
|
|||
app.get("/token", function(req,res) { |
|||
var ts = new Date().getTime(); |
|||
var rand = Math.floor(Math.random()*9999999); |
|||
var secret = ts.toString() + rand.toString(); |
|||
res.send({secret: secret, socketId: createHash(secret)}); |
|||
}); |
|||
|
|||
var createHash = function(secret) { |
|||
var cipher = crypto.createCipher('blowfish', secret); |
|||
return(cipher.final('hex')); |
|||
}; |
|||
|
|||
// Actually listen
|
|||
app.listen(opts.port || null); |
@ -0,0 +1,32 @@ |
|||
(function() { |
|||
// don't emit events from inside the previews themselves
|
|||
if ( window.location.search.match( /receiver/gi ) ) { return; } |
|||
var multiplex = window.globals.multiplex; |
|||
|
|||
var socket = io.connect(multiplex.url); |
|||
|
|||
Reveal.addEventListener( 'slidechanged', function( event ) { |
|||
var nextindexh; |
|||
var nextindexv; |
|||
var slideElement = event.currentSlide; |
|||
|
|||
if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') { |
|||
nextindexh = event.indexh; |
|||
nextindexv = event.indexv + 1; |
|||
} else { |
|||
nextindexh = event.indexh + 1; |
|||
nextindexv = 0; |
|||
} |
|||
|
|||
var slideData = { |
|||
indexh : event.indexh, |
|||
indexv : event.indexv, |
|||
nextindexh : nextindexh, |
|||
nextindexv : nextindexv, |
|||
secret: multiplex.secret, |
|||
socketId : multiplex.id |
|||
}; |
|||
|
|||
if( typeof event.origin === 'undefined' && event.origin !== 'remote' ) socket.emit('slidechanged', slideData); |
|||
} ); |
|||
}()); |
@ -0,0 +1,109 @@ |
|||
<!doctype html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="utf-8"> |
|||
|
|||
<title>reveal.js - Slide Notes</title> |
|||
|
|||
<style> |
|||
body { |
|||
font-family: Helvetica; |
|||
} |
|||
|
|||
#notes { |
|||
font-size: 24px; |
|||
width: 640px; |
|||
margin-top: 5px; |
|||
} |
|||
|
|||
#wrap-current-slide { |
|||
width: 640px; |
|||
height: 512px; |
|||
float: left; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
#current-slide { |
|||
width: 1280px; |
|||
height: 1024px; |
|||
border: none; |
|||
-moz-transform: scale(0.5); |
|||
-moz-transform-origin: 0 0; |
|||
-o-transform: scale(0.5); |
|||
-o-transform-origin: 0 0; |
|||
-webkit-transform: scale(0.5); |
|||
-webkit-transform-origin: 0 0; |
|||
} |
|||
|
|||
#wrap-next-slide { |
|||
width: 320px; |
|||
height: 256px; |
|||
float: left; |
|||
margin: 0 0 0 10px; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
#next-slide { |
|||
width: 1280px; |
|||
height: 1024px; |
|||
border: none; |
|||
-moz-transform: scale(0.25); |
|||
-moz-transform-origin: 0 0; |
|||
-o-transform: scale(0.25); |
|||
-o-transform-origin: 0 0; |
|||
-webkit-transform: scale(0.25); |
|||
-webkit-transform-origin: 0 0; |
|||
} |
|||
|
|||
.slides { |
|||
position: relative; |
|||
margin-bottom: 10px; |
|||
border: 1px solid black; |
|||
border-radius: 2px; |
|||
background: rgb(28, 30, 32); |
|||
} |
|||
|
|||
.slides span { |
|||
position: absolute; |
|||
top: 3px; |
|||
left: 3px; |
|||
font-weight: bold; |
|||
font-size: 14px; |
|||
color: rgba( 255, 255, 255, 0.9 ); |
|||
} |
|||
</style> |
|||
</head> |
|||
|
|||
<body> |
|||
|
|||
<div id="wrap-current-slide" class="slides"> |
|||
<iframe src="/?receiver" width="1280" height="1024" id="current-slide"></iframe> |
|||
</div> |
|||
|
|||
<div id="wrap-next-slide" class="slides"> |
|||
<iframe src="/?receiver" width="640" height="512" id="next-slide"></iframe> |
|||
<span>UPCOMING:</span> |
|||
</div> |
|||
<div id="notes"></div> |
|||
|
|||
<script src="/socket.io/socket.io.js"></script> |
|||
|
|||
<script> |
|||
var socketId = '{{socketId}}'; |
|||
var socket = io.connect(window.location.origin); |
|||
var notes = document.getElementById('notes'); |
|||
var currentSlide = document.getElementById('current-slide'); |
|||
var nextSlide = document.getElementById('next-slide'); |
|||
|
|||
socket.on('slidedata', function(data) { |
|||
// ignore data from sockets that aren't ours |
|||
if (data.socketId !== socketId) { return; } |
|||
|
|||
notes.innerHTML = data.notes; |
|||
currentSlide.contentWindow.Reveal.navigateTo(data.indexh, data.indexv); |
|||
nextSlide.contentWindow.Reveal.navigateTo(data.nextindexh, data.nextindexv); |
|||
}); |
|||
</script> |
|||
|
|||
</body> |
|||
</html> |
Loading…
Reference in new issue