From cb36a499080d998148e9b5fab52932bc0f235a2e Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 4 Jun 2020 16:54:56 +0200 Subject: [PATCH 01/58] Add team mailbox with the SHARE_PAD example --- www/common/common-ui-elements.js | 46 ++++++++++++++++------------- www/common/notifications.js | 21 ++++++++++++- www/common/outer/mailbox.js | 13 ++++++-- www/common/outer/team.js | 36 ++++++++++++++++++++++ www/common/sframe-common-mailbox.js | 16 ++++++---- www/common/toolbar.js | 2 +- 6 files changed, 105 insertions(+), 29 deletions(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 278e8dda8..a7c5d3994 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -272,25 +272,30 @@ define([ var $friends = $div.find('.cp-usergrid-user.cp-selected'); $friends.each(function (i, el) { var curve = $(el).attr('data-curve'); - // Check if the selected element is a friend or a team - if (curve) { // Friend - if (!curve || !friends[curve]) { return; } - var friend = friends[curve]; - if (!friend.notifications || !friend.curvePublic) { return; } - common.mailbox.sendTo("SHARE_PAD", { - href: href, - password: config.password, - isTemplate: config.isTemplate, - name: myName, - title: title - }, { - channel: friend.notifications, - curvePublic: friend.curvePublic - }); - return; - } - // Team var ed = $(el).attr('data-ed'); + var friend = curve && friends[curve]; + var team = teams[ed]; + // If the selected element is a friend or a team without edit right, + // send a notification + var mailbox = friend || ((team && team.viewer) ? team : undefined); + if (mailbox) { // Friend + if (friends[curve] && !mailbox.notifications) { return; } + if (mailbox.notifications && mailbox.curvePublic) { + // XXX we should mark this notification as "viewed" in our own proxy + common.mailbox.sendTo("SHARE_PAD", { + href: href, + password: config.password, + isTemplate: config.isTemplate, + name: myName, + title: title + }, { + channel: mailbox.notifications, + curvePublic: mailbox.curvePublic + }); + return; + } + } + // If it's a team with edit right, add the pad directly var team = teams[ed]; if (!team) { return; } sframeChan.query('Q_STORE_IN_TEAM', { @@ -409,10 +414,11 @@ define([ // config.teamId only exists when we're trying to share a pad from a team drive // In this case, we don't want to share the pad with the current team if (config.teamId && config.teamId === id) { return; } - if (!teamsData[id].hasSecondaryKey) { return; } var t = teamsData[id]; teams[t.edPublic] = { - notifications: true, + viewer: !teamsData[id].hasSecondaryKey, + notifications: t.notifications, + curvePublic: t.curvePublic, displayName: t.name, edPublic: t.edPublic, avatar: t.avatar, diff --git a/www/common/notifications.js b/www/common/notifications.js index 3abc40ca8..348b0cc44 100644 --- a/www/common/notifications.js +++ b/www/common/notifications.js @@ -84,6 +84,10 @@ define([ // Share pad + Messages.notification_padSharedTeam = "{0} has shared a pad with the team {2}: {1}"; // XXX + Messages.notification_fileSharedTeam = "{0} has shared a file with the team {2}: {1}"; // XXX + Messages.notification_folderSharedTeam = "{0} has shared a pad with the team {2}: {1}"; // XXX + handlers['SHARE_PAD'] = function(common, data) { var content = data.content; var msg = content.msg; @@ -91,10 +95,22 @@ define([ var key = type === 'drive' ? 'notification_folderShared' : (type === 'file' ? 'notification_fileShared' : 'notification_padShared'); + + var teamNotification = /^team-/.test(data.type) && Number(data.type.slice(5)); + var teamName = ''; + if (teamNotification) { + var privateData = common.getMetadataMgr().getPrivateData(); + var teamsData = Util.tryParse(JSON.stringify(privateData.teams)) || {}; + var team = teamsData[teamNotification]; + if (!team || !team.name) { return; } + key += "Team"; + teamName = Util.fixHTML(team.name); + } + var name = Util.fixHTML(msg.content.name) || Messages.anonymous; var title = Util.fixHTML(msg.content.title); content.getFormatText = function() { - return Messages._getKey(key, [name, title]); + return Messages._getKey(key, [name, title, teamName]); }; content.handler = function() { var todo = function() { @@ -105,6 +121,9 @@ define([ if (msg.content.isTemplate) { common.sessionStorage.put(Constants.newPadPathKey, ['template'], waitFor()); } + if (teamNotification) { + common.sessionStorage.put(Constants.newPadTeamKey, teamNotification, waitFor()); + } common.sessionStorage.put('newPadPassword', msg.content.password || '', waitFor()); }).nThen(function() { todo(); diff --git a/www/common/outer/mailbox.js b/www/common/outer/mailbox.js index 706f1c8c2..ccae95a7e 100644 --- a/www/common/outer/mailbox.js +++ b/www/common/outer/mailbox.js @@ -467,6 +467,15 @@ proxy.mailboxes = { } }); + Object.keys(store.proxy.teams || {}).forEach(function (teamId) { + var team = store.proxy.teams[teamId]; + var teamMailbox = team.keys.mailbox || {}; + if (!teamMailbox.channel) { return; } + openChannel(ctx, 'team-'+teamId, teamMailbox, function () { + //console.log('Mailbox team', teamId); + }); + }); + mailbox.post = function (box, type, content) { var b = ctx.boxes[box]; if (!b) { return; } @@ -477,8 +486,8 @@ proxy.mailboxes = { }); }; - mailbox.open = function (key, m, cb) { - if (TYPES.indexOf(key) === -1) { return; } + mailbox.open = function (key, m, cb, team) { + if (TYPES.indexOf(key) === -1 && !team) { return; } openChannel(ctx, key, m, cb); }; diff --git a/www/common/outer/team.js b/www/common/outer/team.js index c151de004..92dc1deda 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -494,6 +494,9 @@ define([ var roHash = Hash.getViewHashFromKeys(secret); var keyPair = Nacl.sign.keyPair(); // keyPair.secretKey , keyPair.publicKey + var curveSeed = Nacl.randomBytes(32); + var curvePair = Nacl.box.keyPair.fromSecretKey(curveSeed); + var rosterSeed = Crypto.Team.createSeed(); var rosterKeys = Crypto.Team.deriveMemberKeys(rosterSeed, { curvePublic: ctx.store.proxy.curvePublic, @@ -585,6 +588,14 @@ define([ proxy.on('ready', function () { // Store keys in our drive var keys = { + mailbox: { + channel: Hash.createChannelId(), + viewed: [], + keys: { + curvePrivate: Nacl.util.encodeBase64(curvePair.secretKey), + curvePublic: Nacl.util.encodeBase64(curvePair.publicKey) + } + }, drive: { edPrivate: Nacl.util.encodeBase64(keyPair.secretKey), edPublic: Nacl.util.encodeBase64(keyPair.publicKey) @@ -1566,6 +1577,26 @@ define([ }); }; + var deriveMailbox = function (team) { + if (!team) { return; } + if (team.keys && team.keys.mailbox) { return team.keys.mailbox; } + var channel = team.channel; + if (!channel) { return; } + // XXX maybe use something else than channel? + var hash = Nacl.hash(Nacl.util.decodeUTF8(channel)); + var seed = hash.slice(0,32); + var channel = Util.uint8ArrayToHex(hash.slice(32,48)); + var curvePair = Nacl.box.keyPair.fromSecretKey(seed); + return { + channel: channel, + viewed: [], + keys: { + curvePrivate: Nacl.util.encodeBase64(curvePair.secretKey), + curvePublic: Nacl.util.encodeBase64(curvePair.publicKey) + } + }; + }; + Team.init = function (cfg, waitFor, emit) { var team = {}; var store = cfg.store; @@ -1595,6 +1626,9 @@ define([ Object.keys(teams).forEach(function (id) { ctx.onReadyHandlers[id] = []; + if (!Util.find(teams, id, 'keys', 'mailbox')) { + teams[id].keys.mailbox = deriveMailbox(teams[id]); + } openChannel(ctx, teams[id], id, waitFor(function (err) { if (err) { return void console.error(err); } console.debug('Team '+id+' ready'); @@ -1615,6 +1649,8 @@ define([ edPublic: Util.find(teams[id], ['keys', 'drive', 'edPublic']), avatar: Util.find(teams[id], ['metadata', 'avatar']), viewer: !Util.find(teams[id], ['keys', 'drive', 'edPrivate']), + notifications: Util.find(teams[id], ['keys', 'mailbox', 'channel']), + curvePublic: Util.find(teams[id], ['keys', 'mailbox', 'keys', 'curvePublic']), }; if (safe && ctx.teams[id]) { diff --git a/www/common/sframe-common-mailbox.js b/www/common/sframe-common-mailbox.js index a5602fc3f..eac59462e 100644 --- a/www/common/sframe-common-mailbox.js +++ b/www/common/sframe-common-mailbox.js @@ -105,11 +105,14 @@ define([ }); // Call the onMessage handlers + var isNotification = function (type) { + return type === "notificatons" || /^team-/.test(type); + }; var pushMessage = function (data, handler) { var todo = function (f) { try { var el; - if (data.type === 'notifications') { + if (isNotification(data.type)) { Notifications.add(Common, data); el = createElement(data); } @@ -129,7 +132,7 @@ define([ onViewedHandlers.forEach(function (f) { try { f(data); - if (data.type === 'notifications') { + if (isNotification(data.type)) { Notifications.remove(Common, data); } } catch (e) { @@ -173,20 +176,23 @@ define([ execCommand('SUBSCRIBE', null, function () {}); subscribed = true; } + var teams = types.indexOf('team') !== -1; if (typeof(cfg.onViewed) === "function") { onViewedHandlers.push(function (data) { - if (types.indexOf(data.type) === -1) { return; } + var type = data.type; + if (types.indexOf(type) === -1 && !(teams && /^team-/.test(type))) { return; } cfg.onViewed(data); }); } if (typeof(cfg.onMessage) === "function") { onMessageHandlers.push(function (data, el) { - if (types.indexOf(data.type) === -1) { return; } + var type = data.type; + if (types.indexOf(type) === -1 && !(teams && /^team-/.test(type))) { return; } cfg.onMessage(data, el); }); } Object.keys(history).forEach(function (type) { - if (types.indexOf(type) === -1) { return; } + if (types.indexOf(type) === -1 && !(teams && /^team-/.test(type))) { return; } history[type].forEach(function (data) { pushMessage({ type: type, diff --git a/www/common/toolbar.js b/www/common/toolbar.js index a4683a884..e55cdcf82 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -1025,7 +1025,7 @@ MessengerUI, Messages) { $button.addClass('fa-bell'); }; - Common.mailbox.subscribe(['notifications'], { + Common.mailbox.subscribe(['notifications', 'team'], { onMessage: function (data, el) { if (el) { $(div).prepend(el); From 0390d3df7528ee24ab4f500afaf1f5e512e0b28b Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 5 Jun 2020 12:04:28 +0200 Subject: [PATCH 02/58] Don't show your own team notifications --- www/common/common-ui-elements.js | 2 +- www/common/outer/mailbox.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index a7c5d3994..37a5172db 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -281,7 +281,6 @@ define([ if (mailbox) { // Friend if (friends[curve] && !mailbox.notifications) { return; } if (mailbox.notifications && mailbox.curvePublic) { - // XXX we should mark this notification as "viewed" in our own proxy common.mailbox.sendTo("SHARE_PAD", { href: href, password: config.password, @@ -289,6 +288,7 @@ define([ name: myName, title: title }, { + viewed: team && team.id, channel: mailbox.notifications, curvePublic: mailbox.curvePublic }); diff --git a/www/common/outer/mailbox.js b/www/common/outer/mailbox.js index ccae95a7e..2250257aa 100644 --- a/www/common/outer/mailbox.js +++ b/www/common/outer/mailbox.js @@ -109,6 +109,17 @@ proxy.mailboxes = { }); var ciphertext = crypto.encrypt(text, user.curvePublic); + // If we've sent this message to one of our teams' mailbox, we may want to "dismiss" it + // automatically + if (user.viewed) { + var team = Util.find(ctx, ['store', 'proxy', 'teams', user.viewed]); + if (team) { + var hash = ciphertext.slice(0,64); + var viewed = Util.find(team, ['keys', 'mailbox', 'viewed']); + if (Array.isArray(viewed)) { viewed.push(hash); } + } + } + anonRpc.send("WRITE_PRIVATE_MESSAGE", [ user.channel, ciphertext From f7b61daff325eb9641ad977b6b1aaaf1bea76218 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 5 Jun 2020 12:08:43 +0200 Subject: [PATCH 03/58] lint compliance --- www/common/common-ui-elements.js | 1 - www/common/outer/team.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 37a5172db..acab5085b 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -296,7 +296,6 @@ define([ } } // If it's a team with edit right, add the pad directly - var team = teams[ed]; if (!team) { return; } sframeChan.query('Q_STORE_IN_TEAM', { href: href, diff --git a/www/common/outer/team.js b/www/common/outer/team.js index 92dc1deda..4b5c159ea 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -1585,10 +1585,10 @@ define([ // XXX maybe use something else than channel? var hash = Nacl.hash(Nacl.util.decodeUTF8(channel)); var seed = hash.slice(0,32); - var channel = Util.uint8ArrayToHex(hash.slice(32,48)); + var mailboxChannel = Util.uint8ArrayToHex(hash.slice(32,48)); var curvePair = Nacl.box.keyPair.fromSecretKey(seed); return { - channel: channel, + channel: mailboxChannel, viewed: [], keys: { curvePrivate: Nacl.util.encodeBase64(curvePair.secretKey), From bcfa09f7bce625663d574dfcf0cb18b9124f92f4 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 9 Jun 2020 17:40:52 +0200 Subject: [PATCH 04/58] Fix mailbox issue and add XXX --- www/common/outer/team.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/www/common/outer/team.js b/www/common/outer/team.js index 4b5c159ea..a0c785200 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -1577,6 +1577,8 @@ define([ }); }; + // XXX call mailbox.open when you create or join a team + // XXX close the mailbox hwne you leave the team var deriveMailbox = function (team) { if (!team) { return; } if (team.keys && team.keys.mailbox) { return team.keys.mailbox; } @@ -1626,7 +1628,7 @@ define([ Object.keys(teams).forEach(function (id) { ctx.onReadyHandlers[id] = []; - if (!Util.find(teams, id, 'keys', 'mailbox')) { + if (!Util.find(teams, [id, 'keys', 'mailbox'])) { teams[id].keys.mailbox = deriveMailbox(teams[id]); } openChannel(ctx, teams[id], id, waitFor(function (err) { From 24c7ea985dd385deb9ec6c7f14967d80b3501646 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 10 Jun 2020 12:14:12 +0200 Subject: [PATCH 05/58] Fix issues with the team mailbox --- www/common/outer/mailbox.js | 34 +++++++++++++++++++++-------- www/common/outer/team.js | 27 +++++++++++++++-------- www/common/sframe-common-mailbox.js | 3 ++- www/common/toolbar.js | 1 + 4 files changed, 46 insertions(+), 19 deletions(-) diff --git a/www/common/outer/mailbox.js b/www/common/outer/mailbox.js index 2250257aa..e5b6179c7 100644 --- a/www/common/outer/mailbox.js +++ b/www/common/outer/mailbox.js @@ -137,10 +137,9 @@ proxy.mailboxes = { var dismiss = function (ctx, data, cId, cb) { var type = data.type; var hash = data.hash; - var m = Util.find(ctx, ['store', 'proxy', 'mailboxes', type]); - if (!m) { return void cb({error: 'NOT_FOUND'}); } var box = ctx.boxes[type]; if (!box) { return void cb({error: 'NOT_LOADED'}); } + var m = box.data || {}; // If the hash in in our history, get the index from the history: // - if the index is 0, we can change our lastKnownHash @@ -202,7 +201,16 @@ proxy.mailboxes = { }; - var openChannel = function (ctx, type, m, onReady) { + var leaveChannel = function (ctx, type, cb) { + var box = ctx.boxes[type]; + if (!box) { return void cb(); } + if (!box.cpNf || typeof(box.cpNf.stop) !== "function") { return void cb('EINVAL'); } + box.cpNf.stop(); + delete ctx.boxes[type]; + }; + var openChannel = function (ctx, type, m, onReady, opts) { + console.error(type, m, opts); + opts = opts || {}; var box = ctx.boxes[type] = { channel: m.channel, type: type, @@ -221,7 +229,8 @@ proxy.mailboxes = { console.error(e); } box.queue.push(msg); - } + }, + data: m }; if (!Crypto.Mailbox) { return void console.error("chainpad-crypto is outdated and doesn't support mailboxes."); @@ -235,7 +244,7 @@ proxy.mailboxes = { channel: m.channel, noChainPad: true, crypto: crypto, - owners: [ctx.store.proxy.edPublic], + owners: opts.owners || [ctx.store.proxy.edPublic], lastKnownHash: m.lastKnownHash }; cfg.onConnectionChange = function () {}; // Allow reconnections in chainpad-netflux @@ -357,7 +366,7 @@ proxy.mailboxes = { // Continue onReady(); }; - CpNetflux.start(cfg); + box.cpNf = CpNetflux.start(cfg); }; var initializeHistory = function (ctx) { @@ -480,11 +489,15 @@ proxy.mailboxes = { Object.keys(store.proxy.teams || {}).forEach(function (teamId) { var team = store.proxy.teams[teamId]; + if (!team) { return; } var teamMailbox = team.keys.mailbox || {}; if (!teamMailbox.channel) { return; } + var opts = { + owners: [Util.find(team, ['keys', 'drive', 'edPublic'])] + }; openChannel(ctx, 'team-'+teamId, teamMailbox, function () { //console.log('Mailbox team', teamId); - }); + }, opts); }); mailbox.post = function (box, type, content) { @@ -497,9 +510,12 @@ proxy.mailboxes = { }); }; - mailbox.open = function (key, m, cb, team) { + mailbox.open = function (key, m, cb, team, opts) { if (TYPES.indexOf(key) === -1 && !team) { return; } - openChannel(ctx, key, m, cb); + openChannel(ctx, key, m, cb, opts); + }; + mailbox.close = function (key, cb) { + leaveChannel(ctx, key, cb); }; mailbox.dismiss = function (data, cb) { diff --git a/www/common/outer/team.js b/www/common/outer/team.js index a0c785200..c495bc91c 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -126,6 +126,9 @@ define([ delete ctx.store.proxy.teams[teamId]; ctx.emit('LEAVE_TEAM', teamId, team.clients); ctx.updateMetadata(); + ctx.store.mailbox.close('team-'+teamId, function () { + // Close team mailbox + }); }; var getTeamChannelList = function (ctx, id) { @@ -494,8 +497,7 @@ define([ var roHash = Hash.getViewHashFromKeys(secret); var keyPair = Nacl.sign.keyPair(); // keyPair.secretKey , keyPair.publicKey - var curveSeed = Nacl.randomBytes(32); - var curvePair = Nacl.box.keyPair.fromSecretKey(curveSeed); + var curvePair = Nacl.box.keyPair(); var rosterSeed = Crypto.Team.createSeed(); var rosterKeys = Crypto.Team.deriveMemberKeys(rosterSeed, { @@ -612,7 +614,7 @@ define([ view: rosterKeys.viewKeyStr, } }; - ctx.store.proxy.teams[id] = { + var t = ctx.store.proxy.teams[id] = { owner: true, channel: secret.channel, hash: hash, @@ -629,6 +631,11 @@ define([ onReady(ctx, id, lm, roster, keys, cId, function () { Feedback.send('TEAM_CREATION'); + ctx.store.mailbox.open('team-'+id, t.keys.mailbox, function () { + // Team mailbox loaded + }, true, { + owners: t.keys.drive.edPublic + }); ctx.updateMetadata(); cb(); }); @@ -731,6 +738,11 @@ define([ team.rpc.removePins(waitFor(function (err) { if (err) { console.error(err); } })); + // Delete the mailbox + var mailboxChan = Util.find(teamData, ['keys', 'mailbox', 'channel']); + team.rpc.removeOwnedChannel(mailboxChan, waitFor(function (err) { + if (err) { console.error(err); } + })); // Delete the roster var rosterChan = Util.find(teamData, ['keys', 'roster', 'channel']); ctx.store.rpc.removeOwnedChannel(rosterChan, waitFor(function (err) { @@ -1577,15 +1589,12 @@ define([ }); }; - // XXX call mailbox.open when you create or join a team - // XXX close the mailbox hwne you leave the team var deriveMailbox = function (team) { if (!team) { return; } if (team.keys && team.keys.mailbox) { return team.keys.mailbox; } - var channel = team.channel; - if (!channel) { return; } - // XXX maybe use something else than channel? - var hash = Nacl.hash(Nacl.util.decodeUTF8(channel)); + var strSeed = Util.find(team, ['keys', 'roster', 'edit']); + if (!strSeed) { return; } + var hash = Nacl.hash(Nacl.util.decodeUTF8(strSeed)); var seed = hash.slice(0,32); var mailboxChannel = Util.uint8ArrayToHex(hash.slice(32,48)); var curvePair = Nacl.box.keyPair.fromSecretKey(seed); diff --git a/www/common/sframe-common-mailbox.js b/www/common/sframe-common-mailbox.js index eac59462e..bdf1ae81e 100644 --- a/www/common/sframe-common-mailbox.js +++ b/www/common/sframe-common-mailbox.js @@ -106,7 +106,7 @@ define([ // Call the onMessage handlers var isNotification = function (type) { - return type === "notificatons" || /^team-/.test(type); + return type === "notifications" || /^team-/.test(type); }; var pushMessage = function (data, handler) { var todo = function (f) { @@ -188,6 +188,7 @@ define([ onMessageHandlers.push(function (data, el) { var type = data.type; if (types.indexOf(type) === -1 && !(teams && /^team-/.test(type))) { return; } + console.log('okokok'); cfg.onMessage(data, el); }); } diff --git a/www/common/toolbar.js b/www/common/toolbar.js index e55cdcf82..3afa55d61 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -1027,6 +1027,7 @@ MessengerUI, Messages) { Common.mailbox.subscribe(['notifications', 'team'], { onMessage: function (data, el) { + console.log(data, el, div); if (el) { $(div).prepend(el); } From 4faa0839f9e7d972d0c07b57b6ce64a2e1902f91 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 10 Jun 2020 12:29:29 +0200 Subject: [PATCH 06/58] Open the mailbox when joining a team --- www/common/outer/team.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/www/common/outer/team.js b/www/common/outer/team.js index c495bc91c..5c31621f7 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -773,6 +773,12 @@ define([ ctx.onReadyHandlers[id] = []; openChannel(ctx, team, id, function (obj) { if (!(obj && obj.error)) { console.debug('Team joined:' + id); } + var t = ctx.store.proxy.teams[id]; + ctx.store.mailbox.open('team-'+id, t.keys.mailbox, function () { + // Team mailbox loaded + }, true, { + owners: t.keys.drive.edPublic + }); ctx.updateMetadata(); cb(obj); }); From 9aafd5f3c5594522b681b608386852e6625bbea8 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 10 Jun 2020 18:42:46 +0200 Subject: [PATCH 07/58] Add category and attachments to support tickets --- customize.dist/src/less2/include/support.less | 3 + www/support/inner.js | 3 +- www/support/ui.js | 135 +++++++++++++++++- 3 files changed, 132 insertions(+), 9 deletions(-) diff --git a/customize.dist/src/less2/include/support.less b/customize.dist/src/less2/include/support.less index 890ba810d..1d62157de 100644 --- a/customize.dist/src/less2/include/support.less +++ b/customize.dist/src/less2/include/support.less @@ -4,6 +4,9 @@ @msg-bg: #eee; @fromme-bg: #ddd; .cp-support-form-container { + div { + margin-bottom: 10px; + } [type="text"] { width: @sidebar_button-width; margin-bottom: 10px; diff --git a/www/support/inner.js b/www/support/inner.js index 3d907421d..089af5230 100644 --- a/www/support/inner.js +++ b/www/support/inner.js @@ -166,8 +166,6 @@ define([ var form = APP.support.makeForm(); - $div.find('button').before(form); - var id = Util.uid(); $div.find('button').click(function () { @@ -183,6 +181,7 @@ define([ $('.cp-sidebarlayout-category[data-category="tickets"]').click(); } }); + $div.find('button').before(form); return $div; }; diff --git a/www/support/ui.js b/www/support/ui.js index 04330734e..e95a8e8cf 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -6,8 +6,9 @@ define([ '/common/common-hash.js', '/common/common-util.js', '/common/clipboard.js', + '/common/common-ui-elements.js', '/customize/messages.js', -], function ($, ApiConfig, h, UI, Hash, Util, Clipboard, Messages) { +], function ($, ApiConfig, h, UI, Hash, Util, Clipboard, UIElements, Messages) { var send = function (ctx, id, type, data, dest) { var common = ctx.common; @@ -61,9 +62,14 @@ define([ }; var sendForm = function (ctx, id, form, dest) { - var $title = $(form).find('.cp-support-form-title'); - var $content = $(form).find('.cp-support-form-msg'); + var $form = $(form); + var $cat = $form.find('.cp-support-form-category'); + var $title = $form.find('.cp-support-form-title'); + var $content = $form.find('.cp-support-form-msg'); + var $attachments = $form.find('.cp-support-form-attachments'); + + var category = $cat.val().trim(); var title = $title.val().trim(); if (!title) { return void UI.alert(Messages.support_formTitleError); @@ -72,18 +78,38 @@ define([ if (!content) { return void UI.alert(Messages.support_formContentError); } + $cat.val(''); $content.val(''); $title.val(''); + var attachments = []; + $attachments.find('> span').each(function (i, el) { + var $el = $(el); + attachments.push({ + href: $el.attr('data-href'), + name: $el.attr('data-name') + }); + }); + send(ctx, id, 'TICKET', { + category: category, title: title, + attachments: attachments, message: content, }, dest); return true; }; - var makeForm = function (cb, title) { +Messages.support_cat_account = "User account"; // XXX +Messages.support_cat_data = "Loss of content"; // XXX +Messages.support_cat_bug = "Bug report"; // XXX +Messages.support_cat_other = "Other"; // XXX +Messages.support_category = "Category"; // XXX +Messages.support_attachments = "Attachments"; // XXX +Messages.support_addAttachment = "Add attachment"; // XXX + + var makeForm = function (ctx, cb, title) { var button; if (typeof(cb) === "function") { @@ -93,8 +119,34 @@ define([ var cancel = title ? h('button.btn.btn-secondary', Messages.cancel) : undefined; + var category = h('input.cp-support-form-category', { + type: 'hidden', + value: '' + }); + var categories = ['account', 'data', 'bug', 'other'].map(function (key) { + return { + tag: 'a', + content: h('span', Messages['support_cat_'+key]), + action: function () { + $(category).val(key); + } + }; + }); + var catContainer = h('div.cp-dropdown-container' + (title ? '.cp-hidden': '')); + var dropdownCfg = { + text: Messages.support_category, + options: categories, + container: $(catContainer), + isSelect: true + }; + var $drop = UIElements.createDropdown(dropdownCfg); + + var attachments, addAttachment; + var content = [ h('hr'), + category, + catContainer, h('input.cp-support-form-title' + (title ? '.cp-hidden' : ''), { placeholder: Messages.support_formTitle, type: 'text', @@ -104,11 +156,51 @@ define([ h('textarea.cp-support-form-msg', { placeholder: Messages.support_formMessage }), + h('label', Messages.support_attachments), + attachments = h('div.cp-support-form-attachments'), + addAttachment = h('button', Messages.support_addAttachment), h('hr'), button, cancel ]; + $(addAttachment).click(function () { + var $input = $('', { + 'type': 'file', + 'style': 'display: none;', + 'multiple': 'multiple', + 'accept': 'image/*' + }).on('change', function (e) { + var files = Util.slice(e.target.files); + files.forEach(function (file) { + var ev = {}; + ev.callback = function (data) { + var x, a; + var span = h('span', { + 'data-name': data.name, + 'data-href': data.url + }, [ + x = h('i.fa.fa-times'), + a = h('a', { + href: '#' + }, data.name) + ]); + $(x).click(function () { + $(span).remove(); + }); + $(a).click(function (e) { + e.preventDefault(); + ctx.common.openURL(data.url); + }); + + $(attachments).append(span); + }; + ctx.FM.handleFile(file, ev); + }); + }); + $input.click(); + }); + var form = h('div.cp-support-form-container', content); $(cancel).click(function () { @@ -125,6 +217,7 @@ define([ var privateData = metadataMgr.getPrivateData(); var ticketTitle = content.title + ' (#' + content.id + ')'; + var ticketCategory; var answer = h('button.btn.btn-primary.cp-support-answer', Messages.support_answer); var close = h('button.btn.btn-danger.cp-support-close', Messages.support_close); var hide = h('button.btn.btn-danger.cp-support-hide', Messages.support_remove); @@ -137,6 +230,7 @@ define([ var url; if (ctx.isAdmin) { + ticketCategory = Messages['support_cat_'+(content.category || 'other')] + ' - '; url = h('button.btn.btn-primary.fa.fa-clipboard'); $(url).click(function () { var link = privateData.origin + privateData.pathname + '#' + 'support-' + content.id; @@ -148,7 +242,7 @@ define([ var $ticket = $(h('div.cp-support-list-ticket', { 'data-id': content.id }, [ - h('h2', [ticketTitle, url]), + h('h2', [ticketCategory, ticketTitle, url]), actions ])); @@ -179,7 +273,7 @@ define([ $(answer).click(function () { $ticket.find('.cp-support-form-container').remove(); $(actions).hide(); - var form = makeForm(function () { + var form = makeForm(ctx, function () { var sent = sendForm(ctx, content.id, form, content.sender); if (sent) { $(actions).show(); @@ -215,6 +309,20 @@ define([ ev.stopPropagation(); }); + var attachments = (content.attachments || []).map(function (obj) { + if (!obj || !obj.name || !obj.href) { return; } + var a = h('a', { + href: '#' + }, obj.name) + $(a).click(function (e) { + e.preventDefault(); + ctx.common.openURL(obj.href); + }); + return h('span', [ + a + ]); + }); + var adminClass = (fromAdmin? '.cp-support-fromadmin': ''); var premiumClass = (fromPremium && !fromAdmin? '.cp-support-frompremium': ''); var name = Util.fixHTML(content.sender.name) || Messages.anonymous; @@ -226,6 +334,7 @@ define([ h('span.cp-support-message-time', content.time ? new Date(content.time).toLocaleString() : '') ]), h('pre.cp-support-message-content', content.message), + h('div', attachments), isAdmin ? userData : undefined, ]); }; @@ -257,10 +366,22 @@ define([ adminKeys: Array.isArray(ApiConfig.adminKeys)? ApiConfig.adminKeys.slice(): [], }; + var fmConfig = { + body: $('body'), + onUploaded: function (ev, data) { + if (ev.callback) { + ev.callback(data); + } + } + }; + ctx.FM = common.createFileManager(fmConfig); + ui.sendForm = function (id, form, dest) { return sendForm(ctx, id, form, dest); }; - ui.makeForm = makeForm; + ui.makeForm = function (cb, title) { + return makeForm(ctx, cb, title); + }; ui.makeTicket = function ($div, content, onHide) { return makeTicket(ctx, $div, content, onHide); }; From e7a6397084f5da42f27aeeab02384aac73b62533 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 11 Jun 2020 14:49:59 +0200 Subject: [PATCH 08/58] Add category filter and improve UI --- customize.dist/src/less2/include/support.less | 12 +++++ www/admin/inner.js | 17 +++++++ www/common/common-ui-elements.js | 4 +- www/support/app-support.less | 9 ++++ www/support/ui.js | 51 ++++++++++++------- 5 files changed, 73 insertions(+), 20 deletions(-) diff --git a/customize.dist/src/less2/include/support.less b/customize.dist/src/less2/include/support.less index 1d62157de..d83746b51 100644 --- a/customize.dist/src/less2/include/support.less +++ b/customize.dist/src/less2/include/support.less @@ -18,6 +18,18 @@ height: 300px; } } + .cp-support-attachments { + display: flex; + .fa { + cursor: pointer; + margin-right: 10px; + } + &> span { + border: 1px solid #ddd; + margin-right: 5px; + padding: 10px; + } + } .cp-support-container { .cp-support-list-ticket { display: flex; diff --git a/www/admin/inner.js b/www/admin/inner.js index 2ff62cf1f..90048e76d 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -185,6 +185,20 @@ define([ var $container = makeBlock('support-list'); var $div = $(h('div.cp-support-container')).appendTo($container); + var catContainer = h('div.cp-dropdown-container'); + $div.append(catContainer); + var category = 'all'; + var $drop = APP.support.makeCategoryDropdown(catContainer, function (key) { + category = key; + if (key === 'all') { + $div.find('.cp-support-list-ticket').show(); + return; + } + $div.find('.cp-support-list-ticket').hide(); + $div.find('.cp-support-list-ticket[data-cat="'+key+'"]').show(); + }, true); + $drop.setValue('all'); + var metadataMgr = common.getMetadataMgr(); var privateData = metadataMgr.getPrivateData(); var cat = privateData.category || ''; @@ -277,6 +291,9 @@ define([ UI.alert(Messages.error); }); }); + if (category !== 'all' && $ticket.attr('data-cat') !== category) { + $ticket.hide(); + } } $ticket.append(APP.support.makeMessage(content, hash)); reorder(); diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 4393d1201..4d2f8b3c7 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -2204,7 +2204,9 @@ define([ if (config.isSelect && value) { var $val = $innerblock.find('[data-value="'+value+'"]'); setActive($val); - $innerblock.scrollTop($val.position().top + $innerblock.scrollTop()); + try { + $innerblock.scrollTop($val.position().top + $innerblock.scrollTop()); + } catch (e) {} } if (config.feedback) { Feedback.send(config.feedback); } }; diff --git a/www/support/app-support.less b/www/support/app-support.less index 7684c054e..41af016fd 100644 --- a/www/support/app-support.less +++ b/www/support/app-support.less @@ -18,6 +18,15 @@ display: flex; flex-flow: column; + .cp-support-form-attachments { + .fa { + cursor: pointer; + } + &> span { + padding: 10px; + } + } + .cp-support-language-list { .cp-support-language { margin-left: 5px; diff --git a/www/support/ui.js b/www/support/ui.js index e95a8e8cf..e4d60e919 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -66,7 +66,7 @@ define([ var $cat = $form.find('.cp-support-form-category'); var $title = $form.find('.cp-support-form-title'); var $content = $form.find('.cp-support-form-msg'); - var $attachments = $form.find('.cp-support-form-attachments'); + var $attachments = $form.find('.cp-support-attachments'); var category = $cat.val().trim(); @@ -105,10 +105,32 @@ Messages.support_cat_account = "User account"; // XXX Messages.support_cat_data = "Loss of content"; // XXX Messages.support_cat_bug = "Bug report"; // XXX Messages.support_cat_other = "Other"; // XXX +Messages.support_cat_all = "All"; // XXX Messages.support_category = "Category"; // XXX Messages.support_attachments = "Attachments"; // XXX Messages.support_addAttachment = "Add attachment"; // XXX + var makeCategoryDropdown = function (ctx, container, onChange, all) { + var categories = ['account', 'data', 'bug', 'other']; + if (all) { categories.push('all'); } + categories = categories.map(function (key) { + return { + tag: 'a', + content: h('span', Messages['support_cat_'+key]), + action: function () { + onChange(key); + } + }; + }); + var dropdownCfg = { + text: Messages.support_category, + options: categories, + container: $(container), + isSelect: true + }; + return UIElements.createDropdown(dropdownCfg); + }; + var makeForm = function (ctx, cb, title) { var button; @@ -123,23 +145,10 @@ Messages.support_addAttachment = "Add attachment"; // XXX type: 'hidden', value: '' }); - var categories = ['account', 'data', 'bug', 'other'].map(function (key) { - return { - tag: 'a', - content: h('span', Messages['support_cat_'+key]), - action: function () { - $(category).val(key); - } - }; - }); var catContainer = h('div.cp-dropdown-container' + (title ? '.cp-hidden': '')); - var dropdownCfg = { - text: Messages.support_category, - options: categories, - container: $(catContainer), - isSelect: true - }; - var $drop = UIElements.createDropdown(dropdownCfg); + makeCategoryDropdown(ctx, catContainer, function (key) { + $(category).val(key); + }); var attachments, addAttachment; @@ -157,7 +166,7 @@ Messages.support_addAttachment = "Add attachment"; // XXX placeholder: Messages.support_formMessage }), h('label', Messages.support_attachments), - attachments = h('div.cp-support-form-attachments'), + attachments = h('div.cp-support-attachments'), addAttachment = h('button', Messages.support_addAttachment), h('hr'), button, @@ -240,6 +249,7 @@ Messages.support_addAttachment = "Add attachment"; // XXX } var $ticket = $(h('div.cp-support-list-ticket', { + 'data-cat': content.category, 'data-id': content.id }, [ h('h2', [ticketCategory, ticketTitle, url]), @@ -334,7 +344,7 @@ Messages.support_addAttachment = "Add attachment"; // XXX h('span.cp-support-message-time', content.time ? new Date(content.time).toLocaleString() : '') ]), h('pre.cp-support-message-content', content.message), - h('div', attachments), + h('div.cp-support-attachments', attachments), isAdmin ? userData : undefined, ]); }; @@ -382,6 +392,9 @@ Messages.support_addAttachment = "Add attachment"; // XXX ui.makeForm = function (cb, title) { return makeForm(ctx, cb, title); }; + ui.makeCategoryDropdown = function (container, onChange, all) { + return makeCategoryDropdown(ctx, container, onChange, all); + }; ui.makeTicket = function ($div, content, onHide) { return makeTicket(ctx, $div, content, onHide); }; From 07038045f3fc42bea7cb74c1b7fb713430617d91 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 16 Jun 2020 13:24:20 +0200 Subject: [PATCH 09/58] Prompt the user to refresh OO in readonly mode --- www/common/onlyoffice/inner.js | 49 +++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 6f9c74f27..2b10e9916 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -506,6 +506,33 @@ define([ }, to); }; +Messages.oo_refresh = "Refresh"; // XXX read-only corner popup when receiving remote updates + var refreshReadOnly = function () { + var cancel = h('button.cp-corner-cancel', Messages.cancel); + var reload = h('button.cp-corner-primary', [ + h('i.fa.fa-refresh'), + Messages.oo_refresh + ]); + + var actions = h('div', [cancel, reload]); + var m = UI.cornerPopup("out of date", actions, ''); + $(reload).click(function () { + console.error('todo'); + ooChannel.ready = false; + var lastCp = getLastCp(); + loadLastDocument(lastCp, function () { + // On error, do nothing + }, function (blob, type) { + resetData(blob, type); + }); + delete APP.refreshPopup; + m.delete(); + }); + $(cancel).click(function () { + delete APP.refreshPopup; + m.delete(); + }); + }; var openRtChannel = function (cb) { if (rtChannel.ready) { return void cb(); } @@ -529,6 +556,18 @@ define([ break; case 'MESSAGE': if (ooChannel.ready) { + // In read-only mode, push the message to the queue and prompt + // the user to refresh OO (without reloading the page) + if (readOnly) { + ooChannel.queue.push(obj.data); + if (APP.refreshPopup) { return; } + APP.refreshPopup = true; + + // Don't "spam" the user instantly and no more than + // 1 popup every 30s + setTimeout(refreshReadOnly, 30000); + return; + } ooChannel.send(obj.data.msg); ooChannel.lastHash = obj.data.hash; ooChannel.cpIndex++; @@ -986,8 +1025,10 @@ define([ ooChannel.queue.forEach(function (data) { ooChannel.send(data.msg); }); - var last = ooChannel.queue.pop(); - if (last) { ooChannel.lastHash = last.hash; } + if (!readOnly) { + var last = ooChannel.queue.pop(); + if (last) { ooChannel.lastHash = last.hash; } + } ooChannel.cpIndex += ooChannel.queue.length; // Apply existing locks deleteOfflineLocks(); @@ -1018,7 +1059,7 @@ define([ UI.openCustomModal(UI.dialog.customModal(div, {buttons: []})); setTimeout(function () { makeCheckpoint(true); - }, 1000); + }, 5000); } } } @@ -1788,10 +1829,10 @@ define([ var latest = getLastCp(true); var newLatest = getLastCp(); if (newLatest.index > latest.index) { + ooChannel.queue = []; var hasDrawings = checkDrawings(); if (hasDrawings) { ooChannel.ready = false; - ooChannel.queue = []; } // New checkpoint sframeChan.query('Q_OO_SAVE', { From 38c3d05f9483897f0abc51111cb432f88045eb2a Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 17 Jun 2020 15:43:33 +0200 Subject: [PATCH 10/58] Fix refresh issue with no cp in readonly onlyoffice --- www/common/onlyoffice/inner.js | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 2b10e9916..93a49e892 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -122,7 +122,6 @@ define([ if (!state && !readOnly) { $('#cp-app-oo-editor').append(h('div#cp-app-oo-offline')); } - debug(state); }; var deleteOffline = function () { @@ -507,6 +506,7 @@ define([ }; Messages.oo_refresh = "Refresh"; // XXX read-only corner popup when receiving remote updates +Messages.oo_refreshText = "out of date"; // XXX read-only corner popup when receiving remote updates var refreshReadOnly = function () { var cancel = h('button.cp-corner-cancel', Messages.cancel); var reload = h('button.cp-corner-primary', [ @@ -515,15 +515,17 @@ Messages.oo_refresh = "Refresh"; // XXX read-only corner popup when receiving re ]); var actions = h('div', [cancel, reload]); - var m = UI.cornerPopup("out of date", actions, ''); + var m = UI.cornerPopup(Messages.oo_refreshText, actions, ''); $(reload).click(function () { - console.error('todo'); ooChannel.ready = false; var lastCp = getLastCp(); loadLastDocument(lastCp, function () { - // On error, do nothing - }, function (blob, type) { - resetData(blob, type); + var file = getFileType(); + var type = common.getMetadataMgr().getPrivateData().ooType; + var blob = loadInitDocument(type, true); + resetData(blob, file); + }, function (blob, file) { + resetData(blob, file); }); delete APP.refreshPopup; m.delete(); @@ -1488,6 +1490,23 @@ Messages.oo_refresh = "Refresh"; // XXX read-only corner popup when receiving re }, 100); }; + var loadInitDocument = function (type, useNewDefault) { + var newText; + switch (type) { + case 'sheet' : + newText = EmptyCell(useNewDefault); + break; + case 'oodoc': + newText = EmptyDoc(); + break; + case 'ooslide': + newText = EmptySlide(); + break; + default: + newText = ''; + } + return new Blob([newText], {type: 'text/plain'}); + }; var loadLastDocument = function (lastCp, onCpError, cb) { ooChannel.cpIndex = lastCp.index || 0; var parsed = Hash.parsePadUrl(lastCp.file); @@ -1552,7 +1571,7 @@ Messages.oo_refresh = "Refresh"; // XXX read-only corner popup when receiving re default: newText = ''; } - var blob = new Blob([newText], {type: 'text/plain'}); + var blob = loadInitDocument(type, useNewDefault); startOO(blob, file); }; From 89f1320ee3ba6ac29a24c13ad0db8839e69f3480 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 17 Jun 2020 15:45:13 +0200 Subject: [PATCH 11/58] lint compliance --- www/common/onlyoffice/inner.js | 105 +++++++++++++++++---------------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 93a49e892..7534b552b 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -505,6 +505,59 @@ define([ }, to); }; + var loadInitDocument = function (type, useNewDefault) { + var newText; + switch (type) { + case 'sheet' : + newText = EmptyCell(useNewDefault); + break; + case 'oodoc': + newText = EmptyDoc(); + break; + case 'ooslide': + newText = EmptySlide(); + break; + default: + newText = ''; + } + return new Blob([newText], {type: 'text/plain'}); + }; + var loadLastDocument = function (lastCp, onCpError, cb) { + ooChannel.cpIndex = lastCp.index || 0; + var parsed = Hash.parsePadUrl(lastCp.file); + var secret = Hash.getSecrets('file', parsed.hash); + if (!secret || !secret.channel) { return; } + var hexFileName = secret.channel; + var fileHost = privateData.fileHost || privateData.origin; + var src = fileHost + Hash.getBlobPathFromHex(hexFileName); + var key = secret.keys && secret.keys.cryptKey; + var xhr = new XMLHttpRequest(); + xhr.open('GET', src, true); + xhr.responseType = 'arraybuffer'; + xhr.onload = function () { + if (/^4/.test('' + this.status)) { + onCpError(); + return void console.error('XHR error', this.status); + } + var arrayBuffer = xhr.response; + if (arrayBuffer) { + var u8 = new Uint8Array(arrayBuffer); + FileCrypto.decrypt(u8, key, function (err, decrypted) { + if (err) { return void console.error(err); } + var blob = new Blob([decrypted.content], {type: 'plain/text'}); + if (cb) { + return cb(blob, getFileType()); + } + startOO(blob, getFileType()); + }); + } + }; + xhr.onerror = function () { + onCpError(); + }; + xhr.send(null); + }; + Messages.oo_refresh = "Refresh"; // XXX read-only corner popup when receiving remote updates Messages.oo_refreshText = "out of date"; // XXX read-only corner popup when receiving remote updates var refreshReadOnly = function () { @@ -1490,58 +1543,6 @@ Messages.oo_refreshText = "out of date"; // XXX read-only corner popup when rece }, 100); }; - var loadInitDocument = function (type, useNewDefault) { - var newText; - switch (type) { - case 'sheet' : - newText = EmptyCell(useNewDefault); - break; - case 'oodoc': - newText = EmptyDoc(); - break; - case 'ooslide': - newText = EmptySlide(); - break; - default: - newText = ''; - } - return new Blob([newText], {type: 'text/plain'}); - }; - var loadLastDocument = function (lastCp, onCpError, cb) { - ooChannel.cpIndex = lastCp.index || 0; - var parsed = Hash.parsePadUrl(lastCp.file); - var secret = Hash.getSecrets('file', parsed.hash); - if (!secret || !secret.channel) { return; } - var hexFileName = secret.channel; - var fileHost = privateData.fileHost || privateData.origin; - var src = fileHost + Hash.getBlobPathFromHex(hexFileName); - var key = secret.keys && secret.keys.cryptKey; - var xhr = new XMLHttpRequest(); - xhr.open('GET', src, true); - xhr.responseType = 'arraybuffer'; - xhr.onload = function () { - if (/^4/.test('' + this.status)) { - onCpError(); - return void console.error('XHR error', this.status); - } - var arrayBuffer = xhr.response; - if (arrayBuffer) { - var u8 = new Uint8Array(arrayBuffer); - FileCrypto.decrypt(u8, key, function (err, decrypted) { - if (err) { return void console.error(err); } - var blob = new Blob([decrypted.content], {type: 'plain/text'}); - if (cb) { - return cb(blob, getFileType()); - } - startOO(blob, getFileType()); - }); - } - }; - xhr.onerror = function () { - onCpError(); - }; - xhr.send(null); - }; var loadDocument = function (noCp, useNewDefault, i) { if (ooLoaded) { return; } var type = common.getMetadataMgr().getPrivateData().ooType; From 62dabc0afc15e39b55c79639a5d8e66d1ff8acce Mon Sep 17 00:00:00 2001 From: ansuz Date: Wed, 17 Jun 2020 10:20:03 -0400 Subject: [PATCH 12/58] add some XXX notes to address before the next release --- www/support/ui.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/www/support/ui.js b/www/support/ui.js index e4d60e919..7449e2e07 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -66,10 +66,11 @@ define([ var $cat = $form.find('.cp-support-form-category'); var $title = $form.find('.cp-support-form-title'); var $content = $form.find('.cp-support-form-msg'); + // XXX block submission until pending uploads are complete? var $attachments = $form.find('.cp-support-attachments'); - var category = $cat.val().trim(); + var category = $cat.val().trim(); // XXX make category a required field? var title = $title.val().trim(); if (!title) { return void UI.alert(Messages.support_formTitleError); @@ -182,6 +183,8 @@ Messages.support_addAttachment = "Add attachment"; // XXX }).on('change', function (e) { var files = Util.slice(e.target.files); files.forEach(function (file) { + // XXX validate that the href is hosted on the same instance + // use relative URLs or compare it against a list or allowed domains? var ev = {}; ev.callback = function (data) { var x, a; @@ -324,6 +327,7 @@ Messages.support_addAttachment = "Add attachment"; // XXX var a = h('a', { href: '#' }, obj.name) + // XXX disallow remote URLs $(a).click(function (e) { e.preventDefault(); ctx.common.openURL(obj.href); From f5c710e80ae639182c9360550fd652f6489a6318 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 18 Jun 2020 06:58:28 -0400 Subject: [PATCH 13/58] lint compliance --- www/support/ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/support/ui.js b/www/support/ui.js index 7449e2e07..8451cf55c 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -326,7 +326,7 @@ Messages.support_addAttachment = "Add attachment"; // XXX if (!obj || !obj.name || !obj.href) { return; } var a = h('a', { href: '#' - }, obj.name) + }, obj.name); // XXX disallow remote URLs $(a).click(function (e) { e.preventDefault(); From e12d8c5b70f3a18f45fa1d218b11b328ef777347 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 18 Jun 2020 15:30:55 +0200 Subject: [PATCH 14/58] Fix issues with the new support form --- www/support/ui.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/www/support/ui.js b/www/support/ui.js index 8451cf55c..914862fab 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -91,6 +91,7 @@ define([ name: $el.attr('data-name') }); }); + $attachments.html(''); send(ctx, id, 'TICKET', { category: category, @@ -207,7 +208,8 @@ Messages.support_addAttachment = "Add attachment"; // XXX $(attachments).append(span); }; - ctx.FM.handleFile(file, ev); + // The empty object allows us to bypass the file upload modal + ctx.FM.handleFile(file, ev, {}); }); }); $input.click(); From f686cd645fbe2839e0f7b73ad189d72a11737ab8 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 18 Jun 2020 15:33:13 +0200 Subject: [PATCH 15/58] Update category for old tickets --- www/support/ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/support/ui.js b/www/support/ui.js index 914862fab..c099634b7 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -244,7 +244,7 @@ Messages.support_addAttachment = "Add attachment"; // XXX var url; if (ctx.isAdmin) { - ticketCategory = Messages['support_cat_'+(content.category || 'other')] + ' - '; + ticketCategory = Messages['support_cat_'+(content.category || 'all')] + ' - '; url = h('button.btn.btn-primary.fa.fa-clipboard'); $(url).click(function () { var link = privateData.origin + privateData.pathname + '#' + 'support-' + content.id; From e69e892978bab258f1b9e1ac777030dfcf13dbde Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 18 Jun 2020 16:09:46 +0200 Subject: [PATCH 16/58] Fix ctrl+A in the drive --- www/common/drive-ui.js | 1 + 1 file changed, 1 insertion(+) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 93c36597a..184038d79 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -944,6 +944,7 @@ define([ // Ctrl+A select all if (e.which === 65 && (e.ctrlKey || (e.metaKey && APP.isMac))) { + e.preventDefault(); $content.find('.cp-app-drive-element:not(.cp-app-drive-element-selected)') .each(function (idx, element) { selectElement($(element)); From 145275c9692e32585977deb5c6de29ca73a36a2b Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 18 Jun 2020 11:13:05 -0400 Subject: [PATCH 17/58] remove a translation that is no longer used --- www/common/translations/messages.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.json b/www/common/translations/messages.json index 5cad912da..2fcf5db4f 100644 --- a/www/common/translations/messages.json +++ b/www/common/translations/messages.json @@ -151,7 +151,6 @@ "or": "or", "tags_title": "Tags (for you only)", "tags_add": "Update the tags for selected pads", - "tags_searchHint": "Start a search with # in your CryptDrive to find your tagged pads.", "tags_notShared": "Your tags are not shared with other users", "tags_duplicate": "Duplicate tag: {0}", "tags_noentry": "You can't tag a deleted pad!", From 53a5e0c1e7d4b1908a4f12fb093f3a516b49e7ac Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 18 Jun 2020 17:13:36 +0200 Subject: [PATCH 18/58] Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ --- www/common/translations/messages.ca.json | 1 - www/common/translations/messages.de.json | 1 - www/common/translations/messages.el.json | 1 - www/common/translations/messages.es.json | 1 - www/common/translations/messages.fi.json | 1 - www/common/translations/messages.fr.json | 1 - www/common/translations/messages.it.json | 1 - www/common/translations/messages.nb.json | 1 - www/common/translations/messages.nl.json | 1 - www/common/translations/messages.pt-br.json | 1 - www/common/translations/messages.ro.json | 1 - www/common/translations/messages.ru.json | 1 - www/common/translations/messages.sv.json | 1 - 13 files changed, 13 deletions(-) diff --git a/www/common/translations/messages.ca.json b/www/common/translations/messages.ca.json index a10a9fffd..7bff4cb27 100644 --- a/www/common/translations/messages.ca.json +++ b/www/common/translations/messages.ca.json @@ -148,7 +148,6 @@ "or": "o", "tags_title": "Etiquetes (només vostres)", "tags_add": "Actualitza les etiquetes d'aquesta pàgina", - "tags_searchHint": "Inicieu una cerca amb # al vostre CryptDrive per trobar els vostres documents etiquetats.", "tags_notShared": "Les vostres etiquetes no es comparteixen amb altres persones usuàries", "tags_duplicate": "Etiquetes duplicades: {0}", "tags_noentry": "No podeu etiquetar un document esborrat!", diff --git a/www/common/translations/messages.de.json b/www/common/translations/messages.de.json index 0ed8f0f91..e792c6cc8 100644 --- a/www/common/translations/messages.de.json +++ b/www/common/translations/messages.de.json @@ -146,7 +146,6 @@ "or": "oder", "tags_title": "Tags (nur für dich)", "tags_add": "Tags der ausgewählten Pads bearbeiten", - "tags_searchHint": "Beginne die Suche in deinem CryptDrive mit #, um getaggte Dokumente zu finden.", "tags_notShared": "Deine Tags werden nicht mit anderen Benutzern geteilt", "tags_duplicate": "Doppeltes Tag: {0}", "tags_noentry": "Du kannst keine Tags zu einem gelöschten Pad hinzufügen!", diff --git a/www/common/translations/messages.el.json b/www/common/translations/messages.el.json index 5f3f455c1..406a445f2 100644 --- a/www/common/translations/messages.el.json +++ b/www/common/translations/messages.el.json @@ -119,7 +119,6 @@ "or": "ή", "tags_title": "Ετικέτες (για εσάς μόνο)", "tags_add": "Ενημερώστε τις ετικέτες αυτής της σελίδας", - "tags_searchHint": "Ξεκινήστε μια αναζήτηση με το σύμβολο # στο CryptDrive σας για να βρείτε pads με ετικέτες.", "tags_notShared": "Οι ετικέτες σας δεν μοιράζονται με άλλους χρήστες", "tags_duplicate": "Διπλή ετικέτα: {0}", "tags_noentry": "Δεν μπορείτε να βάλετε ετικέτα σε διεγραμένο pad!", diff --git a/www/common/translations/messages.es.json b/www/common/translations/messages.es.json index 83ccb01e5..bc526986d 100644 --- a/www/common/translations/messages.es.json +++ b/www/common/translations/messages.es.json @@ -472,7 +472,6 @@ "printBackgroundRemove": "Eliminar este fondo de pantalla", "tags_title": "Etiquetas (sólo para tí)", "tags_add": "Actualizar las etiquetas de esta página", - "tags_searchHint": "Comenzar una búsqueda con # en tú CryptDrive para encontrar las notas etiquetadas.", "tags_notShared": "Tus etiquetas no están compartidas con otros usuarios", "tags_duplicate": "Duplicar etiquetas:{0}", "tags_noentry": "No puedes etiquetar una nota eliminada!", diff --git a/www/common/translations/messages.fi.json b/www/common/translations/messages.fi.json index 8a4e36139..0022dc74c 100644 --- a/www/common/translations/messages.fi.json +++ b/www/common/translations/messages.fi.json @@ -151,7 +151,6 @@ "or": "tai", "tags_title": "Tunnisteet (vain sinulle)", "tags_add": "Päivitä sivun tunnisteet", - "tags_searchHint": "Aloita hakusi CryptDrivessa #-merkillä löytääksesi tunnisteita sisältävät padit.", "tags_notShared": "Tunnisteitasi ei jaeta muiden käyttäjien kanssa", "tags_duplicate": "Kaksinkertainen tunniste: {0}", "tags_noentry": "Et voi lisätä tunnistetta poistettuun padiin!", diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json index f38f3f5ef..77e81fcf5 100644 --- a/www/common/translations/messages.fr.json +++ b/www/common/translations/messages.fr.json @@ -148,7 +148,6 @@ "or": "ou", "tags_title": "Mots-clés du pad (pour vous uniquement)", "tags_add": "Modifier les mots-clés de la sélection", - "tags_searchHint": "Commencez une recherche par # dans votre CryptDrive pour retrouver vos pads par mot-clé.", "tags_notShared": "Vos mots-clés ne sont pas partagés avec les autres utilisateurs", "tags_duplicate": "Mot-clé déjà présent : {0}", "tags_noentry": "Vous ne pouvez pas ajouter de mots-clés à un pad supprimé !", diff --git a/www/common/translations/messages.it.json b/www/common/translations/messages.it.json index 16fca3d13..5c654c94d 100644 --- a/www/common/translations/messages.it.json +++ b/www/common/translations/messages.it.json @@ -148,7 +148,6 @@ "or": "o", "tags_title": "Tag (mostrati solo a te)", "tags_add": "Aggiorna i tag di questa pagina", - "tags_searchHint": "Inizia una ricerca con # nel tuo CryptDrive per trovare i pad taggati.", "tags_notShared": "I tuoi tag non sono condivisi con altri utenti", "tags_duplicate": "Duplica tag: {0}", "tags_noentry": "Non puoi taggare un pad eliminato!", diff --git a/www/common/translations/messages.nb.json b/www/common/translations/messages.nb.json index 881bcc8df..5a59a7829 100644 --- a/www/common/translations/messages.nb.json +++ b/www/common/translations/messages.nb.json @@ -140,7 +140,6 @@ "or": "eller", "tags_title": "Tags (kun for ditt bruk)", "tags_add": "Oppdater tags for denne sida", - "tags_searchHint": "Søk med # i CryptDriven din for å finne pads med slike tags.", "tags_notShared": "Dine tags deles ikke med andre brukerer", "tags_duplicate": "Dupliser tag:{0}", "tags_noentry": "Du kan ikke tagge en sletta pad!", diff --git a/www/common/translations/messages.nl.json b/www/common/translations/messages.nl.json index e2da9e201..124e3dc0c 100644 --- a/www/common/translations/messages.nl.json +++ b/www/common/translations/messages.nl.json @@ -74,7 +74,6 @@ "tags_noentry": "U kunt een verwijderde werkomgeving niet markeren!", "tags_duplicate": "Gedupliceerde markering: {0}", "tags_notShared": "Uw markeringen worden niet gedeeld met andere gebruikers", - "tags_searchHint": "Begin een zoekopdracht met # in uw CryptDrive om gemarkeerde werkomgevingen te vinden.", "tags_add": "Werk de markeringen van deze pagina bij", "tags_title": "Markeringen (alleen voor u)", "or": "of", diff --git a/www/common/translations/messages.pt-br.json b/www/common/translations/messages.pt-br.json index f0747694d..e10f3e3c7 100644 --- a/www/common/translations/messages.pt-br.json +++ b/www/common/translations/messages.pt-br.json @@ -392,7 +392,6 @@ "or": "", "tags_title": "", "tags_add": "", - "tags_searchHint": "", "tags_notShared": "", "tags_duplicate": "", "tags_noentry": "", diff --git a/www/common/translations/messages.ro.json b/www/common/translations/messages.ro.json index 190f3250a..14c4aefe0 100644 --- a/www/common/translations/messages.ro.json +++ b/www/common/translations/messages.ro.json @@ -382,7 +382,6 @@ "or": "sau", "tags_title": "Etichete (doar pentru tine)", "tags_add": "Updatează etichetele acestei pagini", - "tags_searchHint": "Începe o căutare cu # în CryptDrive-ul tău pentru a găsi pad-uri etichetate", "tags_notShared": "Etichetele tale nu sunt împărțite cu alți utilizatori", "tags_duplicate": "Duplică eticheta: {0}", "tags_noentry": "Nu poți eticheta un pad șters", diff --git a/www/common/translations/messages.ru.json b/www/common/translations/messages.ru.json index 865394b94..b0b1dbe1b 100644 --- a/www/common/translations/messages.ru.json +++ b/www/common/translations/messages.ru.json @@ -140,7 +140,6 @@ "or": "или", "tags_title": "Теги (только для вас)", "tags_add": "Обновить теги страницы", - "tags_searchHint": "Начните поиск в вашем CryptDrive при помощи # чтобы найти пэды с тегами.", "tags_notShared": "Ваши теги не разделяются с другими пользователями", "button_newsheet": "Новый Лист", "newButtonTitle": "создать новую запись", diff --git a/www/common/translations/messages.sv.json b/www/common/translations/messages.sv.json index 85a199284..8876beebf 100644 --- a/www/common/translations/messages.sv.json +++ b/www/common/translations/messages.sv.json @@ -38,7 +38,6 @@ "tags_noentry": "Du kan inte tagga ett raderat dokument!", "tags_duplicate": "Duplicera tagg: {0}", "tags_notShared": "Dina taggar är inte delade med andra användare", - "tags_searchHint": "Påbörja en sökning med # i din CryptDrive för att hitta dina taggade dokument.", "tags_add": "Uppdatera taggar för denna sida", "tags_title": "Taggar (endast för dig)", "or": "eller", From a25d3fcf4cdc626293fd7ae0799f54b4ebcf5b81 Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 18 Jun 2020 21:02:55 +0200 Subject: [PATCH 19/58] Translated using Weblate (English) Currently translated at 100.0% (1295 of 1295 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1294 of 1294 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1293 of 1293 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1292 of 1292 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1291 of 1291 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1290 of 1290 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1289 of 1289 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1288 of 1288 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1287 of 1287 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1286 of 1286 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1285 of 1285 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ --- www/common/translations/messages.json | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/www/common/translations/messages.json b/www/common/translations/messages.json index 2fcf5db4f..50ca92b93 100644 --- a/www/common/translations/messages.json +++ b/www/common/translations/messages.json @@ -1187,7 +1187,7 @@ "team_rosterPromote": "Promote", "team_rosterDemote": "Demote", "team_rosterKick": "Kick from the team", - "team_inviteButton": "Invite contacts", + "team_inviteButton": "Invite members", "team_leaveButton": "Leave this team", "team_leaveConfirm": "If you leave this team you will lose access to its CryptDrive, chat history, and other contents. Are you sure?", "team_owner": "Owners", @@ -1381,5 +1381,15 @@ "settings_safeLinkDefault": "Safe Links are now turned on by default. Please use the Share menu to copy links rather than your browser's address bar.", "info_imprintFlavour": "Legal information about the administrators of this instance.", "user_about": "About CryptPad", - "info_privacyFlavour": "Our privacy policy describes how we treat your data." + "info_privacyFlavour": "Our privacy policy describes how we treat your data.", + "support_cat_account": "User account", + "support_cat_data": "Loss of content", + "support_cat_bug": "Bug report", + "support_cat_other": "Other", + "support_cat_all": "All", + "support_attachments": "Attachments", + "support_addAttachment": "Add attachment", + "notification_padSharedTeam": "{0} has shared a pad with the team {2}: {1}", + "notification_fileSharedTeam": "{0} has shared a file with the team {2}: {1}", + "notification_folderSharedTeam": "{0} has shared a pad with the team {2}: {1}" } From 1b504731f293156317bd28a94ea24f4b8fd4d8e9 Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 18 Jun 2020 21:02:56 +0200 Subject: [PATCH 20/58] Translated using Weblate (French) Currently translated at 100.0% (1285 of 1285 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/fr/ --- www/common/translations/messages.fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json index 77e81fcf5..3a4536b1c 100644 --- a/www/common/translations/messages.fr.json +++ b/www/common/translations/messages.fr.json @@ -1183,7 +1183,7 @@ "team_rosterPromote": "Promouvoir", "team_rosterDemote": "Rétrograder", "team_rosterKick": "Expulser de l'équipe", - "team_inviteButton": "Inviter des contacts", + "team_inviteButton": "Inviter des membres", "team_leaveButton": "Quitter cette équipe", "team_leaveConfirm": "Si vous quittez cette équipe, vous perdrez l'accès à son CryptDrive, son chat et les autres contenus. Êtes-vous sûr ?", "team_owner": "Propriétaires", From 0afa6b79ae81b590bbdda7658aed6693f842239a Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 18 Jun 2020 15:09:29 -0400 Subject: [PATCH 21/58] remove most pending hardcoded translations --- www/common/notifications.js | 5 ----- www/support/ui.js | 7 ------- 2 files changed, 12 deletions(-) diff --git a/www/common/notifications.js b/www/common/notifications.js index 57ac38f8b..d1fbbaff9 100644 --- a/www/common/notifications.js +++ b/www/common/notifications.js @@ -83,11 +83,6 @@ define([ }; // Share pad - - Messages.notification_padSharedTeam = "{0} has shared a pad with the team {2}: {1}"; // XXX - Messages.notification_fileSharedTeam = "{0} has shared a file with the team {2}: {1}"; // XXX - Messages.notification_folderSharedTeam = "{0} has shared a pad with the team {2}: {1}"; // XXX - handlers['SHARE_PAD'] = function(common, data) { var content = data.content; var msg = content.msg; diff --git a/www/support/ui.js b/www/support/ui.js index c099634b7..30d98f389 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -103,14 +103,7 @@ define([ return true; }; -Messages.support_cat_account = "User account"; // XXX -Messages.support_cat_data = "Loss of content"; // XXX -Messages.support_cat_bug = "Bug report"; // XXX -Messages.support_cat_other = "Other"; // XXX -Messages.support_cat_all = "All"; // XXX Messages.support_category = "Category"; // XXX -Messages.support_attachments = "Attachments"; // XXX -Messages.support_addAttachment = "Add attachment"; // XXX var makeCategoryDropdown = function (ctx, container, onChange, all) { var categories = ['account', 'data', 'bug', 'other']; From 009ac1cc9b4e4d5fe15e251f89c14bdd595e29f7 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 18 Jun 2020 15:24:32 -0400 Subject: [PATCH 22/58] leave a note about the timing of 'refresh reminders' --- www/common/onlyoffice/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 7534b552b..a995752fb 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -55,7 +55,7 @@ define([ var CHECKPOINT_INTERVAL = 100; var DISPLAY_RESTORE_BUTTON = false; var NEW_VERSION = 2; - var PENDING_TIMEOUT = 30000; + var PENDING_TIMEOUT = 30000; // XXX it feels like maybe this should be shorter var debug = function (x) { if (!window.CP_DEV_MODE) { return; } From dcf7d60332ca6e450f7d0d8c15c30b5238bec70d Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 18 Jun 2020 15:24:58 -0400 Subject: [PATCH 23/58] fix unreadable team chat input text color --- www/teams/app-team.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/teams/app-team.less b/www/teams/app-team.less index c59d0dcb9..abd46d121 100644 --- a/www/teams/app-team.less +++ b/www/teams/app-team.less @@ -45,7 +45,7 @@ .cp-app-contacts-input { textarea { border: 0px; - color: white; + color: @cryptpad_text_col; } } } From 58a8705f5018829fa92d833f0030f7002ac64482 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 18 Jun 2020 15:24:58 -0400 Subject: [PATCH 24/58] fix unreadable team chat input text color --- www/teams/app-team.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/teams/app-team.less b/www/teams/app-team.less index c59d0dcb9..abd46d121 100644 --- a/www/teams/app-team.less +++ b/www/teams/app-team.less @@ -45,7 +45,7 @@ .cp-app-contacts-input { textarea { border: 0px; - color: white; + color: @cryptpad_text_col; } } } From a2254fa6f709cf91f9f7d15c0917cd888215a915 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 18 Jun 2020 15:24:58 -0400 Subject: [PATCH 25/58] fix unreadable team chat input text color --- www/teams/app-team.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/teams/app-team.less b/www/teams/app-team.less index c59d0dcb9..abd46d121 100644 --- a/www/teams/app-team.less +++ b/www/teams/app-team.less @@ -45,7 +45,7 @@ .cp-app-contacts-input { textarea { border: 0px; - color: white; + color: @cryptpad_text_col; } } } From 3f75b299a0a71b9f4f3af9c982c2c10e20fdf079 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 19 Jun 2020 14:41:53 +0200 Subject: [PATCH 26/58] Fix stuck ownership modal when the pad has been deleted --- www/common/common-ui-elements.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index abf98aa17..2b8e42790 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -3544,6 +3544,11 @@ define([ link ]); + var dismiss = function () { + common.mailbox.dismiss(data, function (err) { + console.log(err); + }); + }; var answer = function (yes) { common.mailbox.sendTo("ADD_OWNER_ANSWER", { channel: msg.content.channel, @@ -3555,9 +3560,7 @@ define([ channel: msg.content.user.notifications, curvePublic: msg.content.user.curvePublic }); - common.mailbox.dismiss(data, function (err) { - console.log(err); - }); + dismiss(); }; var todo = function (yes) { @@ -3572,6 +3575,8 @@ define([ if (err) { var text = err === "INSUFFICIENT_PERMISSIONS" ? Messages.fm_forbidden : Messages.error; + console.error(err); + dismiss(); return void UI.warn(text); } UI.log(Messages.saved); From fd4e1b98492673c5caaa4a69d0e7471f9d3fb3cd Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 19 Jun 2020 14:53:26 +0200 Subject: [PATCH 27/58] Fix tag prompt shortcuts --- www/common/common-interface.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/www/common/common-interface.js b/www/common/common-interface.js index 4eba3755c..870b33c74 100644 --- a/www/common/common-interface.js +++ b/www/common/common-interface.js @@ -356,11 +356,15 @@ define([ var $cancel = findCancelButton(tagger).click(function (e) { close(null, e); }); - listener = listenForKeys(function () { - $ok.click(); - }, function () { - $cancel.click(); - }, tagger); + $(tagger).on('keydown', function (e) { + if (e.which === 27) { + $cancel.click(); + return; + } + if (e.which === 13) { + $ok.click(); + } + }); $(tagger).on('click submit', function (e) { e.stopPropagation(); From 2a0aa78d0c98aa2c7d71e17bebe4d48237f371db Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 19 Jun 2020 15:46:08 +0200 Subject: [PATCH 28/58] Fix folder download in drive --- www/common/drive-ui.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 184038d79..cd3759d8d 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -4182,7 +4182,8 @@ define([ if (!manager.isSharedFolder(el)) { name = path.path[path.path.length - 1]; folderEl = el; - downloadFolder(folderEl, name); + var sfId = manager.isInSharedFolder(path.path); + downloadFolder(folderEl, name, sfId); } // shared folder else { From 70a4b3bdf21397ec798da09a9b8f78701ded0002 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 19 Jun 2020 15:53:29 +0200 Subject: [PATCH 29/58] Stop using previous values in pad creation screen --- www/common/common-ui-elements.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 2b8e42790..7d829bdb0 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -2856,6 +2856,7 @@ define([ }); }; + /* UIElements.setExpirationValue = function (val, $expire) { if (val && typeof (val) === "number") { $expire.find('#cp-creation-expire').attr('checked', true).trigger('change'); @@ -2879,6 +2880,7 @@ define([ $expire.find('#cp-creation-expire-false').attr('checked', true); } }; + */ UIElements.getPadCreationScreen = function (common, cfg, appCfg, cb) { appCfg = appCfg || {}; if (!common.isLoggedIn()) { return void cb(); } @@ -3191,10 +3193,12 @@ define([ // Initial values + /* if (!cfg.owned && typeof cfg.owned !== "undefined") { $creation.find('#cp-creation-owned').prop('checked', false); } UIElements.setExpirationValue(cfg.expire, $creation); + */ // Create the pad var getFormValues = function () { From 7245123061e5ca27446fb67f1fd6bd9aa396fa1b Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 19 Jun 2020 17:06:25 +0200 Subject: [PATCH 30/58] Refactor buttons.less --- customize.dist/src/less2/include/alertify.less | 2 -- customize.dist/src/less2/include/comments.less | 3 --- .../src/less2/include/{buttons.less => forms.less} | 4 ++-- customize.dist/src/less2/include/framework.less | 3 +++ customize.dist/src/less2/include/modal.less | 5 ----- customize.dist/src/less2/include/sidebar-layout.less | 2 -- www/common/common-interface.js | 5 +++-- www/common/inner/access.js | 2 +- www/common/sframe-app-framework.js | 1 + www/contacts/app-contacts.less | 6 ------ www/kanban/app-kanban.less | 2 -- www/pad/app-pad.less | 2 -- www/secureiframe/app-secure.less | 2 ++ www/whiteboard/app-whiteboard.less | 3 --- 14 files changed, 12 insertions(+), 30 deletions(-) rename customize.dist/src/less2/include/{buttons.less => forms.less} (98%) diff --git a/customize.dist/src/less2/include/alertify.less b/customize.dist/src/less2/include/alertify.less index f9c63215c..2a7fd3761 100644 --- a/customize.dist/src/less2/include/alertify.less +++ b/customize.dist/src/less2/include/alertify.less @@ -3,7 +3,6 @@ @import (reference) "./variables.less"; @import (reference) "./avatar.less"; @import (reference) "./tools.less"; -@import (reference) "./buttons.less"; .alertify_main() { --LessLoader_require: LessLoader_currentFile(); @@ -272,7 +271,6 @@ } } - .buttons_main(); input:not(.form-control), textarea { margin-bottom: 15px; } diff --git a/customize.dist/src/less2/include/comments.less b/customize.dist/src/less2/include/comments.less index becc56f54..479609580 100644 --- a/customize.dist/src/less2/include/comments.less +++ b/customize.dist/src/less2/include/comments.less @@ -1,7 +1,6 @@ @import (reference) "./colortheme-all.less"; @import (reference) "./variables.less"; @import (reference) "./avatar.less"; -@import (reference) "./buttons.less"; @import (reference) "./tools.less"; .comments_main() { @@ -22,8 +21,6 @@ } - .buttons_main(); - .cp-comment-reply { margin-left: 30px; } diff --git a/customize.dist/src/less2/include/buttons.less b/customize.dist/src/less2/include/forms.less similarity index 98% rename from customize.dist/src/less2/include/buttons.less rename to customize.dist/src/less2/include/forms.less index 87fe9b050..7663bee51 100644 --- a/customize.dist/src/less2/include/buttons.less +++ b/customize.dist/src/less2/include/forms.less @@ -1,7 +1,7 @@ @import (reference) "./colortheme-all.less"; @import (reference) "./variables.less"; -.buttons_main() { +.forms_main() { @alertify-fore: @colortheme_modal-fg; @alertify-btn-fg: @alertify-fore; @alertify-light-bg: fade(@alertify-fore, 25%); @@ -83,7 +83,7 @@ margin-bottom: 3px !important; } - button:not(.pure-button):not(.md-button):not(.mdl-button) { + button.btn { background-color: @colortheme_alertify-cancel; box-sizing: border-box; diff --git a/customize.dist/src/less2/include/framework.less b/customize.dist/src/less2/include/framework.less index 94532d5c7..c698b91b9 100644 --- a/customize.dist/src/less2/include/framework.less +++ b/customize.dist/src/less2/include/framework.less @@ -16,6 +16,7 @@ @import (reference) "./cursor.less"; @import (reference) "./usergrid.less"; @import (reference) "./mentions.less"; +@import (reference) "./forms.less"; @import (reference) "./modals-ui-elements.less"; .framework_main(@bg-color, @warn-color, @color) { @@ -48,6 +49,7 @@ ); .cursor_main(); .usergrid_main(); + .forms_main(); .mentions_main(); .creation_main( @bg-color: @bg-color, @@ -84,6 +86,7 @@ .checkmark_main(20px); .password_main(); .usergrid_main(); + .forms_main(); font: @colortheme_app-font; } diff --git a/customize.dist/src/less2/include/modal.less b/customize.dist/src/less2/include/modal.less index 12d3c908c..8ed10a1b2 100644 --- a/customize.dist/src/less2/include/modal.less +++ b/customize.dist/src/less2/include/modal.less @@ -1,8 +1,5 @@ @import (reference) "./colortheme-all.less"; @import (reference) "./variables.less"; -@import (reference) './buttons.less'; - - .modal_base() { font-family: @colortheme_font; @@ -39,8 +36,6 @@ background-color: @colortheme_modal-dim; .cp-modal { - .buttons_main(); - background-color: @colortheme_modal-bg; color: @colortheme_modal-fg; box-shadow: @variables_shadow; diff --git a/customize.dist/src/less2/include/sidebar-layout.less b/customize.dist/src/less2/include/sidebar-layout.less index 7961e1bee..ace7350df 100644 --- a/customize.dist/src/less2/include/sidebar-layout.less +++ b/customize.dist/src/less2/include/sidebar-layout.less @@ -1,6 +1,5 @@ @import (reference) "/customize/src/less2/include/colortheme-all.less"; @import (reference) "/customize/src/less2/include/leftside-menu.less"; -@import (reference) "/customize/src/less2/include/buttons.less"; @import (reference) "/customize/src/less2/include/browser.less"; @sidebar_button-width: 400px; @@ -98,7 +97,6 @@ } } margin-bottom: 20px; - .buttons_main(); } [type="text"], [type="password"], button { vertical-align: middle; diff --git a/www/common/common-interface.js b/www/common/common-interface.js index 870b33c74..601375b96 100644 --- a/www/common/common-interface.js +++ b/www/common/common-interface.js @@ -145,12 +145,12 @@ define([ }; dialog.okButton = function (content, classString) { - var sel = typeof(classString) === 'string'? 'button.ok.' + classString:'button.ok.primary'; + var sel = typeof(classString) === 'string'? 'button.ok.' + classString:'button.btn.ok.primary'; return h(sel, { tabindex: '2', }, content || Messages.okButton); }; dialog.cancelButton = function (content, classString) { - var sel = typeof(classString) === 'string'? 'button.' + classString:'button.cancel'; + var sel = typeof(classString) === 'string'? 'button.' + classString:'button.btn.cancel'; return h(sel, { tabindex: '1'}, content || Messages.cancelButton); }; @@ -396,6 +396,7 @@ define([ buttons.forEach(function (b) { if (!b.name || !b.onClick) { return; } var button = h('button', { tabindex: '1', 'class': b.className || '' }, b.name); + button.classList.add('btn'); var todo = function () { var noClose = b.onClick(); if (noClose) { return; } diff --git a/www/common/inner/access.js b/www/common/inner/access.js index 190af4279..28dd2863b 100644 --- a/www/common/inner/access.js +++ b/www/common/inner/access.js @@ -805,7 +805,7 @@ define([ id: 'cp-app-prop-change-password', style: 'flex: 1;' }); - var passwordOk = h('button', Messages.properties_changePasswordButton); + var passwordOk = h('button.btn', Messages.properties_changePasswordButton); var changePass = h('span.cp-password-change-container', [ newPassword, passwordOk diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index 6e10b0a77..08509dba7 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -490,6 +490,7 @@ define([ }, { typeInput: $select[0] }); + $select.find('button').addClass('btn'); }); toolbar.$drawer.append($export); }; diff --git a/www/contacts/app-contacts.less b/www/contacts/app-contacts.less index 88a93ae9d..99b927b6c 100644 --- a/www/contacts/app-contacts.less +++ b/www/contacts/app-contacts.less @@ -1,7 +1,6 @@ @import (reference) '../../customize/src/less2/include/framework.less'; @import (reference) '../../customize/src/less2/include/messenger.less'; @import (reference) '../../customize/src/less2/include/avatar.less'; -@import (reference) '../../customize/src/less2/include/buttons.less'; // body &.cp-app-contacts { @@ -19,9 +18,6 @@ display: flex; // We need this to remove a 3px border at the bottom of the toolbar } - .cp-app-contacts-friends { - .buttons_main(); - } .cp-contacts-muted-table { .avatar_main(50px); .cp-contacts-muted-user { @@ -33,8 +29,6 @@ } } - - .messenger_main(); } diff --git a/www/kanban/app-kanban.less b/www/kanban/app-kanban.less index f0af6eeca..db796ea61 100644 --- a/www/kanban/app-kanban.less +++ b/www/kanban/app-kanban.less @@ -3,7 +3,6 @@ @import (reference) "../../customize/src/less2/include/tools.less"; @import (reference) "../../customize/src/less2/include/markdown.less"; @import (reference) "../../customize/src/less2/include/avatar.less"; -@import (reference) "../../customize/src/less2/include/buttons.less"; // body &.cp-app-kanban { @@ -310,7 +309,6 @@ position: relative; min-height: 50px; .cp-kanban-filterTags { - .buttons_main(); display: inline-flex; align-items: center; flex: 1; diff --git a/www/pad/app-pad.less b/www/pad/app-pad.less index bf607e801..103241a52 100644 --- a/www/pad/app-pad.less +++ b/www/pad/app-pad.less @@ -1,6 +1,5 @@ @import (reference) "../../customize/src/less2/include/framework.less"; @import (reference) "../../customize/src/less2/include/comments.less"; -@import (reference) "../../customize/src/less2/include/buttons.less"; body.cp-app-pad { .framework_main( @@ -71,7 +70,6 @@ body.cp-app-pad { order: 1; } div.cp-comment-bubble { - .buttons_main(); position: relative; order: 2; button { diff --git a/www/secureiframe/app-secure.less b/www/secureiframe/app-secure.less index bece9d4c0..a8bf43a0f 100644 --- a/www/secureiframe/app-secure.less +++ b/www/secureiframe/app-secure.less @@ -8,6 +8,7 @@ @import (reference) '../../customize/src/less2/include/password-input.less'; @import (reference) '../../customize/src/less2/include/modals-ui-elements.less'; @import (reference) '../../customize/src/less2/include/usergrid.less'; +@import (reference) '../../customize/src/less2/include/forms.less'; &.cp-app-secureiframe { .modals-ui-elements_main(); @@ -19,6 +20,7 @@ .password_main(); .modal_main(); .usergrid_main(); + .forms_main(); #cp-filepicker-dialog { display: none; diff --git a/www/whiteboard/app-whiteboard.less b/www/whiteboard/app-whiteboard.less index 0fe594dda..054bc76a7 100644 --- a/www/whiteboard/app-whiteboard.less +++ b/www/whiteboard/app-whiteboard.less @@ -1,6 +1,5 @@ @import (reference) '../../customize/src/less2/include/tools.less'; @import (reference) "../../customize/src/less2/include/framework.less"; -@import (reference) "../../customize/src/less2/include/buttons.less"; &.cp-app-whiteboard { @@ -74,8 +73,6 @@ padding: 10px; - .buttons_main(); - & > * + * { margin: 0; margin-left: 1em; From bfae7215b1c5d3be7956fc52faf145c726699471 Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 19 Jun 2020 17:23:54 +0200 Subject: [PATCH 31/58] Translated using Weblate (English) Currently translated at 100.0% (1298 of 1298 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1297 of 1297 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1296 of 1296 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (1295 of 1295 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ --- www/common/translations/messages.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.json b/www/common/translations/messages.json index 50ca92b93..2aee6cc19 100644 --- a/www/common/translations/messages.json +++ b/www/common/translations/messages.json @@ -1391,5 +1391,8 @@ "support_addAttachment": "Add attachment", "notification_padSharedTeam": "{0} has shared a pad with the team {2}: {1}", "notification_fileSharedTeam": "{0} has shared a file with the team {2}: {1}", - "notification_folderSharedTeam": "{0} has shared a pad with the team {2}: {1}" + "notification_folderSharedTeam": "{0} has shared a folder with the team {2}: {1}", + "oo_refresh": "Refresh", + "oo_refreshText": "This document has been updated", + "support_category": "Choose a category" } From 571a0ccae7115640370e99acf9850ab91694da51 Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 19 Jun 2020 17:23:54 +0200 Subject: [PATCH 32/58] Translated using Weblate (German) Currently translated at 100.0% (1295 of 1295 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/de/ Translated using Weblate (German) Currently translated at 99.2% (1285 of 1295 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/de/ --- www/common/translations/messages.de.json | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/www/common/translations/messages.de.json b/www/common/translations/messages.de.json index e792c6cc8..a2d09ca8c 100644 --- a/www/common/translations/messages.de.json +++ b/www/common/translations/messages.de.json @@ -21,7 +21,7 @@ "button_newslide": "Neue Präsentation", "button_newwhiteboard": "Neues Whiteboard", "button_newkanban": "Neues Kanban", - "common_connectionLost": "Die Verbindung zum Server ist abgebrochen
Du verwendest jetzt das Dokument schreibgeschützt, bis die Verbindung wieder funktioniert.", + "common_connectionLost": "Die Verbindung zum Server ist abgebrochen
Du kannst das Dokument nicht bearbeiten, bis die Verbindung wieder funktioniert.", "websocketError": "Verbindung zum Websocket fehlgeschlagen...", "typeError": "Dieses Dokument ist nicht mit der ausgewählten Anwendung kompatibel", "onLogout": "Du bist ausgeloggt. {0}Klicke hier{1}, um dich wieder einzuloggen,
oder drücke Escape, um dein Pad schreibgeschützt zu benutzen.", @@ -1123,7 +1123,7 @@ "properties_unknownUser": "{0} unbekannte(r) Benutzer", "fm_morePads": "Mehr", "fc_openInCode": "Im Code-Editor öffnen", - "uploadFolder_modal_title": "Optionen für Ordnerupload", + "uploadFolder_modal_title": "Optionen für Hochladen des Ordners", "uploadFolder_modal_filesPassword": "Passwort für Dateien", "uploadFolder_modal_owner": "Eigene Dateien", "uploadFolder_modal_forceSave": "Dateien im CryptDrive speichern", @@ -1181,7 +1181,7 @@ "team_rosterPromote": "Befördern", "team_rosterDemote": "Degradieren", "team_rosterKick": "Aus dem Team entfernen", - "team_inviteButton": "Kontakte einladen", + "team_inviteButton": "Mitglieder einladen", "team_leaveButton": "Dieses Team verlassen", "team_leaveConfirm": "Wenn du dieses Team verlässt, verlierst du den Zugriff auf das dazugehörige CryptDrive, den Chatverlauf und andere Inhalte. Bist du sicher?", "team_owner": "Eigentümer", @@ -1381,5 +1381,15 @@ "settings_safeLinkDefault": "Sichere Links sind nun standardmäßig aktiviert. Bitte verwende zum Kopieren von Links das Menü Teilen und nicht die Adressleiste des Browsers.", "info_imprintFlavour": "Rechtliche Informationen über die Administratoren dieses Servers.", "info_privacyFlavour": "Unsere Datenschutzerklärung beschreibt, wie wir deine Daten verarbeiten.", - "user_about": "Über CryptPad" + "user_about": "Über CryptPad", + "support_cat_all": "Alle", + "support_cat_other": "Anderes", + "support_cat_account": "Benutzerkonto", + "support_cat_data": "Datenverlust", + "notification_folderSharedTeam": "{0} hat einen Ordner mit dem Team {2} geteilt: {1}", + "notification_fileSharedTeam": "{0} hat eine Datei mit dem Team {2} geteilt: {1}", + "notification_padSharedTeam": "{0} hat ein Pad mit dem Team {2} geteilt: {1}", + "support_addAttachment": "Anhang hinzufügen", + "support_attachments": "Anhänge", + "support_cat_bug": "Fehlerbericht" } From f71e31beafb63693c89c0c093314b98d9d59529d Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 19 Jun 2020 17:23:54 +0200 Subject: [PATCH 33/58] Translated using Weblate (French) Currently translated at 100.0% (1298 of 1298 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/fr/ Translated using Weblate (French) Currently translated at 100.0% (1297 of 1297 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/fr/ Translated using Weblate (French) Currently translated at 100.0% (1295 of 1295 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/fr/ Translated using Weblate (French) Currently translated at 100.0% (1295 of 1295 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/fr/ Translated using Weblate (French) Currently translated at 99.6% (1290 of 1295 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/fr/ --- www/common/translations/messages.fr.json | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json index 3a4536b1c..ef33ad144 100644 --- a/www/common/translations/messages.fr.json +++ b/www/common/translations/messages.fr.json @@ -1164,7 +1164,7 @@ "team_inviteModalButton": "Inviter", "team_pcsSelectLabel": "Sauver dans", "team_pcsSelectHelp": "Créer un pad dans le drive d'une équipe rend cette équipe propriétaire du pad si l'option est cochée.", - "team_invitedToTeam": "{0} vous à inviter à rejoindre l'équipe : {1}", + "team_invitedToTeam": "{0} vous a invité à rejoindre l'équipe : {1}", "team_kickedFromTeam": "{0} vous a exclu de l'équipe : {1}", "team_acceptInvitation": "{0} a accepté votre offre de rejoindre l'équipe : {1}", "team_declineInvitation": "{0} a refusé votre offre de rejoindre l'équipe : {1}", @@ -1381,5 +1381,18 @@ "support_languagesPreamble": "L'équipe de support parle les langues suivantes :", "info_privacyFlavour": "Description de la confidentialité de vos données.", "user_about": "À propos de CryptPad", - "info_imprintFlavour": "Informations légales sur les administateurs de cette instance." + "info_imprintFlavour": "Informations légales sur les administateurs de cette instance.", + "support_cat_all": "Tout", + "support_cat_other": "Autre", + "support_cat_bug": "Rapport de bug", + "support_cat_data": "Perte de données", + "support_cat_account": "Compte utilisateur", + "notification_folderSharedTeam": "{0} a partagé un dossier avec l'équipe {2} : {1}", + "notification_fileSharedTeam": "{0} a partagé un fichier avec l'équipe {2} : {1}", + "notification_padSharedTeam": "{0} a partagé un pad avec l'équipe {2} : {1}", + "support_addAttachment": "Ajouter une pièce jointe", + "support_attachments": "Pièces jointes", + "oo_refreshText": "Ce document a été mis à jour", + "oo_refresh": "Recharger", + "support_category": "Choisir une catégorie" } From d285c6b7916d0e28a2dd61d42c6ef6cf17f1d0ac Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 19 Jun 2020 17:45:01 +0200 Subject: [PATCH 34/58] Fix UI issues in kanban --- www/kanban/app-kanban.less | 4 +++- www/kanban/inner.js | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/www/kanban/app-kanban.less b/www/kanban/app-kanban.less index db796ea61..879121be7 100644 --- a/www/kanban/app-kanban.less +++ b/www/kanban/app-kanban.less @@ -141,6 +141,8 @@ .kanban-edit-item { padding: 5px; + border: 0; + background: transparent; align-self: flex-start; } @@ -344,7 +346,7 @@ margin-left: 10px; display: flex; flex-wrap: wrap; - &:not(:empty) { + &:not(.cp-empty) { margin-top: -5px; } em { diff --git a/www/kanban/inner.js b/www/kanban/inner.js index 10db6261b..f328c3bc8 100644 --- a/www/kanban/inner.js +++ b/www/kanban/inner.js @@ -503,7 +503,7 @@ define([ $container.find('.kanban-item').each(function (i, el) { var itemId = $(el).attr('data-eid'); $('