Elastic: Various improvements for Files on mobile

This commit is contained in:
Aleksander Machniak 2018-04-24 12:28:29 +00:00
parent 0fc9ca3031
commit 931c7e594d
8 changed files with 101 additions and 33 deletions

View file

@ -461,7 +461,8 @@ function kolab_files_folder_create_dialog()
kolab_dialog_show(dialog, { kolab_dialog_show(dialog, {
title: rcmail.gettext('kolab_files.foldercreate'), title: rcmail.gettext('kolab_files.foldercreate'),
buttons: buttons, buttons: buttons,
button_classes: ['mainaction save', 'cancel'] button_classes: ['mainaction save', 'cancel'],
height: 200
}); });
// Fix submitting form with Enter // Fix submitting form with Enter
@ -1366,7 +1367,7 @@ rcube_webmail.prototype.document_close = function()
if (this.commands['document-save']) if (this.commands['document-save'])
this.confirm_dialog(this.gettext('kolab_files.unsavedchanges'), 'kolab_files.terminate', function() { this.confirm_dialog(this.gettext('kolab_files.unsavedchanges'), 'kolab_files.terminate', function() {
file_api.document_delete(rcmail.env.file_data.session.id); file_api.document_delete(rcmail.env.file_data.session.id);
}); }, {button_class: 'delete'});
}; };
// document editors management dialog // document editors management dialog
@ -2009,8 +2010,8 @@ function kolab_files_ui()
collections = ['audio', 'video', 'image', 'document']; collections = ['audio', 'video', 'image', 'document'];
// try parent window if the list element does not exist // try parent window if the list element does not exist
// i.e. called from dialog in parent window // i.e. called from a dialog in parent window
if (!elem.length && rcmail.is_framed()) { if (!elem.length && rcmail.is_framed() && (rcmail.env.task != 'files' || (rcmail.env.action != 'open' && rcmail.env.action != 'edit'))) {
body = window.parent.document.body; body = window.parent.document.body;
elem = $(list_selector, body); elem = $(list_selector, body);
searchbox = $(search_selector, body); searchbox = $(search_selector, body);
@ -2115,6 +2116,14 @@ function kolab_files_ui()
// handle authentication errors on external sources // handle authentication errors on external sources
this.folder_list_auth_errors(response.result); this.folder_list_auth_errors(response.result);
// Elastic: Set notree class on the folder list
var callback = function() {
list[list.find('.treetoggle').length > 0 ? 'removeClass' : 'addClass']('notree');
};
if (window.MutationObserver)
(new MutationObserver(callback)).observe(list.get(0), {childList: true, subtree: true});
callback();
}; };
this.folder_select = function(folder) this.folder_select = function(folder)
@ -2131,7 +2140,7 @@ function kolab_files_ui()
rcmail.update_state(is_collection ? {collection: collection} : {folder: folder}); rcmail.update_state(is_collection ? {collection: collection} : {folder: folder});
if (collection == 'sessions') { if (collection == 'sessions') {
rcmail.enable_command('files-list', 'files-folder-delete', 'folder-rename', 'files-upload', false); rcmail.enable_command('files-list', 'files-folder-delete', 'folder-rename', 'files-upload', 'files-open', 'files-edit', false);
this.sessions_list(); this.sessions_list();
return; return;
} }
@ -3067,16 +3076,22 @@ function kolab_files_ui()
// check if opener window contains files list, if not we can just close current window // check if opener window contains files list, if not we can just close current window
if (rco && rco.fileslist && (opener.file_api.env.folder == dir || !opener.file_api.env.folder)) if (rco && rco.fileslist && (opener.file_api.env.folder == dir || !opener.file_api.env.folder))
self = opener.file_api; self = opener.file_api;
else // also try parent for framed UI (Elastic)
window.close(); else if (rcmail.is_framed() && parent.rcmail.fileslist && (parent.file_api.env.folder == dir || !parent.file_api.env.folder))
self = parent.file_api;
} }
// @TODO: consider list modification "in-place" instead of full reload // @TODO: consider list modification "in-place" instead of full reload
self.file_list(); self.file_list();
self.quota(); self.quota();
if (rcmail.env.file) if (rcmail.env.file) {
window.close(); if (rcmail.is_framed()) {
parent.$('.ui-dialog:visible > .ui-dialog-buttonpane button.cancel').click();
}
else
window.close();
}
}; };
// file(s) move request // file(s) move request
@ -3631,7 +3646,7 @@ function kolab_files_ui()
var win = window, list = rcmail.sessionslist; var win = window, list = rcmail.sessionslist;
if (!list) { if (!list) {
win = window.opener; win = window.opener || window.parent;
if (win && win.rcmail && win.file_api) if (win && win.rcmail && win.file_api)
list = win.rcmail.sessionslist; list = win.rcmail.sessionslist;
} }
@ -3639,8 +3654,13 @@ function kolab_files_ui()
// remove session from the list (if sessions list exist) // remove session from the list (if sessions list exist)
if (list) if (list)
list.remove_row(this.deleted_session); list.remove_row(this.deleted_session);
if (win.file_api && win.file_api.env.sessions_list) if (win && win.file_api && win.file_api.env.sessions_list)
delete win.file_api.env.sessions_list[this.deleted_session]; delete win.file_api.env.sessions_list[this.deleted_session];
// For Elastic: hide the parent dialog
if (rcmail.is_framed()) {
parent.$('.ui-dialog:visible button.cancel').click();
}
}; };
// Invite document session participants // Invite document session participants

View file

@ -1430,7 +1430,7 @@ class kolab_files_engine
$this->file_data['filename'] = $file; $this->file_data['filename'] = $file;
$this->plugin->add_label('filedeleteconfirm', 'filedeleting', 'filedeletenotice'); $this->plugin->add_label('filedeleteconfirm', 'filedeleting', 'filedeletenotice', 'terminate');
// register template objects for dialogs (and main interface) // register template objects for dialogs (and main interface)
$this->rc->output->add_handlers(array( $this->rc->output->add_handlers(array(

View file

@ -3,7 +3,7 @@
<div id="folderlistbox" class="selection-list" role="navigation" aria-labelledby="aria-label-folderlist"> <div id="folderlistbox" class="selection-list" role="navigation" aria-labelledby="aria-label-folderlist">
<h4 id="aria-label-folderlist" class="voice"><roundcube:label name="kolab_files.arialabelfolderlist" /></h4> <h4 id="aria-label-folderlist" class="voice"><roundcube:label name="kolab_files.arialabelfolderlist" /></h4>
<div class="header"> <div class="header">
<a class="button icon back-content-button" href="#back" data-hidden="big" onclick="$('#folderlistbox').hide();$('#filelistcontainer').show()"><span class="inner"><roundcube:label name="back" /></span></a> <a class="button icon back" href="#back" data-hidden="big" onclick="$('#folderlistbox').hide();$('#filelistcontainer').css('display','flex')"><span class="inner"><roundcube:label name="back" /></span></a>
<span class="header-title"><roundcube:label name="folders" /></span> <span class="header-title"><roundcube:label name="folders" /></span>
<roundcube:object name="libkolab.folder_search_form" id="foldersearch" wrapper="searchbar toolbar" <roundcube:object name="libkolab.folder_search_form" id="foldersearch" wrapper="searchbar toolbar"
ariatag="h5" label="foldersearchform" buttontitle="kolab_files.findfolders" /> ariatag="h5" label="foldersearchform" buttontitle="kolab_files.findfolders" />
@ -12,7 +12,7 @@
</div> </div>
<div id="filelistcontainer" class="selection-content content"> <div id="filelistcontainer" class="selection-content content">
<div class="header"> <div class="header">
<a class="button icon back-sidebar-button folders" href="#sidebar" data-hidden="big" onclick="$('#filelistcontainer').hide();$('#folderlistbox').show()"><span class="inner"><roundcube:label name="folders" /></span></a> <a class="button icon folders" href="#sidebar" data-hidden="big" onclick="$('#filelistcontainer').hide();$('#folderlistbox').css('display','flex')"><span class="inner"><roundcube:label name="folders" /></span></a>
<span class="header-title" data-hidden="big" ><roundcube:label name="kolab_files.selectfiles" /></span> <span class="header-title" data-hidden="big" ><roundcube:label name="kolab_files.selectfiles" /></span>
<roundcube:object name="file-search-form" id="filesearchbox" wrapper="searchbar toolbar" <roundcube:object name="file-search-form" id="filesearchbox" wrapper="searchbar toolbar"
label="searchform" buttontitle="kolab_files.findfiles" label-domain="kolab_files" label="searchform" buttontitle="kolab_files.findfiles" label-domain="kolab_files"

View file

@ -28,7 +28,7 @@
<roundcube:endif /> <roundcube:endif />
<roundcube:button command="document-save" type="link" <roundcube:button command="document-save" type="link"
class="button save disabled" classAct="button save" class="button save disabled" classAct="button save"
label="kolab_files.save" title="kolab_files.savefile" innerClass="inner" /> label="kolab_files.save" title="kolab_files.savefile" innerClass="inner" data-hidden="small" />
</div> </div>
<roundcube:if condition="env:editor_type != 'wopi'" /> <roundcube:if condition="env:editor_type != 'wopi'" />
<div id="doc-title" data-hidden="small"> <div id="doc-title" data-hidden="small">
@ -48,6 +48,13 @@
<roundcube:object name="filepreviewframe" id="fileframe" role="main" <roundcube:object name="filepreviewframe" id="fileframe" role="main"
title="kolab_files.arialabelfilecontent" aria-labelledby="aria-label-filecontent" /> title="kolab_files.arialabelfilecontent" aria-labelledby="aria-label-filecontent" />
</div> </div>
<div class="footer toolbar hidden-big">
<roundcube:button command="document-save" type="link"
class="button save disabled" classAct="button save"
label="kolab_files.save" title="kolab_files.savefile" innerClass="inner" />
<roundcube:button name="close-window" type="link" onclick="parent.$('.ui-dialog:visible button.cancel').click()"
class="button cancel" label="cancel" title="cancel" innerClass="inner" />
</div>
</div> </div>
<div id="export-menu" class="popupmenu"> <div id="export-menu" class="popupmenu">

View file

@ -7,7 +7,9 @@
<a class="button icon back-content-button" href="#content" data-hidden="big"><span class="inner"><roundcube:label name="back" /></span></a> <a class="button icon back-content-button" href="#content" data-hidden="big"><span class="inner"><roundcube:label name="back" /></span></a>
<span class="header-title" id="aria-label-contentinfo"><roundcube:label name="properties" /></span> <span class="header-title" id="aria-label-contentinfo"><roundcube:label name="properties" /></span>
</div> </div>
<roundcube:object name="fileinfobox" id="fileinfo" class="listing props-table" /> <div class="scroller">
<roundcube:object name="fileinfobox" id="fileinfo" class="listing props-table" />
</div>
</div> </div>
<div class="content selected"> <div class="content selected">
@ -17,16 +19,16 @@
<span class="inner"><roundcube:label name="properties"></span> <span class="inner"><roundcube:label name="properties"></span>
</a> </a>
<span class="header-title constant"><roundcube:var name="env:filename" /></span> <span class="header-title constant"><roundcube:var name="env:filename" /></span>
<div id="messagetoolbar" class="toolbar"> <div id="filetoolbar" class="toolbar">
<roundcube:button command="files-get" type="link" <roundcube:button command="files-get" type="link"
class="button download disabled" classAct="button download" class="button download disabled" classAct="button download"
label="kolab_files.get" title="kolab_files.getfile" innerClass="inner" /> label="kolab_files.get" title="kolab_files.getfile" innerClass="inner" />
<roundcube:button command="files-edit" type="link" <roundcube:button command="files-edit" type="link"
class="button edit disabled" classAct="button edit" class="button edit disabled" classAct="button edit"
label="kolab_files.edit" title="kolab_files.editfile" innerClass="inner" /> label="kolab_files.edit" title="kolab_files.editfile" innerClass="inner" data-hidden="small" />
<roundcube:button command="files-save" type="link" <roundcube:button command="files-save" type="link"
class="button save disabled" classAct="button save" class="button save disabled" classAct="button save"
label="kolab_files.save" title="kolab_files.savefile" innerClass="inner" style="display:none" /> label="kolab_files.save" title="kolab_files.savefile" innerClass="inner" style="display:none" data-hidden="small" />
<roundcube:button command="files-delete" type="link" <roundcube:button command="files-delete" type="link"
class="button delete disabled" classAct="button delete" class="button delete disabled" classAct="button delete"
label="delete" title="kolab_files.deletefile" innerClass="inner" /> label="delete" title="kolab_files.deletefile" innerClass="inner" />
@ -47,7 +49,7 @@
</div> </div>
</div> </div>
<h2 id="aria-label-filecontent" class="voice"><roundcube:label name="kolab_files.arialabelfilecontent" /></h2> <h2 id="aria-label-filecontent" class="voice"><roundcube:label name="kolab_files.arialabelfilecontent" /></h2>
<div class="iframe-wrapper file-preview"> <div class="iframe-wrapper file-type-<roundcube:exp expression="strtolower(preg_replace('|/.*$|', '', env:mimetype))" />">
<roundcube:object name="filepreviewframe" id="fileframe" role="main" aria-labelledby="aria-label-filecontent" /> <roundcube:object name="filepreviewframe" id="fileframe" role="main" aria-labelledby="aria-label-filecontent" />
</div> </div>
<roundcube:if condition="stripos(env:mimetype, 'image/') === 0" /> <roundcube:if condition="stripos(env:mimetype, 'image/') === 0" />

View file

@ -4,6 +4,15 @@ function kolab_files_enable_command(p)
var toolbar = $('#toolbar-menu'); var toolbar = $('#toolbar-menu');
$('a.button.edit', toolbar).parent().hide(); $('a.button.edit', toolbar).parent().hide();
$('a.button.save', toolbar).show().parent().show(); $('a.button.save', toolbar).show().parent().show();
if (window.editor_edit_button)
window.editor_edit_button.addClass('hidden');
if (window.editor_save_button)
window.editor_save_button.removeClass('hidden');
}
else if (p.command == 'files-edit' && p.status) {
if (window.editor_edit_button)
window.editor_edit_button.removeClass('hidden');
} }
}; };
@ -81,6 +90,26 @@ if (rcmail.env.action == 'open') {
$(this).contents().find('head').append('<style type="text/css">'+ css + '</style>'); $(this).contents().find('head').append('<style type="text/css">'+ css + '</style>');
}); });
} }
// Elastic mobile preview uses an iframe in a dialog
if (rcmail.is_framed()) {
var edit_button = $('#filetoolbar a.button.edit'),
save_button = $('#filetoolbar a.button.save');
parent.$('.ui-dialog:visible .ui-dialog-buttonpane .ui-dialog-buttonset').prepend(
window.editor_save_button = $('<button>')
.addClass('save btn btn-secondary' + (save_button.is('.disabled') ? ' hidden' : ''))
.text(save_button.text())
.on('click', function() { save_button.click(); })
);
parent.$('.ui-dialog:visible .ui-dialog-buttonpane .ui-dialog-buttonset').prepend(
window.editor_edit_button = $('<button>')
.addClass('edit btn btn-secondary' + (edit_button.is('.disabled') ? ' hidden' : ''))
.text(edit_button.text())
.on('click', function() { edit_button.click(); })
);
}
} }
else if (rcmail.env.action == 'edit') { else if (rcmail.env.action == 'edit') {
rcmail.gui_object('exportmenu', 'export-menu'); rcmail.gui_object('exportmenu', 'export-menu');
@ -100,6 +129,11 @@ $(document).ready(function() {
if (rcmail.env.action == 'open') { if (rcmail.env.action == 'open') {
$('#toolbar-menu a.button.save').parent().hide(); $('#toolbar-menu a.button.save').parent().hide();
} }
else if (rcmail.env.action == 'edit') {
if (rcmail.is_framed()) {
parent.$('.ui-dialog:visible .ui-dialog-buttonpane').addClass('hidden');
}
}
if ($('#dragfilemenu').length) { if ($('#dragfilemenu').length) {
rcmail.gui_object('file_dragmenu', 'dragfilemenu'); rcmail.gui_object('file_dragmenu', 'dragfilemenu');

View file

@ -41,6 +41,10 @@ a.button.saveas:before {
content: @fa-var-pen-square; content: @fa-var-pen-square;
} }
.toolbar a.button.cancel:before {
content: @fa-var-times;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset a.btn-link.options.add-folder { .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset a.btn-link.options.add-folder {
order: 99; order: 99;
@ -370,6 +374,10 @@ a.button.saveas:before {
text-align: left !important; text-align: left !important;
} }
.header-title {
margin: 0 !important;
}
a.button.icon.members:before { a.button.icon.members:before {
content: @fa-var-users; content: @fa-var-users;
} }
@ -401,12 +409,13 @@ a.button.saveas:before {
.session-members { .session-members {
img.photo { img.photo {
width: 32px; width: 48px;
height: 32px; height: 48px;
min-width: 48px;
overflow: hidden; overflow: hidden;
background: url(../../../../skins/elastic/images/contactpic.png) center center no-repeat #fff; background: url(../../../../skins/elastic/images/contactpic.png) center center no-repeat #fff;
background-size: cover; background-size: cover;
border-radius: .25rem; border-radius: 50%;
border: solid 3px #eee; border: solid 3px #eee;
margin-left: .5rem; margin-left: .5rem;
} }
@ -422,9 +431,6 @@ a.button.saveas:before {
} }
img.photo { img.photo {
width: 48px;
height: 48px;
min-width: 48px;
margin-left: 0; margin-left: 0;
margin-right: 1em; margin-right: 1em;
} }
@ -462,7 +468,8 @@ button.participant.add:before {
content: @fa-var-user-plus; content: @fa-var-user-plus;
} }
.iframe-wrapper.file-preview { .iframe-wrapper.file-type-audio,
.iframe-wrapper.file-type-video {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -470,8 +477,4 @@ button.participant.add:before {
@media screen and (min-width: (@screen-width-small + 1px)) { @media screen and (min-width: (@screen-width-small + 1px)) {
padding: 1em; padding: 1em;
} }
& + .footer.toolbar {
display: none !important;
}
} }

View file

@ -7,8 +7,10 @@
<a class="button icon back-content-button" href="#content" data-hidden="big"><span class="inner"><roundcube:label name="back" /></span></a> <a class="button icon back-content-button" href="#content" data-hidden="big"><span class="inner"><roundcube:label name="back" /></span></a>
<span class="header-title" id="aria-label-contentinfo"><roundcube:label name="properties" /></span> <span class="header-title" id="aria-label-contentinfo"><roundcube:label name="properties" /></span>
</div> </div>
<roundcube:object name="plugin.attachmentcontrols" class="listing props-table" role="contentinfo" <div class="scroller">
aria-labelledby="aria-label-contentinfo" /> <roundcube:object name="plugin.attachmentcontrols" class="listing props-table" role="contentinfo"
aria-labelledby="aria-label-contentinfo" />
</div>
</div> </div>
<div class="content selected"> <div class="content selected">