diff --git a/plugins/kolab_files/kolab_files.js b/plugins/kolab_files/kolab_files.js index 04370570..0ce75993 100644 --- a/plugins/kolab_files/kolab_files.js +++ b/plugins/kolab_files/kolab_files.js @@ -60,20 +60,16 @@ window.rcmail && window.files_api && rcmail.addEventListener('init', function() kolab_files_from_cloud_widget($('#calendar-attachment-form > div.buttons')); }); } - - kolab_files_init(); } else if (rcmail.task == 'calendar') { // add "attach from cloud" button for event dialog if (!rcmail.env.action) kolab_files_from_cloud_widget($('#calendar-attachment-form > div.buttons')); - kolab_files_init(); } else if (rcmail.task == 'tasks') { // add "attach from cloud" button for task dialog if (!rcmail.env.action) kolab_files_from_cloud_widget($('#taskedit-attachment-form > div.buttons')); - kolab_files_init(); } else if (rcmail.task == 'files') { if (rcmail.gui_objects.filelist) { @@ -106,44 +102,15 @@ window.rcmail && window.files_api && rcmail.addEventListener('init', function() // "one or more file" commands rcmail.env.file_commands_all = ['files-delete', 'files-move', 'files-copy']; - kolab_files_init(); - if (rcmail.env.action == 'open' || rcmail.env.action == 'edit') { rcmail.enable_command('files-get', 'files-delete', rcmail.env.file); - - if (rcmail.env.action == 'edit' && rcmail.env.file_data.viewer && rcmail.env.file_data.viewer.manticore) - manticore = new manticore_api({ - // UI elements - iframe: $('#fileframe').get(0), - export_menu: rcmail.gui_objects.exportmenu ? $('ul', rcmail.gui_objects.exportmenu).get(0) : null, - title_input: $('#document-title').get(0), - members_list: $('#members').get(0), - photo_url: '?_task=addressbook&_action=photo&_email=%email', - photo_default_url: rcmail.env.photo_placeholder, - // events - ready: function(data) { manticore_init(); }, - documentChanged: function(data) { rcmail.enable_command('document-save', true); }, - // notifications/alerts - set_busy: function(state, message) { return rcmail.set_busy(state, message ? 'kolab_files.' + message : ''); }, - hide_message: function(id) { return rcmail.hide_message(id); }, - display_message: function(label, type) { return rcmail.display_message('kolab_files.' + label, type); }, - gettext: function(label) { return rcmail.get_label('kolab_files.' + label); } - }); - - if (rcmail.env.action == 'open') { - // initialize folders list (for dialogs) - file_api.folder_list(); - - // get ongoing sessions - file_api.request('folder_info', {folder: file_api.file_path(rcmail.env.file), sessions: 1}, 'folder_info_response'); - } } else { - file_api.folder_list(); - file_api.browser_capabilities_check(); rcmail.enable_command('folder-mount', rcmail.env.external_sources); } } + + kolab_files_init(); }); @@ -157,6 +124,8 @@ function kolab_files_init() if (window.file_api) return; + var manticore_config = {}; + // Initialize application object (don't change var name!) file_api = $.extend(new files_api(), new kolab_files_ui()); @@ -172,6 +141,59 @@ function kolab_files_init() }); file_api.translations = rcmail.labels; + + if (rcmail.task == 'files') { + if (rcmail.env.action == 'edit' && rcmail.env.file_data.viewer && rcmail.env.file_data.viewer.manticore) { + manticore_config = { + // UI elements + iframe: $('#fileframe').get(0), + export_menu: rcmail.gui_objects.exportmenu ? $('ul', rcmail.gui_objects.exportmenu).get(0) : null, + title_input: $('#document-title').get(0), + members_list: $('#members').get(0), + photo_url: '?_task=addressbook&_action=photo&_email=%email', + photo_default_url: rcmail.env.photo_placeholder, + // events + ready: function(data) { manticore_init(); }, + documentChanged: function(data) { rcmail.enable_command('document-save', true); }, + }; + } + else if (rcmail.env.action == 'open') { + // initialize folders list (for dialogs) + file_api.folder_list(); + + // get ongoing sessions + file_api.request('folder_info', {folder: file_api.file_path(rcmail.env.file), sessions: 1}, 'folder_info_response'); + } + else { + file_api.folder_list(); + file_api.browser_capabilities_check(); + } + } + + if (rcmail.env.files_caps && rcmail.env.files_caps.MANTICORE) + $.extend(manticore_config, { + // invitation notifications + api: file_api, + owner: rcmail.env.files_user, + interval: rcmail.env.files_interval || 60, + invitationMore: true, + invitationChange: manticore_invitation_handler, + invitationSaved: manticore_invitation_save_handler, + }); + + $.extend(manticore_config, { + // notifications/alerts + gettext: function(label) { return rcmail.get_label('kolab_files.' + label); }, + set_busy: function(state, message) { return rcmail.set_busy(state, message ? 'kolab_files.' + message : ''); }, + hide_message: function(id) { return rcmail.hide_message(id); }, + display_message: function(label, type, is_txt) { + if (!is_txt) + label = 'kolab_files.' + label; + return rcmail.display_message(label, type); + } + }); + + manticore = new manticore_api(manticore_config); }; // returns API authorization token @@ -519,7 +541,7 @@ function kolab_files_folder_mount_dialog() // file edit dialog function kolab_files_file_edit_dialog(file, sessions, readonly) { - var content = [], items = [], height = 300; + var content = [], items = [], height = 300, dialog = $('#files-file-edit-dialog'), buttons = {}, name = file_api.file_name(file), title = rcmail.gettext('kolab_files.editfiledialog'), @@ -529,15 +551,19 @@ function kolab_files_file_edit_dialog(file, sessions, readonly) .append($('').attr({name: 'opt', value: id, type: 'radio'})).append($('').text(txt)); }, select_fn = function(dlg) { - var input = $('input:checked', dialog), id = input.val(); + var session, input = $('input:checked', dialog), id = input.val(); if (dlg) kolab_dialog_close(dlg); + if (id && input.parent().is('.session.request')) { + manticore.invitation_request({session_id: id}); + return; + } + if (readonly && (id == 0 || !input.length)) return kolab_files_file_create_dialog(file); - // @todo: invitations rcmail.files_edit(id ? id : true); }; @@ -566,7 +592,7 @@ function kolab_files_file_edit_dialog(file, sessions, readonly) $.each(sessions, function() { if (!this.is_owner && !this.is_invited) { var txt = rcmail.gettext('kolab_files.joinsession').replace('$user', this.owner); - items.push(item_fn(this.id, txt)); + items.push(item_fn(this.id, txt, 'request')); } }); @@ -1286,25 +1312,143 @@ function kolab_files_add_attendees(names) function kolab_files_attendee_record(user, status) { - var buttons = $(''); + var buttons = $(''), + type = status ? status.replace(/-.*$/, '') : ''; - // @todo: accept invitation request button + // @todo: accept/decline invitation request // delete button if (status != 'organizer') { $('').attr({'class': 'delete', href: '#', title: rcmail.gettext('kolab_files.removeparticipant')}) .click(function() { - file_api.document_remove(rcmail.env.file_data.session.id, [user]); + file_api.document_cancel(rcmail.env.file_data.session.id, [user]); }) .appendTo(buttons); } - return $('').attr('class', 'invitation' + (status ? ' ' + status : '')) + return $('').attr('class', 'invitation' + (type ? ' ' + type : '')) .append($('').text(user)) - .append($('').text(rcmail.gettext('kolab_files.status' + status))) + .append($('').text(rcmail.gettext('kolab_files.status' + type))) .append(buttons); }; +function manticore_invitation_handler(invitation) +{ + // make the "More" link clickable + $('#' + invitation.id).click(function() { kolab_files_invitation_dialog(invitation); }); + + // @todo: update session icon state on files list +}; + +function manticore_invitation_save_handler(invitation) +{ + // @todo: update session icon state on files list +}; + +function kolab_files_invitation_dialog(invitation) +{ + var text, records = [], content = [], buttons = {}, + dialog = $('#document-invitation-dialog'), + data_map = {status: 'status', 'changed': 'when', filename: 'file', comment: 'comment'}, + record_fn = function(type, label, value) { + records.push($('').attr('class', type) + .append($('').text(rcmail.gettext('kolab_files.'+ label))) + .append($('').text(value)) + ); + }; +/* + join_session = function() { + var viewer = file_api.file_type_supported('application//vnd.oasis.opendocument.text', rcmail.env.files_caps); + params = {action: 'edit', session: invitation.session_id}; + + file_api.file_open(invitation.file, viewer, params); + }; +*/ + if (!dialog.length) + dialog = $('
').attr({id: 'document-invitation-dialog', role: 'dialog', 'aria-hidden': 'true'}) + .append($('
')) + .appendTo(document.body); + + if (!invitation.is_session_owner) { + if (invitation.status == 'invited') { + text = manticore.invitation_msg(invitation); +/* + buttons[rcmail.gettext('kolab_files.join')] = function() { + join_session(); + kolab_dialog_close(this); + }; +*/ + buttons[rcmail.gettext('kolab_files.accept')] = function() { + manticore.invitation_accept(invitation); + kolab_dialog_close(this); + }; + buttons[rcmail.gettext('kolab_files.decline')] = function() { + manticore.invitation_decline(invitation); + kolab_dialog_close(this); + }; + } + else if (invitation.status == 'declined-owner') { + // @todo: add option to request for an invitation again? + text = manticore.invitation_msg(invitation); + } + else if (invitation.status == 'accepted-owner') { + text = manticore.invitation_msg(invitation); +/* + buttons[rcmail.gettext('kolab_files.join')] = function() { + join_session(); + kolab_dialog_close(this); + }; +*/ + } + } + else { + if (invitation.status == 'accepted') { + text = manticore.invitation_msg(invitation); + } + else if (invitation.status == 'declined') { + // @todo: add option to invite the user again? + text = manticore.invitation_msg(invitation); + } + else if (invitation.status == 'requested') { + text = manticore.invitation_msg(invitation); + buttons[rcmail.gettext('kolab_files.accept')] = function() { + manticore.invitation_accept(invitation); + kolab_dialog_close(this); + }; + buttons[rcmail.gettext('kolab_files.decline')] = function() { + manticore.invitation_decline(invitation); + kolab_dialog_close(this); + }; + } + } + + if (text) { + $.each(data_map, function(i, label) { + var value = invitation[i]; + if (value) { + if (i == 'status') + value = rcmail.gettext('kolab_files.status' + value.replace(/-.*$/, '')); + + record_fn(i, label, value); + } + }); + + content.push($('
').text(text)); + content.push($('').html(records)); + } + + buttons[rcmail.gettext('kolab_files.close')] = function() { + kolab_dialog_close(this); + }; + + $('div', dialog).html(content); + + // show dialog window + kolab_dialog_show(dialog, { + title: rcmail.gettext('kolab_files.invitationtitle').replace('$file', invitation.filename), + buttons: buttons + }); +}; /***********************************************************/ /********** Commands **********/ @@ -3127,17 +3271,17 @@ function kolab_files_ui() }); }; - // Remove document session participants - this.document_remove = function(id, attendees) + // Cancel invitations to an editing session + this.document_cancel = function(id, attendees) { if (attendees.length) { - this.req = this.set_busy(true, 'kolab_files.documentremoving'); - this.request('document_remove', {id: id, users: attendees}, 'document_remove_response'); + this.req = this.set_busy(true, 'kolab_files.documentcancelling'); + this.request('document_cancel', {id: id, users: attendees}, 'document_cancel_response'); } }; - // document remove response handler - this.document_remove_response = function(response) + // document_cancel response handler + this.document_cancel_response = function(response) { if (!this.response(response) || !response.result) return; diff --git a/plugins/kolab_files/lib/kolab_files_engine.php b/plugins/kolab_files/lib/kolab_files_engine.php index 1bd0d728..e19818b0 100644 --- a/plugins/kolab_files/lib/kolab_files_engine.php +++ b/plugins/kolab_files/lib/kolab_files_engine.php @@ -124,15 +124,27 @@ class kolab_files_engine } $this->plugin->include_stylesheet($this->plugin->local_skin_path().'/style.css'); + $this->plugin->include_script($this->url . '/js/files_api.js'); + $this->plugin->include_script('kolab_files.js'); + + $this->rc->output->set_env('files_token', $this->get_api_token()); + $this->rc->output->set_env('files_caps', $_SESSION['kolab_files_caps']); + $this->rc->output->set_env('files_user', $this->rc->get_user_name()); + + if ($_SESSION['kolab_files_caps']['MANTICORE']) { + $this->plugin->add_label('declinednotice', 'invitednotice', 'acceptedownernotice', + 'declinedownernotice', 'requestednotice', 'acceptednotice', 'declinednotice', + 'more', 'accept', 'decline', 'join', 'status', 'when', 'file', 'comment', + 'statusaccepted', 'statusinvited', 'statusdeclined', 'statusrequested', + 'invitationaccepting', 'invitationdeclining', 'invitationrequesting', + 'close', 'invitationtitle'); + } if (!empty($templates)) { $collapsed_folders = (string) $this->rc->config->get('kolab_files_collapsed_folders'); - $this->plugin->include_script($this->url . '/js/files_api.js'); - $this->plugin->include_script('kolab_files.js'); $this->rc->output->include_script('treelist.js'); $this->rc->output->set_env('files_url', $this->url . '/api/'); - $this->rc->output->set_env('files_token', $this->get_api_token()); $this->rc->output->set_env('kolab_files_collapsed_folders', $collapsed_folders); // register template objects for dialogs (and main interface) @@ -359,9 +371,7 @@ class kolab_files_engine 'rows' => 4, 'cols' => 55, 'title' => $this->plugin->gettext('invitationtexttitle'))); $button = new html_inputfield(array('type' => 'button', 'class' => 'button', 'id' => 'invitation-editor-add', 'value' => $this->plugin->gettext('addparticipant'))); - $this->plugin->add_label('close', 'manageeditors', 'statusorganizer', 'statusaccepted', - 'statusinvited', 'statusdeclined', 'statusrequested' - ); + $this->plugin->add_label('manageeditors', 'statusorganizer'); // initialize attendees autocompletion $this->rc->autocomplete_init(); @@ -939,7 +949,6 @@ class kolab_files_engine */ protected function action_open() { - $this->rc->output->set_env('files_caps', $_SESSION['kolab_files_caps']); $this->rc->output->set_env('file_mimetypes', $this->get_mimetypes()); $this->file_opener(intval($_GET['_viewer']) & ~4); @@ -951,7 +960,7 @@ class kolab_files_engine protected function action_edit() { $this->plugin->add_label('sessionterminating', 'unsavedchanges', 'documentinviting', - 'documentremoving', 'removeparticipant'); + 'documentcancelling', 'removeparticipant'); $this->file_opener(intval($_GET['_viewer'])); } @@ -1371,7 +1380,5 @@ class kolab_files_engine $this->rc->output->add_label('foldersubscribing', 'foldersubscribed', 'folderunsubscribing', 'folderunsubscribed', 'searching' ); - - $this->rc->output->set_env('files_caps', $_SESSION['kolab_files_caps']); } } diff --git a/plugins/kolab_files/localization/en_US.inc b/plugins/kolab_files/localization/en_US.inc index b0c0f368..3e242c07 100644 --- a/plugins/kolab_files/localization/en_US.inc +++ b/plugins/kolab_files/localization/en_US.inc @@ -119,8 +119,25 @@ $labels['statusaccepted'] = 'Accepted'; $labels['statusdeclined'] = 'Declined'; $labels['statusrequested'] = 'Requested'; $labels['documentinviting'] = 'Inviting participant(s)...'; -$labels['documentremoving'] = 'Removing participant(s)...'; +$labels['documentcancelling'] = 'Removing participant(s)...'; $labels['removeparticipant'] = 'Remove'; +$labels['invitednotice'] = 'You have been invited to the editing session by $owner.'; +$labels['acceptedownernotice'] = '$owner accepted your request to join the editing session.'; +$labels['declinedownernotice'] = '$owner declined your request to join the editing session.'; +$labels['acceptednotice'] = '$user accepted your invitation to the editing session.'; +$labels['declinednotice'] = '$user declined your invitation to the editing session.'; +$labels['requestednotice'] = '$user requested to join the editing session.'; +$labels['more'] = 'More.'; +$labels['accept'] = 'Accept'; +$labels['join'] = 'Join the session'; +$labels['decline'] = 'Decline'; +$labels['when'] = 'When'; +$labels['file'] = 'File'; +$labels['comment'] = 'Comment'; +$labels['invitationtitle'] = 'Invitation for $file'; +$labels['ivitationaccepting'] = 'Accepting an invitation...'; +$labels['ivitationdeclining'] = 'Declining an invitation...'; +$labels['ivitationrequesting'] = 'Requesting an invitation...'; $labels['storepasswords'] = 'remember password'; $labels['storepasswordsdesc'] = 'Stored passwords will be encrypted. Enable this if you do not want to be asked for the password on every login or you want this storage to be available via WebDAV.'; diff --git a/plugins/kolab_files/skins/larry/style.css b/plugins/kolab_files/skins/larry/style.css index 7f1b6cfa..a008795e 100644 --- a/plugins/kolab_files/skins/larry/style.css +++ b/plugins/kolab_files/skins/larry/style.css @@ -418,6 +418,7 @@ ul.toolbarmenu li span.saveas { #files-folder-auth-dialog, #files-folder-create-dialog, #files-folder-edit-dialog, +#document-invitation-dialog, #document-editors-dialog { display: none; } @@ -575,7 +576,7 @@ table.propform td.source table.propform td { } #document-editors-dialog table th.options { - width: 40px + width: 16px } #document-editors-dialog table td { @@ -603,3 +604,13 @@ table.propform td.source table.propform td { width: 16px; display: block; } + +#document-invitation-dialog table { + margin-top: 15px; +} + +#document-invitation-dialog table td.label { + width: 1%; + white-space: nowrap; + font-weight: bold; +}