Send pending alarm notifications with keep-alive requests
This commit is contained in:
parent
57ae204c4a
commit
74a4e37be3
4 changed files with 118 additions and 16 deletions
|
@ -46,6 +46,21 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
|
|||
var day_clicked = day_clicked_ts = 0;
|
||||
var ignore_click = false;
|
||||
|
||||
// create a nice human-readable string for the date/time range
|
||||
var event_date_text = function(event) {
|
||||
var fromto, duration = event.end.getTime() / 1000 - event.start.getTime() / 1000;
|
||||
if (event.allDay)
|
||||
fromto = $.fullCalendar.formatDate(event.start, settings['date_format']) + (duration > 86400 ? ' — ' + $.fullCalendar.formatDate(event.end, settings['date_format']) : '');
|
||||
else if (duration < 86400 && event.start.getDay() == event.end.getDay())
|
||||
fromto = $.fullCalendar.formatDate(event.start, settings['date_format']) + ' ' + $.fullCalendar.formatDate(event.start, settings['time_format']) + ' — '
|
||||
+ $.fullCalendar.formatDate(event.end, settings['time_format']);
|
||||
else
|
||||
fromto = $.fullCalendar.formatDate(event.start, settings['date_format']) + ' ' + $.fullCalendar.formatDate(event.start, settings['time_format']) + ' — '
|
||||
+ $.fullCalendar.formatDate(event.end, settings['date_format']) + ' ' + $.fullCalendar.formatDate(event.end, settings['time_format']);
|
||||
|
||||
return fromto;
|
||||
};
|
||||
|
||||
// event details dialog (show only)
|
||||
var event_show_dialog = function(event) {
|
||||
var $dialog = $("#eventshow");
|
||||
|
@ -59,17 +74,8 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
|
|||
if (event.description)
|
||||
$('#event-description').show().children('.event-text').html(nl2br(Q(event.description))); // TODO: format HTML with clickable links and stuff
|
||||
|
||||
// TODO: create a nice human-readable string for the date/time range
|
||||
var fromto, duration = event.end.getTime() / 1000 - event.start.getTime() / 1000;
|
||||
if (event.allDay)
|
||||
fromto = $.fullCalendar.formatDate(event.start, settings['date_format']) + ' — ' + $.fullCalendar.formatDate(event.end, settings['date_format']);
|
||||
else if (duration < 86400 && event.start.getDay() == event.end.getDay())
|
||||
fromto = $.fullCalendar.formatDate(event.start, settings['date_format']) + ' ' + $.fullCalendar.formatDate(event.start, settings['time_format']) + ' — '
|
||||
+ $.fullCalendar.formatDate(event.end, settings['time_format']);
|
||||
else
|
||||
fromto = $.fullCalendar.formatDate(event.start, settings['date_format']) + ' ' + $.fullCalendar.formatDate(event.start, settings['time_format']) + ' — '
|
||||
+ $.fullCalendar.formatDate(event.end, settings['date_format']) + ' ' + $.fullCalendar.formatDate(event.end, settings['time_format']);
|
||||
$('#event-date').html(Q(fromto)).show();
|
||||
// render from-to in a nice human-readable way
|
||||
$('#event-date').html(Q(event_date_text(event))).show();
|
||||
|
||||
if (event.recurrence && event.recurrence_text)
|
||||
$('#event-repeat').show().children('.event-text').html(Q(event.recurrence_text));
|
||||
|
@ -417,6 +423,47 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
|
|||
return false;
|
||||
};
|
||||
|
||||
// display a notification for the given pending alarms
|
||||
this.display_alarms = function(alarms) {
|
||||
// clear old alert first
|
||||
$('#alarm-display').dialog('destroy');
|
||||
|
||||
var event_ids = [];
|
||||
var display = $('<div>').attr('id', 'alarm-display');
|
||||
for (var html, alarm, i=0; i < alarms.length; i++) {
|
||||
alarm = alarms[i];
|
||||
alarm.start = new Date(alarm.start);
|
||||
alarm.end = new Date(alarm.end);
|
||||
event_ids.push(alarm.id);
|
||||
|
||||
html = '<h3 class="event-title">' + Q(alarm.title) + '</h3>';
|
||||
html += '<div class="event-section">' + Q(alarm.location) + '</div>';
|
||||
html += '<div class="event-section">' + Q(event_date_text(alarm)) + '</div>';
|
||||
$('<div>').addClass('alarm-item').html(html).appendTo(display);
|
||||
}
|
||||
|
||||
display.appendTo(document.body).dialog({
|
||||
modal: true,
|
||||
resizable: true,
|
||||
closeOnEscape: false,
|
||||
dialogClass: 'alert',
|
||||
title: rcmail.gettext('alarmtitle', 'calendar'),
|
||||
buttons: {
|
||||
"Snooze": function() {
|
||||
$(this).dialog('close');
|
||||
},
|
||||
"Dismiss": function() {
|
||||
$(this).dialog('close');
|
||||
}
|
||||
},
|
||||
close: function() {
|
||||
$(this).dialog('destroy');
|
||||
// TODO: submit dismissed event_ids to server
|
||||
$(this).remove();
|
||||
}
|
||||
}).data('event_ids', event_ids.join(','));
|
||||
};
|
||||
|
||||
|
||||
// create list of event sources AKA calendars
|
||||
this.calendars = {};
|
||||
|
@ -626,11 +673,11 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
|
|||
rcmail.register_command('plugin.export', function(){ rcmail.goto_url('plugin.export_events', { source:cal.selected_calendar }); }, true);
|
||||
rcmail.enable_command('plugin.export', true);
|
||||
|
||||
// register callback commands
|
||||
rcmail.addEventListener('plugin.display_alarms', function(alarms){ cal.display_alarms(alarms); });
|
||||
|
||||
// reload calendar
|
||||
rcmail.addEventListener('plugin.reload_calendar', reload_calendar);
|
||||
function reload_calendar() {
|
||||
$('#calendar').fullCalendar('refetchEvents');
|
||||
}
|
||||
rcmail.addEventListener('plugin.reload_calendar', function() { $('#calendar').fullCalendar('refetchEvents'); });
|
||||
|
||||
|
||||
var formattime = function(hour, minutes) {
|
||||
|
|
|
@ -74,6 +74,7 @@ class calendar extends rcube_plugin
|
|||
$this->register_action('plugin.load_events', array($this, 'load_events'));
|
||||
$this->register_action('plugin.event', array($this, 'event'));
|
||||
$this->register_action('plugin.export_events', array($this, 'export_events'));
|
||||
$this->add_hook('keep_alive', array($this, 'keep_alive'));
|
||||
|
||||
// set user's timezone
|
||||
if ($this->rc->config->get('timezone') === 'auto')
|
||||
|
@ -360,6 +361,20 @@ class calendar extends rcube_plugin
|
|||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for keep-alive requests
|
||||
* This will check for pending notifications and pass them to the client
|
||||
*/
|
||||
function keep_alive($attr)
|
||||
{
|
||||
$alarms = $this->driver->pending_alarms(time());
|
||||
#if ($alarms)
|
||||
# $this->rc->output->command('plugin.display_alarms', $this->_alarms_output($alarms));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function export_events()
|
||||
{
|
||||
$start = get_input_value('start', RCUBE_INPUT_GET);
|
||||
|
@ -375,6 +390,9 @@ class calendar extends rcube_plugin
|
|||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function load_settings()
|
||||
{
|
||||
$settings = array();
|
||||
|
@ -478,6 +496,28 @@ class calendar extends rcube_plugin
|
|||
return json_encode($json);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate reduced and streamlined output for pending alarms
|
||||
*/
|
||||
private function _alarms_output($alarms)
|
||||
{
|
||||
$out = array();
|
||||
foreach ($alarms as $alarm) {
|
||||
$out[] = array(
|
||||
'id' => $alarm['id'],
|
||||
'start' => $alarm['start'],
|
||||
'end' => $alarm['end'],
|
||||
'allDay' => ($event['all_day'] == 1)?true:false,
|
||||
'title' => $alarm['title'],
|
||||
'location' => $alarm['location'],
|
||||
'calendar' => $alarm['calendar'],
|
||||
);
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render localized text for alarm settings
|
||||
*/
|
||||
|
|
|
@ -65,6 +65,7 @@ $labels['trigger+D'] = 'days after';
|
|||
$labels['addalarm'] = 'add alarm';
|
||||
$labels['defaultalarmtype'] = 'Default reminder setting';
|
||||
$labels['defaultalarmoffset'] = 'Default reminder time';
|
||||
$labels['alarmtitle'] = 'Upcoming events';
|
||||
|
||||
// event dialog tabs
|
||||
$labels['tabsummary'] = 'Summary';
|
||||
|
|
|
@ -341,6 +341,20 @@ a.dropdown-link:after {
|
|||
min-height: 20em;
|
||||
}
|
||||
|
||||
.alarm-item {
|
||||
margin: 0.4em 0 1em 0;
|
||||
}
|
||||
|
||||
.alarm-item .event-title {
|
||||
font-size: 14px;
|
||||
margin: 0.1em 0 0.3em 0;
|
||||
}
|
||||
|
||||
.alarm-item div.event-section {
|
||||
margin-top: 0.1em;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
|
||||
.ui-dialog-buttonset a.dropdown-link {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue