From 90f892de9c8e84d6a2df61daf5e6946c658576d1 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 18 Aug 2017 16:34:41 +0200 Subject: [PATCH] Useradmin menu, notifications and share button in pad2 --- www/common/cryptpad-common.js | 20 +++ www/common/metadata-manager.js | 2 +- www/common/sframe-common.js | 28 +++- www/common/sframe-protocol.js | 12 +- www/common/toolbar3.js | 253 +++++++++++++-------------------- www/pad2/main.js | 2 +- www/pad2/outer.js | 36 ++++- 7 files changed, 195 insertions(+), 158 deletions(-) diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 473fa815c..d2b361284 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -1794,6 +1794,26 @@ define([ return $userAdmin; }; + common.getShareHashes = function (cb) { + common.getRecentPads(function (err, recent) { + var parsed = parsePadUrl(window.location.href); + if (!parsed.type || !parsed.hashData) { return void cb('E_INVALID_HREF'); } + var secret = common.getSecrets(parsed.type, parsed.hash); + var channel = common.base64ToHex(parsed.hashData.channel); + var hashes = common.getHashes(channel, secret); + var options = []; + + // If we have a stronger version in drive, add it and add a redirect button + var stronger = recent && common.findStronger(null, recent); + if (stronger) { + var parsed = parsePadUrl(stronger); + hashes.editHash = parsed.hash; + } + + cb(null, hashes); + }); + }; + var CRYPTPAD_VERSION = 'cryptpad-version'; var updateLocalVersion = function () { // Check for CryptPad updates diff --git a/www/common/metadata-manager.js b/www/common/metadata-manager.js index 0d4976305..55606e78b 100644 --- a/www/common/metadata-manager.js +++ b/www/common/metadata-manager.js @@ -126,7 +126,7 @@ define([], function () { var list = members.slice().filter(function (m) { return m.length === 32; }); return list.length - Object.keys(metadataObj.users).length; }, - getPrivatedata : function () { + getPrivateData : function () { return priv; }, getNetfluxId : function () { diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index 88cea7fde..1a59e7475 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -3,9 +3,10 @@ define([ '/common/sframe-chainpad-netflux-inner.js', '/common/sframe-channel.js', '/common/sframe-common-title.js', + '/common/sframe-common-interface.js', '/common/metadata-manager.js', -], function (nThen, CpNfInner, SFrameChannel, Title, MetadataMgr) { +], function (nThen, CpNfInner, SFrameChannel, Title, UI, MetadataMgr) { // Chainpad Netflux Inner var funcs = {}; @@ -31,6 +32,9 @@ define([ titleUpdated = cb; }; + // UI + funcs.createUserAdminMenu = UI.createUserAdminMenu; + // Title module funcs.createTitle = Title.create; @@ -39,12 +43,34 @@ define([ return ctx.cpNfInner.metadataMgr.getMetadata().defaultTitle; }; + + funcs.setDisplayName = function (name, cb) { ctx.sframeChan.query('Q_SETTINGS_SET_DISPLAY_NAME', name, function (err) { if (cb) { cb(err); } }); }; + funcs.logout = function (cb) { + ctx.sframeChan.query('Q_LOGOUT', null, function (err) { + if (cb) { cb(err); } + }); + }; + + funcs.setLoginRedirect = function (cb) { + ctx.sframeChan.query('Q_SET_LOGIN_REDIRECT', null, function (err) { + if (cb) { cb(err); } + }); + }; + + funcs.storeLinkToClipboard = function (readOnly, cb) { + ctx.sframeChan.query('Q_STORE_LINK_TO_CLIPBOARD', readOnly, function (err) { + if (cb) { cb(err); } + }); + }; + + // TODO + funcs.feedback = function () {}; Object.freeze(funcs); diff --git a/www/common/sframe-protocol.js b/www/common/sframe-protocol.js index 0d980ed11..6bc2285ad 100644 --- a/www/common/sframe-protocol.js +++ b/www/common/sframe-protocol.js @@ -44,4 +44,14 @@ define({ // Update the user's display-name which will be shown to contacts and people in the same pads. 'Q_SETTINGS_SET_DISPLAY_NAME': true, -}); \ No newline at end of file + + // Log the user out in all the tabs + 'Q_LOGOUT': true, + + // When moving to the login or register page from a pad, we need to redirect to that pad at the + // end of the login process. This query set the current href to the sessionStorage. + 'Q_SET_LOGIN_REDIRECT': true, + + // Store the editing or readonly link of the current pad to the clipboard (share button) + 'Q_STORE_LINK_TO_CLIPBOARD': true, +}); diff --git a/www/common/toolbar3.js b/www/common/toolbar3.js index 6f2ca4871..2a2fe9d77 100644 --- a/www/common/toolbar3.js +++ b/www/common/toolbar3.js @@ -153,24 +153,7 @@ define([ return $.inArray(i, b) > -1; }); }; - var updateDisplayName = function (toolbar, config) { - // Change username in useradmin dropdown - var name = Cryptpad.getDisplayName(); - if (config.displayed.indexOf('useradmin') !== -1) { - var $userAdminElement = toolbar.$userAdmin; - var $userElement = $userAdminElement.find('.' + USERNAME_CLS); - $userElement.show(); - if (config.readOnly === 1) { - $userElement.addClass(READONLY_CLS).text(Messages.readonly); - } - else { - if (!name) { - name = Messages.anonymous; - } - $userElement.removeClass(READONLY_CLS).text(name); - } - } - }; + var avatars = {}; var updateUserList = function (toolbar, config) { // Make sure the elements are displayed @@ -276,8 +259,6 @@ define([ var fa_viewusers = ''; var $spansmall = $('').html(fa_editusers + ' ' + numberOfEditUsers + '   ' + fa_viewusers + ' ' + numberOfViewUsers); $userButtons.find('.buttonTitle').html('').append($spansmall); - - updateDisplayName(toolbar, config); }; var initUserList = function (toolbar, config) { @@ -300,8 +281,7 @@ define([ // Create sub-elements var createUserList = function (toolbar, config) { - if (!config.metadataMgr) { /* || !config.userList.list || - !config.userList.data || !config.userList.userNetfluxId) {*/ + if (!config.metadataMgr) { throw new Error("You must provide a `metadataMgr` to display the userlist"); } var $content = $('
', {'class': 'userlist-drawer'}); @@ -381,107 +361,91 @@ define([ }; var createShare = function (toolbar, config) { - var secret = Cryptpad.find(config, ['share', 'secret']); - var channel = Cryptpad.find(config, ['share', 'channel']); - if (!secret || !channel) { - throw new Error("Unable to display the share button: share.secret and share.channel required"); + if (!config.metadataMgr) { + throw new Error("You must provide a `metadataMgr` to display the userlist"); } - Cryptpad.getRecentPads(function (err, recent) { - var $shareIcon = $('', {'class': 'fa fa-share-alt'}); - var hashes = Cryptpad.getHashes(channel, secret); - var options = []; - - // If we have a stronger version in drive, add it and add a redirect button - var stronger = recent && Cryptpad.findStronger(null, recent); - if (stronger) { - var parsed = Cryptpad.parsePadUrl(stronger); - hashes.editHash = parsed.hash; - } + var metadataMgr = config.metadataMgr; + var $shareIcon = $('', {'class': 'fa fa-share-alt'}); + var availableHashes = metadataMgr.getPrivateData().availableHashes; + var readOnly = metadataMgr.getPrivateData().readOnly; + var options = []; + var hashes = { + editHash: availableHashes.indexOf('editHash') !== -1, + viewHash: availableHashes.indexOf('viewHash') !== -1 + }; - if (hashes.editHash) { - options.push({ - tag: 'a', - attributes: {title: Messages.editShareTitle, 'class': 'editShare'}, - content: ' ' + Messages.editShare - }); - if (stronger) { - // We're in view mode, display the "open editing link" button - options.push({ - tag: 'a', - attributes: { - title: Messages.editOpenTitle, - 'class': 'editOpen', - href: window.location.pathname + '#' + hashes.editHash, - target: '_blank' - }, - content: ' ' + Messages.editOpen - }); - } - options.push({tag: 'hr'}); - } - if (hashes.viewHash) { + if (hashes.editHash) { + options.push({ + tag: 'a', + attributes: {title: Messages.editShareTitle, 'class': 'editShare'}, + content: ' ' + Messages.editShare + }); + /* TODO iframe + if (readOnly) { + // We're in view mode, display the "open editing link" button options.push({ tag: 'a', - attributes: {title: Messages.viewShareTitle, 'class': 'viewShare'}, - content: ' ' + Messages.viewShare + attributes: { + title: Messages.editOpenTitle, + 'class': 'editOpen', + href: window.location.pathname + '#' + hashes.editHash, + target: '_blank' + }, + content: ' ' + Messages.editOpen }); - if (hashes.editHash && !stronger) { - // We're in edit mode, display the "open readonly" button - options.push({ - tag: 'a', - attributes: { - title: Messages.viewOpenTitle, - 'class': 'viewOpen', - href: window.location.pathname + '#' + hashes.viewHash, - target: '_blank' - }, - content: ' ' + Messages.viewOpen - }); - } } - if (hashes.fileHash) { + */ + options.push({tag: 'hr'}); + } + if (hashes.viewHash) { + options.push({ + tag: 'a', + attributes: {title: Messages.viewShareTitle, 'class': 'viewShare'}, + content: ' ' + Messages.viewShare + }); + /* TODO iframe + if (!readOnly) { + // We're in edit mode, display the "open readonly" button options.push({ tag: 'a', - attributes: {title: Messages.viewShareTitle, 'class': 'fileShare'}, - content: ' ' + Messages.viewShare - }); - } - var dropdownConfigShare = { - text: $('
').append($shareIcon).html(), - options: options, - feedback: 'SHARE_MENU', - }; - var $shareBlock = Cryptpad.createDropdown(dropdownConfigShare); - //$shareBlock.find('button').attr('id', 'shareButton'); - $shareBlock.find('.dropdown-bar-content').addClass(SHARE_CLS).addClass(EDITSHARE_CLS).addClass(VIEWSHARE_CLS); - $shareBlock.addClass('shareButton'); - $shareBlock.find('button').attr('title', Messages.shareButton); - - if (hashes.editHash) { - $shareBlock.find('a.editShare').click(function () { - var url = window.location.origin + window.location.pathname + '#' + hashes.editHash; - var success = Cryptpad.Clipboard.copy(url); - if (success) { Cryptpad.log(Messages.shareSuccess); } + attributes: { + title: Messages.viewOpenTitle, + 'class': 'viewOpen', + href: window.location.pathname + '#' + hashes.viewHash, + target: '_blank' + }, + content: ' ' + Messages.viewOpen }); } - if (hashes.viewHash) { - $shareBlock.find('a.viewShare').click(function () { - var url = window.location.origin + window.location.pathname + '#' + hashes.viewHash ; - var success = Cryptpad.Clipboard.copy(url); - if (success) { Cryptpad.log(Messages.shareSuccess); } + */ + } + var dropdownConfigShare = { + text: $('
').append($shareIcon).html(), + options: options, + feedback: 'SHARE_MENU', + }; + var $shareBlock = Cryptpad.createDropdown(dropdownConfigShare); + $shareBlock.find('.dropdown-bar-content').addClass(SHARE_CLS).addClass(EDITSHARE_CLS).addClass(VIEWSHARE_CLS); + $shareBlock.addClass('shareButton'); + $shareBlock.find('button').attr('title', Messages.shareButton); + + if (hashes.editHash) { + $shareBlock.find('a.editShare').click(function () { + Common.storeLinkToClipboard(false, function (err) { + if (!err) { Cryptpad.log(Messages.shareSuccess); } }); - } - if (hashes.fileHash) { - $shareBlock.find('a.fileShare').click(function () { - var url = window.location.origin + window.location.pathname + '#' + hashes.fileHash ; - var success = Cryptpad.Clipboard.copy(url); - if (success) { Cryptpad.log(Messages.shareSuccess); } + }); + } + if (hashes.viewHash) { + $shareBlock.find('a.viewShare').click(function () { + Common.storeLinkToClipboard(true, function (err) { + if (!err) { Cryptpad.log(Messages.shareSuccess); } }); - } + }); + } - toolbar.$leftside.append($shareBlock); - toolbar.share = $shareBlock; - }); + toolbar.$leftside.append($shareBlock); + toolbar.share = $shareBlock; return "Loading share button"; }; @@ -738,12 +702,11 @@ define([ return $limit; }; - var createNewPad = function (toolbar) { - /*var $newPad = $('', { - 'class': NEWPAD_CLS + " dropdown-bar" - }).appendTo(toolbar.$top);*/ + var createNewPad = function (toolbar, config) { var $newPad = toolbar.$top.find('.'+NEWPAD_CLS).show(); + var origin = config.metadataMgr.getPrivateData().origin; + var pads_options = []; Config.availablePadTypes.forEach(function (p) { if (p === 'drive') { return; } @@ -753,7 +716,7 @@ define([ tag: 'a', attributes: { 'target': '_blank', - 'href': '/' + p + '/', + 'href': origin + '/' + p + '/', }, content: $('
').append(Cryptpad.getIcon(p)).html() + Messages.type[p] }); @@ -777,10 +740,11 @@ define([ throw new Error("You must provide a `metadataMgr` to display the user menu"); } var metadataMgr = config.metadataMgr; - var myData = metadataMgr.getMetadata().users[metadataMgr.getNetfluxId()]; var $userAdmin = toolbar.$userAdmin.find('.'+USERADMIN_CLS).show(); var userMenuCfg = { - $initBlock: $userAdmin + $initBlock: $userAdmin, + metadataMgr: metadataMgr, + Common: Common }; if (!config.hideDisplayName) { $.extend(true, userMenuCfg, { @@ -792,45 +756,30 @@ define([ userMenuCfg.displayName = 1; userMenuCfg.displayChangeName = 1; } - Cryptpad.createUserAdminMenu(userMenuCfg); + Common.createUserAdminMenu(userMenuCfg); $userAdmin.find('button').attr('title', Messages.userAccountButton); - // TODO iframe var $userButton = toolbar.$userNameButton = $userAdmin.find('a.' + USERBUTTON_CLS); $userButton.click(function (e) { e.preventDefault(); e.stopPropagation(); - var lastName = myData.displayName; - //Cryptpad.getLastName(function (err, lastName) { - //if (err) { return void console.error("Cannot get last name", err); } - Cryptpad.prompt(Messages.changeNamePrompt, lastName || '', function (newName) { - if (newName === null && typeof(lastName) === "string") { return; } - if (newName === null) { newName = ''; } - else { Common.feedback('NAME_CHANGED'); } - Common.setDisplayName(newName, function (err) { - if (err) { - console.log("Couldn't set username"); - console.error(err); - return; - } - //Cryptpad.changeDisplayName(newName, true); Already done? - }); + var myData = metadataMgr.getMetadata().users[metadataMgr.getNetfluxId()]; + var lastName = myData.name; + Cryptpad.prompt(Messages.changeNamePrompt, lastName || '', function (newName) { + if (newName === null && typeof(lastName) === "string") { return; } + if (newName === null) { newName = ''; } + else { Common.feedback('NAME_CHANGED'); } + Common.setDisplayName(newName, function (err) { + if (err) { + console.log("Couldn't set username"); + console.error(err); + return; + } + //Cryptpad.changeDisplayName(newName, true); Already done? }); - //}); - }); - Cryptpad.onDisplayNameChanged(function () { - window.setTimeout(function () { - Cryptpad.findCancelButton().click(); - if (config.metadataMgr) { - updateUserList(toolbar, config); - return; - } - updateDisplayName(toolbar, config); - }, 0); + }); }); - updateDisplayName(toolbar, config); - return $userAdmin; }; @@ -886,7 +835,7 @@ define([ Cryptpad.log(Messages._getKey("notifyJoined", [name])); break; case 0: - oldname = (oldname === "") ? Messages.anonymous : oldname; + oldname = (!oldname) ? Messages.anonymous : oldname; Cryptpad.log(Messages._getKey("notifyRenamed", [oldname, name])); break; case -1: @@ -988,14 +937,14 @@ define([ // Create the subelements var tb = {}; tb['userlist'] = createUserList; - tb['share'] = createShare; - tb['fileshare'] = createFileShare; + tb['share'] = createShare; //TODO + tb['fileshare'] = createFileShare;//TODO tb['title'] = createTitle; - tb['pageTitle'] = createPageTitle; + tb['pageTitle'] = createPageTitle;//TODO tb['lag'] = $.noop; tb['spinner'] = createSpinner; tb['state'] = $.noop; - tb['limit'] = createLimit; + tb['limit'] = createLimit; // TODO tb['upgrade'] = $.noop; tb['newpad'] = createNewPad; tb['useradmin'] = createUserAdmin; diff --git a/www/pad2/main.js b/www/pad2/main.js index 65cebc166..fe8fbf603 100644 --- a/www/pad2/main.js +++ b/www/pad2/main.js @@ -471,7 +471,7 @@ define([ var titleCfg = { getHeadingText: getHeadingText }; Title = common.createTitle(titleCfg, realtimeOptions.onLocal, common, cpNfInner.metadataMgr); var configTb = { - displayed: ['userlist', 'title', 'useradmin'], + displayed: ['userlist', 'title', 'useradmin', 'spinner', 'newpad', 'share'], title: Title.getTitleConfig(), metadataMgr: cpNfInner.metadataMgr, readOnly: readOnly, diff --git a/www/pad2/outer.js b/www/pad2/outer.js index 017736025..5d88b765d 100644 --- a/www/pad2/outer.js +++ b/www/pad2/outer.js @@ -10,6 +10,7 @@ define([ ], function (ApiConfig, SFrameChannel, $, CpNfOuter, nThen, Cryptpad, Crypto) { console.log('xxx'); var sframeChan; + var hashes; nThen(function (waitFor) { $(waitFor()); }).nThen(function (waitFor) { @@ -20,11 +21,16 @@ define([ console.log('sframe initialized'); })); Cryptpad.ready(waitFor()); + }).nThen(function (waitFor) { + Cryptpad.getShareHashes(function (err, h) { + hashes = h; + waitFor()(); + }); }).nThen(function (waitFor) { var secret = Cryptpad.getSecrets(); var readOnly = secret.keys && !secret.keys.editKeyStr; if (!secret.keys) { secret.keys = secret.key; } - + var parsed = Cryptpad.parsePadUrl(window.location.href); parsed.type = parsed.type.replace('pad2', 'pad'); if (!parsed.type) { throw new Error(); } @@ -52,7 +58,10 @@ define([ netfluxId: Cryptpad.getNetwork().webChannels[0].myID, }, priv: { - accountName: Cryptpad.getAccountName() + accountName: Cryptpad.getAccountName(), + origin: window.location.origin, + readOnly: readOnly, + availableHashes: Object.keys(hashes) } }); }); @@ -87,6 +96,29 @@ define([ }); }); + sframeChan.on('Q_LOGOUT', function (data, cb) { + Cryptpad.logout(cb); + }); + + sframeChan.on('Q_SET_LOGIN_REDIRECT', function (data, cb) { + sessionStorage.redirectTo = window.location.href; + cb(); + }); + + sframeChan.on('Q_STORE_LINK_TO_CLIPBOARD', function (readOnly, cb) { + if (readOnly) { + if (!hashes.viewHash) { return void cb('E_INVALID_HASH'); } + var url = window.location.origin + window.location.pathname + '#' + hashes.viewHash; + var success = Cryptpad.Clipboard.copy(url); + cb(!success); + return; + } + if (!hashes.editHash) { return void cb('E_INVALID_HASH'); } + var eUrl = window.location.origin + window.location.pathname + '#' + hashes.editHash; + var eSuccess = Cryptpad.Clipboard.copy(eUrl); + cb(!eSuccess); + }); + CpNfOuter.start({ sframeChan: sframeChan, channel: secret.channel,