Merge branch 'staging' into restricted-registration

This commit is contained in:
ansuz 2021-04-29 06:50:38 +05:30
commit b1e69e5c91
16 changed files with 1531 additions and 45 deletions

View File

@ -102,8 +102,7 @@ define([
Pages.privacyLink = footLink(AppConfig.privacy, 'privacy');
Pages.githubLink = footLink('https://github.com/xwiki-labs/cryptpad', null, 'GitHub');
Pages.docsLink = footLink('https://docs.cryptpad.fr', 'docs_link');
Msg.home_roadmap = "Roadmap"; // XXX
Pages.roadmapLink = footLink(AppConfig.roadmap, 'home_roadmap');
Pages.roadmapLink = footLink(AppConfig.roadmap, 'footer_roadmap');
Pages.infopageFooter = function () {
var terms = footLink('/terms.html', 'footer_tos'); // FIXME this should be configurable like the other legal pages

View File

@ -11,6 +11,10 @@
display: flex;
flex-flow: column;
.cp-toolbar-bottom-mid > div {
.cp-small { display: none; }
}
#cp-sidebarlayout-container #cp-sidebarlayout-rightside {
padding: 0;
& > div {
@ -385,5 +389,43 @@
cursor: pointer;
border: 1px solid @cp_forms-border;
}
@media (max-width: @browser_media-medium-screen) {
.cp-calendar-newevent {
i {
margin: 0 !important;
}
span {
display: none;
}
}
.tui-full-calendar-dayname-leftmargin, .tui-full-calendar-timegrid-right {
margin-left: 40px !important;
}
.tui-full-calendar-allday-left, .tui-full-calendar-timegrid-left {
width: 40px !important;
}
.tui-full-calendar-dayname > span {
display: flex;
flex-flow: column;
line-height: 0;
justify-content: center;
align-items: center;
height: 100%;
}
.tui-full-calendar-dayname * {
font-size: 11px;
line-height: initial;
height: auto;
}
.cp-toolbar-bottom-mid > div {
:not(:first-child) {
display: none;
}
:first-child {
display: inline-block;
}
}
}
}

View File

@ -70,7 +70,6 @@ Messages.calendar_deleteConfirm = "Are you sure you want to delete this calendar
Messages.calendar_deleteTeamConfirm = "Are you sure you want to delete this calendar from this team?";
Messages.calendar_deleteOwned = " It will still be visible for the users it has been shared with.";
Messages.calendar_errorNoCalendar = "No editable calendar selected!";
Messages.calendar_myCalendars = "My calendars";
Messages.calendar_tempCalendar = "Viewing";
Messages.calendar_import = "Import to my calendars";
Messages.calendar_import_temp = "Import this calendar";
@ -78,6 +77,7 @@ Messages.calendar_newEvent = "New event";
Messages.calendar_new = "New calendar";
Messages.calendar_dateRange = "{0} - {1}";
Messages.calendar_dateTimeRange = "{0} {1} - {2}";
Messages.calendar_weekNumber = "Week {0}";
Messages.calendar_update = "Update";
Messages.calendar_title = "Title";
Messages.calendar_loc = "Location";
@ -153,13 +153,16 @@ Messages.calendar_noNotification = "None";
return (brightness > 125) ? '#424242' : '#EEEEEE';
};
var getWeekDays = function () {
var getWeekDays = function (large) {
var baseDate = new Date(Date.UTC(2017, 0, 1)); // just a Sunday
var weekDays = [];
for(var i = 0; i < 7; i++) {
weekDays.push(baseDate.toLocaleDateString(undefined, { weekday: 'long' }));
baseDate.setDate(baseDate.getDate() + 1);
}
if (!large) {
weekDays = weekDays.map(function (day) { return day.slice(0,3); });
}
return weekDays.map(function (day) { return day.replace(/^./, function (str) { return str.toUpperCase(); }); });
};
@ -314,7 +317,6 @@ Messages.calendar_noNotification = "None";
}
};
// XXX Note: always create calendars in your own proxy. If you want a team calendar, you can share it with the team later.
var editCalendar = function (id) {
var isNew = !id;
var data = APP.calendars[id];
@ -449,7 +451,7 @@ Messages.calendar_noNotification = "None";
pathname: "/calendar/",
friends: friends,
title: title,
password: cal.password, // XXX support passwords
password: cal.password,
calendar: {
title: title,
color: color,
@ -476,7 +478,7 @@ Messages.calendar_noNotification = "None";
var href = Hash.hashToHref(h.editHash || h.viewHash, 'calendar');
Access.getAccessModal(common, {
title: title,
password: cal.password, // XXX support passwords
password: cal.password,
calendar: {
title: title,
color: color,
@ -633,7 +635,6 @@ Messages.calendar_noNotification = "None";
return UIElements.createDropdown(dropdownConfig)[0];
};
var makeCalendarEntry = function (id, teamId) {
// XXX handle RESTRICTED calendars (data.restricted)
var data = APP.calendars[id];
var edit;
if (data.loading) {
@ -686,8 +687,8 @@ Messages.calendar_noNotification = "None";
var filter = function (teamId) {
return Object.keys(APP.calendars || {}).filter(function (id) {
var cal = APP.calendars[id] || {};
var teams = cal.teams || [];
return teams.indexOf(typeof(teamId) !== "undefined" ? teamId : 1) !== -1;
var teams = (cal.teams || []).map(function (tId) { return Number(tId); });
return teams.indexOf(typeof(teamId) !== "undefined" ? Number(teamId) : 1) !== -1;
});
};
var tempCalendars = filter(0);
@ -717,8 +718,13 @@ Messages.calendar_noNotification = "None";
}
var myCalendars = filter(1);
if (myCalendars.length) {
var user = metadataMgr.getUserData();
var avatar = h('span.cp-avatar');
var name = user.name || Messages.anonymous;
common.displayAvatar($(avatar), user.avatar, name);
APP.$calendars.append(h('div.cp-calendar-team', [
h('span', Messages.calendar_myCalendars)
avatar,
h('span.cp-name', {title: name}, name)
]));
}
myCalendars.forEach(function (id) {
@ -754,11 +760,26 @@ Messages.calendar_noNotification = "None";
onCalendarsUpdate.fire();
};
var ISO8601_week_no = function (dt) {
var tdt = new Date(dt.valueOf());
var dayn = (dt.getDay() + 6) % 7;
tdt.setDate(tdt.getDate() - dayn + 3);
var firstThursday = tdt.valueOf();
tdt.setMonth(0, 1);
if (tdt.getDay() !== 4) {
tdt.setMonth(0, 1 + ((4 - tdt.getDay()) + 7) % 7);
}
return 1 + Math.ceil((firstThursday - tdt) / 604800000);
};
var updateDateRange = function () {
var range = APP.calendar._renderRange;
var start = range.start._date.toLocaleDateString();
var end = range.end._date.toLocaleDateString();
var week = ISO8601_week_no(range.start._date);
var date = [
h('b.cp-small', Messages._getKey('calendar_weekNumber', [week])),
h('b', start),
h('span', ' - '),
h('b', end),
@ -791,6 +812,7 @@ Messages.calendar_noNotification = "None";
h('div#cp-sidebarlayout-rightside')
]);
var large = $(window).width() >= 800;
var cal = APP.calendar = new Calendar('#cp-sidebarlayout-rightside', {
defaultView: view || 'week', // weekly view option
taskView: false,
@ -800,19 +822,36 @@ Messages.calendar_noNotification = "None";
calendars: getCalendars(),
template: templates,
month: {
daynames: getWeekDays(),
daynames: getWeekDays(large),
startDayOfWeek: 1,
},
week: {
daynames: getWeekDays(),
daynames: getWeekDays(large),
startDayOfWeek: 1,
}
});
$(window).on('resize', function () {
var _large = $(window).width() >= 800;
if (large !== _large) {
large = _large;
cal.setOptions({
month: {
daynames: getWeekDays(_large),
startDayOfWeek: 1,
},
week: {
daynames: getWeekDays(_large),
startDayOfWeek: 1,
}
});
}
});
makeLeftside(cal, $(leftside));
cal.on('beforeCreateSchedule', function(event) {
// XXX Recurrence (later)
// TODO Recurrence (later)
// On creation, select a recurrence rule (daily / weekly / monthly / more weird rules)
// then mark it under recurrence rule with a uid (the same for all the recurring events)
// ie: recurrenceRule: DAILY|{uid}
@ -925,7 +964,7 @@ Messages.calendar_noNotification = "None";
APP.toolbar.$bottomR.append($block);
// New event button
var newEventBtn = h('button', [
var newEventBtn = h('button.cp-calendar-newevent', [
h('i.fa.fa-plus'),
h('span', Messages.calendar_newEvent)
]);
@ -974,7 +1013,7 @@ Messages.calendar_noNotification = "None";
var getNotificationDropdown = function () {
var ev = APP.editModalData;
var calId = ev.selectedCal.id;
// XXX DEFAULT HERE [10] ==> 10 minutes before the event
// DEFAULT HERE [10] ==> 10 minutes before the event
var oldReminders = Util.find(APP.calendars, [calId, 'content', 'content', ev.id, 'reminders']) || [10];
APP.notificationsEntries = [];
var number = h('input.tui-full-calendar-content', {

View File

@ -45,10 +45,12 @@ define(function() {
*/
// config.privacy = 'https://xwiki.com/en/company/PrivacyPolicy';
/* XXX
*
/* We (the project's developers) include the ability to display a 'Roadmap' in static pages footer.
* This is disabled by default.
* We use this to publish the project's development roadmap, but you can use it however you like.
* To do so, set the following value to an absolute URL.
*/
//config.roadmap = 'https://cryptpad.fr/kanban/#/2/kanban/view/PLM0C3tFWvYhd+EPzXrbT+NxB76Z5DtZhAA5W5hG9wo/'; // XXX
//config.roadmap = 'https://cryptpad.fr/kanban/#/2/kanban/view/PLM0C3tFWvYhd+EPzXrbT+NxB76Z5DtZhAA5W5hG9wo/';
/* Cryptpad apps use a common API to display notifications to users
* by default, notifications are hidden after 5 seconds

View File

@ -9,7 +9,7 @@ define([
'/common/media-tag.js',
'/customize/messages.js',
'/common/highlight/highlight.pack.js',
'/bower_components/diff-dom/diffDOM.js',
'/lib/diff-dom/diffDOM.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
'css!/common/highlight/styles/'+ (window.CryptPad_theme === 'dark' ? 'dark.css' : 'github.css')
],function ($, ApiConfig, Marked, Hash, Util, h, MT, MediaTag, Messages) {

View File

@ -356,10 +356,39 @@ define([
}
};
// Add a lock
var isLockedModal = {
content: UI.dialog.customModal(h('div.cp-oo-x2tXls', [
h('span.fa.fa-spin.fa-spinner'),
h('span', Messages.oo_isLocked)
]))
};
var onUploaded = function (ev, data, err) {
content.saveLock = undefined;
if (err) {
console.error(err);
if (content.saveLock === myOOId) { delete content.saveLock; } // Unlock checkpoints
if (APP.migrateModal) {
try { getEditor().asc_setRestriction(true); } catch (e) {}
setEditable(true);
delete content.migration;
APP.migrateModal.closeModal();
APP.onLocal();
}
if (isLockedModal.modal && err === "TOO_LARGE") {
if (APP.migrate) {
UI.warn(Messages.oo_cantMigrate);
}
APP.cantCheckpoint = true;
isLockedModal.modal.closeModal();
delete isLockedModal.modal;
if (content.saveLock === myOOId) {
delete content.saveLock;
}
APP.onLocal();
return;
}
return void UI.alert(Messages.oo_saveError);
}
// Get the last cp idx
@ -422,14 +451,6 @@ define([
};
APP.FM = common.createFileManager(fmConfig);
// Add a lock
var isLockedModal = {
content: UI.dialog.customModal(h('div.cp-oo-x2tXls', [
h('span.fa.fa-spin.fa-spinner'),
h('span', Messages.oo_isLocked)
]))
};
var resetData = function (blob, type) {
// If a read-only refresh popup was planned, abort it
delete APP.refreshPopup;
@ -453,7 +474,19 @@ define([
};
var saveToServer = function () {
if (APP.cantCheckpoint) { return; } // TOO_LARGE
var text = getContent();
if (!text) {
setEditable(false, true);
sframeChan.query('Q_CLEAR_CACHE_CHANNELS', [
'chainpad',
content.channel,
], function () {});
UI.alert(Messages.realtime_unrecoverableError, function () {
common.gotoURL();
});
return;
}
var blob = new Blob([text], {type: 'plain/text'});
var file = getFileType();
blob.name = (metadataMgr.getMetadataLazy().title || file.doc) + '.' + file.type;
@ -479,6 +512,8 @@ define([
var noLogin = false;
var makeCheckpoint = function (force) {
if (APP.cantCheckpoint) { return; } // TOO_LARGE
var locked = content.saveLock;
var lastCp = getLastCp();
@ -1374,7 +1409,7 @@ define([
h('span.fa.fa-spin.fa-spinner'),
h('span', Messages.oo_sheetMigration_loading)
]);
UI.openCustomModal(UI.dialog.customModal(div, {buttons: []}));
APP.migrateModal = UI.openCustomModal(UI.dialog.customModal(div, {buttons: []}));
makeCheckpoint(true);
});
// DEPRECATED: from version 3, the queue is sent again during init

View File

@ -114,7 +114,7 @@ define([
}
}
// XXX add a limit to make sure we don't go too far in the past?
// XXX add a limit to make sure we don't go too far in the past? ==> 1 week
var missed = useLastVisit && ev.start > last && ev.end <= now;
if (ev.end <= now && !missed) {
// No reminder for past events
@ -283,7 +283,6 @@ define([
var onDeleted = function () {
// Remove this calendar from all our teams
// XXX Maybe not? don't remove automatically so that we can tell the user to do so.
c.stores.forEach(function (storeId) {
var store = getStore(ctx, storeId);
if (!store || !store.rpc || !store.proxy.calendars) { return; }
@ -412,6 +411,7 @@ define([
}
if (info.error === "ERESTRICTED" ) {
c.restricted = true;
setTimeout(update);
}
cb(info);
});
@ -846,7 +846,7 @@ define([
Calendar.init = function (cfg, waitFor, emit) {
var calendar = {};
var store = cfg.store;
if (!store.loggedIn || !store.proxy.edPublic) { return; } // XXX logged in only?
if (!store.loggedIn || !store.proxy.edPublic) { return; } // XXX logged in only? we should al least allow read-only for URL calendars
var ctx = {
store: store,
Store: cfg.Store,

View File

@ -133,6 +133,7 @@ define([
$pv.text(Messages.error);
queue.inProgress = false;
queue.next();
if (config.onError) { config.onError("TOO_LARGE"); }
return void UI.alert(Messages._getKey('upload_tooLargeBrief', [maxSizeStr]));
}

View File

@ -44,8 +44,8 @@ define([
// loading screen setup.
var done = waitFor();
var onMsg = function (msg) {
var data = JSON.parse(msg.data);
if (data.q !== 'READY') { return; }
var data = typeof(msg.data) === "string" ? JSON.parse(msg.data) : msg.data;
if (!data || data.q !== 'READY') { return; }
window.removeEventListener('message', onMsg);
var _done = done;
done = function () { };
@ -182,8 +182,8 @@ define([
};
var whenReady = waitFor(function (msg) {
if (msg.source !== iframe) { return; }
var data = JSON.parse(msg.data);
if (!data.txid) { return; }
var data = typeof(msg.data) === "string" ? JSON.parse(msg.data) : msg.data;
if (!data || !data.txid) { return; }
// Remove the listener once we've received the READY message
window.removeEventListener('message', whenReady);
// Answer with the requested data
@ -1533,6 +1533,16 @@ define([
sframeChan.on('Q_CLEAR_CACHE', function (data, cb) {
Utils.Cache.clear(cb);
});
sframeChan.on('Q_CLEAR_CACHE_CHANNELS', function (channels, cb) {
if (!Array.isArray(channels)) { return void cb({error: "NOT_AN_ARRAY"}); }
nThen(function (waitFor) {
channels.forEach(function (chan) {
if (chan === "chainpad") { chan = secret.channel; }
console.error(chan);
Utils.Cache.clearChannel(chan, waitFor());
});
}).nThen(cb);
});
sframeChan.on('Q_PIN_GET_USAGE', function (teamId, cb) {
Cryptpad.isOverPinLimit(teamId, function (err, overLimit, data) {

View File

@ -541,7 +541,7 @@
"four04_pageNotFound": "Wir konnten die Seite, die du angefordert hast, nicht finden.",
"header_logoTitle": "Zu deinem CryptDrive",
"header_homeTitle": "Zur CryptPad-Hauptseite",
"help_genericMore": "Erfahre mehr über die Nutzung von CryptPad, indem du unsere <a>Documentation</a> liest.",
"help_genericMore": "Erfahre mehr über die Nutzung von CryptPad, indem du unsere <a>Dokumentation</a> liest.",
"driveReadmeTitle": "Was ist CryptPad?",
"edit": "Bearbeiten",
"view": "Ansehen",

View File

@ -1181,5 +1181,7 @@
"admin_maintenanceButton": "Planifier maintenance",
"admin_maintenanceHint": "Planifier une maintenance sur cette instance et avertir tous les utilisateurs. Limité à une maintenance active à la fois.",
"admin_maintenanceTitle": "Maintenance",
"admin_cat_broadcast": "Annonces"
"admin_cat_broadcast": "Annonces",
"oo_cantMigrate": "Ce tableur dépasse la taille maximale de téléchargement et est trop grand pour être mis à jour.",
"footer_roadmap": "Feuille de route"
}

View File

@ -1184,5 +1184,7 @@
"broadcast_newCustom": "Message from the administrators",
"settings_deleteWarning": "Warning: you are currently subscribed to a premium plan (paid or given by another user). Please cancel your plan before deleting your account as will not be possible without contacting support once your account is deleted.",
"settings_deleteContinue": "Delete my account",
"settings_deleteSubscription": "Manage my subscription"
"settings_deleteSubscription": "Manage my subscription",
"footer_roadmap": "Roadmap",
"oo_cantMigrate": "This sheet exceeds the maximum upload size and is too large to be migrated."
}

View File

@ -30,10 +30,6 @@ define([
'css!/bower_components/codemirror/lib/codemirror.css',
'css!/bower_components/codemirror/addon/dialog/dialog.css',
'css!/bower_components/codemirror/addon/fold/foldgutter.css',
'css!/kanban/jkanban.css',
'less!/kanban/app-kanban.less'
], function (
$,

1358
www/lib/diff-dom/diffDOM.js Executable file

File diff suppressed because it is too large Load Diff

View File

@ -45,7 +45,7 @@ define([
'/customize/application_config.js',
'/common/test.js',
'/bower_components/diff-dom/diffDOM.js',
'/lib/diff-dom/diffDOM.js',
'/bower_components/file-saver/FileSaver.min.js',
'css!/customize/src/print.css',

View File

@ -6,7 +6,7 @@ define([
'/common/common-util.js',
'/customize/messages.js',
'/bower_components/diff-dom/diffDOM.js'
'/lib/diff-dom/diffDOM.js',
], function ($, Hyperjson, TextCursor, ChainPad, Util, Messages) {
var DiffDOM = window.diffDOM;