diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss index 8ae8fac6c2190..c03b1ce6fad54 100644 --- a/apps/files/css/files.scss +++ b/apps/files/css/files.scss @@ -230,9 +230,6 @@ table th#headerName { position: relative; height: 50px; } -.has-favorites #headerName-container { - padding-left: 50px; -} table th#headerSize, table td.filesize { text-align: right; @@ -294,7 +291,12 @@ table td.filename a.name { line-height: 50px; padding: 0; } -table td.filename label.icon-loading-small { +table td.filename .thumbnail-wrapper { + position: absolute; + width: 50px; + height: 50px; +} +table td.filename .thumbnail-wrapper.icon-loading-small { &:after { z-index: 10; } @@ -306,10 +308,10 @@ table td.filename .thumbnail { display: inline-block; width: 32px; height: 32px; + background-size: 32px; margin-left: 9px; margin-top: 9px; cursor: pointer; - float: left; position: absolute; z-index: 4; } @@ -319,12 +321,9 @@ table td.filename input.filename { margin-left: 48px; cursor: text; } -.has-favorites table td.filename input.filename { - margin-left: 52px; -} table td.filename a, table td.login, table td.logout, table td.download, table td.upload, table td.create, table td.delete { padding:3px 8px 8px 3px; } -table td.filename .nametext, .uploadtext, .modified, .column-last>span:first-child { float:left; padding:15px 0; } +table td.filename .nametext, .modified, .column-last>span:first-child { float:left; padding:15px 0; } .modified, .column-last>span:first-child { position: relative; @@ -336,22 +335,23 @@ table td.filename .nametext, .uploadtext, .modified, .column-last>span:first-chi /* TODO fix usability bug (accidental file/folder selection) */ table td.filename .nametext { position: absolute; - left: 55px; padding: 0; + padding-left: 55px; overflow: hidden; text-overflow: ellipsis; width: 70%; max-width: 800px; height: 100%; + z-index: 10; +} +table td.filename .uploadtext { + position: absolute; + left: 55px; } /* ellipsis on file names */ table td.filename .nametext .innernametext { max-width: calc(100% - 100px) !important; } -.has-favorites #fileList td.filename a.name { - left: 50px; - margin-right: 50px; -} .hide-hidden-files #fileList tr.hidden-file, .hide-hidden-files #fileList tr.hidden-file.dragging { @@ -437,49 +437,27 @@ table td.filename .uploadtext { opacity: .5; } +table td.selection { + padding: 0; +} + /* File checkboxes */ -#fileList tr td.filename>.selectCheckBox + label:before { - opacity: 0; - position: absolute; - bottom: 4px; - right: 0; - z-index: 10; +#fileList tr td.selection>.selectCheckBox + label:before { + opacity: 0.3; } -/* Show checkbox when hovering, checked, or selected */ -#fileList tr:hover td.filename>.selectCheckBox + label:before, -#fileList tr:focus td.filename>.selectCheckBox + label:before, -#fileList tr td.filename>.selectCheckBox:checked + label:before, -#fileList tr.selected td.filename>.selectCheckBox + label:before { +/* Show checkbox with full opacity when hovering, checked, or selected */ +#fileList tr:hover td.selection>.selectCheckBox + label:before, +#fileList tr:focus td.selection>.selectCheckBox + label:before, +#fileList tr td.selection>.selectCheckBox:checked + label:before, +#fileList tr.selected td.selection>.selectCheckBox + label:before { opacity: 1; } /* Use label to have bigger clickable size for checkbox */ -#fileList tr td.filename>.selectCheckBox + label, +#fileList tr td.selection>.selectCheckBox + label, .select-all + label { - background-position: 30px 30px; - height: 50px; - position: absolute; - width: 50px; - z-index: 5; -} -#fileList tr td.filename>.selectCheckBox { - /* sometimes checkbox height is bigger (KDE/Qt), so setting to absolute - * to prevent it to increase the height */ - position: absolute; - z-index: 10; -} -.select-all + label { - top: 0; -} -.select-all + label:before { - position: absolute; - top: 18px; - left: 18px; - z-index: 10; -} -.has-favorites .select-all { - left: 68px; + padding: 16px; } #fileList tr td.filename { @@ -500,10 +478,11 @@ table td.filename .uploadtext { display: inline-block; float: left; } -#fileList tr td.filename .action-favorite { +#fileList tr td.filename .favorite-mark { + position: absolute; display: block; - float: left; - width: 30px; + top: -6px; + right: -6px; line-height: 100%; text-align: center; } @@ -615,7 +594,7 @@ a.action > img { padding-left: 6px; } -#fileList .action.action-favorite.permanent { +#fileList .favorite-mark.permanent { opacity: 1; } @@ -659,9 +638,6 @@ table tr.summary td { .summary .info { margin-left: 40px; } -.has-favorites .summary .info { - margin-left: 90px; -} table.dragshadow { width:auto; @@ -714,12 +690,24 @@ table.dragshadow td.size { #filestable .filename .action .icon, #filestable .selectedActions a .icon, +#filestable .filename .favorite-mark .icon, #controls .actions .button .icon { display: inline-block; vertical-align: middle; background-size: 16px 16px; } +#filestable .filename .favorite-mark { + // Override default icons to always hide the star icon and always show the + // starred icon even when hovered or focused. + & .icon-star { + background-image: none; + } + & .icon-starred { + background-image: url('../../../core/img/actions/starred.svg?v=1'); + } +} + #filestable .filename .action .icon.hidden, #filestable .selectedActions a .icon.hidden, #controls .actions .button .icon.hidden { diff --git a/apps/files/css/mobile.scss b/apps/files/css/mobile.scss index eefc92c816b88..e7b75910fa93c 100644 --- a/apps/files/css/mobile.scss +++ b/apps/files/css/mobile.scss @@ -24,10 +24,6 @@ table td.date { table td { padding: 0; } -/* and accordingly fix left margin of file list summary on mobile */ -.summary .info { - margin-left: 105px; -} /* remove shift for multiselect bar to account for missing navigation */ table.multiselect thead { diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index 3da9b06b0d3aa..0f320c8b3c7c9 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -706,7 +706,7 @@ * @property {String} mime mime type * @property {int} permissions permissions * @property {(Function|String)} icon icon path to the icon or function that returns it (deprecated, use iconClass instead) - * @property {(Function|String)} iconClass class name of the icon (recommended for theming) + * @property {(String|OCA.Files.FileActions~iconClassFunction)} iconClass class name of the icon (recommended for theming) * @property {OCA.Files.FileActions~renderActionFunction} [render] optional rendering function * @property {OCA.Files.FileActions~actionHandler} actionHandler action handler function */ @@ -745,6 +745,17 @@ * @return {String} display name */ + /** + * Icon class function for actions. + * The function returns the icon class of the action using + * the given context information. + * + * @callback OCA.Files.FileActions~iconClassFunction + * @param {String} fileName name of the file on which the action must be performed + * @param {OCA.Files.FileActionContext} context action context + * @return {String} icon class + */ + /** * Action handler function for file actions * diff --git a/apps/files/js/fileactionsmenu.js b/apps/files/js/fileactionsmenu.js index 45d2bd83049aa..b8022f137341b 100644 --- a/apps/files/js/fileactionsmenu.js +++ b/apps/files/js/fileactionsmenu.js @@ -115,6 +115,11 @@ item = _.extend({}, item); item.displayName = item.displayName(self._context); } + if (_.isFunction(item.iconClass)) { + var fileName = self._context.$file.attr('data-file'); + item = _.extend({}, item); + item.iconClass = item.iconClass(fileName, self._context); + } return item; }); items = items.sort(function(actionA, actionB) { diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index cc23ac73979f3..0d45c29b25abb 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -332,7 +332,7 @@ this.$fileList.on('click','td.filename>a.name, td.filesize, td.date', _.bind(this._onClickFile, this)); - this.$fileList.on('change', 'td.filename>.selectCheckBox', _.bind(this._onClickFileCheckbox, this)); + this.$fileList.on('change', 'td.selection>.selectCheckBox', _.bind(this._onClickFileCheckbox, this)); this.$el.on('show', _.bind(this._onShow, this)); this.$el.on('urlChanged', _.bind(this._onUrlChanged, this)); this.$el.find('.select-all').click(_.bind(this._onClickSelectAll, this)); @@ -593,7 +593,7 @@ * @param {bool} state true to select, false to deselect */ _selectFileEl: function($tr, state, showDetailsView) { - var $checkbox = $tr.find('td.filename>.selectCheckBox'); + var $checkbox = $tr.find('td.selection>.selectCheckBox'); var oldData = !!this._selectedFiles[$tr.data('id')]; var data; $checkbox.prop('checked', state); @@ -649,7 +649,7 @@ else { this._lastChecked = $tr; } - var $checkbox = $tr.find('td.filename>.selectCheckBox'); + var $checkbox = $tr.find('td.selection>.selectCheckBox'); this._selectFileEl($tr, !$checkbox.prop('checked')); this.updateSelectionSummary(); } else { @@ -704,7 +704,7 @@ */ _onClickSelectAll: function(e) { var checked = $(e.target).prop('checked'); - this.$fileList.find('td.filename>.selectCheckBox').prop('checked', checked) + this.$fileList.find('td.selection>.selectCheckBox').prop('checked', checked) .closest('tr').toggleClass('selected', checked); this._selectedFiles = {}; this._selectionSummary.clear(); @@ -1063,6 +1063,13 @@ this.$fileList.empty(); + if (this._allowSelection) { + // The results table, which has no selection column, checks + // whether the main table has a selection column or not in order + // to align its contents with those of the main table. + this.$el.addClass('has-selection'); + } + // clear "Select all" checkbox this.$el.find('.select-all').prop('checked', false); @@ -1192,6 +1199,20 @@ path = this.getCurrentDirectory(); } + // selection td + if (this._allowSelection) { + td = $('