Invitaton handling: show current invitation status in mail view (asynchronously)
This commit is contained in:
parent
08a1a99d27
commit
166bf43f2d
5 changed files with 140 additions and 27 deletions
|
@ -600,6 +600,37 @@ class calendar extends rcube_plugin
|
|||
|
||||
break;
|
||||
|
||||
case "rsvp-status":
|
||||
$status = 'unknown';
|
||||
$action = 'rsvp';
|
||||
$html = html::div('rsvp-status', $this->gettext('acceptinvitation'));
|
||||
$this->load_driver();
|
||||
if ($existing = $this->driver->get_event($event)) {
|
||||
$emails = $this->get_user_emails();
|
||||
foreach ($existing['attendees'] as $i => $attendee) {
|
||||
if ($attendee['email'] && in_array($attendee['email'], $emails)) {
|
||||
$status = $attendee['status'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array($status, array('ACCEPTED','TENTATIVE','DECLINED'))) {
|
||||
$html = html::div('rsvp-status ' . strtolower($status), $this->gettext('youhave'.strtolower($status)));
|
||||
if ($event['changed'] < $existing['changed']) {
|
||||
$action = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->rc->output->command('plugin.update_event_rsvp_status', array(
|
||||
'uid' => $event['uid'],
|
||||
'id' => asciiwords($event['uid'], true),
|
||||
'status' => $status,
|
||||
'action' => $action,
|
||||
'html' => $html,
|
||||
));
|
||||
return;
|
||||
|
||||
case "rsvp":
|
||||
$ev = $this->driver->get_event($event);
|
||||
$ev['attendees'] = $event['attendees'];
|
||||
|
@ -774,6 +805,7 @@ class calendar extends rcube_plugin
|
|||
$identity = $rec;
|
||||
$identity['emails'][] = $rec['email'];
|
||||
}
|
||||
$identity['emails'][] = $this->rc->user->get_username();
|
||||
$settings['identity'] = array('name' => $identity['name'], 'email' => $identity['email'], 'emails' => ';' . join(';', $identity['emails']));
|
||||
}
|
||||
|
||||
|
@ -1577,25 +1609,28 @@ class calendar extends rcube_plugin
|
|||
else if ($this->ical->method == 'REQUEST') {
|
||||
$title = $event['SEQUENCE'] > 0 ? $this->gettext('itipupdate') : $this->gettext('itipinvitation');
|
||||
|
||||
// TODO: check for a copy in my calendar in order to show the right options
|
||||
if (!$event['SEQUENCE']) {
|
||||
foreach (array('accepted','tentative','declined') as $method) {
|
||||
$buttons .= html::tag('input', array(
|
||||
'type' => 'button',
|
||||
'class' => 'button',
|
||||
'onclick' => "rcube_calendar.add_event_from_mail('" . JQ($mime_id.':'.$idx) . "', '$method')",
|
||||
'value' => $this->gettext('itip' . $method),
|
||||
));
|
||||
}
|
||||
}
|
||||
else {
|
||||
$buttons = html::tag('input', array(
|
||||
// add (hidden) buttons and activate them from asyncronous request
|
||||
foreach (array('accepted','tentative','declined') as $method) {
|
||||
$rsvp_buttons .= html::tag('input', array(
|
||||
'type' => 'button',
|
||||
'class' => 'button',
|
||||
'onclick' => "rcube_calendar.add_event_from_mail('" . JQ($mime_id.':'.$idx) . "')",
|
||||
'value' => $this->gettext('importtocalendar'),
|
||||
'onclick' => "rcube_calendar.add_event_from_mail('" . JQ($mime_id.':'.$idx) . "', '$method')",
|
||||
'value' => $this->gettext('itip' . $method),
|
||||
));
|
||||
}
|
||||
$import_button = html::tag('input', array(
|
||||
'type' => 'button',
|
||||
'class' => 'button',
|
||||
'onclick' => "rcube_calendar.add_event_from_mail('" . JQ($mime_id.':'.$idx) . "')",
|
||||
'value' => $this->gettext('importtocalendar'),
|
||||
));
|
||||
|
||||
$dom_id = asciiwords($event['uid'], true);
|
||||
$buttons = html::div(array('id' => 'rsvp-'.$dom_id, 'style' => 'display:none'), $rsvp_buttons);
|
||||
$buttons .= html::div(array('id' => 'import-'.$dom_id, 'style' => 'display:none'), $import_button);
|
||||
$buttons_pre = html::div(array('id' => 'loading-'.$dom_id, 'class' => 'rsvp-status loading'), $this->gettext('loading'));
|
||||
|
||||
$this->rc->output->add_script('rcube_calendar.fetch_event_rsvp_status(' . json_serialize(array('uid' => $event['uid'], 'changed' => $event['changed'])) . ')', 'docready');
|
||||
}
|
||||
else if ($this->ical->method == 'CANCEL') {
|
||||
$title = $this->gettext('itipcancellation');
|
||||
|
@ -1627,7 +1662,7 @@ class calendar extends rcube_plugin
|
|||
}
|
||||
|
||||
// add box below messsage body
|
||||
$html .= html::div('calendar-invitebox', $table->show() . html::div('rsvp-buttons', $buttons));
|
||||
$html .= html::div('calendar-invitebox', $table->show() . $buttons_pre . html::div('rsvp-buttons', $buttons));
|
||||
|
||||
// limit listing
|
||||
if ($idx >= 3)
|
||||
|
@ -1643,8 +1678,8 @@ class calendar extends rcube_plugin
|
|||
|
||||
return $p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Handler for POST request to import an event attached to a mail message
|
||||
*/
|
||||
|
@ -1691,10 +1726,8 @@ class calendar extends rcube_plugin
|
|||
|
||||
// update my attendee status according to submitted method
|
||||
if (!empty($status)) {
|
||||
$emails = array($this->rc->user->get_username());
|
||||
foreach ($this->rc->user->list_identities() as $identity)
|
||||
$emails[] = $identity['email'];
|
||||
$organizer = null;
|
||||
$emails = $this->get_user_emails();
|
||||
foreach ($event['attendees'] as $i => $attendee) {
|
||||
if ($attendee['role'] == 'ORGANIZER') {
|
||||
$organizer = $attendee;
|
||||
|
@ -1706,7 +1739,7 @@ class calendar extends rcube_plugin
|
|||
}
|
||||
|
||||
// save to calendar
|
||||
if ($calendar && !$calendar['readonly'] && $status != 'declined') {
|
||||
if ($calendar && !$calendar['readonly']) {
|
||||
$event['id'] = $event['uid'];
|
||||
$event['calendar'] = $calendar['id'];
|
||||
|
||||
|
@ -1751,14 +1784,21 @@ class calendar extends rcube_plugin
|
|||
}
|
||||
// import the (newer) event
|
||||
// TODO: compare SEQUENCE numbers instead of changed dates
|
||||
else if ($event['changed'] >= $existing['changed'])
|
||||
else if ($event['changed'] >= $existing['changed']) {
|
||||
$success = $this->driver->edit_event($event);
|
||||
}
|
||||
else if (!empty($status)) {
|
||||
$existing['attendees'] = $event['attendees'];
|
||||
$success = $this->driver->edit_event($existing);
|
||||
}
|
||||
else
|
||||
$error_msg = $this->gettext('newerversionexists');
|
||||
}
|
||||
else if (!$existing) {
|
||||
else if (!$existing && $status != 'declined') {
|
||||
$success = $this->driver->new_event($event);
|
||||
}
|
||||
else if ($status == 'declined')
|
||||
$error_msg = null;
|
||||
}
|
||||
else if ($status == 'declined')
|
||||
$error_msg = null;
|
||||
|
@ -1896,5 +1936,18 @@ class calendar extends rcube_plugin
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of email addresses of the current user (from login and identities)
|
||||
*/
|
||||
private function get_user_emails()
|
||||
{
|
||||
$emails = array($this->rc->user->get_username());
|
||||
foreach ($this->rc->user->list_identities() as $identity)
|
||||
$emails[] = $identity['email'];
|
||||
|
||||
return array_unique($emails);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -171,6 +171,19 @@ rcube_calendar.add_event_from_mail = function(mime_id, status)
|
|||
return false;
|
||||
};
|
||||
|
||||
rcube_calendar.fetch_event_rsvp_status = function(event)
|
||||
{
|
||||
/*
|
||||
var id = event.uid.replace(rcmail.identifier_expr, '');
|
||||
$('#import-'+id+', #rsvp-'+id+', div.rsvp-status').hide();
|
||||
$('#loading-'+id).show();
|
||||
*/
|
||||
rcmail.http_post('calendar/event', {
|
||||
e:event,
|
||||
action:'rsvp-status'
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// extend jQuery
|
||||
(function($){
|
||||
|
@ -187,8 +200,19 @@ rcube_calendar.add_event_from_mail = function(mime_id, status)
|
|||
window.rcmail && rcmail.addEventListener('init', function(evt) {
|
||||
if (rcmail.task != 'calendar') {
|
||||
var cal = new rcube_calendar(rcmail.env.calendar_settings);
|
||||
|
||||
rcmail.addEventListener('plugin.display_alarms', function(alarms){ cal.display_alarms(alarms); });
|
||||
|
||||
rcmail.addEventListener('plugin.update_event_rsvp_status', function(p){
|
||||
if (p.html)
|
||||
$('#loading-'+p.id).hide().after(p.html);
|
||||
else
|
||||
$('#loading-'+p.id).hide();
|
||||
|
||||
$('#'+p.action+'-'+p.id).show();
|
||||
});
|
||||
}
|
||||
|
||||
rcmail.addEventListener('plugin.ping_url', function(p){
|
||||
var action = p.action;
|
||||
p.action = p.event = null;
|
||||
|
|
|
@ -311,15 +311,25 @@ class kolab_driver extends calendar_driver
|
|||
|
||||
|
||||
/**
|
||||
* Move a single event
|
||||
* Fetch a single event
|
||||
*
|
||||
* @see calendar_driver::get_event()
|
||||
* @return array Hash array with event properties, false if not found
|
||||
*/
|
||||
public function get_event($event)
|
||||
{
|
||||
if ($storage = $this->calendars[$event['calendar']])
|
||||
return $storage->get_event($event['id']);
|
||||
$id = $event['id'] ? $event['id'] : $event['uid'];
|
||||
if ($event['calendar'] && ($storage = $this->calendars[$event['calendar']])) {
|
||||
return $storage->get_event($id);
|
||||
}
|
||||
// iterate over all calendar folders and search for the event ID
|
||||
else if (!$event['calendar']) {
|
||||
foreach ($this->calendars as $storage) {
|
||||
if ($result = $storage->get_event($id)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -138,6 +138,9 @@ $labels['itipmailbodydeclined'] = "\$sender has declined the invitation to the f
|
|||
$labels['importtocalendar'] = 'Save to my calendar';
|
||||
$labels['updateattendeestatus'] = 'Update the participant\'s status';
|
||||
$labels['acceptinvitation'] = 'Do you accept this invitation?';
|
||||
$labels['youhaveaccepted'] = 'You have accepted this invitation';
|
||||
$labels['youhavetentative'] = 'You have tentatively accepted this invitation';
|
||||
$labels['youhavedeclined'] = 'You have declined this invitation';
|
||||
|
||||
// event dialog tabs
|
||||
$labels['tabsummary'] = 'Summary';
|
||||
|
|
|
@ -1111,6 +1111,7 @@ div.calendar-invitebox td.label {
|
|||
}
|
||||
|
||||
#event-rsvp .rsvp-buttons,
|
||||
div.calendar-invitebox .rsvp-status,
|
||||
div.calendar-invitebox .rsvp-buttons {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
@ -1120,3 +1121,25 @@ div.calendar-invitebox input.button {
|
|||
font-size: 11px;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .rsvp-status.loading {
|
||||
color: #666;
|
||||
padding: 1px 0 2px 24px;
|
||||
background: url('images/loading-small.gif') top left no-repeat;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .rsvp-status.declined,
|
||||
div.calendar-invitebox .rsvp-status.tentative,
|
||||
div.calendar-invitebox .rsvp-status.accepted {
|
||||
padding: 0 0 1px 22px;
|
||||
background: url('images/attendee-status.gif') 2px -20px no-repeat;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .rsvp-status.declined {
|
||||
background-position: 2px -40px;
|
||||
}
|
||||
|
||||
div.calendar-invitebox .rsvp-status.tentative {
|
||||
background-position: 2px -60px;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue