Skip to content

Commit

Permalink
Merge pull request #4 from sashokbg/feat/opts_args
Browse files Browse the repository at this point in the history
added arg options and QR code generation
  • Loading branch information
hakimel authored May 16, 2024
2 parents 005d109 + c77d02d commit 6ea74be
Show file tree
Hide file tree
Showing 7 changed files with 2,071 additions and 62 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
.idea
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,34 @@ reveal.js includes a speaker notes plugin which shows your speaker notes and an
```html
<script src="socket.io/socket.io.js"></script>
<script src="node_modules/reveal-notes-server/client.js"></script>
<script>
startClient({
enableQR: true // set to false if you wish to disable the QR code generation
})
</script>
```

## Cli Options

Here is the list of command line arguments you can use when running the notes server.

```
hostname: argv.hostname,
port: argv.port || 1947,
revealDir: argv.revealDir || process.cwd(),
presentationDir: argv.presentationDir || '.',
presentationIndex: argv.presentationIndex || '/index.html',
pluginDir: __dirname
```
Example shell script to start the server on your Wi-Fi IP:
```shell
# Replace "wlp3s0" wit your Wi-Fi adapter's name
address=$(ip addr show wlp3s0 | grep 'inet ' | sed -E 's/.*inet (([0-9]{0,3}\.?){4}).*/\1/g')
npx reveal-notes-server \
--presentationDir=./ \
--presentationIndex=/my-presentation.adoc \
--hostname="$address"
```
3 changes: 3 additions & 0 deletions cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node
const main = require('./index.js')
main();
76 changes: 61 additions & 15 deletions client.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,48 @@
(function() {
function generateQR(location) {
var div = document.createElement("div");
div.id="qr";
div.style = "position: absolute; top: 0px; display: grid; background-color: white; z-index: 999; padding: 10px;";
div.onclick = function () {
hideQr();
}

var spanTop = document.createElement("span");
spanTop.textContent = "Scan to open notes."

var spanBot = document.createElement("span");
spanBot.textContent = "Click to close."

var img = document.createElement("img");
img.src = "https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=" + encodeURIComponent(location);
img.style = "padding: 5px";

div.appendChild(spanTop);
div.appendChild(img);
div.appendChild(spanBot);

document.body.appendChild(div);
}

function hideQr() {
document.getElementById("qr").style.display = "none";
}

function startClient (options = { enableQR: true }){
console.log('Options are', options);

// don't emit events from inside the previews themselves
if( window.location.search.match( /receiver/gi ) ) { return; }

var socket = io.connect( window.location.origin ),
socketId = Math.random().toString().slice( 2 );

console.log( 'View slide notes at ' + window.location.origin + '/notes/' + socketId );
let location = window.location.origin + '/notes/' + socketId;
console.log( 'View slide notes at ' + location);


if(options.enableQR) {
generateQR(location);
}

window.open( window.location.origin + '/notes/' + socketId, 'notes-' + socketId );

Expand Down Expand Up @@ -42,6 +78,9 @@

// When a new notes window connects, post our current state
socket.on( 'new-subscriber', function( data ) {
if(options.enableQR) {
hideQr();
}
post();
} );

Expand All @@ -50,16 +89,23 @@
Reveal.setState( data.state );
} );

// Monitor events that trigger a change in state
Reveal.on( 'slidechanged', post );
Reveal.on( 'fragmentshown', post );
Reveal.on( 'fragmenthidden', post );
Reveal.on( 'overviewhidden', post );
Reveal.on( 'overviewshown', post );
Reveal.on( 'paused', post );
Reveal.on( 'resumed', post );

// Post the initial state
post();

}());
var interval = setInterval(function() {
if (typeof Reveal == 'undefined') return;
clearInterval(interval);

Reveal.initialize().then( () => {
// reveal.js is ready
// Monitor events that trigger a change in state
Reveal.on( 'slidechanged', post );
Reveal.on( 'fragmentshown', post );
Reveal.on( 'fragmenthidden', post );
Reveal.on( 'overviewhidden', post );
Reveal.on( 'overviewshown', post );
Reveal.on( 'paused', post );
Reveal.on( 'resumed', post );

// Post the initial state
post();
} )
}, 10);
}
106 changes: 60 additions & 46 deletions index.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -3,63 +3,77 @@ let express = require('express');
let fs = require('fs');
let mustache = require('mustache');

let app = express();
let server = http.createServer(app);
let io = require('socket.io')(server);
const yargs = require('yargs/yargs')
const { hideBin } = require('yargs/helpers')
const argv = yargs(hideBin(process.argv)).argv

const main = () => {
let app = express();
let server = http.createServer(app);
let io = require('socket.io')(server);

let opts = {
hostname: argv.hostname,
port: argv.port || 1947,
revealDir: argv.revealDir || process.cwd(),
presentationDir: argv.presentationDir || '.',
presentationIndex: argv.presentationIndex || '/index.html',
pluginDir: __dirname
};

io.on( 'connection', socket => {

socket.on( 'new-subscriber', data => {
socket.broadcast.emit( 'new-subscriber', data );
});

socket.on( 'statechanged', data => {
delete data.state.overview;
socket.broadcast.emit( 'statechanged', data );
});

socket.on( 'statechanged-speaker', data => {
delete data.state.overview;
socket.broadcast.emit( 'statechanged-speaker', data );
});

let opts = {
port: process.env.PORT || 1947,
revealDir: process.cwd(),
pluginDir: __dirname
};

io.on( 'connection', socket => {

socket.on( 'new-subscriber', data => {
socket.broadcast.emit( 'new-subscriber', data );
});

socket.on( 'statechanged', data => {
delete data.state.overview;
socket.broadcast.emit( 'statechanged', data );
});
app.use( express.static( opts.revealDir ) );
app.use( express.static( opts.presentationDir ) );

socket.on( 'statechanged-speaker', data => {
delete data.state.overview;
socket.broadcast.emit( 'statechanged-speaker', data );
app.get('/', ( req, res ) => {
res.writeHead( 200, { 'Content-Type': 'text/html' } );
fs.createReadStream( opts.presentationDir + opts.presentationIndex ).pipe( res );
});

});

app.use( express.static( opts.revealDir ) );

app.get('/', ( req, res ) => {
app.get( '/notes/:socketId', ( req, res ) => {

res.writeHead( 200, { 'Content-Type': 'text/html' } );
fs.createReadStream( opts.revealDir + '/index.html' ).pipe( res );
fs.readFile( opts.pluginDir + '/index.html', ( err, data ) => {
res.send( mustache.render( data.toString(), {
socketId : req.params.socketId
}));
});

});

app.get( '/notes/:socketId', ( req, res ) => {

fs.readFile( opts.pluginDir + '/index.html', ( err, data ) => {
res.send( mustache.render( data.toString(), {
socketId : req.params.socketId
}));
});

});

// Actually listen
server.listen( opts.port || null );
if(opts.hostname) {
server.listen( opts.port || null, opts.hostname);
} else {
server.listen( opts.port || null);
}

let brown = '\033[33m',
green = '\033[32m',
reset = '\033[0m';

let brown = '\033[33m',
green = '\033[32m',
reset = '\033[0m';
let slidesLocation = 'http://' + (opts.hostname ? opts.hostname : 'localhost') + ( opts.port ? ( ':' + opts.port ) : '' );

let slidesLocation = 'http://localhost' + ( opts.port ? ( ':' + opts.port ) : '' );
console.log( brown + 'reveal.js - Speaker Notes' + reset );
console.log( '1. Open the slides at ' + green + slidesLocation + reset );
console.log( '2. Click on the link in your JS console to go to the notes page' );
console.log( '3. Advance through your slides and your notes will advance automatically' );
}

console.log( brown + 'reveal.js - Speaker Notes' + reset );
console.log( '1. Open the slides at ' + green + slidesLocation + reset );
console.log( '2. Click on the link in your JS console to go to the notes page' );
console.log( '3. Advance through your slides and your notes will advance automatically' );
module.exports = main;
Loading

0 comments on commit 6ea74be

Please sign in to comment.