Merge branch 'notifications' of github.com:xwiki-labs/cryptpad into notifications
This commit is contained in:
commit
b2d2fa4e46
@ -103,7 +103,7 @@ define([
|
||||
])*/
|
||||
])
|
||||
]),
|
||||
h('div.cp-version-footer', "CryptPad v2.24.0 (Yak)")
|
||||
h('div.cp-version-footer', "CryptPad v2.25.0 (Zebra)")
|
||||
]);
|
||||
};
|
||||
|
||||
|
||||
@ -26,6 +26,8 @@
|
||||
@colortheme_form-warning: #f49842;
|
||||
@colortheme_form-warning-hov: darken(@colortheme_form-warning, 5%);
|
||||
|
||||
@colortheme_context-menu-icon-color: #7b7b7b;
|
||||
|
||||
@colortheme_modal-bg: @colortheme_form-bg-alt; // TODO Modals bg
|
||||
@colortheme_modal-fg: @colortheme_form-color-alt;
|
||||
@colortheme_modal-link: @colortheme_link-color;
|
||||
|
||||
@ -13,7 +13,17 @@
|
||||
font-size: @colortheme_app-font-size;
|
||||
a {
|
||||
cursor: pointer;
|
||||
.fa, .cptools {
|
||||
margin-right: 1rem;
|
||||
color: @colortheme_context-menu-icon-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cp-app-drive-context-noAction {
|
||||
font-style: italic;
|
||||
color: #aaa;
|
||||
cursor: default;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "cryptpad",
|
||||
"description": "realtime collaborative visual editor with zero knowlege server",
|
||||
"version": "2.24.0",
|
||||
"version": "2.25.0",
|
||||
"license": "AGPL-3.0+",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@ -3,8 +3,6 @@
|
||||
const Nacl = require('tweetnacl');
|
||||
|
||||
const keyPair = Nacl.box.keyPair();
|
||||
console.log(keyPair);
|
||||
|
||||
console.log("You've just generated a new key pair for your support mailbox.");
|
||||
|
||||
console.log("The public key should first be added to your config.js file ('supportMailboxPublicKey'), then save and restart the server.");
|
||||
|
||||
@ -232,11 +232,11 @@ define([
|
||||
create['support-init'] = function () {
|
||||
var $div = makeBlock('support-init');
|
||||
if (!supportKey) {
|
||||
$div.append(h('p', Messages.admin_supportInitHelp || "Your server is not configured to have a support mailbox. If you want a support mailbox to receive messages from your users, you should ask your server administrator to run the script located in './scripts/generate-admin-keys.js', store the public key in the 'config.js' file, and send you the private key.")); // XXX
|
||||
$div.append(h('p', Messages.admin_supportInitHelp));
|
||||
return $div;
|
||||
}
|
||||
if (!APP.privateKey || !checkAdminKey(APP.privateKey)) {
|
||||
$div.append(h('p', Messages.admin_supportInitPrivate || "Your CryptPad instance is configured to use a support mailbox but your account doesn't have the correct private key to access it. Please use the following form to add or update the private key to your account")); // XXX
|
||||
$div.append(h('p', Messages.admin_supportInitPrivate));
|
||||
|
||||
var error = h('div.cp-admin-support-error');
|
||||
var input = h('input.cp-admin-add-private-key');
|
||||
|
||||
@ -162,7 +162,7 @@ define([
|
||||
}
|
||||
|
||||
var parsed = Hash.parsePadUrl(data.href || data.roHref);
|
||||
if (!data.noEditPassword && owned && parsed.hashData.type === 'pad') {
|
||||
if (!data.noEditPassword && owned && parsed.hashData.type === 'pad' && parsed.type !== "sheet") { // FIXME SHEET fix password change for sheets
|
||||
var sframeChan = common.getSframeChannel();
|
||||
var changePwTitle = Messages.properties_changePassword;
|
||||
var changePwConfirm = Messages.properties_confirmChange;
|
||||
@ -412,6 +412,7 @@ define([
|
||||
if (!friend.notifications || !friend.curvePublic) { return; }
|
||||
common.mailbox.sendTo("SHARE_PAD", {
|
||||
href: href,
|
||||
password: config.password,
|
||||
name: myName,
|
||||
title: title
|
||||
}, {
|
||||
|
||||
@ -78,7 +78,12 @@ define([
|
||||
return Messages._getKey(key, [msg.content.name || Messages.anonymous, msg.content.title]);
|
||||
};
|
||||
content.handler = function () {
|
||||
common.openURL(msg.content.href);
|
||||
var todo = function () { common.openURL(msg.content.href); };
|
||||
if (!msg.content.password) { return void todo(); }
|
||||
common.getSframeChannel().query('Q_SESSIONSTORAGE_PUT', {
|
||||
key: 'newPadPassword',
|
||||
value: msg.content.password
|
||||
}, todo);
|
||||
};
|
||||
if (!content.archived) {
|
||||
content.dismissHandler = defaultDismiss(common, data);
|
||||
|
||||
@ -102,9 +102,12 @@ define([
|
||||
Cryptpad.onlyoffice.onEvent.reg(function (obj) {
|
||||
if (obj.ev === 'MESSAGE' && !/^cp\|/.test(obj.data)) {
|
||||
try {
|
||||
var validateKey = obj.data.validateKey || true;
|
||||
var skipCheck = validateKey === true;
|
||||
var msg = obj.data.msg;
|
||||
obj.data = {
|
||||
msg: JSON.parse(Utils.crypto.decrypt(obj.data, Utils.secret.keys.validateKey)),
|
||||
hash: obj.data.slice(0,64)
|
||||
msg: JSON.parse(Utils.crypto.decrypt(msg, validateKey, skipCheck)),
|
||||
hash: msg.slice(0,64)
|
||||
};
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
||||
@ -1076,6 +1076,7 @@ define([
|
||||
curvePrivate: priv
|
||||
}
|
||||
};
|
||||
Store.pinPads(null, [channel], function () {});
|
||||
store.mailbox.open('supportadmin', box, function () {
|
||||
console.log('ready');
|
||||
});
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
define([
|
||||
'/common/common-messaging.js',
|
||||
], function (Messaging) {
|
||||
'/common/common-hash.js',
|
||||
], function (Messaging, Hash) {
|
||||
|
||||
var getRandomTimeout = function (ctx) {
|
||||
var lag = ctx.store.realtime.getLag().lag || 0;
|
||||
@ -156,6 +157,50 @@ define([
|
||||
cb(true);
|
||||
};
|
||||
|
||||
// Hide duplicates when receiving a SHARE_PAD notification:
|
||||
// Keep only one notification per channel: the stronger and more recent one
|
||||
var channels = {};
|
||||
handlers['SHARE_PAD'] = function (ctx, box, data, cb) {
|
||||
var msg = data.msg;
|
||||
var hash = data.hash;
|
||||
var content = msg.content;
|
||||
// content.name, content.title, content.href, content.password
|
||||
|
||||
var channel = Hash.hrefToHexChannelId(content.href, content.password);
|
||||
var parsed = Hash.parsePadUrl(content.href);
|
||||
var mode = parsed.hashData && parsed.hashData.mode || 'n/a';
|
||||
|
||||
var old = channels[channel];
|
||||
var toRemove;
|
||||
if (old) {
|
||||
// New hash is weaker, ignore
|
||||
if (old.mode === 'edit' && mode === 'view') {
|
||||
return void cb(true);
|
||||
}
|
||||
// New hash is not weaker, clear the old one
|
||||
toRemove = old.data;
|
||||
}
|
||||
|
||||
// Update the data
|
||||
channels[channel] = {
|
||||
mode: mode,
|
||||
data: {
|
||||
type: box.type,
|
||||
hash: hash
|
||||
}
|
||||
};
|
||||
|
||||
cb(false, toRemove);
|
||||
};
|
||||
removeHandlers['SHARE_PAD'] = function (ctx, box, data, hash) {
|
||||
var content = data.content;
|
||||
var channel = Hash.hrefToHexChannelId(content.href, content.password);
|
||||
var old = channels[channel];
|
||||
if (old && old.data && old.data.hash === hash) {
|
||||
delete channels[channel];
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
add: function (ctx, box, data, cb) {
|
||||
/**
|
||||
|
||||
@ -187,6 +187,7 @@ proxy.mailboxes = {
|
||||
var openChannel = function (ctx, type, m, onReady) {
|
||||
var box = ctx.boxes[type] = {
|
||||
channel: m.channel,
|
||||
type: type,
|
||||
queue: [], // Store the messages to send when the channel is ready
|
||||
history: [], // All the hashes loaded from the server in corretc order
|
||||
content: {}, // Content of the messages that should be displayed
|
||||
@ -259,8 +260,8 @@ proxy.mailboxes = {
|
||||
msg: msg,
|
||||
hash: hash
|
||||
};
|
||||
Handlers.add(ctx, box, message, function (toDismiss) {
|
||||
if (toDismiss) {
|
||||
Handlers.add(ctx, box, message, function (dismissed, toDismiss) {
|
||||
if (dismissed) { // This message should be removed
|
||||
dismiss(ctx, {
|
||||
type: type,
|
||||
hash: hash
|
||||
@ -269,6 +270,11 @@ proxy.mailboxes = {
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (toDismiss) { // List of other messages to remove
|
||||
dismiss(ctx, toDismiss, '', function () {
|
||||
console.log('Notification handled automatically');
|
||||
});
|
||||
}
|
||||
box.content[hash] = msg;
|
||||
showMessage(ctx, type, message);
|
||||
});
|
||||
|
||||
@ -26,7 +26,10 @@ define([
|
||||
if (!c.id) { c.id = chan.wc.myID + '-' + client; }
|
||||
|
||||
chan.history.forEach(function (msg) {
|
||||
ctx.emit('MESSAGE', msg, [client]);
|
||||
ctx.emit('MESSAGE', {
|
||||
msg: msg,
|
||||
validateKey: chan.validateKey
|
||||
}, [client]);
|
||||
});
|
||||
|
||||
// ==> And push the new tab to the list
|
||||
@ -37,7 +40,8 @@ define([
|
||||
var onOpen = function (wc) {
|
||||
|
||||
ctx.channels[channel] = ctx.channels[channel] || {
|
||||
history: []
|
||||
history: [],
|
||||
validateKey: obj.validateKey
|
||||
};
|
||||
|
||||
chan = ctx.channels[channel];
|
||||
@ -61,7 +65,10 @@ define([
|
||||
});
|
||||
wc.on('message', function (msg) {
|
||||
chan.history.push(msg);
|
||||
ctx.emit('MESSAGE', msg, chan.clients);
|
||||
ctx.emit('MESSAGE', {
|
||||
msg: msg,
|
||||
validateKey: chan.validateKey
|
||||
}, chan.clients);
|
||||
});
|
||||
|
||||
chan.wc = wc;
|
||||
@ -101,6 +108,7 @@ define([
|
||||
};
|
||||
|
||||
network.on('message', function (msg, sender) {
|
||||
if (!ctx.channels[channel]) { return; }
|
||||
var hk = network.historyKeeper;
|
||||
if (sender !== hk) { return; }
|
||||
|
||||
@ -115,7 +123,12 @@ define([
|
||||
// Keep only metadata messages for the current channel
|
||||
if (parsed.channel && parsed.channel !== channel) { return; }
|
||||
// Ignore the metadata message
|
||||
if (parsed.validateKey && parsed.channel) { return; }
|
||||
if (parsed.validateKey && parsed.channel) {
|
||||
if (!chan.validateKey) {
|
||||
chan.validateKey = parsed.validateKey;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// End of history: emit READY
|
||||
if (parsed.state && parsed.state === 1 && parsed.channel) {
|
||||
ctx.emit('READY', '', chan.clients);
|
||||
@ -132,7 +145,9 @@ define([
|
||||
if (hash === chan.lastKnownHash || hash === chan.lastCpHash) { return; }
|
||||
|
||||
chan.lastKnownHash = hash;
|
||||
ctx.emit('MESSAGE', msg, chan.clients);
|
||||
ctx.emit('MESSAGE', {
|
||||
msg: msg,
|
||||
}, chan.clients);
|
||||
chan.history.push(msg);
|
||||
});
|
||||
|
||||
@ -176,7 +191,9 @@ define([
|
||||
return void chan.sendMsg(data.isCp, cb);
|
||||
}
|
||||
chan.sendMsg(data.msg, cb);
|
||||
ctx.emit('MESSAGE', data.msg, chan.clients.filter(function (cl) {
|
||||
ctx.emit('MESSAGE', {
|
||||
msg: data.msg
|
||||
}, chan.clients.filter(function (cl) {
|
||||
return cl !== clientId;
|
||||
}));
|
||||
};
|
||||
|
||||
@ -625,6 +625,11 @@ define([
|
||||
var root = exp.find([ROOT]);
|
||||
var toClean = [];
|
||||
for (var id in fd) {
|
||||
if (String(id) !== String(Number(id))) {
|
||||
debug("Invalid file ID in filesData.", id);
|
||||
toClean.push(id);
|
||||
continue;
|
||||
}
|
||||
id = Number(id);
|
||||
var el = fd[id];
|
||||
|
||||
|
||||
@ -252,6 +252,9 @@ define([
|
||||
var obj = Env.folders[el].proxy.metadata || {};
|
||||
if (obj) { key = obj.title; }
|
||||
} else {
|
||||
try {
|
||||
el = JSON.parse(JSON.stringify(el));
|
||||
} catch (e) { return undefined; }
|
||||
userObject.getFilesRecursively(el, files);
|
||||
}
|
||||
|
||||
@ -342,7 +345,7 @@ define([
|
||||
});
|
||||
|
||||
// Remove the elements from the old location (without unpinning)
|
||||
Env.user.userObject.delete(resolved.main, waitFor());
|
||||
Env.user.userObject.delete(resolved.main, waitFor()); // FIXME waitFor() is called synchronously
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -369,7 +372,7 @@ define([
|
||||
if (copy) { return; }
|
||||
|
||||
// Remove the elements from the old location (without unpinning)
|
||||
uoFrom.delete(paths, waitFor());
|
||||
uoFrom.delete(paths, waitFor()); // FIXME waitFor() is called synchronously
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -707,6 +710,7 @@ define([
|
||||
if (type === 'expirable') {
|
||||
return function (fileId) {
|
||||
var data = userObject.getFileData(fileId);
|
||||
if (!data) { return; }
|
||||
// Don't push duplicates
|
||||
if (result.indexOf(data.channel) !== -1) { return; }
|
||||
// Return pads owned by someone else or expired by time
|
||||
@ -718,6 +722,7 @@ define([
|
||||
if (type === 'owned') {
|
||||
return function (fileId) {
|
||||
var data = userObject.getFileData(fileId);
|
||||
if (!data) { return; }
|
||||
// Don't push duplicates
|
||||
if (result.indexOf(data.channel) !== -1) { return; }
|
||||
// Return owned pads
|
||||
@ -729,6 +734,7 @@ define([
|
||||
if (type === "pin") {
|
||||
return function (fileId) {
|
||||
var data = userObject.getFileData(fileId);
|
||||
if (!data) { return; }
|
||||
// Don't pin pads owned by someone else
|
||||
if (_ownedByOther(Env, data.owners)) { return; }
|
||||
// Don't push duplicates
|
||||
|
||||
@ -223,6 +223,11 @@ define([
|
||||
sframeChan.event("EV_PAD_PASSWORD");
|
||||
};
|
||||
|
||||
if (!val && sessionStorage.newPadPassword) {
|
||||
val = sessionStorage.newPadPassword;
|
||||
delete sessionStorage.newPadPassword;
|
||||
}
|
||||
|
||||
if (val) {
|
||||
password = val;
|
||||
Cryptpad.getFileSize(window.location.href, password, waitFor(function (e, size) {
|
||||
|
||||
@ -832,11 +832,17 @@ MessengerUI, Messages) {
|
||||
return $spin;
|
||||
};
|
||||
|
||||
var createLimit = function (toolbar) {
|
||||
var createLimit = function (toolbar, config) {
|
||||
var $limitIcon = $('<span>', {'class': 'fa fa-exclamation-triangle'});
|
||||
var $limit = toolbar.$userAdmin.find('.'+LIMIT_CLS).attr({
|
||||
'title': Messages.pinLimitReached
|
||||
}).append($limitIcon).hide();
|
||||
|
||||
var priv = config.metadataMgr.getPrivateData();
|
||||
var origin = priv.origin;
|
||||
var l = document.createElement("a");
|
||||
l.href = origin;
|
||||
|
||||
var todo = function (e, overLimit) {
|
||||
if (e) { return void console.error("Unable to get the pinned usage", e); }
|
||||
if (overLimit) {
|
||||
@ -845,7 +851,7 @@ MessengerUI, Messages) {
|
||||
key = 'pinLimitReachedAlertNoAccounts';
|
||||
}
|
||||
$limit.show().click(function () {
|
||||
UI.alert(Messages._getKey(key, [encodeURIComponent(window.location.hostname)]), null, true);
|
||||
UI.alert(Messages._getKey(key, [encodeURIComponent(l.hostname)]), null, true);
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -946,7 +952,7 @@ MessengerUI, Messages) {
|
||||
var $notif = toolbar.$top.find('.'+NOTIFICATIONS_CLS).show();
|
||||
var openNotifsApp = h('div.cp-notifications-gotoapp', h('p', Messages.openNotificationsApp || "Open notifications App"));
|
||||
$(openNotifsApp).click(function () {
|
||||
Common.openURL("/notifications");
|
||||
Common.openURL("/notifications/");
|
||||
});
|
||||
var div = h('div.cp-notifications-container', [
|
||||
h('div.cp-notifications-empty', Messages.notifications_empty)
|
||||
|
||||
@ -565,7 +565,7 @@
|
||||
"download_step1": "Laden...",
|
||||
"download_step2": "Entschlüsselung...",
|
||||
"todo_title": "CryptTodo",
|
||||
"todo_newTodoNamePlaceholder": "Beschreibe deine Aufgabe...",
|
||||
"todo_newTodoNamePlaceholder": "Beschreibe deine Aufgabe…",
|
||||
"todo_newTodoNameTitle": "Diese Aufgabe zu deiner ToDo-Liste hinzufügen",
|
||||
"todo_markAsCompleteTitle": "Diese Aufgabe als erledigt markieren",
|
||||
"todo_markAsIncompleteTitle": "Diese Aufgabe als nicht erledigt markieren",
|
||||
@ -830,7 +830,7 @@
|
||||
"generic": {
|
||||
"more": "Erfahre mehr über die Nutzung von CryptPad, indem du unsere <a href=\"/faq.html\" target=\"_blank\">FAQ</a> liest",
|
||||
"share": "Benutze das Teilen-Menü (<span class=\"fa fa-share-alt\"></span>), um Links zu generieren, die Mitarbeiter zum Lesen oder Bearbeiten einladen",
|
||||
"save": "Alle Änderungen werden automatisch synchronisiert. Du misst sie also nicht speichern"
|
||||
"save": "Alle Änderungen werden automatisch synchronisiert. Du musst sie also nicht selbst speichern"
|
||||
},
|
||||
"text": {
|
||||
"formatting": "Du kannst die Werkzeugleiste anzeigen oder verbergen, indem du auf <span class=\"fa fa-caret-down\"></span> oder <span class=\"fa fa-caret-up\"></span> klickst",
|
||||
@ -1075,5 +1075,33 @@
|
||||
"share_description": "Wähle aus, was du teilen möchtest. Dir wird dann ein entsprechender Link anzeigt. Du kannst es auch direkt an deine Freunde in CryptPad senden.",
|
||||
"fc_expandAll": "Alle ausklappen",
|
||||
"fc_collapseAll": "Alle einklappen",
|
||||
"fc_color": "Farbe ändern"
|
||||
"fc_color": "Farbe ändern",
|
||||
"supportPage": "",
|
||||
"admin_cat_support": "",
|
||||
"admin_supportInitHelp": "",
|
||||
"admin_supportInitPrivate": "",
|
||||
"admin_supportAddKey": "",
|
||||
"admin_supportAddError": "",
|
||||
"admin_supportInitTitle": "",
|
||||
"admin_supportInitHint": "",
|
||||
"admin_supportListTitle": "",
|
||||
"admin_supportListHint": "",
|
||||
"support_disabledTitle": "",
|
||||
"support_disabledHint": "",
|
||||
"support_cat_new": "",
|
||||
"support_formTitle": "",
|
||||
"support_formHint": "",
|
||||
"support_formButton": "",
|
||||
"support_formTitleError": "",
|
||||
"support_formContentError": "",
|
||||
"support_formMessage": "",
|
||||
"support_cat_tickets": "",
|
||||
"support_listTitle": "",
|
||||
"support_listHint": "",
|
||||
"support_answer": "",
|
||||
"support_close": "",
|
||||
"support_remove": "",
|
||||
"support_showData": "",
|
||||
"support_from": "",
|
||||
"support_closed": ""
|
||||
}
|
||||
|
||||
@ -1056,7 +1056,7 @@
|
||||
"friendRequest_accepted": "<b>{0}</b> a accepté votre demande d'ami",
|
||||
"friendRequest_received": "<b>{0}</b> souhaite être votre ami",
|
||||
"friendRequest_notification": "<b>{0}</b> vous a envoyé une demande d'ami",
|
||||
"notifications_empty": "Vous n'avez pas de nouvelle notification",
|
||||
"notifications_empty": "Pas de nouvelle notification",
|
||||
"notifications_title": "Vous avez des notifications non lues",
|
||||
"profile_addDescription": "Ajouter une description",
|
||||
"profile_editDescription": "Modifier votre description",
|
||||
@ -1075,5 +1075,35 @@
|
||||
"notifications_dismiss": "Cacher",
|
||||
"fm_info_sharedFolderHistory": "Vous regardez l'historique de votre dossier partagé <b>{0}</b><br/>Votre CryptDrive restera en lecture seule pendant la navigation.",
|
||||
"share_description": "Choisissez ce que vous souhaitez partager puis obtenez le lien ou envoyez-le directement à vos amis CryptPad.",
|
||||
"fc_color": "Changer la couleur"
|
||||
"fc_color": "Changer la couleur",
|
||||
"supportPage": "Support",
|
||||
"admin_cat_support": "Support",
|
||||
"admin_supportAddKey": "Ajouter la clé",
|
||||
"admin_supportAddError": "Clé privée non valide",
|
||||
"admin_supportInitTitle": "Initialisation du support",
|
||||
"admin_supportListTitle": "Messagerie du support",
|
||||
"support_disabledTitle": "Le support n'est pas activé",
|
||||
"support_disabledHint": "Cette instance de CryptPad n'est pas encore configurée pour utiliser le formulaire de support.",
|
||||
"support_cat_new": "Nouveau ticket",
|
||||
"support_formTitle": "Titre du ticket",
|
||||
"support_formButton": "Envoyer",
|
||||
"support_formTitleError": "Erreur : le titre est vide",
|
||||
"support_formContentError": "Erreur : le contenu est vide",
|
||||
"support_formMessage": "Taper votre message...",
|
||||
"support_cat_tickets": "Tickets existants",
|
||||
"support_listTitle": "Tickets de support",
|
||||
"support_answer": "Répondre",
|
||||
"support_close": "Fermer le ticket",
|
||||
"support_remove": "Supprimer le ticket",
|
||||
"support_showData": "Afficher/cacher les données de l'utilisateur",
|
||||
"support_from": "<b>De :</b> {0}",
|
||||
"support_closed": "Ce ticket a été fermé",
|
||||
"fc_noAction": "Pas d'action disponible",
|
||||
"notificationsPage": "Notifications",
|
||||
"openNotificationsApp": "Ouvrir le panneau de notifications",
|
||||
"notifications_cat_all": "Toutes",
|
||||
"notifications_cat_friends": "Demandes d'ami",
|
||||
"notifications_cat_pads": "Partagé avec moi",
|
||||
"notifications_cat_archived": "Historique",
|
||||
"notifications_dismissAll": "Tout cacher"
|
||||
}
|
||||
|
||||
@ -1057,7 +1057,7 @@
|
||||
"friendRequest_accepted": "<b>{0}</b> accepted your friend request",
|
||||
"friendRequest_received": "<b>{0}</b> would like to be your friend",
|
||||
"friendRequest_notification": "<b>{0}</b> sent you a friend request",
|
||||
"notifications_empty": "You have no new notifications",
|
||||
"notifications_empty": "No notifications available",
|
||||
"notifications_title": "You have unread notifications",
|
||||
"profile_addDescription": "Add a description",
|
||||
"profile_editDescription": "Edit your description",
|
||||
@ -1075,5 +1075,41 @@
|
||||
"share_withFriends": "Share",
|
||||
"notifications_dismiss": "Dismiss",
|
||||
"fm_info_sharedFolderHistory": "This is only the history of your shared folder: <b>{0}</b><br/>Your CryptDrive will stay in read-only mode while you navigate.",
|
||||
"share_description": "Choose what you'd like to share and either get the link or send it directly to your CryptPad friends."
|
||||
"share_description": "Choose what you'd like to share and either get the link or send it directly to your CryptPad friends.",
|
||||
"supportPage": "Support",
|
||||
"admin_cat_support": "Support",
|
||||
"admin_supportInitHelp": "Your server is not yet configured to have a support mailbox. If you want a support mailbox to receive messages from your users, you should ask your server administrator to run the script located in \"./scripts/generate-admin-keys.js\", then store the public key in the \"config.js\" file and send you the private key.",
|
||||
"admin_supportInitPrivate": "Your CryptPad instance is configured to use a support mailbox but your account doesn't have the correct private key to access it. Please use the following form to add or update the private key to your account.",
|
||||
"admin_supportAddKey": "Add private key",
|
||||
"admin_supportAddError": "Invalid private key",
|
||||
"admin_supportInitTitle": "Support mailbox initialization",
|
||||
"admin_supportInitHint": "You can configure a support mailbox in order to give users of your CryptPad instance a way to contact you securely if they have an issue with their account.",
|
||||
"admin_supportListTitle": "Support mailbox",
|
||||
"admin_supportListHint": "Here is the list of tickets sent by the users to the support mailbox. All the administrators can see the messages and the answers. A closed ticket cannot be reopened. You can only remove (hide) closed tickets, and the removed tickets are still visible by the other administrators.",
|
||||
"support_disabledTitle": "Support is not enabled",
|
||||
"support_disabledHint": "This CryptPad instance is not yet configured to use a support form.",
|
||||
"support_cat_new": "New ticket",
|
||||
"support_formTitle": "Ticket title",
|
||||
"support_formHint": "This form can be used to create a new support ticket. Using this form, you can contact the administrators to solve issues or ask any question in a secure way. Please don't create a new ticket if you already have an open ticket about the same issue, but use reply button to provide more information.",
|
||||
"support_formButton": "Send",
|
||||
"support_formTitleError": "Error: title is empty",
|
||||
"support_formContentError": "Error: content is empty",
|
||||
"support_formMessage": "Type your message...",
|
||||
"support_cat_tickets": "Existing tickets",
|
||||
"support_listTitle": "Support tickets",
|
||||
"support_listHint": "Here is the list of tickets sent to the administrators and their answers. A closed ticket cannot be re-opened, you have to make a new one. You can hide tickets that have been closed but they will still be visible by the administrators.",
|
||||
"support_answer": "Reply",
|
||||
"support_close": "Close the ticket",
|
||||
"support_remove": "Remove the ticket",
|
||||
"support_showData": "Show/hide user data",
|
||||
"support_from": "<b>From:</b> {0}",
|
||||
"support_closed": "This ticket has been closed",
|
||||
"fc_noAction": "No action available",
|
||||
"notificationsPage": "Notifications",
|
||||
"openNotificationsApp": "Open notifications panel",
|
||||
"notifications_cat_all": "All",
|
||||
"notifications_cat_friends": "Friend requests",
|
||||
"notifications_cat_pads": "Shared with me",
|
||||
"notifications_cat_archived": "History",
|
||||
"notifications_dismissAll": "Dismiss all"
|
||||
}
|
||||
|
||||
@ -311,12 +311,12 @@ define([
|
||||
_getFiles[FILES_DATA] = function () {
|
||||
var ret = [];
|
||||
if (!files[FILES_DATA]) { return ret; }
|
||||
return Object.keys(files[FILES_DATA]).map(Number);
|
||||
return Object.keys(files[FILES_DATA]).map(Number).filter(Boolean);
|
||||
};
|
||||
_getFiles[SHARED_FOLDERS] = function () {
|
||||
var ret = [];
|
||||
if (!files[SHARED_FOLDERS]) { return ret; }
|
||||
return Object.keys(files[SHARED_FOLDERS]).map(Number);
|
||||
return Object.keys(files[SHARED_FOLDERS]).map(Number).filter(Boolean);
|
||||
};
|
||||
var getFiles = exp.getFiles = function (categories) {
|
||||
var ret = [];
|
||||
@ -514,6 +514,31 @@ define([
|
||||
data: exp.getFileData(l)
|
||||
});
|
||||
});
|
||||
|
||||
// find folders
|
||||
var resFolders = [];
|
||||
var findFoldersRec = function (folder, path) {
|
||||
for (var key in folder) {
|
||||
if (isFolder(folder[key]) && !isSharedFolder(folder[key])) {
|
||||
if (key.toLowerCase().indexOf(lValue) !== -1) {
|
||||
resFolders.push({
|
||||
id: null,
|
||||
paths: [path.concat(key)],
|
||||
data: {
|
||||
title: key
|
||||
}
|
||||
});
|
||||
}
|
||||
findFoldersRec(folder[key], path.concat(key));
|
||||
}
|
||||
}
|
||||
};
|
||||
findFoldersRec(files[ROOT], [ROOT]);
|
||||
resFolders = resFolders.sort(function (a, b) {
|
||||
return a.data.title.toLowerCase() > b.data.title.toLowerCase();
|
||||
});
|
||||
ret = resFolders.concat(ret);
|
||||
|
||||
return ret;
|
||||
};
|
||||
exp.getRecentPads = function () {
|
||||
|
||||
@ -513,12 +513,18 @@
|
||||
}
|
||||
.cp-app-drive-search-path {
|
||||
font-style: italic;
|
||||
display: flex;
|
||||
flex-flow: row-reverse;
|
||||
justify-content: right;
|
||||
.cp-app-drive-path-element {
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
.cp-app-drive-path-inner {
|
||||
display: flex;
|
||||
flex-flow: row-reverse wrap-reverse;
|
||||
justify-content: flex-end;
|
||||
.cp-app-drive-path-element {
|
||||
flex-shrink: 0;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cp-app-drive-search-title {
|
||||
|
||||
@ -124,6 +124,7 @@ define([
|
||||
var $tagsIcon = $('<span>', {"class": "fa " + faTags});
|
||||
var $passwordIcon = $('<span>', {"class": "fa fa-lock"});
|
||||
var $expirableIcon = $('<span>', {"class": "fa fa-clock-o"});
|
||||
var $separator = $('<div>', {"class": "dropdown-divider"});
|
||||
|
||||
var LS_LAST = "app-drive-lastOpened";
|
||||
var LS_OPENED = "app-drive-openedFolders";
|
||||
@ -303,6 +304,7 @@ define([
|
||||
'aria-labelledby': 'dropdownMenu',
|
||||
'style': 'display:block;position:static;margin-bottom:5px;'
|
||||
}, [
|
||||
h('span.cp-app-drive-context-noAction.dropdown-item.disabled', Messages.fc_noAction || "No action possible"),
|
||||
h('li', h('a.cp-app-drive-context-open.dropdown-item', {
|
||||
'tabindex': '-1',
|
||||
'data-icon': faFolderOpen,
|
||||
@ -311,6 +313,7 @@ define([
|
||||
'tabindex': '-1',
|
||||
'data-icon': faReadOnly,
|
||||
}, Messages.fc_open_ro)),
|
||||
$separator.clone()[0],
|
||||
h('li', h('a.cp-app-drive-context-expandall.dropdown-item', {
|
||||
'tabindex': '-1',
|
||||
'data-icon': "expandAll",
|
||||
@ -319,6 +322,7 @@ define([
|
||||
'tabindex': '-1',
|
||||
'data-icon': "collapseAll",
|
||||
}, Messages.fc_collapseAll)),
|
||||
$separator.clone()[0],
|
||||
h('li', h('a.cp-app-drive-context-color.dropdown-item.cp-app-drive-context-editable', {
|
||||
'tabindex': '-1',
|
||||
'data-icon': faColor,
|
||||
@ -347,6 +351,7 @@ define([
|
||||
'tabindex': '-1',
|
||||
'data-icon': faTags,
|
||||
}, Messages.fc_hashtag)),
|
||||
$separator.clone()[0],
|
||||
h('li', h('a.cp-app-drive-context-newdoc.dropdown-item.cp-app-drive-context-editable', {
|
||||
'tabindex': '-1',
|
||||
'data-icon': AppConfig.applicationsIcon.pad,
|
||||
@ -372,6 +377,7 @@ define([
|
||||
'data-icon': AppConfig.applicationsIcon.whiteboard,
|
||||
'data-type': 'whiteboard'
|
||||
}, Messages.button_newwhiteboard)),
|
||||
$separator.clone()[0],
|
||||
h('li', h('a.cp-app-drive-context-empty.dropdown-item.cp-app-drive-context-editable', {
|
||||
'tabindex': '-1',
|
||||
'data-icon': faEmpty,
|
||||
@ -380,6 +386,7 @@ define([
|
||||
'tabindex': '-1',
|
||||
'data-icon': faRestore,
|
||||
}, Messages.fc_restore)),
|
||||
$separator.clone()[0],
|
||||
h('li', h('a.cp-app-drive-context-rename.dropdown-item.cp-app-drive-context-editable', {
|
||||
'tabindex': '-1',
|
||||
'data-icon': faRename,
|
||||
@ -406,6 +413,16 @@ define([
|
||||
}, Messages.fc_prop)),
|
||||
])
|
||||
]);
|
||||
$(menu).find("li a.dropdown-item").each(function (i, el) {
|
||||
var $icon = $("<span>");
|
||||
if ($(el).attr('data-icon')) {
|
||||
var font = $(el).attr('data-icon').indexOf('cptools') === 0 ? 'cptools' : 'fa';
|
||||
$icon.addClass(font).addClass($(el).attr('data-icon'));
|
||||
} else {
|
||||
$icon.text($(el).text());
|
||||
}
|
||||
$(el).prepend($icon);
|
||||
});
|
||||
return $(menu);
|
||||
};
|
||||
|
||||
@ -1053,8 +1070,7 @@ define([
|
||||
show = ['newfolder', 'newsharedfolder', 'newdoc'];
|
||||
break;
|
||||
case 'tree':
|
||||
show = ['open', 'openro', 'expandall', 'collapseall', 'color', 'download', 'share', 'rename', 'delete', 'deleteowned', 'removesf',
|
||||
'newfolder', 'properties', 'hashtag'];
|
||||
show = ['open', 'openro', 'expandall', 'collapseall', 'color', 'download', 'share', 'rename', 'delete', 'deleteowned', 'removesf', 'properties', 'hashtag'];
|
||||
break;
|
||||
case 'default':
|
||||
show = ['open', 'openro', 'share', 'openparent', 'delete', 'deleteowned', 'properties', 'hashtag'];
|
||||
@ -1238,6 +1254,20 @@ define([
|
||||
|
||||
var displayMenu = function (e) {
|
||||
var $menu = $contextMenu;
|
||||
var showSep = false;
|
||||
var $lastVisibleSep = null;
|
||||
$menu.find(".dropdown-menu").children().each(function (i, el) {
|
||||
var $el = $(el);
|
||||
if ($el.is(".dropdown-divider")) {
|
||||
$el.css("display", showSep ? "list-item" : "none");
|
||||
if (showSep) { $lastVisibleSep = $el; }
|
||||
showSep = false;
|
||||
}
|
||||
else if ($el.is("li") && $el.css("display") !== "none") {
|
||||
showSep = true;
|
||||
}
|
||||
});
|
||||
if (!showSep && $lastVisibleSep) { $lastVisibleSep.css("display", "none"); } // remove last divider if no options after
|
||||
$menu.css({ display: "block" });
|
||||
if (APP.mobile()) { return; }
|
||||
var h = $menu.outerHeight();
|
||||
@ -1313,11 +1343,7 @@ define([
|
||||
|
||||
displayMenu(e);
|
||||
|
||||
if ($contextMenu.find('li:visible').length === 0) {
|
||||
debug("No visible element in the context menu. Abort.");
|
||||
$contextMenu.hide();
|
||||
return true;
|
||||
}
|
||||
$(".cp-app-drive-context-noAction").toggle($contextMenu.find('li:visible').length === 0);
|
||||
|
||||
$contextMenu.data('paths', paths);
|
||||
return false;
|
||||
@ -1345,6 +1371,7 @@ define([
|
||||
});
|
||||
cb();
|
||||
};
|
||||
if (paths.some(function (p) { return manager.comparePath(newPath, p); })) { return void cb(); }
|
||||
manager.move(paths, newPath, newCb, copy);
|
||||
};
|
||||
// Delete paths from the drive and/or shared folders (without moving them to the trash)
|
||||
@ -2173,6 +2200,7 @@ define([
|
||||
pathname: "/drive/",
|
||||
friends: friends,
|
||||
title: data.title,
|
||||
password: data.password,
|
||||
common: common,
|
||||
hashes: {
|
||||
editHash: parsed.hash
|
||||
@ -2600,32 +2628,17 @@ define([
|
||||
var displaySearch = function ($list, value) {
|
||||
var filesList = manager.search(value);
|
||||
filesList.forEach(function (r) {
|
||||
// if r.id === null, then it's a folder, not a file
|
||||
r.paths.forEach(function (path) {
|
||||
if (!r.inSharedFolder &&
|
||||
APP.hideDuplicateOwned && manager.isDuplicateOwned(path)) { return; }
|
||||
var href = r.data.href;
|
||||
var parsed = Hash.parsePadUrl(href);
|
||||
var $table = $('<table>');
|
||||
var $icon = $('<td>', {'rowspan': '3', 'class': 'cp-app-drive-search-icon'})
|
||||
.append(getFileIcon(r.id));
|
||||
var $icon = $('<td>', {'rowspan': '3', 'class': 'cp-app-drive-search-icon'});
|
||||
var $title = $('<td>', {
|
||||
'class': 'cp-app-drive-search-col1 cp-app-drive-search-title'
|
||||
}).text(r.data.title)
|
||||
.click(function () {
|
||||
openFile(null, r.data.href);
|
||||
});
|
||||
var $typeName = $('<td>', {'class': 'cp-app-drive-search-label2'})
|
||||
.text(Messages.fm_type);
|
||||
var $type = $('<td>', {'class': 'cp-app-drive-search-col2'})
|
||||
.text(Messages.type[parsed.type] || parsed.type);
|
||||
var $atimeName = $('<td>', {'class': 'cp-app-drive-search-label2'})
|
||||
.text(Messages.fm_lastAccess);
|
||||
var $atime = $('<td>', {'class': 'cp-app-drive-search-col2'})
|
||||
.text(new Date(r.data.atime).toLocaleString());
|
||||
var $ctimeName = $('<td>', {'class': 'cp-app-drive-search-label2'})
|
||||
.text(Messages.fm_creation);
|
||||
var $ctime = $('<td>', {'class': 'cp-app-drive-search-col2'})
|
||||
.text(new Date(r.data.ctime).toLocaleString());
|
||||
}).text(r.data.title);
|
||||
if (manager.isPathIn(path, ['hrefArray'])) {
|
||||
path.pop();
|
||||
path.push(r.data.title);
|
||||
@ -2634,25 +2647,48 @@ define([
|
||||
'class': 'cp-app-drive-search-col1 cp-app-drive-search-path'
|
||||
});
|
||||
createTitle($path, path, true);
|
||||
var parentPath = path.slice();
|
||||
var $a;
|
||||
if (parentPath) {
|
||||
$a = $('<a>').text(Messages.fm_openParent).click(function (e) {
|
||||
e.preventDefault();
|
||||
if (manager.isInTrashRoot(parentPath)) { parentPath = [TRASH]; }
|
||||
else { parentPath.pop(); }
|
||||
APP.selectedFiles = [r.id];
|
||||
APP.displayDirectory(parentPath);
|
||||
var $typeName = $('<td>', {'class': 'cp-app-drive-search-label2'}).text(Messages.fm_type);
|
||||
var $type = $('<td>', {'class': 'cp-app-drive-search-col2'});
|
||||
var $atimeName = $('<td>', {'class': 'cp-app-drive-search-label2'});
|
||||
var $atime = $('<td>', {'class': 'cp-app-drive-search-col2'});
|
||||
var $ctimeName = $('<td>', {'class': 'cp-app-drive-search-label2'});
|
||||
var $ctime = $('<td>', {'class': 'cp-app-drive-search-col2'});
|
||||
var $openDir = $('<td>', {'class': 'cp-app-drive-search-opendir'});
|
||||
if (r.id) {
|
||||
$icon.append(getFileIcon(r.id));
|
||||
$type.text(Messages.type[parsed.type] || parsed.type);
|
||||
$title.click(function () {
|
||||
openFile(null, r.data.href);
|
||||
});
|
||||
$atimeName.text(Messages.fm_lastAccess);
|
||||
$atime.text(new Date(r.data.atime).toLocaleString());
|
||||
$ctimeName.text(Messages.fm_creation);
|
||||
$ctime.text(new Date(r.data.ctime).toLocaleString());
|
||||
var parentPath = path.slice();
|
||||
if (parentPath) {
|
||||
$('<a>').text(Messages.fm_openParent).click(function (e) {
|
||||
e.preventDefault();
|
||||
if (manager.isInTrashRoot(parentPath)) { parentPath = [TRASH]; }
|
||||
else { parentPath.pop(); }
|
||||
APP.selectedFiles = [r.id];
|
||||
APP.displayDirectory(parentPath);
|
||||
}).appendTo($openDir);
|
||||
}
|
||||
$('<a>').text(Messages.fc_prop).click(function () {
|
||||
APP.getProperties(r.id, function (e, $prop) {
|
||||
if (e) { return void logError(e); }
|
||||
UI.alert($prop[0], undefined, true);
|
||||
});
|
||||
}).appendTo($openDir);
|
||||
}
|
||||
else {
|
||||
$icon.append($folderIcon.clone());
|
||||
$type.text(Messages.fm_folder);
|
||||
$('<a>').text(Messages.fc_open).click(function (e) {
|
||||
e.preventDefault();
|
||||
APP.displayDirectory(path);
|
||||
}).appendTo($openDir);
|
||||
}
|
||||
var $openDir = $('<td>', {'class': 'cp-app-drive-search-opendir'}).append($a);
|
||||
|
||||
$('<a>').text(Messages.fc_prop).click(function () {
|
||||
APP.getProperties(r.id, function (e, $prop) {
|
||||
if (e) { return void logError(e); }
|
||||
UI.alert($prop[0], undefined, true);
|
||||
});
|
||||
}).appendTo($openDir);
|
||||
|
||||
// rows 1-3
|
||||
$('<tr>').append($icon).append($title).append($typeName).append($type).appendTo($table);
|
||||
@ -3198,7 +3234,7 @@ define([
|
||||
placeholder: Messages.fm_searchPlaceholder
|
||||
}).keyup(function (e) {
|
||||
if (search.to) { window.clearTimeout(search.to); }
|
||||
if ([38, 39, 40, 41].indexOf(e.which) !== -1) {
|
||||
if ([37, 38, 39, 40].indexOf(e.which) !== -1) {
|
||||
if (!$input.val()) {
|
||||
$input.blur();
|
||||
$content.focus();
|
||||
@ -3510,6 +3546,7 @@ define([
|
||||
friends: friends,
|
||||
title: data.title,
|
||||
common: common,
|
||||
password: data.password,
|
||||
hashes: {
|
||||
editHash: parsed.hash
|
||||
}
|
||||
@ -3523,6 +3560,7 @@ define([
|
||||
origin: APP.origin,
|
||||
pathname: "/" + padType + "/",
|
||||
friends: friends,
|
||||
password: data.password,
|
||||
hashes: {
|
||||
editHash: parsed.hash,
|
||||
viewHash: roParsed.hash,
|
||||
@ -3644,6 +3682,14 @@ define([
|
||||
APP.hideMenu();
|
||||
});
|
||||
|
||||
$content.on("keydown", function (e) {
|
||||
if (e.which === 113) {
|
||||
var paths = $contextMenu.data('paths');
|
||||
if (paths.length !== 1) { return; }
|
||||
displayRenameInput(paths[0].element, paths[0].path);
|
||||
}
|
||||
});
|
||||
|
||||
// Chrome considers the double-click means "select all" in the window
|
||||
$content.on('mousedown', function (e) {
|
||||
$content.focus();
|
||||
|
||||
@ -55,7 +55,7 @@ define([
|
||||
var makeNotificationList = function (key, filterTypes) {
|
||||
filterTypes = filterTypes || [];
|
||||
var safeKey = key.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
|
||||
var categoryName = Messages['notification_cat_' + safeKey] || safeKey;
|
||||
var categoryName = Messages['notifications_cat_' + safeKey] || safeKey;
|
||||
|
||||
var notifsData = [];
|
||||
if (key === "all") {
|
||||
@ -68,7 +68,7 @@ define([
|
||||
h("span.cp-app-notifications-panel-title",
|
||||
(Messages.notificationsPage || "Notifications") + " - " + categoryName),
|
||||
h("div.cp-app-notifications-panel-titlebar-buttons", [
|
||||
dismissAll = h("div.cp-app-notifications-dismissall.cp-clickable", { title: Messages.dismissAll || "Dismiss All" }, h("span.fa.fa-trash")),
|
||||
dismissAll = h("div.cp-app-notifications-dismissall.cp-clickable", { title: Messages.notifications_dismissAll || "Dismiss All" }, h("span.fa.fa-trash")),
|
||||
]),
|
||||
]),
|
||||
notifsList = h("div.cp-app-notifications-panel-list", [
|
||||
@ -87,13 +87,13 @@ define([
|
||||
var addArchivedNotification = function (data) {
|
||||
// if the type is allowed
|
||||
if (data.content.archived && notifsAllowedTypes.indexOf(data.content.msg.type) !== -1) {
|
||||
var isDataUnread = unreadData.findIndex(function (ud) {
|
||||
var isDataUnread = unreadData.some(function (ud) {
|
||||
return ud.content.hash === data.content.hash;
|
||||
}) !== -1;
|
||||
});
|
||||
notifsData.push(data);
|
||||
var el = common.mailbox.createElement(data);
|
||||
var time = new Date(data.content.time);
|
||||
$(el).find(".cp-notification-content").append(h("span.notification-time", time.toLocaleDateString() + " - " + time.toLocaleTimeString()));
|
||||
$(el).find(".cp-notification-content").append(h("span.notification-time", time.toLocaleString()));
|
||||
$(el).addClass("cp-app-notification-archived");
|
||||
$(el).toggle(!isDataUnread);
|
||||
$(notifsList).append(el);
|
||||
@ -106,7 +106,7 @@ define([
|
||||
var loadmore;
|
||||
var lastKnownHash;
|
||||
$(dismissAll).remove();
|
||||
loadmore = h("div.cp-app-notification-loadmore.cp-clickable", Messages.loadMore || "Load more ...");
|
||||
loadmore = h("div.cp-app-notification-loadmore.cp-clickable", Messages.history_loadMore);
|
||||
$(loadmore).click(function () {
|
||||
common.mailbox.getNotificationsHistory('notifications', 10, lastKnownHash, function (err, messages, end) {
|
||||
if (!Array.isArray(messages)) { return; }
|
||||
@ -211,7 +211,7 @@ define([
|
||||
showCategories(categories[key]);
|
||||
});
|
||||
|
||||
$category.append(Messages['notification_cat_'+key] || key);
|
||||
$category.append(Messages['notifications_cat_'+key] || key);
|
||||
});
|
||||
showCategories(categories[active]);
|
||||
};
|
||||
|
||||
@ -42,6 +42,7 @@ define([
|
||||
var modal = f({
|
||||
origin: origin,
|
||||
pathname: pathname,
|
||||
password: priv.password,
|
||||
hashes: hashes,
|
||||
common: common,
|
||||
title: data.title,
|
||||
|
||||
@ -151,6 +151,7 @@ define([
|
||||
channel: privateData.support,
|
||||
curvePublic: user.curvePublic
|
||||
});
|
||||
id = Util.uid();
|
||||
if (sent) {
|
||||
$('.cp-sidebarlayout-category[data-category="tickets"]').click();
|
||||
}
|
||||
|
||||
@ -21,7 +21,8 @@ define([
|
||||
name: user.name,
|
||||
channel: privateData.support,
|
||||
curvePublic: user.curvePublic,
|
||||
edPublic: privateData.edPublic
|
||||
edPublic: privateData.edPublic,
|
||||
notifications: user.notifications,
|
||||
};
|
||||
data.id = id;
|
||||
data.time = +new Date();
|
||||
@ -41,13 +42,13 @@ define([
|
||||
var $title = $(form).find('.cp-support-form-title');
|
||||
var $content = $(form).find('.cp-support-form-msg');
|
||||
|
||||
var title = $title.val();
|
||||
var title = $title.val().trim();
|
||||
if (!title) {
|
||||
return void UI.alert(Messages.support_formTitleError);
|
||||
}
|
||||
var content = $content.val();
|
||||
var content = $content.val().trim();
|
||||
if (!content) {
|
||||
return void UI.alert(form, Messages.support_formContentError);
|
||||
return void UI.alert(Messages.support_formContentError);
|
||||
}
|
||||
$content.val('');
|
||||
$title.val('');
|
||||
@ -160,7 +161,7 @@ define([
|
||||
'data-hash': hash
|
||||
}, [
|
||||
h('div.cp-support-message-from' + (fromMe ? '.cp-support-fromme' : ''), [
|
||||
h('span', Messages._getKey('support_from', [content.sender.name])),
|
||||
UI.setHTML(h('span'), Messages._getKey('support_from', [content.sender.name])),
|
||||
h('span.cp-support-message-time', content.time ? new Date(content.time).toLocaleString() : '')
|
||||
]),
|
||||
h('pre.cp-support-message-content', content.message),
|
||||
@ -177,7 +178,7 @@ define([
|
||||
'data-hash': hash
|
||||
}, [
|
||||
h('div.cp-support-message-from' + (fromMe ? '.cp-support-fromme' : ''), [
|
||||
h('span', Messages._getKey('support_from', [content.sender.name])),
|
||||
UI.setHTML(h('span'), Messages._getKey('support_from', [content.sender.name])),
|
||||
h('span.cp-support-message-time', content.time ? new Date(content.time).toLocaleString() : '')
|
||||
]),
|
||||
h('pre.cp-support-message-content', Messages.support_closed)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user