Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging
This commit is contained in:
commit
b8343b5483
15 changed files with 112 additions and 64 deletions
|
@ -5,6 +5,7 @@ var map = {
|
||||||
'es': 'Español',
|
'es': 'Español',
|
||||||
'el': 'Ελληνικά',
|
'el': 'Ελληνικά',
|
||||||
'fr': 'Français',
|
'fr': 'Français',
|
||||||
|
'nb': 'Norwegian Bokmål',
|
||||||
'pl': 'Polski',
|
'pl': 'Polski',
|
||||||
'pt-br': 'Português do Brasil',
|
'pt-br': 'Português do Brasil',
|
||||||
'ro': 'Română',
|
'ro': 'Română',
|
||||||
|
|
14
customize.dist/translations/messages.nb.js
Normal file
14
customize.dist/translations/messages.nb.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* You can override the translation text using this file.
|
||||||
|
* The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js)
|
||||||
|
in a 'customize' directory (/customize/translations/messages.{LANG}.js).
|
||||||
|
* If you want to check all the existing translation keys, you can open the internal language file
|
||||||
|
but you should not change it directly (/common/translations/messages.{LANG}.js)
|
||||||
|
*/
|
||||||
|
define(['/common/translations/messages.nb.js'], function (Messages) {
|
||||||
|
// Replace the existing keys in your copied file here:
|
||||||
|
// Messages.button_newpad = "New Rich Text Document";
|
||||||
|
|
||||||
|
return Messages;
|
||||||
|
});
|
||||||
|
|
|
@ -58147,37 +58147,6 @@ function Log(level) {
|
||||||
this.warn = function () {};
|
this.warn = function () {};
|
||||||
this.error = function () {};
|
this.error = function () {};
|
||||||
this.log = function () {};
|
this.log = function () {};
|
||||||
return;
|
|
||||||
this.log = function () {
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
|
||||||
var level = args.shift();
|
|
||||||
var logLevel = this.level;
|
|
||||||
if (typeof logLevel === 'undefined') {
|
|
||||||
logLevel = defaultLevel;
|
|
||||||
}
|
|
||||||
if (logLevel <= level) {
|
|
||||||
if (typeof console !== 'undefined') {
|
|
||||||
//eslint-disable-line no-console
|
|
||||||
if (typeof console.log !== 'undefined') {
|
|
||||||
//eslint-disable-line no-console
|
|
||||||
//return console.log('[' + formatTime(new Date()) + '] ' , str); //eslint-disable-line no-console
|
|
||||||
args.unshift('[' + formatTime(new Date()) + '] ');
|
|
||||||
console.log.apply(console, args.map(function (a) {
|
|
||||||
if (typeof a === "object") {
|
|
||||||
return a.toString() + JSON.stringify(a, null, 2);
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.trace = window.console.debug.bind(window.console, format('TRACE', name), 'color:grey;', 'color: grey;');
|
|
||||||
this.debug = window.console.debug.bind(window.console, format('DEBUG', name), 'color:grey;', 'color: green;');
|
|
||||||
this.info = window.console.debug.bind(window.console, format('INFO', name), 'color:grey;', 'color: blue;');
|
|
||||||
this.warn = window.console.debug.bind(window.console, format('WARN', name), 'color:grey;', 'color: orange;');
|
|
||||||
this.error = window.console.debug.bind(window.console, format('ERROR', name), 'color:grey;', 'color: red;');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.Log = Log;
|
exports.Log = Log;
|
||||||
|
|
|
@ -965,6 +965,7 @@ define([
|
||||||
if (channel.padChan !== padChan) { return; }
|
if (channel.padChan !== padChan) { return; }
|
||||||
if (channel.wc) { channel.wc.leave(); }
|
if (channel.wc) { channel.wc.leave(); }
|
||||||
channel.stopped = true;
|
channel.stopped = true;
|
||||||
|
delete channels[chatChan];
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1058,14 +1058,12 @@ define([
|
||||||
};
|
};
|
||||||
|
|
||||||
var timeout = false;
|
var timeout = false;
|
||||||
|
common.onTimeoutEvent = Util.mkEvent();
|
||||||
var onTimeout = function () {
|
var onTimeout = function () {
|
||||||
return;
|
|
||||||
/*
|
|
||||||
timeout = true;
|
timeout = true;
|
||||||
common.onNetworkDisconnect.fire();
|
common.onNetworkDisconnect.fire();
|
||||||
// FIXME: no UI in outer...
|
common.padRpc.onDisconnectEvent.fire();
|
||||||
window.alert("Timeout error, please reload this tab");
|
common.onTimeoutEvent.fire();
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var queries = {
|
var queries = {
|
||||||
|
|
|
@ -18,6 +18,25 @@ define(['json.sortify'], function (Sortify) {
|
||||||
var lazyChangeHandlers = [];
|
var lazyChangeHandlers = [];
|
||||||
var titleChangeHandlers = [];
|
var titleChangeHandlers = [];
|
||||||
|
|
||||||
|
// When someone leaves the document, their metadata is removed from our metadataObj
|
||||||
|
// but it is not removed instantly from the chainpad document metadata. This is
|
||||||
|
// the result of the lazy object: if we had to remove the metadata instantly, all
|
||||||
|
// the remaining members would try to push a patch to do it, and it could create
|
||||||
|
// conflicts. Their metadata is instead removed from the chainpad doc only when
|
||||||
|
// someone calls onLocal to make another change.
|
||||||
|
// The leaving user is not visible in the userlist UI because we filter it using
|
||||||
|
// the list of "members" (netflux ID currently online).
|
||||||
|
// Our Problem:
|
||||||
|
// With the addition of shared workers, a user can leave and join back with the same
|
||||||
|
// netflux ID (just reload the pad). If nobody has made any change in the mean time,
|
||||||
|
// their metadata will still be in the document, but they won't be in our metadataObj.
|
||||||
|
// This causes the presence of a "viewer" instead of an editor, because they don't
|
||||||
|
// have user data.
|
||||||
|
// To fix this problem, the metadata manager can request "syncs" from a chainpad app,
|
||||||
|
// and the app should trigger a "metadataMgr.updateMetadata(data)" in the handler.
|
||||||
|
// See "metadataMgr.onRequestSync" in sframe-app-framework for an example.
|
||||||
|
var syncHandlers = [];
|
||||||
|
|
||||||
var rememberedTitle;
|
var rememberedTitle;
|
||||||
|
|
||||||
var checkUpdate = function (lazy) {
|
var checkUpdate = function (lazy) {
|
||||||
|
@ -41,26 +60,25 @@ define(['json.sortify'], function (Sortify) {
|
||||||
|
|
||||||
var mdo = {};
|
var mdo = {};
|
||||||
// We don't want to add our user data to the object multiple times.
|
// We don't want to add our user data to the object multiple times.
|
||||||
//var containsYou = false;
|
|
||||||
//console.log(metadataObj);
|
|
||||||
Object.keys(metadataObj.users).forEach(function (x) {
|
Object.keys(metadataObj.users).forEach(function (x) {
|
||||||
if (members.indexOf(x) === -1) { return; }
|
if (members.indexOf(x) === -1) { return; }
|
||||||
mdo[x] = metadataObj.users[x];
|
mdo[x] = metadataObj.users[x];
|
||||||
/*if (metadataObj.users[x].uid === meta.user.uid) {
|
|
||||||
//console.log('document already contains you');
|
|
||||||
containsYou = true;
|
|
||||||
}*/
|
|
||||||
});
|
});
|
||||||
//if (!containsYou) { mdo[meta.user.netfluxId] = meta.user; }
|
|
||||||
if (!priv.readOnly) {
|
if (!priv.readOnly) {
|
||||||
mdo[meta.user.netfluxId] = meta.user;
|
mdo[meta.user.netfluxId] = meta.user;
|
||||||
}
|
}
|
||||||
metadataObj.users = mdo;
|
metadataObj.users = mdo;
|
||||||
|
|
||||||
|
// Always update the userlist in the lazy object, otherwise it may be outdated
|
||||||
|
// and metadataMgr.updateMetadata() won't do anything, and so we won't push events
|
||||||
|
// to the userlist UI ==> phantom viewers
|
||||||
var lazyUserStr = Sortify(metadataLazyObj.users[meta.user.netfluxId]);
|
var lazyUserStr = Sortify(metadataLazyObj.users[meta.user.netfluxId]);
|
||||||
dirty = false;
|
dirty = false;
|
||||||
if (lazy || lazyUserStr !== Sortify(meta.user)) {
|
if (lazy || lazyUserStr !== Sortify(meta.user)) {
|
||||||
metadataLazyObj = JSON.parse(JSON.stringify(metadataObj));
|
metadataLazyObj = JSON.parse(JSON.stringify(metadataObj));
|
||||||
lazyChangeHandlers.forEach(function (f) { f(); });
|
lazyChangeHandlers.forEach(function (f) { f(); });
|
||||||
|
} else {
|
||||||
|
metadataLazyObj.users = JSON.parse(JSON.stringify(mdo));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metadataObj.title !== rememberedTitle) {
|
if (metadataObj.title !== rememberedTitle) {
|
||||||
|
@ -127,6 +145,7 @@ define(['json.sortify'], function (Sortify) {
|
||||||
members.push(ev);
|
members.push(ev);
|
||||||
if (!meta.user) { return; }
|
if (!meta.user) { return; }
|
||||||
change(false);
|
change(false);
|
||||||
|
syncHandlers.forEach(function (f) { f(); });
|
||||||
});
|
});
|
||||||
sframeChan.on('EV_RT_LEAVE', function (ev) {
|
sframeChan.on('EV_RT_LEAVE', function (ev) {
|
||||||
var idx = members.indexOf(ev);
|
var idx = members.indexOf(ev);
|
||||||
|
@ -171,13 +190,14 @@ define(['json.sortify'], function (Sortify) {
|
||||||
onTitleChange: function (f) { titleChangeHandlers.push(f); },
|
onTitleChange: function (f) { titleChangeHandlers.push(f); },
|
||||||
onChange: function (f) { changeHandlers.push(f); },
|
onChange: function (f) { changeHandlers.push(f); },
|
||||||
onChangeLazy: function (f) { lazyChangeHandlers.push(f); },
|
onChangeLazy: function (f) { lazyChangeHandlers.push(f); },
|
||||||
|
onRequestSync: function (f) { syncHandlers.push(f); },
|
||||||
isConnected : function () {
|
isConnected : function () {
|
||||||
return members.indexOf(meta.user.netfluxId) !== -1;
|
return members.indexOf(meta.user.netfluxId) !== -1;
|
||||||
},
|
},
|
||||||
getViewers : function () {
|
getViewers : function () {
|
||||||
checkUpdate(false);
|
checkUpdate(false);
|
||||||
var list = members.slice().filter(function (m) { return m.length === 32; });
|
var list = members.slice().filter(function (m) { return m.length === 32; });
|
||||||
return list.length - Object.keys(metadataObj.users).length;
|
return list.length - Object.keys(metadataLazyObj.users).length;
|
||||||
},
|
},
|
||||||
getChannelMembers: function () { return members.slice(); },
|
getChannelMembers: function () { return members.slice(); },
|
||||||
getPrivateData : function () {
|
getPrivateData : function () {
|
||||||
|
|
|
@ -1262,9 +1262,15 @@ define([
|
||||||
var messengerEventClients = [];
|
var messengerEventClients = [];
|
||||||
|
|
||||||
var dropChannel = function (chanId) {
|
var dropChannel = function (chanId) {
|
||||||
store.messenger.leavePad(chanId);
|
try {
|
||||||
store.cursor.leavePad(chanId);
|
store.messenger.leavePad(chanId);
|
||||||
store.onlyoffice.leavePad(chanId);
|
} catch (e) { console.error(e); }
|
||||||
|
try {
|
||||||
|
store.cursor.leavePad(chanId);
|
||||||
|
} catch (e) { console.error(e); }
|
||||||
|
try {
|
||||||
|
store.onlyoffice.leavePad(chanId);
|
||||||
|
} catch (e) { console.error(e); }
|
||||||
|
|
||||||
if (!Store.channels[chanId]) { return; }
|
if (!Store.channels[chanId]) { return; }
|
||||||
|
|
||||||
|
@ -1283,8 +1289,12 @@ define([
|
||||||
if (messengerIdx !== -1) {
|
if (messengerIdx !== -1) {
|
||||||
messengerEventClients.splice(messengerIdx, 1);
|
messengerEventClients.splice(messengerIdx, 1);
|
||||||
}
|
}
|
||||||
store.cursor.removeClient(clientId);
|
try {
|
||||||
store.onlyoffice.removeClient(clientId);
|
store.cursor.removeClient(clientId);
|
||||||
|
} catch (e) { console.error(e); }
|
||||||
|
try {
|
||||||
|
store.onlyoffice.removeClient(clientId);
|
||||||
|
} catch (e) { console.error(e); }
|
||||||
|
|
||||||
Object.keys(Store.channels).forEach(function (chanId) {
|
Object.keys(Store.channels).forEach(function (chanId) {
|
||||||
var chanIdx = Store.channels[chanId].clients.indexOf(clientId);
|
var chanIdx = Store.channels[chanId].clients.indexOf(clientId);
|
||||||
|
@ -1602,12 +1612,11 @@ define([
|
||||||
broadcast([], 'NETWORK_RECONNECT', {myId: info.myId});
|
broadcast([], 'NETWORK_RECONNECT', {myId: info.myId});
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
// Ping clients regularly to make sure one tab was not closed without sending a removeClient()
|
// Ping clients regularly to make sure one tab was not closed without sending a removeClient()
|
||||||
// command. This allow us to avoid phantom viewers in pads.
|
// command. This allow us to avoid phantom viewers in pads.
|
||||||
var PING_INTERVAL = 30000;
|
var PING_INTERVAL = 30000;
|
||||||
var MAX_PING = 1000;
|
var MAX_PING = 5000;
|
||||||
var MAX_FAILED_PING = 5;
|
var MAX_FAILED_PING = 2;
|
||||||
|
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
var clients = [];
|
var clients = [];
|
||||||
|
@ -1635,7 +1644,6 @@ define([
|
||||||
ping();
|
ping();
|
||||||
});
|
});
|
||||||
}, PING_INTERVAL);
|
}, PING_INTERVAL);
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -533,6 +533,12 @@ define([
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
cpNfInner.metadataMgr.onChange(checkReady);
|
cpNfInner.metadataMgr.onChange(checkReady);
|
||||||
|
cpNfInner.metadataMgr.onRequestSync(function () {
|
||||||
|
var newContentStr = cpNfInner.chainpad.getUserDoc();
|
||||||
|
var newContent = JSON.parse(newContentStr);
|
||||||
|
var meta = extractMetadata(newContent);
|
||||||
|
cpNfInner.metadataMgr.updateMetadata(meta);
|
||||||
|
});
|
||||||
checkReady();
|
checkReady();
|
||||||
|
|
||||||
var infiniteSpinnerModal = false;
|
var infiniteSpinnerModal = false;
|
||||||
|
|
|
@ -269,6 +269,9 @@ define([
|
||||||
sessionStorage[Utils.Constants.displayPadCreationScreen];
|
sessionStorage[Utils.Constants.displayPadCreationScreen];
|
||||||
delete sessionStorage[Utils.Constants.displayPadCreationScreen];
|
delete sessionStorage[Utils.Constants.displayPadCreationScreen];
|
||||||
var updateMeta = function () {
|
var updateMeta = function () {
|
||||||
|
// TODO availableHashes in privateData may need updates once we have
|
||||||
|
// a better privileges workflow
|
||||||
|
|
||||||
//console.log('EV_METADATA_UPDATE');
|
//console.log('EV_METADATA_UPDATE');
|
||||||
var metaObj, isTemplate;
|
var metaObj, isTemplate;
|
||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
|
@ -874,6 +877,10 @@ define([
|
||||||
Cryptpad.cursor.execCommand(data, cb);
|
Cryptpad.cursor.execCommand(data, cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Cryptpad.onTimeoutEvent.reg(function () {
|
||||||
|
sframeChan.event('EV_WORKER_TIMEOUT');
|
||||||
|
});
|
||||||
|
|
||||||
if (cfg.messaging) {
|
if (cfg.messaging) {
|
||||||
Notifier.getPermission();
|
Notifier.getPermission();
|
||||||
|
|
||||||
|
|
|
@ -51,14 +51,16 @@ define([
|
||||||
metadataMgr.onChange(function () {
|
metadataMgr.onChange(function () {
|
||||||
var md = metadataMgr.getMetadata();
|
var md = metadataMgr.getMetadata();
|
||||||
if ($title) {
|
if ($title) {
|
||||||
$title.find('span.cp-toolbar-title-value').text(md.title || md.defaultTitle);
|
|
||||||
$title.find('input').val(md.title || md.defaultTitle);
|
|
||||||
$title.find('input').prop('placeholder', md.defaultTitle);
|
$title.find('input').prop('placeholder', md.defaultTitle);
|
||||||
}
|
}
|
||||||
exp.defaultTitle = md.defaultTitle;
|
exp.defaultTitle = md.defaultTitle;
|
||||||
exp.title = md.title;
|
|
||||||
});
|
});
|
||||||
metadataMgr.onTitleChange(function (title, defaultTitle) {
|
metadataMgr.onTitleChange(function (title, defaultTitle) {
|
||||||
|
if ($title) {
|
||||||
|
$title.find('span.cp-toolbar-title-value').text(title || defaultTitle);
|
||||||
|
$title.find('input').val(title || defaultTitle);
|
||||||
|
}
|
||||||
|
exp.title = title;
|
||||||
sframeChan.query('Q_SET_PAD_TITLE_IN_DRIVE', {
|
sframeChan.query('Q_SET_PAD_TITLE_IN_DRIVE', {
|
||||||
title: title,
|
title: title,
|
||||||
defaultTitle: defaultTitle
|
defaultTitle: defaultTitle
|
||||||
|
|
|
@ -613,6 +613,10 @@ define([
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ctx.sframeChan.on('EV_WORKER_TIMEOUT', function () {
|
||||||
|
UI.errorLoadingScreen(Messages.timeoutError);
|
||||||
|
});
|
||||||
|
|
||||||
ctx.sframeChan.on('EV_CHROME_68', function () {
|
ctx.sframeChan.on('EV_CHROME_68', function () {
|
||||||
UI.alert(Messages.chrome68);
|
UI.alert(Messages.chrome68);
|
||||||
});
|
});
|
||||||
|
|
|
@ -475,11 +475,11 @@ MessengerUI, Messages) {
|
||||||
};
|
};
|
||||||
$closeIcon.click(function () {
|
$closeIcon.click(function () {
|
||||||
Common.setAttribute(['toolbar', 'chat-drawer'], false);
|
Common.setAttribute(['toolbar', 'chat-drawer'], false);
|
||||||
hide();
|
hide(true);
|
||||||
});
|
});
|
||||||
$button.click(function () {
|
$button.click(function () {
|
||||||
var visible = $content.is(':visible');
|
var visible = $content.is(':visible');
|
||||||
if (visible) { hide(); }
|
if (visible) { hide(true); }
|
||||||
else { show(); }
|
else { show(); }
|
||||||
visible = !visible;
|
visible = !visible;
|
||||||
Common.setAttribute(['toolbar', 'chat-drawer'], visible);
|
Common.setAttribute(['toolbar', 'chat-drawer'], visible);
|
||||||
|
|
2
www/common/translations/messages.nb.json
Normal file
2
www/common/translations/messages.nb.json
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{
|
||||||
|
}
|
|
@ -143,7 +143,7 @@
|
||||||
"tags_notShared": "Ваши теги не разделяются с другими пользователями",
|
"tags_notShared": "Ваши теги не разделяются с другими пользователями",
|
||||||
"button_newsheet": "Новый Лист",
|
"button_newsheet": "Новый Лист",
|
||||||
"newButtonTitle": "Создать новый блокнот",
|
"newButtonTitle": "Создать новый блокнот",
|
||||||
"useTemplateCancel": "Начать без образца (Esc)",
|
"useTemplateCancel": "Начать заново (Esc)",
|
||||||
"previewButtonTitle": "Отобразить или скрыть режим предпросмотра разметки",
|
"previewButtonTitle": "Отобразить или скрыть режим предпросмотра разметки",
|
||||||
"printOptions": "Опции расположения",
|
"printOptions": "Опции расположения",
|
||||||
"printBackgroundValue": "<b>Текущий фон:</b> <em>{0}</em>",
|
"printBackgroundValue": "<b>Текущий фон:</b> <em>{0}</em>",
|
||||||
|
@ -163,7 +163,7 @@
|
||||||
"editOpen": "Открыть редактируемую ссылку в новой вкладке",
|
"editOpen": "Открыть редактируемую ссылку в новой вкладке",
|
||||||
"editOpenTitle": "Открыть блокнот в режиме редактирования в новой вкладке",
|
"editOpenTitle": "Открыть блокнот в режиме редактирования в новой вкладке",
|
||||||
"viewShare": "Ссылка только для чтения",
|
"viewShare": "Ссылка только для чтения",
|
||||||
"viewShareTitle": "Копировать ссылку для чтения",
|
"viewShareTitle": "Скопировать ссылку для чтения в буфер обмена",
|
||||||
"viewOpen": "Открыть ссылку в режиме чтения в новой вкладке",
|
"viewOpen": "Открыть ссылку в режиме чтения в новой вкладке",
|
||||||
"viewOpenTitle": "Открыть блокнот в режиме чтения в новой вкладке",
|
"viewOpenTitle": "Открыть блокнот в режиме чтения в новой вкладке",
|
||||||
"fileShare": "Скопировать ссылку",
|
"fileShare": "Скопировать ссылку",
|
||||||
|
@ -204,10 +204,10 @@
|
||||||
"kanban_working": "В процессе",
|
"kanban_working": "В процессе",
|
||||||
"kanban_deleteBoard": "Вы уверены, что хотите удалить эту доску?",
|
"kanban_deleteBoard": "Вы уверены, что хотите удалить эту доску?",
|
||||||
"kanban_addBoard": "Добавить доску",
|
"kanban_addBoard": "Добавить доску",
|
||||||
"kanban_removeItem": "",
|
"kanban_removeItem": "Удалить этот элемент",
|
||||||
"poll_p_save": "Ваши настройки применяются мгновенно, так что вам не нужно их сохранять",
|
"poll_p_save": "Ваши настройки применяются мгновенно, так что вам не нужно их сохранять.",
|
||||||
"wizardTitle": "Используйте помощник, чтобы создать опрос",
|
"wizardTitle": "Используйте помощник, чтобы создать опрос",
|
||||||
"wizardConfirm": "Вы хотите добавить эти варианты в опрос?",
|
"wizardConfirm": "Вы действительно хотите добавить эти варианты в ваш опрос?",
|
||||||
"poll_publish_button": "Опубликовать",
|
"poll_publish_button": "Опубликовать",
|
||||||
"poll_admin_button": "Админ",
|
"poll_admin_button": "Админ",
|
||||||
"poll_create_user": "Добавить нового пользователя",
|
"poll_create_user": "Добавить нового пользователя",
|
||||||
|
@ -305,5 +305,17 @@
|
||||||
"crowdfunding_popup_no": "Не сейчас",
|
"crowdfunding_popup_no": "Не сейчас",
|
||||||
"crowdfunding_popup_never": "Не спрашивать меня снова",
|
"crowdfunding_popup_never": "Не спрашивать меня снова",
|
||||||
"markdown_toc": "Содержимое",
|
"markdown_toc": "Содержимое",
|
||||||
"fm_expirablePad": "Этот блокнот удалится через {0}"
|
"fm_expirablePad": "Этот блокнот удалится через {0}",
|
||||||
|
"fileEmbedTitle": "Вставить файл во внешнюю страницу",
|
||||||
|
"kanban_removeItemConfirm": "Вы уверенны, что хотите удалить этот пункт?",
|
||||||
|
"settings_backup2": "Скачать мой CryptDrive",
|
||||||
|
"settings_backup2Confirm": "Это позволит скачать все пэды и файлы с вашего CryptDrive. Если вы хотите продолжить, выберите имя и нажмите OK",
|
||||||
|
"settings_exportTitle": "Экспортировать Ваш CryptDrive",
|
||||||
|
"fileEmbedScript": "Чтобы вставить этот файл, включите этот скрипт один раз на своей странице, чтобы загрузить медиатег:",
|
||||||
|
"fileEmbedTag": "Затем поместите медиатег в любое место на странице, куда вы хотите его вставить:",
|
||||||
|
"pad_mediatagRatio": "Оставить соотношение",
|
||||||
|
"kanban_item": "Элемент {0}",
|
||||||
|
"poll_p_encryption": "Все ваши данные зашифрованы, доступ к ним имеют только пользователи, имеющие доступ к этой ссылке. Даже сервер не видит, что вы меняете.",
|
||||||
|
"wizardLog": "Нажмите кнопку в левом верхнем углу, чтобы вернуться к опросу",
|
||||||
|
"poll_bookmark_col": "Добавить этот столбец в закладку, чтобы он всегда был разблокирован и отображался для вас в начале"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1158,6 +1158,10 @@ define([
|
||||||
var md = copyObject(metadataMgr.getMetadata());
|
var md = copyObject(metadataMgr.getMetadata());
|
||||||
APP.proxy.metadata = md;
|
APP.proxy.metadata = md;
|
||||||
});
|
});
|
||||||
|
metadataMgr.onRequestSync(function () {
|
||||||
|
var meta = JSON.parse(JSON.stringify(APP.proxy.metadata));
|
||||||
|
metadataMgr.updateMetadata(meta);
|
||||||
|
});
|
||||||
|
|
||||||
/* add a forget button */
|
/* add a forget button */
|
||||||
var forgetCb = function (err) {
|
var forgetCb = function (err) {
|
||||||
|
|
Loading…
Reference in a new issue