Broadcast deletion (manual and automatic)

pull/1/head
yflory 4 years ago
parent c38ba1936e
commit 171d00a943

@ -17,6 +17,19 @@
.cp-notification { .cp-notification {
min-height: @notif-height; min-height: @notif-height;
display: flex; display: flex;
.cp-broadcast {
display: flex;
img {
width: 30px;
}
padding: 0 5px;
&.admin {
cursor: pointer;
&:hover {
background-color: @cp_dropdown-bg-hover;
}
}
}
.cp-avatar { .cp-avatar {
.avatar_main(30px); .avatar_main(30px);
padding: 0 5px; padding: 0 5px;

@ -226,6 +226,30 @@
.cp-broadcast-preview { .cp-broadcast-preview {
vertical-align: bottom !important; vertical-align: bottom !important;
} }
.cp-broadcast-delete {
width: 100%;
min-width: 600px;
.cp-notification {
display: flex;
align-items: center;
.cp-avatar, .cp-broadcast, .cp-notification-dismiss {
display: none;
}
p {
margin: 0 !important;
}
.cp-notification-content {
width: 100%;
padding: 10px;
}
.cp-clickable {
cursor: pointer;
&:hover {
background-color: @cp_dropdown-bg-hover;
}
}
}
}
} }
} }

@ -944,12 +944,17 @@ define([
Messages.broadcast_survey = 'survey'; // XXX Messages.broadcast_survey = 'survey'; // XXX
Messages.broadcast_version = 'version'; // XXX Messages.broadcast_version = 'version'; // XXX
Messages.broadcast_custom = 'custom'; // XXX Messages.broadcast_custom = 'custom'; // XXX
Messages.broadcast_delete = 'delete'; // XXX
Messages.broadcast_newVersionReload = 'Force a worker reload on all clients'; // XXX Messages.broadcast_newVersionReload = 'Force a worker reload on all clients'; // XXX
Messages.broadcast_surveyURL = 'Survey URL'; Messages.broadcast_surveyURL = 'Survey URL';
Messages.broadcast_translations = 'Translations'; Messages.broadcast_translations = 'Translations';
Messages.broadcast_defaultLanguage = 'Default language'; Messages.broadcast_defaultLanguage = 'Fallback to this language (optional)';
Messages.broadcast_start = 'Start time'; Messages.broadcast_start = 'Start time';
Messages.broadcast_end = 'End time'; Messages.broadcast_end = 'End time';
Messages.broadcast_preview = "Preview in a fake notification";
Messages.broadcast_setLKH = "Mark as latest";
Messages.broadcast_deleteBtn = "Delete for all";
Messages.broadcast_reset = "Reset my visible messages";
var getBroadcastForm = function ($form, key) { var getBroadcastForm = function ($form, key) {
$form.empty(); $form.empty();
@ -966,6 +971,7 @@ define([
var data = getData(); var data = getData();
if (data === false) { return void UI.warn(Messages.error); } if (data === false) { return void UI.warn(Messages.error); }
$button.prop('disabled', 'disabled'); $button.prop('disabled', 'disabled');
data.time = +new Date();
common.mailbox.sendTo('BROADCAST_'+key.toUpperCase(), data, {}, function (err) { common.mailbox.sendTo('BROADCAST_'+key.toUpperCase(), data, {}, function (err) {
$button.prop('disabled', ''); $button.prop('disabled', '');
if (err) { return UI.warn(Messages.error); } if (err) { return UI.warn(Messages.error); }
@ -997,7 +1003,7 @@ define([
UI.log(Messages.saved); UI.log(Messages.saved);
}); });
}; };
var preview = h('button.cp-broadcast-preview.btn.btn-secondary', Messages.share_linkOpen); var preview = h('button.cp-broadcast-preview.btn.btn-secondary', Messages.broadcast_preview);
$(preview).click(function () { $(preview).click(function () {
onPreview(); onPreview();
}); });
@ -1022,7 +1028,7 @@ define([
}; };
var addLang = function (l) { var addLang = function (l) {
if ($container.find('.cp-broadcast-lang[data-lang="'+l+'"]').length) { return; } if ($container.find('.cp-broadcast-lang[data-lang="'+l+'"]').length) { return; }
var preview = h('button.btn.btn-secondary', Messages.share_linkOpen); var preview = h('button.btn.btn-secondary', Messages.broadcast_preview);
$(preview).click(function () { $(preview).click(function () {
onPreview(l); onPreview(l);
}); });
@ -1197,12 +1203,74 @@ define([
return; return;
} }
if (key === 'delete') {
(function () {
var table = h('table.cp-broadcast-delete');
var $table = $(table);
common.mailbox.subscribe(["broadcast"], {
onMessage: function (data, el) {
if (Util.find(data, ['content', 'msg', 'type']) === 'BROADCAST_DELETE') {
var _uid = Util.find(data, ['content', 'msg', 'content', 'uid']);
var $button = $table.find('[data-uid="'+_uid+'"] td.delete button');
$button.prop('disabled', 'disabled').text(Messages.deleted);
return;
}
var uid = Util.find(data, ['content', 'msg', 'uid']);
var time = Util.find(data, ['content', 'msg', 'content', 'time']);
var setLKHBtn = h('button.btn.btn-secondary', Messages.broadcast_setLKH);
var deleteBtn = h('button.btn.btn-danger', Messages.broadcast_deleteBtn);
$(setLKHBtn).click(function () {
// XXX
});
var tr = h('tr', { 'data-uid': uid }, [
h('td', 'ID: '+uid),
h('td', new Date(time || 0).toLocaleString()),
h('td', el),
h('td', setLKHBtn),
h('td.delete', deleteBtn),
]);
UI.confirmButton(deleteBtn, {
classes: 'btn-danger',
multiple: true
}, function () {
getData = function () {
if (!uid) { return false; }
return { uid: uid };
};
reset = function () {
$(deleteBtn).prop('disabled', 'disabled').text(Messages.deleted);
};
send();
});
$table.append(tr);
},
history: true // won't receive new messages: not a "subscription"
});
var resetMine = h('button.btn.btn-primary', Messages.broadcast_reset);
UI.confirmButton(resetMine, {}, function () {
common.mailbox.reset('broadcast', function () {
// XXX
console.error(arguments);
});
});
$form.append([
resetMine,
table
]);
})();
return;
}
}; };
create['broadcast'] = function () { create['broadcast'] = function () {
var key = 'broadcast'; var key = 'broadcast';
var $div = makeBlock(key); var $div = makeBlock(key);
var form = h('div.cp-admin-broadcast-form') var form = h('div.cp-admin-broadcast-form');
var $select = $(h('div.cp-dropdown-container')).appendTo($div); var $select = $(h('div.cp-dropdown-container')).appendTo($div);
var $form = $(form).appendTo($div); var $form = $(form).appendTo($div);
@ -1210,7 +1278,8 @@ define([
'maintenance', 'maintenance',
'survey', 'survey',
'version', 'version',
'custom' 'custom',
'delete'
]; ];
categories = categories.map(function (key) { categories = categories.map(function (key) {
return { return {
@ -1400,8 +1469,7 @@ define([
var privateData = metadataMgr.getPrivateData(); var privateData = metadataMgr.getPrivateData();
common.setTabTitle(Messages.adminPage || 'Administration'); common.setTabTitle(Messages.adminPage || 'Administration');
if (!privateData.edPublic || !ApiConfig.adminKeys || !Array.isArray(ApiConfig.adminKeys) if (!common.isAdmin()) {
|| ApiConfig.adminKeys.indexOf(privateData.edPublic) === -1) {
return void UI.errorLoadingScreen(Messages.admin_authError || '403 Forbidden'); return void UI.errorLoadingScreen(Messages.admin_authError || '403 Forbidden');
} }

@ -686,6 +686,71 @@ define([
}; };
// Broadcast
var broadcasts = {};
handlers['BROADCAST_MAINTENANCE'] = function (ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
if (content.end < (+new Date())) {
// Expired maintenance: dismiss
return void cb(true);
}
var uid = msg.uid;
broadcasts[uid] = {
type: box.type,
hash: data.hash
};
cb(false);
};
handlers['BROADCAST_VERSION'] = function (ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
if (!box.ready) {
// This is an old version message: dismiss
return void cb(true);
}
if (content.reload) {
// We're going to force a disconnect, dismiss
// XXX
return void cb(true);
}
var uid = msg.uid;
broadcasts[uid] = {
type: box.type,
hash: data.hash
};
cb(false);
};
handlers['BROADCAST_SURVEY'] = function (ctx, box, data, cb) {
var msg = data.msg;
var uid = msg.uid;
broadcasts[uid] = {
type: box.type,
hash: data.hash
};
cb(false);
};
handlers['BROADCAST_CUSTOM'] = function (ctx, box, data, cb) {
var msg = data.msg;
var uid = msg.uid;
broadcasts[uid] = {
type: box.type,
hash: data.hash
};
cb(false);
};
handlers['BROADCAST_DELETE'] = function (ctx, box, data, cb) {
var msg = data.msg;
var content = msg.content;
var uid = content.uid; // uid of the message to delete
if (!broadcasts[uid]) {
// We don't have this message in memory, nothing to delete
return void cb(true);
}
cb(false, broadcasts[uid]);
delete broadcasts[uid];
};
return { return {
add: function (ctx, box, data, cb) { add: function (ctx, box, data, cb) {
/** /**

@ -464,6 +464,21 @@ proxy.mailboxes = {
}); });
}; };
var resetBox = function (ctx, cId, type, cb) {
var box = ctx.mailboxes && ctx.mailboxes[type];
if (!box) { return void cb({error: 'ENOENT'}); }
console.log(box);
if (type === 'broadcast') {
box.viewed = [];
box.lastKnownHash = ''; // XXX Use api/broadcast
return void cb();
}
box.lastKnownHash = '';
box.viewed = [];
};
var subscribe = function (ctx, data, cId, cb) { var subscribe = function (ctx, data, cId, cb) {
// Get existing notifications // Get existing notifications
Object.keys(ctx.boxes).forEach(function (type) { Object.keys(ctx.boxes).forEach(function (type) {
@ -491,19 +506,21 @@ proxy.mailboxes = {
Mailbox.init = function (cfg, waitFor, emit) { Mailbox.init = function (cfg, waitFor, emit) {
var mailbox = {}; var mailbox = {};
var store = cfg.store; var store = cfg.store;
var mailboxes = store.proxy.mailboxes = store.proxy.mailboxes || {};
var ctx = { var ctx = {
Store: cfg.Store, Store: cfg.Store,
store: store, store: store,
pinPads: cfg.pinPads, pinPads: cfg.pinPads,
updateMetadata: cfg.updateMetadata, updateMetadata: cfg.updateMetadata,
updateDrive: cfg.updateDrive, updateDrive: cfg.updateDrive,
mailboxes: mailboxes,
emit: emit, emit: emit,
clients: [], clients: [],
boxes: {}, boxes: {},
req: {} req: {}
}; };
var mailboxes = store.proxy.mailboxes = store.proxy.mailboxes || {};
initializeMailboxes(ctx, mailboxes); initializeMailboxes(ctx, mailboxes);
initializeHistory(ctx); initializeHistory(ctx);
@ -580,6 +597,9 @@ proxy.mailboxes = {
if (cmd === 'LOAD_HISTORY') { if (cmd === 'LOAD_HISTORY') {
return void loadHistory(ctx, clientId, data, cb); return void loadHistory(ctx, clientId, data, cb);
} }
if (cmd === 'RESET') {
return void resetBox(ctx, clientId, data, cb);
}
}; };
return mailbox; return mailbox;

@ -1,13 +1,16 @@
define([ define([
'jquery', 'jquery',
'/api/config',
'/common/common-util.js', '/common/common-util.js',
'/common/common-hash.js', '/common/common-hash.js',
'/common/common-interface.js', '/common/common-interface.js',
'/common/common-ui-elements.js', '/common/common-ui-elements.js',
'/common/notifications.js', '/common/notifications.js',
'/common/hyperscript.js', '/common/hyperscript.js',
'/common/clipboard.js',
'/customize/messages.js', '/customize/messages.js',
], function ($, Util, Hash, UI, UIElements, Notifications, h, Messages) { ], function ($, ApiConfig, Util, Hash, UI, UIElements, Notifications, h,
Clipboard, Messages) {
var Mailbox = {}; var Mailbox = {};
Mailbox.create = function (Common) { Mailbox.create = function (Common) {
@ -56,7 +59,24 @@ define([
var notif; var notif;
var avatar; var avatar;
var userData = Util.find(data, ['content', 'msg', 'content', 'user']); var userData = Util.find(data, ['content', 'msg', 'content', 'user']);
if (userData && typeof(userData) === "object" && userData.profile) {
if (Util.find(data, ['content', 'msg', 'type']) === 'BROADCAST_DELETE') {
return;
}
if (data.type === 'broadcast') {
var urlArgs = Util.find(ApiConfig, ['requireConf', 'urlArgs']) || '';
var adminCls = Common.isAdmin() ? '.admin' : '';
avatar = h('span.cp-broadcast'+adminCls, h('img', {
src: '/customize/CryptPad_logo.svg?' + urlArgs,
title: adminCls ? 'Copy UID' : '' // XXX
}));
if (adminCls) {
$(avatar).click(function () {
var success = Clipboard.copy(Util.find(data, ['content', 'msg', 'uid']));
if (success) { UI.log(Messages.shareSuccess); }
});
}
} else if (userData && typeof(userData) === "object" && userData.profile) {
avatar = h('span.cp-avatar'); avatar = h('span.cp-avatar');
Common.displayAvatar($(avatar), userData.avatar, userData.displayName || userData.name); Common.displayAvatar($(avatar), userData.avatar, userData.displayName || userData.name);
$(avatar).click(function (e) { $(avatar).click(function (e) {
@ -160,7 +180,7 @@ define([
hash: data.content.hash, hash: data.content.hash,
type: data.type type: data.type
}; };
if (/^LOCAL|/.test(dataObj.hash)) { if (/^LOCAL\|/.test(dataObj.hash)) {
onViewed(dataObj); onViewed(dataObj);
cb(); cb();
return; return;
@ -188,7 +208,7 @@ define([
cfg.onViewed(data); cfg.onViewed(data);
}); });
} }
if (typeof(cfg.onMessage) === "function") { if (typeof(cfg.onMessage) === "function" && !cfg.history) {
onMessageHandlers.push(function (data, el) { onMessageHandlers.push(function (data, el) {
var type = data.type; var type = data.type;
if (types.indexOf(type) === -1 && !(teams && /^team-/.test(type))) { return; } if (types.indexOf(type) === -1 && !(teams && /^team-/.test(type))) { return; }
@ -206,6 +226,13 @@ define([
}); });
}; };
mailbox.reset = function (type, cb) {
if (!type) { return; }
execCommand('RESET', type, function (obj) {
cb(obj);
});
};
var historyState = false; var historyState = false;
var onHistory = function () {}; var onHistory = function () {};
mailbox.getMoreHistory = function (type, count, lastKnownHash, cb) { mailbox.getMoreHistory = function (type, count, lastKnownHash, cb) {

@ -1,5 +1,6 @@
define([ define([
'jquery', 'jquery',
'/api/config',
'/bower_components/nthen/index.js', '/bower_components/nthen/index.js',
'/customize/messages.js', '/customize/messages.js',
'/common/sframe-chainpad-netflux-inner.js', '/common/sframe-chainpad-netflux-inner.js',
@ -26,6 +27,7 @@ define([
'/bower_components/localforage/dist/localforage.min.js' '/bower_components/localforage/dist/localforage.min.js'
], function ( ], function (
$, $,
ApiConfig,
nThen, nThen,
Messages, Messages,
CpNfInner, CpNfInner,
@ -703,6 +705,12 @@ define([
}); });
}; };
funcs.isAdmin = function () {
var privateData = ctx.metadataMgr.getPrivateData();
return privateData.edPublic && Array.isArray(ApiConfig.adminKeys) &&
ApiConfig.adminKeys.indexOf(privateData.edPublic) !== -1;
};
funcs.mailbox = {}; funcs.mailbox = {};
Object.freeze(funcs); Object.freeze(funcs);

Loading…
Cancel
Save