diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 2c9d7a742..67e0f6060 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -316,22 +316,18 @@ define([ }); }; - var getFriendsList = function (common) { - var priv = common.getMetadataMgr().getPrivateData(); - var friends = priv.friends; + var getFriendsList = function (config) { // XXX test from the drive and don't forget to pass the title + var common = config.common; + var title = config.title; + var friends = config.friends; + var myName = common.getMetadataMgr().getUserData().name; var order = []; if (!friends) { return; } - // XXX - for (var i = 0; i < 30; i++) { - friends[i] = { - curvePublic: Hash.createChannelId(), - displayName: i+ ' blu' - }; - } - var others = Object.keys(friends).map(function (curve, i) { + if (curve.length <= 40) { return; } var data = friends[curve]; + if (!data.notifications) { return; } var avatar = h('span.cp-share-friend-avatar.cp-avatar'); UIElements.displayAvatar(common, $(avatar), data.avatar, data.displayName); return h('div.cp-share-friend', { @@ -343,32 +339,32 @@ define([ avatar, h('span.cp-share-friend-name', data.displayName) ]); - }); + }).filter(function (x) { return x; }); var smallCurves = Object.keys(friends).map(function (c) { return friends[c].curvePublic.slice(0,8); }); var noOthers = others.length === 0 ? '.cp-recent-only' : ''; - var buttonSelect = h('button.cp-share-with-friends', Messages.shareSelectAll || 'Select'); // XXX - var buttonDeselect = h('button.cp-share-with-friends', Messages.shareDeselectAll || 'Deselect'); // XXX + var buttonSelect = h('button.cp-share-with-friends', Messages.share_selectAll); + var buttonDeselect = h('button.cp-share-with-friends', Messages.share_deselectAll); var inputFilter = h('input', { - placeholder: 'Search friend...' + placeholder: Messages.share_filterFriend }); - var bloc = h('div.cp-share-friends.cp-share-column' + noOthers, [ - h('label', Messages.share_linkFriends || "Friends"), // XXX + var div = h('div.cp-share-friends.cp-share-column' + noOthers, [ + h('label', Messages.share_linkFriends), h('div.cp-share-grid-filter', [ inputFilter, buttonSelect, buttonDeselect ]), ]); - var $bloc = $(bloc); + var $div = $(div); // Fill with fake friends to have a uniform spacing (from the flexbox) var addFake = function (els) { - $(bloc).find('.cp-fake-friend').remove(); + $div.find('.cp-fake-friend').remove(); var n = (6 - els.length%6)%6; for (var j = 0; j < n; j++) { els.push(h('div.cp-share-friend.cp-fake-friend', { @@ -380,17 +376,17 @@ define([ var redraw = function () { var name = $(inputFilter).val().trim().replace(/"/g, ''); - $bloc.find('.cp-share-friend').show(); + $div.find('.cp-share-friend').show(); if (!name) { return; } - $bloc.find('.cp-share-friend:not(.cp-selected):not([data-name*="'+name+'"])').hide(); + $div.find('.cp-share-friend:not(.cp-selected):not([data-name*="'+name+'"])').hide(); }; $(inputFilter).on('keydown keyup change', redraw); $(buttonSelect).click(function () { - $bloc.find('.cp-share-friend:not(.cp-selected):visible').addClass('cp-selected'); + $div.find('.cp-share-friend:not(.cp-selected):visible').addClass('cp-selected'); }); $(buttonDeselect).click(function () { - $bloc.find('.cp-share-friend.cp-selected').removeClass('cp-selected').each(function (i, el) { + $div.find('.cp-share-friend.cp-selected').removeClass('cp-selected').each(function (i, el) { var order = $(el).attr('data-order'); if (!order) { return; } $(el).attr('style', 'order:'+order); @@ -398,38 +394,51 @@ define([ redraw(); }); - console.log(smallCurves); var refreshButtons = function () { - var $nav = $bloc.parents('.alertify-tabs-content').find('nav'); + var $nav = $div.parents('.alertify-tabs-content').find('nav'); if (!$nav.find('.cp-share-with-friends').length) { var button = h('button.primary.cp-share-with-friends', { 'data-keys': '[13]' - }, Messages.shareLinkWithFriends || 'Share with friends'); // XXX + }, Messages.share_withFriends); $(button).click(function () { + var href = Hash.getRelativeHref($('#cp-share-link-preview').val()); + var $friends = $div.find('.cp-share-friend.cp-selected'); + $friends.each(function (i, el) { + var curve = $(el).attr('data-curve'); + if (!curve || !friends[curve]) { return; } + var friend = friends[curve]; + if (!friend.notifications || !friend.curvePublic) { return; } + common.mailbox.sendTo("SHARE_PAD", { + href: href, + name: myName, + title: title + }, { + channel: friend.notifications, + curvePublic: friend.curvePublic + }); + }); + + console.log(UI.findCancelButton()); + UI.findCancelButton().click(); + + // Update the "recently shared with" array: // Get the selected curves - var $friends = $bloc.find('.cp-share-friend.cp-selected'); var curves = $friends.toArray().map(function (el) { return ($(el).attr('data-curve') || '').slice(0,8); }).filter(function (x) { return x; }); // Prepend them to the "order" array Array.prototype.unshift.apply(order, curves); - console.log(order); order = Util.deduplicateString(order); - console.log(order); // Make sure we don't have "old" friends and save order = order.filter(function (curve) { return smallCurves.indexOf(curve) !== -1; }); - console.log(order); common.setAttribute(['general', 'share-friends'], order); - - // XXX send to mailboxes - // Notes: we need to filter the friend to only have th eones with mailboxes! }); $nav.append(button); } - var friendMode = $bloc.find('.cp-share-friend.cp-selected').length; + var friendMode = $div.find('.cp-share-friend.cp-selected').length; if (friendMode) { $nav.find('button.primary[data-keys]').hide(); $nav.find('button.cp-share-with-friends').show(); @@ -462,8 +471,8 @@ define([ $(el).attr('data-order', i).css('order', i); }); // Display them - $bloc.append(h('div.cp-share-grid', others)); - $bloc.find('.cp-share-friend').click(function () { + $div.append(h('div.cp-share-grid', others)); + $div.find('.cp-share-friend').click(function () { var sel = $(this).hasClass('cp-selected'); if (!sel) { $(this).addClass('cp-selected'); @@ -475,7 +484,7 @@ define([ refreshButtons(); }); }); - return bloc; + return div; }; UIElements.createShareModal = function (config) { @@ -487,28 +496,18 @@ define([ if (!hashes) { return; } // Share link tab - var friendsList = getFriendsList(common); - var link = h('div.cp-share-modal.cp-share-columns', [ + var hasFriends = Object.keys(config.friends || {}).length !== 0; + var friendsList = hasFriends ? getFriendsList(config) : undefined; + var friendsUIClass = hasFriends ? '.cp-share-columns' : ''; + var link = h('div.cp-share-modal' + friendsUIClass, [ h('div.cp-share-column', [ - h('p', 'Select the access rights you want to use and copy the share URL or send it directly to your CryptPad friends'), // XXX + hasFriends ? h('p', Messages.share_description) : undefined, h('label', Messages.share_linkAccess), h('br'), UI.createRadio('cp-share-editable', 'cp-share-editable-true', Messages.share_linkEdit, true, { mark: {tabindex:1} }), UI.createRadio('cp-share-editable', 'cp-share-editable-false', Messages.share_linkView, false, { mark: {tabindex:1} }), - /*h('input#cp-share-editable-true.cp-share-editable-value', { - type: 'radio', - name: 'cp-share-editable', - value: 1, - }), - h('label', { 'for': 'cp-share-editable-true' }, Messages.share_linkEdit), - h('input#cp-share-editable-false.cp-share-editable-value', { - type: 'radio', - name: 'cp-share-editable', - value: 0 - }), - h('label', { 'for': 'cp-share-editable-false' }, Messages.share_linkView),*/ h('br'), h('label', Messages.share_linkOptions), h('br'), @@ -549,6 +548,7 @@ define([ $(link).find('#cp-share-link-preview').val(getLinkValue()); }); var linkButtons = [{ + className: 'cancel', name: Messages.cancel, onClick: function () {}, keys: [27] @@ -592,6 +592,7 @@ define([ UI.dialog.selectable(getEmbedValue()) ]); var embedButtons = [{ + className: 'cancel', name: Messages.cancel, onClick: function () {}, keys: [27] @@ -664,6 +665,7 @@ define([ var getLinkValue = function () { return url; }; $(link).find('#cp-share-link-preview').val(getLinkValue()); var linkButtons = [{ + className: 'cancel', name: Messages.cancel, onClick: function () {}, keys: [27] @@ -690,6 +692,7 @@ define([ UI.dialog.selectable(common.getMediatagFromHref(fileData)), ]); var embedButtons = [{ + className: 'cancel', name: Messages.cancel, onClick: function () {}, keys: [27] diff --git a/www/common/notifications.js b/www/common/notifications.js index dc95fe3d4..9296646f4 100644 --- a/www/common/notifications.js +++ b/www/common/notifications.js @@ -7,6 +7,8 @@ define([ var handlers = {}; + // Friend request + handlers['FRIEND_REQUEST'] = function (common, data, el) { var content = data.content; var msg = content.msg; @@ -41,6 +43,20 @@ define([ $(el).find('.cp-notification-dismiss').css('display', 'flex'); }; + // Share pad + + handlers['SHARE_PAD'] = function (common, data, el) { + var content = data.content; + var msg = content.msg; + $(el).find('.cp-notification-content').addClass("cp-clickable"); + $(el).find('.cp-notification-content p') + .html(Messages._getKey('notification_padShared', [msg.content.name || Messages.anonymous, msg.content.title])) + .click(function () { + common.openURL(msg.content.href); + }); + $(el).find('.cp-notification-dismiss').css('display', 'flex'); + }; + return { add: function (common, data, el) { var type = data.content.msg.type; diff --git a/www/common/sframe-common-mailbox.js b/www/common/sframe-common-mailbox.js index 65d9965c8..4fb088191 100644 --- a/www/common/sframe-common-mailbox.js +++ b/www/common/sframe-common-mailbox.js @@ -132,9 +132,14 @@ define([ }); }; + var subscribed = false; // Get all existing notifications + the new ones when they come mailbox.subscribe = function (cfg) { + if (!subscribed) { + execCommand('SUBSCRIBE', null, function () {}); + subscribed = true; + } if (typeof(cfg.onViewed) === "function") { onViewedHandlers.push(cfg.onViewed); } @@ -166,10 +171,6 @@ define([ } }); - execCommand('SUBSCRIBE', null, function () { - //console.log('subscribed'); - }); - return mailbox; }; diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 7c5b18fff..9cb53a668 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -397,6 +397,14 @@ define([ cb({error:e}); }); }); + + Cryptpad.mailbox.onEvent.reg(function (data) { + sframeChan.event('EV_MAILBOX_EVENT', data); + }); + sframeChan.on('Q_MAILBOX_COMMAND', function (data, cb) { + Cryptpad.mailbox.execCommand(data, cb); + }); + }; addCommonRpc(sframeChan); @@ -921,13 +929,6 @@ define([ Cryptpad.universal.execCommand(data, cb); }); - Cryptpad.mailbox.onEvent.reg(function (data) { - sframeChan.event('EV_MAILBOX_EVENT', data); - }); - sframeChan.on('Q_MAILBOX_COMMAND', function (data, cb) { - Cryptpad.mailbox.execCommand(data, cb); - }); - Cryptpad.onTimeoutEvent.reg(function () { sframeChan.event('EV_WORKER_TIMEOUT'); }); diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index 14ea81d10..f93021bd3 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -422,6 +422,19 @@ define([ return JSON.parse(JSON.stringify(friendRequests)); }; + funcs.getFriends = function () { + var priv = ctx.metadataMgr.getPrivateData(); + var friends = priv.friends; + var goodFriends = {}; + Object.keys(friends).forEach(function (curve) { + if (curve.length !== 44) { return; } + var data = friends[curve]; + if (!data.notifications) { return; } + goodFriends[curve] = friends[curve]; + }); + return goodFriends; + }; + // Feedback funcs.prepareFeedback = function (key) { if (typeof(key) !== 'string') { return $.noop; } diff --git a/www/common/toolbar3.js b/www/common/toolbar3.js index 5cadb908d..065561214 100644 --- a/www/common/toolbar3.js +++ b/www/common/toolbar3.js @@ -491,7 +491,7 @@ MessengerUI, Messages) { if ($messagebox.length) { $messagebox.scrollTop($messagebox[0].scrollHeight); } - + $button.addClass('cp-toolbar-button-active'); config.$contentContainer.addClass('cp-chat-visible'); $button.removeClass('cp-toolbar-notification'); @@ -532,7 +532,9 @@ MessengerUI, Messages) { hidden: true }); $shareBlock.click(function () { - Common.getSframeChannel().event('EV_SHARE_OPEN', {}); + Common.getSframeChannel().event('EV_SHARE_OPEN', { + title: Common.getMetadataMgr().getMetadata().title + }); }); toolbar.$leftside.append($shareBlock); diff --git a/www/drive/app-drive.less b/www/drive/app-drive.less index 3554306e8..6a71decb5 100644 --- a/www/drive/app-drive.less +++ b/www/drive/app-drive.less @@ -4,6 +4,7 @@ @import (reference) "../../customize/src/less2/include/limit-bar.less"; @import (reference) "../../customize/src/less2/include/tokenfield.less"; @import (reference) '../../customize/src/less2/include/framework.less'; +@import (reference) '../../customize/src/less2/include/share.less'; &.cp-app-drive { .framework_min_main( @@ -14,6 +15,7 @@ .limit-bar_main(); .tokenfield_main(); + .share_main(); @drive_hover: #eee; @drive_hover-light: lighten(@drive_hover, 20%); diff --git a/www/drive/inner.js b/www/drive/inner.js index 43b351690..d4425b653 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -3237,6 +3237,8 @@ define([ if (paths.length !== 1) { return; } el = manager.find(paths[0].path); var parsed, modal; + var friends = common.getFriends(); + if (manager.isSharedFolder(el)) { data = manager.getSharedFolderData(el); parsed = Hash.parsePadUrl(data.href); @@ -3255,6 +3257,7 @@ define([ var padData = { origin: APP.origin, pathname: "/" + padType + "/", + friends: friends, hashes: { editHash: parsed.hash, viewHash: roParsed.hash, @@ -3264,13 +3267,16 @@ define([ hash: parsed.hash, password: data.password }, + title: data.title, common: common }; modal = padType === 'file' ? UIElements.createFileShareModal(padData) : UIElements.createShareModal(padData); modal = UI.dialog.tabs(modal); } - UI.openCustomModal(modal); + UI.openCustomModal(modal, { + wide: Object.keys(friends).length !== 0 + }); } else if ($(this).hasClass('cp-app-drive-context-newfolder')) { if (paths.length !== 1) { return; } diff --git a/www/share/app-share.less b/www/share/app-share.less index 0f06c76b1..56d926690 100644 --- a/www/share/app-share.less +++ b/www/share/app-share.less @@ -1,85 +1,8 @@ @import (reference) '../../customize/src/less2/include/colortheme-all.less'; -@import (reference) '../../customize/src/less2/include/modal.less'; -@import (reference) '../../customize/src/less2/include/alertify.less'; @import (reference) '../../customize/src/less2/include/tippy.less'; -@import (reference) '../../customize/src/less2/include/avatar.less'; -@import (reference) '../../customize/src/less2/include/checkmark.less'; -@import (reference) '../../customize/src/less2/include/password-input.less'; +@import (reference) '../../customize/src/less2/include/share.less'; &.cp-app-share { - .alertify_main(); .tippy_main(); - .checkmark_main(20px); - .password_main(); - .modal_main(); - - .cp-share-columns { - display: flex; - flex-flow: row; - - .cp-share-column { - width: 50%; - padding: 0 10px; - } - } - .cp-share-grid, .cp-share-list { - .avatar_main(50px); - display: flex; - justify-content: space-between; - flex-wrap: wrap; - } - .cp-share-list { - margin-bottom: 15px; - } - .cp-share-grid { - height: 228px; - max-height: 228px; - overflow-x: auto; - } - .cp-recent-only { - .cp-share-grid, .cp-share-grid-filter { - display: none; - } - } - .cp-share-grid-filter { - display: flex; - input { - flex: 1; - margin-bottom: 0 !important; - &::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */ - color: @colortheme_alertify-primary-text; - opacity: 1; /* Firefox */ - } - } - margin-bottom: 15px; - } - .cp-share-friend { - width: 70px; - height: 70px; - display: flex; - flex-flow: column; - justify-content: center; - align-items: center; - padding: 5px; - margin-bottom: 6px; - cursor: default; - transition: order 0.5s, background-color 0.5s; - - &.cp-selected { - background-color: @colortheme_alertify-primary; - color: @colortheme_alertify-primary-text; - order: -1 !important; - } - .cp-share-friend-name { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - width: 100%; - text-align: center; - } - border: 1px solid @colortheme_alertify-primary; - &.cp-fake-friend { - visibility: hidden; - } - } + .share_main(); } diff --git a/www/share/inner.js b/www/share/inner.js index e20280c6a..35d337c9f 100644 --- a/www/share/inner.js +++ b/www/share/inner.js @@ -24,14 +24,6 @@ define([ var hideShareDialog = function () { sframeChan.event('EV_SHARE_CLOSE'); }; - /* - var onShareAction = function (data) { - hideShareDialog(); - sframeChan.event("EV_SHARE_ACTION", { - // XXX data - }); - }; - */ var createShareDialog = function (data) { var priv = metadataMgr.getPrivateData(); @@ -40,11 +32,16 @@ define([ var pathname = priv.pathname; var f = (data && data.file) ? UIElements.createFileShareModal : UIElements.createShareModal; + + var friends = common.getFriends(); + var modal = f({ origin: origin, pathname: pathname, hashes: hashes, common: common, + title: data.title, + friends: friends, onClose: function () { hideShareDialog(); }, @@ -53,15 +50,14 @@ define([ password: priv.password } }); + UI.findCancelButton().click(); UI.openCustomModal(UI.dialog.tabs(modal), { - wide: true + wide: Object.keys(friends).length !== 0 }); }; sframeChan.on('EV_SHARE_REFRESH', function (data) { createShareDialog(data); }); - - //UI.removeLoadingScreen(); }; var main = function () { @@ -70,7 +66,6 @@ define([ nThen(function (waitFor) { $(waitFor(function () { UI.removeLoadingScreen(); - //UI.addLoadingScreen({hideTips: true, hideLogo: true}); })); SFCommon.create(waitFor(function (c) { APP.common = common = c; })); }).nThen(function (/*waitFor*/) {