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) {