plugins/calendar plugins/libcalendaring
Thomas Brüderli
bruederli at kolabsys.com
Wed Sep 10 10:31:05 CEST 2014
plugins/calendar/calendar.php | 46 ++++++++++++++-
plugins/calendar/calendar_ui.js | 51 ++++++++++++++++-
plugins/calendar/localization/en_US.inc | 1
plugins/calendar/skins/classic/templates/calendar.html | 2
plugins/calendar/skins/larry/calendar.css | 8 ++
plugins/calendar/skins/larry/templates/calendar.html | 2
plugins/libcalendaring/lib/libcalendaring_itip.php | 14 ++++
plugins/libcalendaring/libcalendaring.js | 12 ++++
plugins/libcalendaring/localization/en_US.inc | 1
9 files changed, 128 insertions(+), 9 deletions(-)
New commits:
commit 09cf967ed5799a3e8701f906123df2b9746e70c2
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Sep 10 10:30:40 2014 +0200
Add button to iTip RSVP UI in mail view to open the calendar preview with an option to accept/decline the invitation from there (#3161)
diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index afcc052..9c0a892 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -309,10 +309,13 @@ class calendar extends rcube_plugin
$view = get_input_value('view', RCUBE_INPUT_GPC);
if (in_array($view, array('agendaWeek', 'agendaDay', 'month', 'table')))
$this->rc->output->set_env('view', $view);
-
+
if ($date = get_input_value('date', RCUBE_INPUT_GPC))
$this->rc->output->set_env('date', $date);
+ if ($msgref = get_input_value('itip', RCUBE_INPUT_GPC))
+ $this->rc->output->set_env('itip_events', $this->itip_events($msgref));
+
$this->rc->output->send("calendar.calendar");
}
@@ -1123,6 +1126,43 @@ class calendar extends rcube_plugin
}
/**
+ * Load event data from an iTip message attachment
+ */
+ public function itip_events($msgref)
+ {
+ $path = explode('/', $msgref);
+ $msg = array_pop($path);
+ $mbox = join('/', $path);
+ list($uid, $mime_id) = explode('#', $msg);
+ $events = array();
+
+ if ($event = $this->lib->mail_get_itip_object($mbox, $uid, $mime_id, 'event')) {
+ $partstat = 'NEEDS-ACTION';
+/*
+ $user_emails = $this->lib->get_user_emails();
+ foreach ($event['attendees'] as $attendee) {
+ if (in_array($attendee['email'], $user_emails)) {
+ $partstat = $attendee['status'];
+ break;
+ }
+ }
+*/
+ $event['id'] = $event['uid'];
+ $event['temporary'] = true;
+ $event['readonly'] = true;
+ $event['calendar'] = '--invitation--itip';
+ $event['className'] = 'fc-invitation-' . strtolower($partstat);
+ $event['_mbox'] = $mbox;
+ $event['_uid'] = $uid;
+ $event['_part'] = $mime_id;
+
+ $events[] = $this->_client_event($event, true);
+ }
+
+ return $events;
+ }
+
+ /**
* Handler for keep-alive requests
* This will check for updated data in active calendars and sync them to the client
*/
@@ -2357,7 +2397,8 @@ class calendar extends rcube_plugin
$ical_objects->method,
$ical_objects->mime_id . ':' . $idx,
'calendar',
- rcube_utils::anytodatetime($ical_objects->message_date)
+ rcube_utils::anytodatetime($ical_objects->message_date),
+ $this->rc->url(array('task' => 'calendar')) . '&view=agendaDay&date=' . $event['start']->format('U')
)
);
}
@@ -2566,6 +2607,7 @@ class calendar extends rcube_plugin
}
if ($success || $dontsave) {
+ $metadata['calendar'] = $event['calendar'];
$metadata['nosave'] = $dontsave;
$metadata['rsvp'] = intval($metadata['rsvp']);
$metadata['after_action'] = $this->rc->config->get('calendar_itip_after_action', $this->defaults['calendar_itip_after_action']);
diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index 558a014..ef40938 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -599,7 +599,7 @@ function rcube_calendar_ui(settings)
me.dialog_resize($dialog.get(0), $dialog.height(), 420);
// add link for "more options" drop-down
- if (!temp) {
+ if (!temp && !event.temporary) {
$('<a>')
.attr('href', '#')
.html(rcmail.gettext('eventoptions','calendar'))
@@ -2339,7 +2339,19 @@ function rcube_calendar_ui(settings)
var submit_data = $.extend({}, me.selected_event, { source:null, comment:$('#reply-comment-event-rsvp').val() }),
noreply = $('#noreply-event-rsvp:checked').length ? 1 : 0;
- if (settings.invitation_calendars) {
+ // import event from mail (temporary iTip event)
+ if (submit_data._mbox && submit_data._uid) {
+ me.saving_lock = rcmail.set_busy(true, 'calendar.savingdata');
+ rcmail.http_post('mailimportitip', {
+ _mbox: submit_data._mbox,
+ _uid: submit_data._uid,
+ _part: submit_data._part,
+ _status: response,
+ _noreply: noreply,
+ _comment: submit_data.comment
+ });
+ }
+ else if (settings.invitation_calendars) {
update_event('rsvp', submit_data, { status:response, noreply:noreply });
}
else {
@@ -3089,6 +3101,25 @@ function rcube_calendar_ui(settings)
return query;
};
+ // callback after an iTip message event was imported
+ this.itip_message_processed = function(data)
+ {
+ // remove temporary iTip source
+ fc.fullCalendar('removeEventSource', this.calendars['--invitation--itip']);
+
+ $('#eventshow:ui-dialog').dialog('close');
+ this.selected_event = null;
+
+ // refresh destination calendar source
+ this.refresh({ source:data.calendar, refetch:true });
+
+ this.unlock_saving();
+
+ // process 'after_action' in mail task
+ if (window.opener && window.opener.rcube_libcalendaring)
+ window.opener.rcube_libcalendaring.itip_message_processed(data);
+ };
+
// reload the calendar view by keeping the current date/view selection
this.reload_view = function()
{
@@ -3462,7 +3493,20 @@ function rcube_calendar_ui(settings)
var viewdate = new Date();
if (rcmail.env.date)
viewdate.setTime(fromunixtime(rcmail.env.date));
-
+
+ // add source with iTip event data for rendering
+ if (rcmail.env.itip_events && rcmail.env.itip_events.length) {
+ me.calendars['--invitation--itip'] = {
+ events: rcmail.env.itip_events,
+ className: 'fc-event-cal---invitation--itip',
+ color: '#fff',
+ textColor: '#333',
+ editable: false,
+ attendees: true
+ };
+ event_sources.push(me.calendars['--invitation--itip']);
+ }
+
// initalize the fullCalendar plugin
var fc = $('#calendar').fullCalendar($.extend({}, fullcalendar_defaults, {
header: {
@@ -3940,6 +3984,7 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
rcmail.addEventListener('plugin.render_event_changelog', function(data){ cal.render_event_changelog(data); });
rcmail.addEventListener('plugin.event_show_diff', function(data){ cal.event_show_diff(data); });
rcmail.addEventListener('plugin.event_show_revision', function(data){ cal.event_show_dialog(data, null, true); });
+ rcmail.addEventListener('plugin.itip_message_processed', function(data){ cal.itip_message_processed(data); });
rcmail.addEventListener('requestrefresh', function(q){ return cal.before_refresh(q); });
// let's go
diff --git a/plugins/calendar/localization/en_US.inc b/plugins/calendar/localization/en_US.inc
index e52f62a..6023366 100644
--- a/plugins/calendar/localization/en_US.inc
+++ b/plugins/calendar/localization/en_US.inc
@@ -201,6 +201,7 @@ $labels['eventcancelled'] = 'The event has been cancelled';
$labels['saveincalendar'] = 'save in';
$labels['updatemycopy'] = 'Update in my calendar';
$labels['savetocalendar'] = 'Save to calendar';
+$labels['openpreview'] = 'Check Calendar';
// resources
$labels['resource'] = 'Resource';
diff --git a/plugins/calendar/skins/classic/templates/calendar.html b/plugins/calendar/skins/classic/templates/calendar.html
index 516cf58..5f006d2 100644
--- a/plugins/calendar/skins/classic/templates/calendar.html
+++ b/plugins/calendar/skins/classic/templates/calendar.html
@@ -6,7 +6,7 @@
<script type="text/javascript" src="/functions.js"></script>
<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="./plugins/calendar/skins/classic/iehacks.css" /><![endif]-->
</head>
-<body class="calendarmain">
+<roundcube:if condition="env:extwin" /><body class="calendarmain extwin"><roundcube:else /><body class="calendarmain"><roundcube:endif />
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css
index ca439ff..5e8c09d 100644
--- a/plugins/calendar/skins/larry/calendar.css
+++ b/plugins/calendar/skins/larry/calendar.css
@@ -1,7 +1,7 @@
/**
* Roundcube Calendar plugin styles for skin "Larry"
*
- * Copyright (c) 2012, Kolab Systems AG <contact at kolabsys.com>
+ * Copyright (c) 2012-2014, Kolab Systems AG <contact at kolabsys.com>
* Screendesign by FLINT / Büro für Gestaltung, bueroflint.com
*
* The contents are subject to the Creative Commons Attribution-ShareAlike
@@ -2016,9 +2016,15 @@ div.calendar-invitebox input.button {
margin-right: 0.5em;
}
+div.calendar-invitebox input.button.preview {
+ margin-left: 1em;
+ margin-right: 0;
+}
+
div.calendar-invitebox .folder-select {
font-weight: 10px;
margin-left: 1em;
+ white-space: nowrap;
}
div.calendar-invitebox .rsvp-status {
diff --git a/plugins/calendar/skins/larry/templates/calendar.html b/plugins/calendar/skins/larry/templates/calendar.html
index c607c87..1df1748 100644
--- a/plugins/calendar/skins/larry/templates/calendar.html
+++ b/plugins/calendar/skins/larry/templates/calendar.html
@@ -5,7 +5,7 @@
<roundcube:include file="/includes/links.html" />
<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="/this/iehacks.css" /><![endif]-->
</head>
-<body class="calendarmain">
+<roundcube:if condition="env:extwin" /><body class="calendarmain extwin"><roundcube:else /><body class="calendarmain"><roundcube:endif />
<roundcube:include file="/includes/header.html" />
diff --git a/plugins/libcalendaring/lib/libcalendaring_itip.php b/plugins/libcalendaring/lib/libcalendaring_itip.php
index ce68655..a5b056f 100644
--- a/plugins/libcalendaring/lib/libcalendaring_itip.php
+++ b/plugins/libcalendaring/lib/libcalendaring_itip.php
@@ -361,6 +361,7 @@ class libcalendaring_itip
return array(
'uid' => $event['uid'],
'id' => asciiwords($event['uid'], true),
+ 'existing' => $existing ? true : false,
'saved' => $existing ? true : false,
'latest' => $latest,
'status' => $status,
@@ -372,7 +373,7 @@ class libcalendaring_itip
/**
* Build inline UI elements for iTip messages
*/
- public function mail_itip_inline_ui($event, $method, $mime_id, $task, $message_date = null)
+ public function mail_itip_inline_ui($event, $method, $mime_id, $task, $message_date = null, $preview_url = null)
{
$buttons = array();
$dom_id = asciiwords($event['uid'], true);
@@ -450,6 +451,17 @@ class libcalendaring_itip
));
}
+ // add button to open calendar/preview
+ if (!empty($preview_url)) {
+ $msgref = $this->lib->ical_message->folder . '/' . $this->lib->ical_message->uid . '#' . $mime_id;
+ $rsvp_buttons .= html::tag('input', array(
+ 'type' => 'button',
+ 'class' => "button preview",
+ 'onclick' => "rcube_libcalendaring.open_itip_preview('" . JQ($preview_url) . "', '" . JQ($msgref) . "')",
+ 'value' => $this->gettext('openpreview'),
+ ));
+ }
+
// 2. update the local copy with minor changes
$update_button = html::tag('input', array(
'type' => 'button',
diff --git a/plugins/libcalendaring/libcalendaring.js b/plugins/libcalendaring/libcalendaring.js
index cd06827..b23a3fe 100644
--- a/plugins/libcalendaring/libcalendaring.js
+++ b/plugins/libcalendaring/libcalendaring.js
@@ -892,6 +892,7 @@ rcube_libcalendaring.fetch_itip_object_status = function(p)
rcube_libcalendaring.update_itip_object_status = function(p)
{
rcmail.env.rsvp_saved = p.saved;
+ rcmail.env.itip_existing = p.existing;
// hide all elements first
$('#itip-buttons-'+p.id+' > div').hide();
@@ -953,6 +954,17 @@ rcube_libcalendaring.itip_after_action = function(action)
}
};
+/**
+ * Open the calendar preview for the current iTip event
+ */
+rcube_libcalendaring.open_itip_preview = function(url, msgref)
+{
+ if (!rcmail.env.itip_existing)
+ url += '&itip=' + escape(msgref);
+
+ var win = rcmail.open_window(url);
+};
+
// extend jQuery
(function($){
diff --git a/plugins/libcalendaring/localization/en_US.inc b/plugins/libcalendaring/localization/en_US.inc
index 82fb7a8..9c3507c 100644
--- a/plugins/libcalendaring/localization/en_US.inc
+++ b/plugins/libcalendaring/localization/en_US.inc
@@ -134,6 +134,7 @@ $labels['outdatedinvitation'] = 'This invitation has been replaced by a newer ve
$labels['importtocalendar'] = 'Save to my calendar';
$labels['removefromcalendar'] = 'Remove from my calendar';
$labels['updatemycopy'] = 'Update my copy';
+$labels['openpreview'] = 'Open Preview';
$labels['deleteobjectconfirm'] = 'Do you really want to delete this object?';
$labels['declinedeleteconfirm'] = 'Do you also want to delete this declined object from your account?';
More information about the commits
mailing list