diff --git a/customize.dist/main.css b/customize.dist/main.css index baba8cd5c..b3d8d2b21 100644 --- a/customize.dist/main.css +++ b/customize.dist/main.css @@ -1127,6 +1127,29 @@ html.cp, .cp div.realtime #addoption { border-bottom-left-radius: 5px; } +.cp.slide #modal .button { + position: absolute; + cursor: pointer; + font-size: 30px; + opacity: 0.6; + display: none; +} +.cp.slide #modal .button:hover { + opacity: 1; + display: block !important; +} +.cp.slide #modal #button_exit { + left: 20px; + top: 20px; +} +.cp.slide #modal #button_left { + left: 6vw; + bottom: 10vh; +} +.cp.slide #modal #button_right { + right: 6vw; + bottom: 10vh; +} .cp.slide #modal #content p, .cp.slide #modal #content ul, .cp.slide #modal #content ol { diff --git a/customize.dist/src/less/cryptpad.less b/customize.dist/src/less/cryptpad.less index 305dc333b..a6fd93b69 100644 --- a/customize.dist/src/less/cryptpad.less +++ b/customize.dist/src/less/cryptpad.less @@ -722,6 +722,31 @@ form.realtime, div.realtime { } &.slide { + #modal { + .button { + position: absolute; + cursor: pointer; + font-size: 30px; + opacity: 0.6; + display: none; + } + .button:hover { + opacity: 1; + display: block !important; + } + #button_exit { + left: 20px; + top: 20px; + } + #button_left { + left: 6vw; + bottom: 10vh; + } + #button_right { + right: 6vw; + bottom: 10vh; + } + } #modal #content { p, ul, ol { font-size: 26px; } diff --git a/www/code/main.js b/www/code/main.js index 3af11316d..9a37efa99 100644 --- a/www/code/main.js +++ b/www/code/main.js @@ -684,8 +684,9 @@ define([ module.patchText(shjson2); } } - - notify(); + if (oldDoc !== remoteDoc) { + notify(); + } }; var onAbort = config.onAbort = function (info) { diff --git a/www/pad/main.js b/www/pad/main.js index 852ad7cd5..60f64bce5 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -477,6 +477,8 @@ define([ var onRemote = realtimeOptions.onRemote = function (info) { if (initializing) { return; } + var oldShjson = stringifyDOM(inner); + var shjson = info.realtime.getUserDoc(); // remember where the cursor is @@ -485,6 +487,11 @@ define([ // Update the user list (metadata) from the hyperjson updateMetadata(shjson); + var newInner = JSON.parse(shjson); + if (newInner.length > 2) { + var newSInner = stringify(newInner[2]); + } + // build a dom from HJSON, diff, and patch the editor applyHjson(shjson); @@ -518,7 +525,12 @@ define([ } } } - notify(); + + // Notify only when the content has changed, not when someone has joined/left + var oldSInner = stringify(JSON.parse(oldShjson)[2]); + if (newSInner !== oldSInner) { + notify(); + } }; var getHTML = function (Dom) { diff --git a/www/poll/index.html b/www/poll/index.html index a55996dce..1b03b54a7 100644 --- a/www/poll/index.html +++ b/www/poll/index.html @@ -4,6 +4,11 @@ Zero Knowledge Date Picker + diff --git a/www/poll/main.js b/www/poll/main.js index 8a07b4ee9..9f009bd69 100644 --- a/www/poll/main.js +++ b/www/poll/main.js @@ -12,7 +12,7 @@ define([ '/common/notify.js', '/bower_components/file-saver/FileSaver.min.js', '/bower_components/jquery/dist/jquery.min.js', -], function (Config, Messages, TextPatcher, Listmap, Crypto, Cryptpad, Hyperjson, Renderer, Toolbar) { +], function (Config, Messages, TextPatcher, Listmap, Crypto, Cryptpad, Hyperjson, Renderer, Toolbar, Visible, Notify) { var $ = window.jQuery; var unlockHTML = ''; @@ -187,6 +187,9 @@ define([ /* Any time the realtime object changes, call this function */ var change = function (o, n, path, throttle) { + if (!Cryptpad.isArray(path)) { + return; + } if (path && path.join) { console.log("Change from [%s] to [%s] at [%s]", o, n, path.join(', ')); @@ -210,6 +213,7 @@ define([ https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion */ + notify(); if (throttle) { if (APP.throttled) { window.clearTimeout(APP.throttled); } @@ -391,87 +395,101 @@ define([ }); }; - var userData = APP.userData = {}; // List of pretty names for all users (mapped with their ID) - var userList; // List of users still connected to the channel (server IDs) - var addToUserData = function(data) { - var users = userList ? userList.users : undefined; - //var userData = APP.proxy.info.userData; - for (var attrname in data) { userData[attrname] = data[attrname]; } + var unnotify = function () { + if (APP.tabNotification && + typeof(APP.tabNotification.cancel) === 'function') { + APP.tabNotification.cancel(); + } + }; - if (users && users.length) { - for (var userKey in userData) { - if (users.indexOf(userKey) === -1) { delete userData[userKey]; } - } - } + var notify = function () { + if (Visible.isSupported() && !Visible.currently()) { + unnotify(); + APP.tabNotification = Notify.tab(1000, 10); + } + }; - if(userList && typeof userList.onChange === "function") { - userList.onChange(userData); - } + var userData = APP.userData = {}; // List of pretty names for all users (mapped with their ID) + var userList; // List of users still connected to the channel (server IDs) + var addToUserData = function(data) { + var users = userList ? userList.users : undefined; + //var userData = APP.proxy.info.userData; + for (var attrname in data) { userData[attrname] = data[attrname]; } - APP.proxy.info.userData = userData; - }; + if (users && users.length) { + for (var userKey in userData) { + if (users.indexOf(userKey) === -1) { delete userData[userKey]; } + } + } - //var myData = {}; - var getLastName = function (cb) { - Cryptpad.getAttribute('username', function (err, userName) { - cb(err, userName || ''); - }); - }; + if(userList && typeof userList.onChange === "function") { + userList.onChange(userData); + } - var setName = APP.setName = function (newName) { - if (typeof(newName) !== 'string') { return; } - var myUserNameTemp = Cryptpad.fixHTML(newName.trim()); - if(myUserNameTemp.length > 32) { - myUserNameTemp = myUserNameTemp.substr(0, 32); - } - var myUserName = myUserNameTemp; - var myID = APP.myID; - var myData = {}; - myData[myID] = { - name: myUserName - }; - addToUserData(myData); - Cryptpad.setAttribute('username', newName, function (err, data) { - if (err) { - console.error("Couldn't set username"); - return; - } - APP.userName.lastName = myUserName; - //change(); - }); - }; - - var updateTitle = function (newTitle) { - if (newTitle === document.title) { return; } - // Change the title now, and set it back to the old value if there is an error - var oldTitle = document.title; - document.title = newTitle; - Cryptpad.renamePad(newTitle, function (err, data) { - if (err) { - console.log("Couldn't set pad title"); - console.error(err); - document.title = oldTitle; - return; - } - document.title = data; - APP.$bar.find('.' + Toolbar.constants.title).find('span.title').text(data); - APP.$bar.find('.' + Toolbar.constants.title).find('input').val(data); - }); - }; + APP.proxy.info.userData = userData; + }; - var updateDefaultTitle = function (defaultTitle) { - defaultName = defaultTitle; - APP.$bar.find('.' + Toolbar.constants.title).find('input').attr("placeholder", defaultName); - }; - var renameCb = function (err, title) { - if (err) { return; } - document.title = title; - APP.proxy.info.title = title; - }; + //var myData = {}; + var getLastName = function (cb) { + Cryptpad.getAttribute('username', function (err, userName) { + cb(err, userName || ''); + }); + }; - var suggestName = function (fallback) { - return document.title || defaultName || ""; - }; + var setName = APP.setName = function (newName) { + if (typeof(newName) !== 'string') { return; } + var myUserNameTemp = Cryptpad.fixHTML(newName.trim()); + if(myUserNameTemp.length > 32) { + myUserNameTemp = myUserNameTemp.substr(0, 32); + } + var myUserName = myUserNameTemp; + var myID = APP.myID; + var myData = {}; + myData[myID] = { + name: myUserName + }; + addToUserData(myData); + Cryptpad.setAttribute('username', newName, function (err, data) { + if (err) { + console.error("Couldn't set username"); + return; + } + APP.userName.lastName = myUserName; + //change(); + }); + }; + + var updateTitle = function (newTitle) { + if (newTitle === document.title) { return; } + // Change the title now, and set it back to the old value if there is an error + var oldTitle = document.title; + document.title = newTitle; + Cryptpad.renamePad(newTitle, function (err, data) { + if (err) { + console.log("Couldn't set pad title"); + console.error(err); + document.title = oldTitle; + return; + } + document.title = data; + APP.$bar.find('.' + Toolbar.constants.title).find('span.title').text(data); + APP.$bar.find('.' + Toolbar.constants.title).find('input').val(data); + }); + }; + + var updateDefaultTitle = function (defaultTitle) { + defaultName = defaultTitle; + APP.$bar.find('.' + Toolbar.constants.title).find('input').attr("placeholder", defaultName); + }; + var renameCb = function (err, title) { + if (err) { return; } + document.title = title; + APP.proxy.info.title = title; + }; + + var suggestName = function (fallback) { + return document.title || defaultName || ""; + }; var copyObject = function (obj) { @@ -575,6 +593,7 @@ define([ .on('change', ['info'], function (o, n, p) { if (p[1] === 'title') { updateTitle(n); + notify(); } else if (p[1] === "userData") { addToUserData(APP.proxy.info.userData); } else if (p[1] === 'description') { @@ -591,6 +610,7 @@ define([ el.selectionStart = selects[0]; el.selectionEnd = selects[1]; } + notify(); } console.log("change: (%s, %s, [%s])", o, n, p.join(', ')); @@ -600,6 +620,13 @@ define([ addToUserData(APP.proxy.info.userData); + if (Visible.isSupported()) { + Visible.onChange(function (yes) { + if (yes) { unnotify(); } + }); + } + + getLastName(function (err, lastName) { APP.ready = true; diff --git a/www/slide/inner.html b/www/slide/inner.html index e3cdae259..1b8dbbf55 100644 --- a/www/slide/inner.html +++ b/www/slide/inner.html @@ -92,6 +92,9 @@ diff --git a/www/slide/main.js b/www/slide/main.js index a44f11c85..b580c8ed8 100644 --- a/www/slide/main.js +++ b/www/slide/main.js @@ -768,7 +768,9 @@ define([ } Slide.update(remoteDoc); - notify(); + if (oldDoc !== newDoc) { + notify(); + } }; var onAbort = config.onAbort = function (info) { diff --git a/www/slide/slide.js b/www/slide/slide.js index cae81204f..501415cad 100644 --- a/www/slide/slide.js +++ b/www/slide/slide.js @@ -202,6 +202,31 @@ define([ }; var addEvent = function () { + var icon_to; + $modal.mousemove(function (e) { + var $buttons = $modal.find('.button'); + $buttons.show(); + if (icon_to) { window.clearTimeout(icon_to); } + icon_to = window.setTimeout(function() { + $buttons.fadeOut(); + }, 1000); + }); + $modal.find('#button_exit').click(function (e) { + var e = jQuery.Event("keyup"); + e.which = 27; + $modal.trigger(e); + }); + $modal.find('#button_left').click(function (e) { + var e = jQuery.Event("keyup"); + e.which = 37; + $modal.trigger(e); + }); + $modal.find('#button_right').click(function (e) { + var e = jQuery.Event("keyup"); + e.which = 39; + $modal.trigger(e); + }); + $(ifrw).on('keyup', function (e) { if (!Slide.shown) { return; } switch(e.which) {