Calendar export
parent
dfff667a6e
commit
8a7f5556c4
|
@ -0,0 +1,121 @@
|
|||
// This file is used when a user tries to export the entire CryptDrive.
|
||||
// Calendars will be exported using this format instead of plain text.
|
||||
define([
|
||||
'/customize/pages.js',
|
||||
], function (Pages) {
|
||||
var module = {};
|
||||
|
||||
var getICSDate = function (str) {
|
||||
var date = new Date(str);
|
||||
|
||||
var m = date.getUTCMonth() + 1;
|
||||
var d = date.getUTCDate();
|
||||
var h = date.getUTCHours();
|
||||
var min = date.getUTCMinutes();
|
||||
|
||||
var year = date.getUTCFullYear().toString();
|
||||
var month = m < 10 ? "0" + m : m.toString();
|
||||
var day = d < 10 ? "0" + d : d.toString();
|
||||
var hours = h < 10 ? "0" + h : h.toString();
|
||||
var minutes = min < 10 ? "0" + min : min.toString();
|
||||
|
||||
return year + month + day + "T" + hours + minutes + "00Z";
|
||||
}
|
||||
|
||||
|
||||
var getDate = function (str, end) {
|
||||
var date = new Date(str);
|
||||
if (end) {
|
||||
date.setDate(date.getDate() + 1);
|
||||
}
|
||||
var m = date.getUTCMonth() + 1;
|
||||
var d = date.getUTCDate();
|
||||
|
||||
var year = date.getUTCFullYear().toString();
|
||||
var month = m < 10 ? "0" + m : m.toString();
|
||||
var day = d < 10 ? "0" + d : d.toString();
|
||||
|
||||
return year+month+day;
|
||||
};
|
||||
|
||||
var MINUTE = 60;
|
||||
var HOUR = MINUTE * 60;
|
||||
var DAY = HOUR * 24;
|
||||
|
||||
|
||||
module.main = function (userDoc) {
|
||||
var content = userDoc.content;
|
||||
var md = userDoc.metadata;
|
||||
|
||||
var ICS = [
|
||||
'BEGIN:VCALENDAR',
|
||||
'VERSION:2.0',
|
||||
'PRODID:-//CryptPad//CryptPad Calendar '+Pages.versionString+'//EN',
|
||||
'METHOD:PUBLISH',
|
||||
];
|
||||
|
||||
Object.keys(content).forEach(function (uid) {
|
||||
var data = content[uid];
|
||||
// DTSTAMP: now...
|
||||
// UID: uid
|
||||
var start, end;
|
||||
if (data.isAllDay && data.startDay && data.endDay) {
|
||||
start = "DTSTART;VALUE=DATE:" + getDate(data.startDay);
|
||||
end = "DTEND;VALUE=DATE:" + getDate(data.endDay, true);
|
||||
} else {
|
||||
start = "DTSTART:"+getICSDate(data.start);
|
||||
end = "DTEND:"+getICSDate(data.end);
|
||||
}
|
||||
|
||||
Array.prototype.push.apply(ICS, [
|
||||
'BEGIN:VEVENT',
|
||||
'DTSTAMP:'+getICSDate(+new Date()),
|
||||
'UID:'+uid,
|
||||
start,
|
||||
end,
|
||||
'SUMMARY:'+ data.title,
|
||||
'LOCATION:'+ data.location,
|
||||
]);
|
||||
|
||||
if (Array.isArray(data.reminders)) {
|
||||
data.reminders.forEach(function (valueMin) {
|
||||
var time = valueMin * 60;
|
||||
var days = Math.floor(time / DAY);
|
||||
time -= days * DAY;
|
||||
var hours = Math.floor(time / HOUR);
|
||||
time -= hours * HOUR;
|
||||
var minutes = Math.floor(time / MINUTE);
|
||||
time -= minutes * MINUTE;
|
||||
var seconds = time;
|
||||
|
||||
var str = "-P" + days + "D";
|
||||
if (hours || minutes || seconds) {
|
||||
str += "T" + hours + "H" + minutes + "M" + seconds + "S";
|
||||
}
|
||||
Array.prototype.push.apply(ICS, [
|
||||
'BEGIN:VALARM',
|
||||
'ACTION:DISPLAY',
|
||||
'DESCRIPTION:This is an event reminder',
|
||||
'TRIGGER:'+str,
|
||||
'END:VALARM'
|
||||
]);
|
||||
// XXX ACTION:EMAIL
|
||||
// XXX ATTENDEE:mailto:xxx@xxx.xxx
|
||||
// XXX SUMMARY:Alarm notification
|
||||
});
|
||||
}
|
||||
|
||||
// XXX add hidden data (from imports)
|
||||
|
||||
ICS.push('END:VEVENT');
|
||||
});
|
||||
|
||||
ICS.push('END:VCALENDAR');
|
||||
|
||||
return new Blob([ ICS.join('\n') ], { type: 'text/calendar;charset=utf-8' });
|
||||
};
|
||||
|
||||
return module;
|
||||
});
|
||||
|
||||
|
|
@ -15,12 +15,14 @@ define([
|
|||
'/customize/messages.js',
|
||||
'/customize/application_config.js',
|
||||
'/lib/calendar/tui-calendar.min.js',
|
||||
'/calendar/export.js',
|
||||
|
||||
'/common/inner/share.js',
|
||||
'/common/inner/access.js',
|
||||
'/common/inner/properties.js',
|
||||
|
||||
'/common/jscolor.js',
|
||||
'/bower_components/file-saver/FileSaver.min.js',
|
||||
'css!/lib/calendar/tui-calendar.min.css',
|
||||
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||
'less!/calendar/app-calendar.less',
|
||||
|
@ -41,9 +43,11 @@ define([
|
|||
Messages,
|
||||
AppConfig,
|
||||
Calendar,
|
||||
Export,
|
||||
Share, Access, Properties
|
||||
)
|
||||
{
|
||||
var SaveAs = window.saveAs;
|
||||
var APP = window.APP = {
|
||||
calendars: {}
|
||||
};
|
||||
|
@ -453,6 +457,65 @@ Messages.calendar_allDay = "All day";
|
|||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!data.readOnly) {
|
||||
options.push({
|
||||
tag: 'a',
|
||||
attributes: {
|
||||
'class': 'fa fa-upload',
|
||||
},
|
||||
content: h('span', Messages.importButton),
|
||||
action: function (e) {
|
||||
e.stopPropagation();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
options.push({
|
||||
tag: 'a',
|
||||
attributes: {
|
||||
'class': 'fa fa-download',
|
||||
},
|
||||
content: h('span', Messages.exportButton),
|
||||
action: function (e) {
|
||||
e.stopPropagation();
|
||||
var cal = APP.calendars[id];
|
||||
var suggestion = Util.find(cal, ['content', 'metadata', 'title']);
|
||||
var types = [];
|
||||
types.push({
|
||||
tag: 'a',
|
||||
attributes: {
|
||||
'data-value': '.ics',
|
||||
'href': '#'
|
||||
},
|
||||
content: '.ics'
|
||||
});
|
||||
var dropdownConfig = {
|
||||
text: '.ics', // Button initial text
|
||||
caretDown: true,
|
||||
options: types, // Entries displayed in the menu
|
||||
isSelect: true,
|
||||
initialValue: '.ics',
|
||||
common: common
|
||||
};
|
||||
var $select = UIElements.createDropdown(dropdownConfig);
|
||||
UI.prompt(Messages.exportPrompt,
|
||||
Util.fixFileName(suggestion), function (filename)
|
||||
{
|
||||
if (!(typeof(filename) === 'string' && filename)) { return; }
|
||||
var ext = $select.getValue();
|
||||
filename = filename + ext;
|
||||
var blob = Export.main(cal.content);
|
||||
SaveAs(blob, filename);
|
||||
}, {
|
||||
typeInput: $select[0]
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
options.push({
|
||||
tag: 'a',
|
||||
attributes: {
|
||||
|
|
Loading…
Reference in New Issue