diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index 87caa929f..2d21cf9a6 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -33,6 +33,7 @@ define(function () { out.anonymousStoreDisabled = "L'administrateur de cette instance de CryptPad a désactivé le drive pour les utilisateurs non enregistrés. Vous devez vous connecter pour pouvoir utiliser CryptDrive."; out.expiredError = "Ce pad a atteint sa date d'expiration est n'est donc plus disponible."; out.expiredErrorCopy = ' Vous pouvez toujours copier son contenu ailleurs en appuyant sur Échap.
Dés que vous aurez quitté la page, il sera impossible de le récupérer.'; + out.deletedError = 'Ce pad a été supprimé par son propriétaire et n\'est donc plus disponible.'; out.loading = "Chargement..."; out.error = "Erreur"; diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index 367e704c9..0113dbd84 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -34,6 +34,7 @@ define(function () { out.anonymousStoreDisabled = "The webmaster of this CryptPad instance has disabled the store for anonymous users. You have to log in to be able to use CryptDrive."; out.expiredError = 'This pad has reached its expiration time and is no longer available.'; out.expiredErrorCopy = ' You can still copy the content to another location by pressing Esc.
Once you leave this page, it will disappear forever!'; + out.deletedError = 'This pad has been deleted by its owner and is no longer available.'; out.loading = "Loading..."; out.error = "Error"; diff --git a/rpc.js b/rpc.js index 94d4d4e7e..8148c189c 100644 --- a/rpc.js +++ b/rpc.js @@ -1348,7 +1348,7 @@ RPC.create = function ( case 'REMOVE_OWNED_CHANNEL': return void removeOwnedChannel(Env, msg[1], publicKey, function (e, response) { if (e) { return void Respond(e); } - Respond(void 0, response); + Respond(void 0, "OK"); }); // restricted to privileged users... case 'UPLOAD': diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 432061d2e..e0e5f1ff7 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -1655,8 +1655,6 @@ define([ var metadataMgr = common.getMetadataMgr(); var type = metadataMgr.getMetadataLazy().type; - // XXX check text for pad creation screen + translate it in French - var $body = $('body'); var $creationContainer = $('
', { id: 'cp-creation-container' }).appendTo($body); var $creation = $('
', { id: 'cp-creation' }).appendTo($creationContainer); diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 1ca46e7f1..ae7d752b6 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -897,7 +897,7 @@ define([ case 'addFolder': store.userObject.addFolder(data.path, data.name, cb); break; case 'delete': - store.userObject.delete(data.paths, cb, data.nocheck); break; + store.userObject.delete(data.paths, cb, data.nocheck, data.isOwnPadRemoved); break; case 'emptyTrash': store.userObject.emptyTrash(cb); break; case 'rename': diff --git a/www/common/outer/userObject.js b/www/common/outer/userObject.js index 3293dcb36..70a8445f7 100644 --- a/www/common/outer/userObject.js +++ b/www/common/outer/userObject.js @@ -85,8 +85,11 @@ define([ delete files[FILES_DATA][id]; }; - exp.checkDeletedFiles = function () { - // Nothing in OLD_FILES_DATA for workgroups + // Find files in FILES_DATA that are not anymore in the drive, and remove them from + // FILES_DATA. If there are owned pads, remove them from server too, unless the flag tells + // us they're already removed + exp.checkDeletedFiles = function (isOwnPadRemoved) { + // Nothing in FILES_DATA for workgroups if (workgroup || (!loggedIn && !config.testMode)) { return; } var filesList = exp.getFiles([ROOT, 'hrefArray', TRASH]); @@ -96,7 +99,8 @@ define([ var fd = exp.getFileData(id); var channelId = fd && fd.href && Hash.hrefToHexChannelId(fd.href); // If trying to remove an owned pad, remove it from server also - if (fd.owners && fd.owners.indexOf(edPublic) !== -1 && channelId) { + if (!isOwnPadRemoved && + fd.owners && fd.owners.indexOf(edPublic) !== -1 && channelId) { removeOwnedChannel(channelId, function (obj) { if (obj && obj.error) { console.error(obj.error); } }); @@ -123,7 +127,7 @@ define([ files[TRASH][obj.name].splice(idx, 1); }); }; - exp.deleteMultiplePermanently = function (paths, nocheck) { + exp.deleteMultiplePermanently = function (paths, nocheck, isOwnPadRemoved) { var hrefPaths = paths.filter(function(x) { return exp.isPathIn(x, ['hrefArray']); }); var rootPaths = paths.filter(function(x) { return exp.isPathIn(x, [ROOT]); }); var trashPaths = paths.filter(function(x) { return exp.isPathIn(x, [TRASH]); }); @@ -179,7 +183,7 @@ define([ // In some cases, we want to remove pads from a location without removing them from // OLD_FILES_DATA (replaceHref) - if (!nocheck) { exp.checkDeletedFiles(); } + if (!nocheck) { exp.checkDeletedFiles(isOwnPadRemoved); } }; // Move diff --git a/www/common/pinpad.js b/www/common/pinpad.js index 0bbaddd37..f38d7fc57 100644 --- a/www/common/pinpad.js +++ b/www/common/pinpad.js @@ -157,8 +157,8 @@ define([ } rpc.send('REMOVE_OWNED_CHANNEL', channel, function (e, response) { if (e) { return void cb(e); } - if (response && response.length) { - cb(void 0, response[0]); // I haven't tested this... + if (response && response.length && response[0] === "OK") { + cb(); } else { cb('INVALID_RESPONSE'); } diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index 2e51776d6..ef516e86d 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -340,6 +340,11 @@ define([ if (err.loaded) { msg += Messages.expiredErrorCopy; } + } else if (err.type === 'EDELETED') { + msg = Messages.deletedError; + if (err.loaded) { + msg += Messages.expiredErrorCopy; + } } UI.errorLoadingScreen(msg, true, true); }; @@ -436,7 +441,9 @@ define([ var priv = common.getMetadataMgr().getPrivateData(); if (priv.isNewFile) { var c = (priv.settings.general && priv.settings.general.creation) || {}; - if (c.skip && !priv.forceCreationScreen) { return void common.createPad(c, waitFor()); } + if (c.skip && !priv.forceCreationScreen) { + return void common.createPad(c, waitFor()); + } common.getPadCreationScreen(c, waitFor()); } }).nThen(function (waitFor) { diff --git a/www/common/toolbar3.js b/www/common/toolbar3.js index cb1bb764c..e014503c6 100644 --- a/www/common/toolbar3.js +++ b/www/common/toolbar3.js @@ -1100,6 +1100,7 @@ define([ toolbar.deleted = function (/*userId*/) { toolbar.isErrorState = true; toolbar.connected = false; + updateUserList(toolbar, config); if (toolbar.spinner) { toolbar.spinner.text(Messages.deletedFromServer); } diff --git a/www/common/userObject.js b/www/common/userObject.js index 223376963..4f7f03b23 100644 --- a/www/common/userObject.js +++ b/www/common/userObject.js @@ -556,17 +556,18 @@ define([ // DELETE // Permanently delete multiple files at once using a list of paths // NOTE: We have to be careful when removing elements from arrays (trash root, unsorted or template) - exp.delete = function (paths, cb, nocheck) { + exp.delete = function (paths, cb, nocheck, isOwnPadRemoved) { if (sframeChan) { return void sframeChan.query("Q_DRIVE_USEROBJECT", { cmd: "delete", data: { paths: paths, - nocheck: nocheck + nocheck: nocheck, + isOwnPadRemoved: isOwnPadRemoved } }, cb); } - exp.deleteMultiplePermanently(paths, nocheck); + exp.deleteMultiplePermanently(paths, nocheck, isOwnPadRemoved); if (typeof cb === "function") { cb(); } }; exp.emptyTrash = function (cb) { diff --git a/www/drive/inner.js b/www/drive/inner.js index be4909415..2f5ff9fa0 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -2715,6 +2715,8 @@ define([ UI.confirm(msgD, function(res) { $(window).focus(); if (!res) { return; } + filesOp.delete(pathsList, refresh); + /* // Try to delete each selected pad from server, and delete from drive if no error var n = nThen(function () {}); pathsList.forEach(function (p) { @@ -2726,10 +2728,12 @@ define([ sframeChan.query('Q_REMOVE_OWNED_CHANNEL', channel, waitFor(function (e) { if (e) { return void console.error(e); } - filesOp.delete([p], refresh); + filesOp.delete([p], function () {}, false, true); })); }); }); + n.nThen(function () { refresh(); }); + */ }); }; $contextMenu.on("click", "a", function(e) { diff --git a/www/poll/app-poll.less b/www/poll/app-poll.less index 88839f96e..0a5d5ca59 100644 --- a/www/poll/app-poll.less +++ b/www/poll/app-poll.less @@ -6,6 +6,7 @@ @import (once) '../../customize/src/less2/include/tokenfield.less'; @import (once) '../../customize/src/less2/include/tools.less'; @import (once) '../../customize/src/less2/include/avatar.less'; +@import (once) '../../customize/src/less2/include/creation.less'; .toolbar_main( @bg-color: @colortheme_poll-bg, @@ -15,6 +16,7 @@ .fileupload_main(); .alertify_main(); .tokenfield_main(); +.creation_main(); @poll-fore: #555; diff --git a/www/poll/inner.js b/www/poll/inner.js index dd585ec31..f88ac5763 100644 --- a/www/poll/inner.js +++ b/www/poll/inner.js @@ -1119,13 +1119,34 @@ define([ } UI.removeLoadingScreen(); - if (isNew) { + var privateDat = metadataMgr.getPrivateData(); + var skipTemp = Util.find(privateDat, + ['settings', 'general', 'creation', 'noTemplate']); + var skipCreation = Util.find(privateDat, ['settings', 'general', 'creation', 'skip']); + if (isNew && (!AppConfig.displayCreationScreen || (!skipTemp && skipCreation))) { common.openTemplatePicker(); } }; - var onDisconnect = function () { + // Manage disconnections because of network or error + var onDisconnect = function (info) { setEditable(false); + if (info && ['EEXPIRED', 'EDELETED'].indexOf(info.type) !== -1) { + APP.toolbar.deleted(); + var msg = info.type; + if (info.type === 'EEXPIRED') { + msg = Messages.expiredError; + if (info.loaded) { + msg += Messages.expiredErrorCopy; + } + } else if (info.type === 'EDELETED') { + msg = Messages.deletedError; + if (info.loaded) { + msg += Messages.expiredErrorCopy; + } + } + return void UI.errorLoadingScreen(msg, true, true); + } UI.alert(Messages.common_connectionLost, undefined, true); }; @@ -1175,6 +1196,7 @@ define([ Title.setToolbar(APP.toolbar); var $rightside = APP.toolbar.$rightside; + var $drawer = APP.toolbar.$drawer; metadataMgr.onChange(function () { var md = copyObject(metadataMgr.getMetadata()); @@ -1189,6 +1211,9 @@ define([ var $forgetPad = common.createButton('forget', true, {}, forgetCb); $rightside.append($forgetPad); + var $properties = common.createButton('properties', true); + $drawer.append($properties); + /* save as template */ if (!metadataMgr.getPrivateData().isTemplate) { var templateObj = { @@ -1201,7 +1226,7 @@ define([ /* add an export button */ var $export = common.createButton('export', true, {}, exportFile); - $rightside.append($export); + $drawer.append($export); var $help = common.createButton('', true).click(function () { showHelp(); }) .appendTo($rightside); @@ -1255,6 +1280,16 @@ define([ SFCommon.create(waitFor(function (c) { APP.common = common = c; })); }).nThen(function (waitFor) { common.getSframeChannel().onReady(waitFor()); + }).nThen(function (waitFor) { + if (!AppConfig.displayCreationScreen) { return; } + var priv = common.getMetadataMgr().getPrivateData(); + if (priv.isNewFile) { + var c = (priv.settings.general && priv.settings.general.creation) || {}; + if (c.skip && !priv.forceCreationScreen) { + return void common.createPad(c, waitFor()); + } + common.getPadCreationScreen(c, waitFor()); + } }).nThen(function (/* waitFor */) { Test.registerInner(common.getSframeChannel()); var metadataMgr = common.getMetadataMgr(); diff --git a/www/poll/main.js b/www/poll/main.js index 737038ead..85bbb6f62 100644 --- a/www/poll/main.js +++ b/www/poll/main.js @@ -36,6 +36,8 @@ define([ }; window.addEventListener('message', onMsg); }).nThen(function (/*waitFor*/) { - SFCommonO.start(); + SFCommonO.start({ + useCreationScreen: true + }); }); }); diff --git a/www/whiteboard/app-whiteboard.less b/www/whiteboard/app-whiteboard.less index 28e6a6e0c..29c739b6e 100644 --- a/www/whiteboard/app-whiteboard.less +++ b/www/whiteboard/app-whiteboard.less @@ -5,6 +5,7 @@ @import (once) '../../customize/src/less2/include/alertify.less'; @import (once) '../../customize/src/less2/include/tools.less'; @import (once) '../../customize/src/less2/include/tokenfield.less'; +@import (once) '../../customize/src/less2/include/creation.less'; .toolbar_main( @bg-color: @colortheme_whiteboard-bg, @@ -14,6 +15,7 @@ .fileupload_main(); .alertify_main(); .tokenfield_main(); +.creation_main(); // body &.cp-app-whiteboard { diff --git a/www/whiteboard/inner.js b/www/whiteboard/inner.js index 4e5729fa8..febf63c5b 100644 --- a/www/whiteboard/inner.js +++ b/www/whiteboard/inner.js @@ -415,6 +415,7 @@ define([ Title.setToolbar(toolbar); var $rightside = toolbar.$rightside; + var $drawer = toolbar.$drawer; /* save as template */ if (!metadataMgr.getPrivateData().isTemplate) { @@ -428,7 +429,7 @@ define([ /* add an export button */ var $export = common.createButton('export', true, {}, saveImage); - $rightside.append($export); + $drawer.append($export); if (common.isLoggedIn()) { common.createButton('savetodrive', true, {}, function () {}) @@ -449,6 +450,9 @@ define([ }); $rightside.append($forget); + var $properties = common.createButton('properties', true); + toolbar.$drawer.append($properties); + if (!readOnly) { makeColorButton($rightside); @@ -562,7 +566,12 @@ define([ if (readOnly) { return; } - if (isNew) { + + var privateDat = metadataMgr.getPrivateData(); + var skipTemp = Util.find(privateDat, + ['settings', 'general', 'creation', 'noTemplate']); + var skipCreation = Util.find(privateDat, ['settings', 'general', 'creation', 'skip']); + if (isNew && (!AppConfig.displayCreationScreen || (!skipTemp && skipCreation))) { common.openTemplatePicker(); } }); @@ -605,6 +614,24 @@ define([ } }; + config.onError = function (err) { + setEditable(false); + toolbar.deleted(); + var msg = err.type; + if (err.type === 'EEXPIRED') { + msg = Messages.expiredError; + if (err.loaded) { + msg += Messages.expiredErrorCopy; + } + } else if (err.type === 'EDELETED') { + msg = Messages.deletedError; + if (err.loaded) { + msg += Messages.expiredErrorCopy; + } + } + UI.errorLoadingScreen(msg, true, true); + }; + cpNfInner = common.startRealtime(config); metadataMgr = cpNfInner.metadataMgr; @@ -640,6 +667,18 @@ define([ $('body').append($div.html()); })); SFCommon.create(waitFor(function (c) { APP.common = common = c; })); + }).nThen(function (waitFor) { + common.getSframeChannel().onReady(waitFor()); + }).nThen(function (waitFor) { + if (!AppConfig.displayCreationScreen) { return; } + var priv = common.getMetadataMgr().getPrivateData(); + if (priv.isNewFile) { + var c = (priv.settings.general && priv.settings.general.creation) || {}; + if (c.skip && !priv.forceCreationScreen) { + return void common.createPad(c, waitFor()); + } + common.getPadCreationScreen(c, waitFor()); + } }).nThen(function (/*waitFor*/) { andThen(common); }); diff --git a/www/whiteboard/main.js b/www/whiteboard/main.js index ce1f14d9c..1c63ad811 100644 --- a/www/whiteboard/main.js +++ b/www/whiteboard/main.js @@ -36,6 +36,8 @@ define([ }; window.addEventListener('message', onMsg); }).nThen(function (/*waitFor*/) { - SFCommonO.start(); + SFCommonO.start({ + useCreationScreen: true + }); }); });