From 5a3da11c40d6af78a040617a3a0051ed871db6f2 Mon Sep 17 00:00:00 2001 From: ansuz Date: Wed, 17 Aug 2016 11:28:50 +0200 Subject: [PATCH] very simple presentation with markdown --- www/slide/index.html | 81 +++++++++++++++++++++++++++++ www/slide/main.js | 118 +++++++++++++++++++++++++++++++++++++++++++ www/slide/slide.js | 77 ++++++++++++++++++++++++++++ 3 files changed, 276 insertions(+) create mode 100644 www/slide/index.html create mode 100644 www/slide/main.js create mode 100644 www/slide/slide.js diff --git a/www/slide/index.html b/www/slide/index.html new file mode 100644 index 000000000..1e66e73fc --- /dev/null +++ b/www/slide/index.html @@ -0,0 +1,81 @@ + + + + + + + + + +
+ +
+ + +
+ + + diff --git a/www/slide/main.js b/www/slide/main.js new file mode 100644 index 000000000..9b364ca9c --- /dev/null +++ b/www/slide/main.js @@ -0,0 +1,118 @@ +define([ + '/api/config?cb=' + Math.random().toString(16).substring(2), + '/bower_components/chainpad-netflux/chainpad-netflux.js', + '/bower_components/chainpad-crypto/crypto.js', + '/bower_components/textpatcher/TextPatcher.amd.js', + '/common/cryptpad-common.js', + '/slide/slide.js', + '/bower_components/jquery/dist/jquery.min.js', + '/customize/pad.js' +], function (Config, Realtime, Crypto, TextPatcher, Cryptpad, Slide) { + var $ = window.jQuery; + + /* + TODO + * patch in changes using DiffDOM + * predraw some things in case they use external assets + * strip out script tags? + * better CSS + * use codemirror instead of a text editor + * add ability to link to a rendered slide + * ui hint for escaping presentation mode + */ + + var secret = Cryptpad.getSecrets(); + + var module = window.APP = { + TextPatcher: TextPatcher, + Slide: Slide, + }; + + var userName = module.userName = Crypto.rand64(8); + + var initializing = true; + var $textarea = $('textarea'); + + var $modal = $('#modal'); + var $content = $('#content'); + Slide.setModal($modal, $content); + + var $present = $('#present').click(function () { + Slide.show(true, $textarea.val()); + Cryptpad.log("Hit ESC to exit presentation mode"); + }); + + var config = module.config = { + initialState: '', + websocketURL: Config.websocketURL, + channel: secret.channel, + crypto: Crypto.createEncryptor(secret.key), + }; + + var setEditable = function (bool) { $textarea.attr('disabled', !bool); }; + var canonicalize = function (text) { return text.replace(/\r\n/g, '\n'); }; + + setEditable(false); + + var onInit = config.onInit = function (info) { + window.location.hash = info.channel + secret.key; + $(window).on('hashchange', function() { + window.location.reload(); + }); + }; + + var onRemote = config.onRemote = function (info) { + if (initializing) { return; } + var userDoc = module.realtime.getUserDoc(); + var content = canonicalize($textarea.val()); + + var op = TextPatcher.diff(content, userDoc); + var elem = $textarea[0]; + + var selects = ['selectionStart', 'selectionEnd'].map(function (attr) { + return TextPatcher.transformCursor(elem[attr], op); + }); + + $textarea.val(userDoc); + elem.selectionStart = selects[0]; + elem.selectionEnd = selects[1]; + + Slide.update(content); + }; + + var onLocal = config.onLocal = function () { + if (initializing) { return; } + var content = canonicalize($textarea.val()); + module.patchText(content); + Slide.update(content); + }; + + var onReady = config.onReady = function (info) { + var realtime = module.realtime = info.realtime; + module.patchText = TextPatcher.create({ + realtime: realtime + }); + + var content = canonicalize(realtime.getUserDoc()); + $textarea.val(content); + + Slide.update(content); + + setEditable(true); + initializing = false; + }; + + var onAbort = config.onAbort = function (info) { + $textarea.attr('disabled', true); + window.alert("Server Connection Lost"); + }; + + var rt = Realtime.start(config); + + ['cut', 'paste', 'change', 'keyup', 'keydown', 'select', 'textInput'] + .forEach(function (evt) { + $textarea.on(evt, onLocal); + }); + + +}); diff --git a/www/slide/slide.js b/www/slide/slide.js new file mode 100644 index 000000000..3e0227250 --- /dev/null +++ b/www/slide/slide.js @@ -0,0 +1,77 @@ +define([ + '/bower_components/marked/marked.min.js', + '/bower_components/jquery/dist/jquery.min.js', +],function (Marked) { + var $ = window.jQuery; + + var truthy = function (x) { return x; }; + + var Slide = { + index: 0, + lastIndex: 0, + content: [], + }; + var $modal; + var $content; + Slide.setModal = function ($m, $c) { + $modal = Slide.$modal = $m; + $content = Slide.$content = $c; + }; + var draw = Slide.draw = function (i) { + console.log("Trying to draw slide #%s", i); + if (typeof(Slide.content[i]) !== 'string') { return; } + + var c = Slide.content[i]; + console.log(c); + $content.html(Marked(c)); + }; + + var show = Slide.show = function (bool, content) { + Slide.shown = bool; + if (bool) { + Slide.update(content); + Slide.draw(Slide.index); + $modal.addClass('shown'); + return; + } + $modal.removeClass('shown'); + }; + + var update = Slide.update = function (content) { + if (!Slide.shown) { return; } + console.log(content); + Slide.content = content.split(/\n\-\-\-\n/).filter(truthy); + draw(Slide.index); + }; + + var left = Slide.left = function () { + console.log('left'); + var i = Slide.index = Math.max(0, Slide.index - 1); + Slide.draw(i); + }; + + var right = Slide.right = function () { + console.log('right'); + var i = Slide.index = Math.min(Slide.content.length, Slide.index + 1); + Slide.draw(i); + }; + + $(document).on('keyup', function (e) { + if (!Slide.shown) { return; } + switch(e.which) { + case 37: + Slide.left(); + break; + case 39: // right + Slide.right(); + break; + case 27: // esc + show(false); + break; + default: + console.log(e.which); + } + }); + + return Slide; +});