From 0d3f9db1843e029c959a2c2a9ed4b1ec7236a419 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 18 Sep 2019 16:02:58 +0200 Subject: [PATCH] Improve sharing between drive and teams --- www/common/common-ui-elements.js | 27 +++++++++++++++------- www/common/cryptpad-common.js | 8 +++++++ www/common/drive-ui.js | 30 +++++++++++++++++++++++- www/common/outer/async-store.js | 8 +++++-- www/common/outer/team.js | 39 +++++++++++--------------------- 5 files changed, 75 insertions(+), 37 deletions(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index cd2c1e370..d427de526 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -1069,30 +1069,37 @@ define([ var hasFriends = Object.keys(config.friends || {}).length !== 0; var friendsList = hasFriends ? createShareWithFriends(config) : undefined; var friendsUIClass = hasFriends ? '.cp-share-columns' : ''; - var link = h('div.cp-share-modal' + friendsUIClass, [ + var mainShareColumn = h('div.cp-share-column.contains-nav', [ h('div.cp-share-column', [ hasFriends ? h('p', Messages.share_description) : undefined, UI.dialog.selectable('', { id: 'cp-share-link-preview' }), ]), - friendsList ]); + var link = h('div.cp-share-modal' + friendsUIClass); var getLinkValue = function () { return url; }; - $(link).find('#cp-share-link-preview').val(getLinkValue()); + $(mainShareColumn).find('#cp-share-link-preview').val(getLinkValue()); var linkButtons = [{ className: 'cancel', name: Messages.cancel, onClick: function () {}, keys: [27] - }, { + }]; + var shareButtons = [{ className: 'primary', name: Messages.share_linkCopy, onClick: function () { + saveValue(); var v = getLinkValue(); var success = Clipboard.copy(v); if (success) { UI.log(Messages.shareSuccess); } }, keys: [13] }]; + + var $link = $(link); + $(mainShareColumn).append(UI.dialog.getButtons(shareButtons, config.onClose)).appendTo($link); + $(friendsList).appendTo($link); + var frameLink = UI.dialog.customModal(link, { buttons: linkButtons, onClose: config.onClose, @@ -1157,21 +1164,22 @@ define([ var hasFriends = Object.keys(config.friends || {}).length !== 0; var friendsList = hasFriends ? createShareWithFriends(config) : undefined; var friendsUIClass = hasFriends ? '.cp-share-columns' : ''; - var link = h('div.cp-share-modal' + friendsUIClass, [ + var mainShareColumn = h('div.cp-share-column.contains-nav', [ h('div.cp-share-column', [ h('label', Messages.sharedFolders_share), h('br'), hasFriends ? h('p', Messages.share_description) : undefined, UI.dialog.selectable(url, { id: 'cp-share-link-preview', tabindex: 1 }) - ]), - friendsList + ]) ]); + var link = h('div.cp-share-modal' + friendsUIClass); var linkButtons = [{ className: 'cancel', name: Messages.cancel, onClick: function () {}, keys: [27] - }, { + }]; + var shareButtons = [{ className: 'primary', name: Messages.share_linkCopy, onClick: function () { @@ -1180,6 +1188,9 @@ define([ }, keys: [13] }]; + var $link = $(link); + $(mainShareColumn).append(UI.dialog.getButtons(shareButtons, config.onClose)).appendTo($link); + $(friendsList).appendTo($link); return UI.dialog.customModal(link, {buttons: linkButtons}); }; diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 1dc553b59..53715f7c1 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -692,6 +692,14 @@ define([ var parsed = Hash.parsePadUrl(data.href); var secret = Hash.getSecrets(parsed.type, parsed.hash, data.password); if (!secret || !secret.channel) { return void cb ({error: 'EINVAL'}); } + + if (parsed.type === 'drive') { + // Shared folder + var teamId = data.teamId === -1 ? undefined : data.teamId; + common.addSharedFolder(teamId, secret, cb); + return; + } + Nthen(function (waitFor) { if (parsed.hashData.type !== 'pad') { return; } // Set the correct owner and expiration time if we can find them diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index b8a58b96e..452aadeb6 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -335,6 +335,10 @@ define([ 'tabindex': '-1', 'data-icon': 'fa-shhare-alt', }, Messages.shareButton)), + h('li', h('a.cp-app-drive-context-savelocal.dropdown-item', { + 'tabindex': '-1', + 'data-icon': 'fa-cloud-upload', + }, Messages.pad_mediatagImport)), // Save in your CryptDrive h('li', h('a.cp-app-drive-context-download.dropdown-item', { 'tabindex': '-1', 'data-icon': faDownload, @@ -1113,6 +1117,7 @@ define([ hide.push('delete'); hide.push('rename'); hide.push('share'); + hide.push('savelocal'); hide.push('color'); } if (!$element.is('.cp-app-drive-element-owned')) { @@ -1165,6 +1170,7 @@ define([ } containsFolder = true; hide.push('share'); // XXX CONVERT + hide.push('savelocal'); // XXX CONVERT hide.push('openro'); hide.push('openincode'); hide.push('properties'); @@ -1200,6 +1206,7 @@ define([ hide.push('hashtag'); hide.push('download'); hide.push('share'); + hide.push('savelocal'); hide.push('openincode'); // can't because of race condition } if (containsFolder && paths.length > 1) { @@ -1217,7 +1224,9 @@ define([ show = ['newfolder', 'newsharedfolder', 'uploadfiles', 'uploadfolder', 'newdoc']; break; case 'tree': - show = ['open', 'openro', 'openincode', 'expandall', 'collapseall', 'color', 'download', 'share', 'rename', 'delete', 'deleteowned', 'removesf', 'properties', 'hashtag']; + show = ['open', 'openro', 'openincode', 'expandall', 'collapseall', + 'color', 'download', 'share', 'savelocal', 'rename', 'delete', + 'deleteowned', 'removesf', 'properties', 'hashtag']; break; case 'default': show = ['open', 'openro', 'share', 'openparent', 'delete', 'deleteowned', 'properties', 'hashtag']; @@ -4014,6 +4023,25 @@ define([ }); } } + else if ($this.hasClass('cp-app-drive-context-savelocal')) { + if (paths.length !== 1) { return; } + el = manager.find(paths[0].path); + if (manager.isFile(el)) { + data = manager.getFileData(el); + } else if (manager.isSharedFolder(el)) { + data = manager.getSharedFolderData(el); + } + if (!data) { return; } + sframeChan.query('Q_STORE_IN_TEAM', { + href: data.href || data.rohref, + password: data.password, + path: paths[0].path[0] === 'template' ? ['template'] : undefined, + title: data.title || '', + teamId: -1 + }, function (err) { + if (err) { return void console.error(err); } + }); + } else if ($this.hasClass('cp-app-drive-context-newfolder')) { if (paths.length !== 1) { return; } var onFolderCreated = function (err, info) { diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index b766370c3..e83cd441a 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -958,10 +958,13 @@ define([ expire = data.expire; } + var storeLocally = data.teamId === -1; + if (data.teamId === -1) { data.teamId = undefined; } + // If a teamId is provided, it means we want to store the pad in a specific // team drive. In this case, we just need to check if the pad is already - // stored in th eteam drive. - // If no team ID is provided, this may be a pad shared iwth its URL. + // stored in this team drive. + // If no team ID is provided, this may be a pad shared with its URL. // We need to check if the pad is stored in any managers (user or teams). // If it is stored, update its data, otherwise ask the user if they want to store it var allData = []; @@ -969,6 +972,7 @@ define([ var inMyDrive; getAllStores().forEach(function (s) { if (data.teamId && s.id !== data.teamId) { return; } + if (storeLocally && s.id) { return; } var res = s.manager.findChannel(channel); if (res.length) { diff --git a/www/common/outer/team.js b/www/common/outer/team.js index 0c00c8a01..a49b27016 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -447,16 +447,8 @@ define([ }); }; - var subscribe = function (ctx, id, cId, cb) { - // Unsubscribe from other teams: one tab can only receive events about one team - Object.keys(ctx.teams).forEach(function (teamId) { - var c = ctx.teams[teamId].clients; - var idx = c.indexOf(cId); - if (idx !== -1) { - c.splice(idx, 1); - } - }); - // Also remove from pending subscriptions + // Remove a client from all the team they're subscribed to + var removeClient = function (ctx, cId) { Object.keys(ctx.onReadyHandlers).forEach(function (teamId) { var idx = -1; ctx.onReadyHandlers[teamId].some(function (obj, _idx) { @@ -469,6 +461,17 @@ define([ ctx.onReadyHandlers[teamId].splice(idx, 1); } }); + + Object.keys(ctx.teams).forEach(function (id) { + var clients = ctx.teams[id].clients; + var idx = clients.indexOf(cId); + if (idx !== -1) { clients.splice(idx, 1); } + }); + }; + + var subscribe = function (ctx, id, cId, cb) { + // Unsubscribe from other teams: one tab can only receive events about one team + removeClient(ctx, cId); // And leave the channel channel try { ctx.store.messenger.removeClient(cId); @@ -504,22 +507,6 @@ define([ ctx.store.messenger.openTeamChat(team.getChatData(), cId, cb); }; - // Remove a client from all the team they're subscribed to - var removeClient = function (ctx, cId) { - Object.keys(ctx.teams).forEach(function (id) { - // Remove from the subscribers - var clients = ctx.teams[id].clients; - var idx = clients.indexOf(cId); - if (idx !== -1) { clients.splice(idx, 1); } - - // And remove from the onReady handlers in case they haven't finished loading - if (ctx.onReadyHandlers[id]) { - var idx2 = ctx.onReadyHandlers.indexOf(cId); - if (idx2 !== -1) { ctx.onReadyHandlers.splice(idx2, 1); } - } - }); - }; - Team.init = function (cfg, waitFor, emit) { var team = {}; var store = cfg.store;