Merge pull request #11573 from nextcloud/gridview-table
Files grid view
This commit is contained in:
commit
37782b1084
|
@ -61,6 +61,16 @@ $application->registerRoutes(
|
|||
'url' => '/api/v1/showhidden',
|
||||
'verb' => 'POST'
|
||||
],
|
||||
[
|
||||
'name' => 'API#showGridView',
|
||||
'url' => '/api/v1/showgridview',
|
||||
'verb' => 'POST'
|
||||
],
|
||||
[
|
||||
'name' => 'API#getGridView',
|
||||
'url' => '/api/v1/showgridview',
|
||||
'verb' => 'GET'
|
||||
],
|
||||
[
|
||||
'name' => 'view#index',
|
||||
'url' => '/',
|
||||
|
|
|
@ -172,7 +172,7 @@ table th, table th a {
|
|||
color: var(--color-text-maxcontrast);
|
||||
}
|
||||
table.multiselect th a {
|
||||
color: #000;
|
||||
color: var(--color-main-text);
|
||||
}
|
||||
table th .columntitle {
|
||||
display: block;
|
||||
|
@ -262,8 +262,7 @@ table.multiselect thead {
|
|||
}
|
||||
|
||||
table.multiselect thead th {
|
||||
background-color: rgba(255, 255, 255, 0.95); /* like controls bar */
|
||||
color: #000;
|
||||
background-color: var(--color-main-background);
|
||||
font-weight: bold;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
@ -595,7 +594,13 @@ a.action > img {
|
|||
.summary {
|
||||
opacity: .3;
|
||||
/* add whitespace to bottom of files list to correctly show dropdowns */
|
||||
height: 300px;
|
||||
height: 250px;
|
||||
}
|
||||
/* Less whitespace needed on link share page
|
||||
* as there is a footer and action menus have fewer entries.
|
||||
*/
|
||||
#body-public .summary {
|
||||
height: 180px;
|
||||
}
|
||||
.summary:hover,
|
||||
.summary:focus,
|
||||
|
@ -723,3 +728,277 @@ table.dragshadow td.size {
|
|||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
/* GRID */
|
||||
#filestable.view-grid:not(.hidden) {
|
||||
$grid-size: 160px;
|
||||
$grid-pad: 14px;
|
||||
|
||||
/* HEADER and MULTISELECT */
|
||||
thead {
|
||||
tr {
|
||||
display: block;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
background-color: var(--color-main-background);
|
||||
th {
|
||||
width: auto;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* MAIN FILE LIST */
|
||||
tbody {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, $grid-size);
|
||||
justify-content: space-around;
|
||||
row-gap: 15px;
|
||||
margin: 15px 0;
|
||||
|
||||
tr {
|
||||
display: block;
|
||||
position: relative;
|
||||
height: $grid-size + 44px - $grid-pad;
|
||||
border-radius: var(--border-radius);
|
||||
|
||||
&:hover, &:focus, &:active,
|
||||
&.selected,
|
||||
&.searchresult,
|
||||
.name:focus,
|
||||
&.highlighted {
|
||||
background-color: transparent;
|
||||
|
||||
.thumbnail-wrapper,
|
||||
.nametext,
|
||||
.fileactions {
|
||||
transition: background-color 0.3s ease;
|
||||
background-color: var(--color-background-dark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
display: inline;
|
||||
border-bottom: none;
|
||||
|
||||
&.filename {
|
||||
.thumbnail-wrapper {
|
||||
min-width: 0;
|
||||
max-width: none;
|
||||
position: absolute;
|
||||
width: $grid-size;
|
||||
height: $grid-size;
|
||||
padding: $grid-pad; // same as action icon bottom and right padding
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: -1; // make sure the default click is the link
|
||||
|
||||
.thumbnail {
|
||||
width: calc(100% - 2 * #{$grid-pad});
|
||||
height: calc(100% - 2 * #{$grid-pad}); //action icon padding
|
||||
background-size: contain;
|
||||
margin: 0;
|
||||
border-radius: var(--border-radius);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
|
||||
/* Position favorite star related to checkbox to left and 3-dot menu below
|
||||
* Position is inherited from the selection while in grid view
|
||||
*/
|
||||
.favorite-mark {
|
||||
padding: $grid-pad;
|
||||
left: auto;
|
||||
top: -22px; // center in corner of thumbnail
|
||||
right: -22px; // center in corner of thumbnail
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
height: 100%;
|
||||
border-radius: var(--border-radius);
|
||||
// since we're using thumbnail, name and actions bg
|
||||
// we need to hide the overflow for the radius to show
|
||||
// luckily the popovermenu is outside .name
|
||||
overflow: hidden;
|
||||
// we but the thumbnail in background to ensure
|
||||
// the name is the default click handler
|
||||
// force back the cursor which have been overrided
|
||||
// and disabled for some reason...
|
||||
cursor: pointer !important;
|
||||
|
||||
.nametext {
|
||||
display: flex;
|
||||
height: 44px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-top: $grid-size - $grid-pad;
|
||||
padding-right: 0;
|
||||
text-align: right;
|
||||
line-height: 44px;
|
||||
padding-left: $grid-pad; // same as action icon right padding
|
||||
|
||||
.innernametext {
|
||||
display: inline-block;
|
||||
max-width: 80px;
|
||||
}
|
||||
|
||||
/* No space for extension in grid view */
|
||||
.extension {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.fileactions {
|
||||
height: initial;
|
||||
margin-top: $grid-size - $grid-pad;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.action {
|
||||
padding: $grid-pad;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&.action-share.permanent.shared-style span {
|
||||
/* Do not show "Shared" text next to icon as there is no space */
|
||||
&:not(.icon) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* If an avatar is present, show that instead of the icon */
|
||||
&.avatar {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
/* In "Deleted files", do not show "Restore" text next to icon as there is no space */
|
||||
&.action-restore.permanent span {
|
||||
&:not(.icon) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is a comment, show it instead of the share icon */
|
||||
&.action-comment ~ .action-share {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* No space for filesize and date in grid view */
|
||||
&.filesize,
|
||||
&.date {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.selection,
|
||||
&.filename .favorite-mark {
|
||||
position: absolute;
|
||||
top: -8px; // half the checkbox width, center on corner of thumbnail
|
||||
left: -8px; // half the checkbox width, center on corner of thumbnail
|
||||
display: flex;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
z-index: 10;
|
||||
background: transparent;
|
||||
|
||||
label {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
display: inline-flex;
|
||||
padding: $grid-pad; // like any action icon
|
||||
&::before {
|
||||
margin: 0;
|
||||
width: $grid-pad; // 16px - border
|
||||
height: $grid-pad; // 16px - border
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Position actions menu below file */
|
||||
.popovermenu {
|
||||
left: 0;
|
||||
width: $grid-size - 10px; // 2 * margin
|
||||
margin: 0 5px;
|
||||
|
||||
/* Ellipsize long entries, normally menu width is adjusted but for grid we use fixed width. */
|
||||
.menuitem span:not(.icon) {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Center align the footer file number & size summary */
|
||||
tfoot {
|
||||
display: grid;
|
||||
|
||||
.summary:not(.hidden) {
|
||||
display: inline-block;
|
||||
margin: 0 auto;
|
||||
|
||||
td {
|
||||
padding-top: 50px;
|
||||
|
||||
&:first-child,
|
||||
&.date {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Grid view toggle */
|
||||
#view-toggle {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 22px;
|
||||
opacity: .5;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
#showgridview:focus + & {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjustments for link share page */
|
||||
#body-public {
|
||||
#filestable.view-grid:not(.hidden) tbody td {
|
||||
/* More space for filename since there is no share icon */
|
||||
&.filename .name .nametext .innernametext {
|
||||
max-width: 124px;
|
||||
}
|
||||
|
||||
/* Position actions menu correctly below 3-dot-menu */
|
||||
.popovermenu {
|
||||
left: -80px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Right-align view toggle on link share page */
|
||||
#view-toggle {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide legacy Gallery toggle */
|
||||
#gallery-button {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -331,6 +331,11 @@
|
|||
|
||||
this.$el.find('thead th .columntitle').click(_.bind(this._onClickHeader, this));
|
||||
|
||||
// Toggle for grid view
|
||||
this.$showGridView = $('input#showgridview');
|
||||
this.$showGridView.on('change', _.bind(this._onGridviewChange, this));
|
||||
$('#view-toggle').tooltip({placement: 'bottom', trigger: 'hover'});
|
||||
|
||||
this._onResize = _.debounce(_.bind(this._onResize, this), 250);
|
||||
$('#app-content').on('appresized', this._onResize);
|
||||
$(window).resize(this._onResize);
|
||||
|
@ -591,6 +596,26 @@
|
|||
this.$table.find('>thead').width($('#app-content').width() - OC.Util.getScrollBarWidth());
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle showing gridview by default or not
|
||||
*
|
||||
* @returns {undefined}
|
||||
*/
|
||||
_onGridviewChange: function() {
|
||||
var show = this.$showGridView.is(':checked');
|
||||
// only save state if user is logged in
|
||||
if (OC.currentUser) {
|
||||
$.post(OC.generateUrl('/apps/files/api/v1/showgridview'), {
|
||||
show: show
|
||||
});
|
||||
}
|
||||
this.$showGridView.next('#view-toggle')
|
||||
.removeClass('icon-toggle-filelist icon-toggle-pictures')
|
||||
.addClass(show ? 'icon-toggle-filelist' : 'icon-toggle-pictures')
|
||||
|
||||
$('.list-container').toggleClass('view-grid', show);
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler when leaving previously hidden state
|
||||
*/
|
||||
|
@ -2776,7 +2801,9 @@
|
|||
var permissions = this.getDirectoryPermissions();
|
||||
var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0;
|
||||
this.$el.find('#emptycontent').toggleClass('hidden', !this.isEmpty);
|
||||
this.$el.find('#emptycontent').toggleClass('hidden', !this.isEmpty);
|
||||
this.$el.find('#emptycontent .uploadmessage').toggleClass('hidden', !isCreatable || !this.isEmpty);
|
||||
this.$el.find('#filestable').toggleClass('hidden', this.isEmpty);
|
||||
this.$el.find('#filestable thead th').toggleClass('hidden', this.isEmpty);
|
||||
},
|
||||
/**
|
||||
|
|
|
@ -38,6 +38,7 @@ use OCP\Files\NotFoundException;
|
|||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\Http\FileDisplayResponse;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCA\Files\Service\TagService;
|
||||
|
@ -267,6 +268,28 @@ class ApiController extends Controller {
|
|||
return new Response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle default for files grid view
|
||||
*
|
||||
* @NoAdminRequired
|
||||
*
|
||||
* @param bool $show
|
||||
*/
|
||||
public function showGridView($show) {
|
||||
$this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'show_grid', (int)$show);
|
||||
return new Response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default settings for the grid view
|
||||
*
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function getGridView() {
|
||||
$status = $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', 'show_grid', '1') === '1';
|
||||
return new JSONResponse(['gridview' => $status]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle default for showing/hiding xxx folder
|
||||
*
|
||||
|
|
|
@ -22,11 +22,14 @@
|
|||
*/
|
||||
|
||||
$config = \OC::$server->getConfig();
|
||||
$userSession = \OC::$server->getUserSession();
|
||||
// TODO: move this to the generated config.js
|
||||
$publicUploadEnabled = $config->getAppValue('core', 'shareapi_allow_public_upload', 'yes');
|
||||
$showgridview = $config->getUserValue($userSession->getUser()->getUID(), 'files', 'show_grid', true);
|
||||
|
||||
// renders the controls and table headers template
|
||||
$tmpl = new OCP\Template('files', 'list', '');
|
||||
$tmpl->assign('publicUploadEnabled', $publicUploadEnabled);
|
||||
$tmpl->assign('showgridview', $showgridview);
|
||||
$tmpl->printPage();
|
||||
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
<?php endif;?>
|
||||
<input type="hidden" class="max_human_file_size"
|
||||
value="(max <?php isset($_['uploadMaxHumanFilesize']) ? p($_['uploadMaxHumanFilesize']) : ''; ?>)">
|
||||
<input type="checkbox" class="hidden-visually" id="showgridview"
|
||||
<?php if($_['showgridview']) { ?>checked="checked" <?php } ?>/>
|
||||
<label id="view-toggle" for="showgridview" class="button <?php p($_['showgridview'] ? 'icon-toggle-filelist' : 'icon-toggle-pictures') ?>"
|
||||
title="<?php p($l->t('Toggle grid view'))?>"></label>
|
||||
</div>
|
||||
|
||||
<div id="emptycontent" class="hidden">
|
||||
|
@ -38,7 +42,7 @@
|
|||
<p></p>
|
||||
</div>
|
||||
|
||||
<table id="filestable" data-allow-public-upload="<?php p($_['publicUploadEnabled'])?>" data-preview-x="32" data-preview-y="32">
|
||||
<table id="filestable" class="list-container <?php p($_['showgridview'] ? 'view-grid' : '') ?>" data-allow-public-upload="<?php p($_['publicUploadEnabled'])?>" data-preview-x="250" data-preview-y="250">
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="headerSelection" class="hidden column-selection">
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<p></p>
|
||||
</div>
|
||||
|
||||
<table id="filestable">
|
||||
<table id="filestable" class="list-container view-grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th id='headerName' class="hidden column-name">
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<h2><?php p($l->t('No entries found in this folder')); ?></h2>
|
||||
<p></p>
|
||||
</div>
|
||||
<table id="filestable">
|
||||
<table id="filestable" class="list-container view-grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th id='headerName' class="hidden column-name">
|
||||
|
|
|
@ -25,7 +25,7 @@ describe('OCA.Files.FavoritesFileList tests', function() {
|
|||
'</div>' +
|
||||
// dummy table
|
||||
// TODO: at some point this will be rendered by the fileList class itself!
|
||||
'<table id="filestable">' +
|
||||
'<table id="filestable" class="list-container view-grid">' +
|
||||
'<thead><tr>' +
|
||||
'<th id="headerName" class="hidden column-name">' +
|
||||
'<a class="name columntitle" data-sort="name"><span>Name</span><span class="sort-indicator"></span></a>' +
|
||||
|
|
|
@ -117,7 +117,7 @@ describe('OC.Upload tests', function() {
|
|||
beforeEach(function() {
|
||||
$('#testArea').append(
|
||||
'<div id="tableContainer">' +
|
||||
'<table id="filestable">' +
|
||||
'<table id="filestable" class="list-container view-grid">' +
|
||||
'<thead><tr>' +
|
||||
'<th id="headerName" class="hidden column-name">' +
|
||||
'<input type="checkbox" id="select_all_files" class="select-all">' +
|
||||
|
|
|
@ -28,7 +28,7 @@ describe('OCA.Files.FileActions tests', function() {
|
|||
var $body = $('#testArea');
|
||||
$body.append('<input type="hidden" id="dir" value="/subdir"></input>');
|
||||
$body.append('<input type="hidden" id="permissions" value="31"></input>');
|
||||
$body.append('<table id="filestable"><tbody id="fileList"></tbody></table>');
|
||||
$body.append('<table id="filestable" class="list-container view-grid"><tbody id="fileList"></tbody></table>');
|
||||
// dummy files table
|
||||
fileActions = new OCA.Files.FileActions();
|
||||
fileActions.registerAction({
|
||||
|
|
|
@ -88,7 +88,7 @@ describe('OCA.Files.FileList tests', function() {
|
|||
'<input type="file" id="file_upload_start" name="files[]" multiple="multiple">' +
|
||||
// dummy table
|
||||
// TODO: at some point this will be rendered by the fileList class itself!
|
||||
'<table id="filestable">' +
|
||||
'<table id="filestable" class="list-container view-grid">' +
|
||||
'<thead><tr>' +
|
||||
'<th id="headerName" class="hidden column-name">' +
|
||||
'<input type="checkbox" id="select_all_files" class="select-all checkbox">' +
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
<input type="hidden" name="dir" value="" id="dir">
|
||||
|
||||
<table id="filestable">
|
||||
<table id="filestable" class="list-container view-grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th id='headerName' class="hidden column-name">
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#preview {
|
||||
background: var(--color-main-background);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
|
@ -229,10 +229,10 @@ OCA.Sharing.PublicApp = {
|
|||
this.fileList.generatePreviewUrl = function (urlSpec) {
|
||||
urlSpec = urlSpec || {};
|
||||
if (!urlSpec.x) {
|
||||
urlSpec.x = 32;
|
||||
urlSpec.x = this.$table.data('preview-x') || 32;
|
||||
}
|
||||
if (!urlSpec.y) {
|
||||
urlSpec.y = 32;
|
||||
urlSpec.y = this.$table.data('preview-y') || 32;
|
||||
}
|
||||
urlSpec.x *= window.devicePixelRatio;
|
||||
urlSpec.y *= window.devicePixelRatio;
|
||||
|
|
|
@ -357,6 +357,7 @@ class ShareController extends AuthPublicShareController {
|
|||
$folder->assign('isPublic', true);
|
||||
$folder->assign('hideFileList', $hideFileList);
|
||||
$folder->assign('publicUploadEnabled', 'no');
|
||||
$folder->assign('showgridview', true);
|
||||
$folder->assign('uploadMaxFilesize', $maxUploadFilesize);
|
||||
$folder->assign('uploadMaxHumanFilesize', \OCP\Util::humanFileSize($maxUploadFilesize));
|
||||
$folder->assign('freeSpace', $freeSpace);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<h2><?php p($l->t('No entries found in this folder')); ?></h2>
|
||||
</div>
|
||||
|
||||
<table id="filestable">
|
||||
<table id="filestable" class="list-container view-grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th id='headerName' class="hidden column-name">
|
||||
|
|
|
@ -60,7 +60,7 @@ describe('OCA.Sharing.PublicApp tests', function() {
|
|||
'<input type="file" id="file_upload_start" name="files[]" multiple="multiple">' +
|
||||
// dummy table
|
||||
// TODO: at some point this will be rendered by the fileList class itself!
|
||||
'<table id="filestable">' +
|
||||
'<table id="filestable" class="list-container view-grid">' +
|
||||
'<thead><tr>' +
|
||||
'<th id="headerName" class="hidden column-name">' +
|
||||
'<input type="checkbox" id="select_all_files" class="select-all">' +
|
||||
|
|
|
@ -28,7 +28,7 @@ describe('OCA.Sharing.Util tests', function() {
|
|||
// dummy file list
|
||||
var $div = $(
|
||||
'<div id="listContainer">' +
|
||||
'<table id="filestable">' +
|
||||
'<table id="filestable" class="list-container view-grid">' +
|
||||
'<thead></thead>' +
|
||||
'<tbody id="fileList"></tbody>' +
|
||||
'</table>' +
|
||||
|
@ -510,8 +510,8 @@ describe('OCA.Sharing.Util tests', function() {
|
|||
OCA.Sharing.Util.attach(fileList);
|
||||
fileList.setFiles(testFiles);
|
||||
});
|
||||
afterEach(function() {
|
||||
shareTabSpy.restore();
|
||||
afterEach(function() {
|
||||
shareTabSpy.restore();
|
||||
});
|
||||
|
||||
it('updates fileInfoModel when shares changed', function() {
|
||||
|
|
|
@ -28,7 +28,7 @@ describe('OCA.Sharing.FileList tests', function() {
|
|||
'</div>' +
|
||||
// dummy table
|
||||
// TODO: at some point this will be rendered by the fileList class itself!
|
||||
'<table id="filestable">' +
|
||||
'<table id="filestable" class="list-container view-grid">' +
|
||||
'<thead><tr>' +
|
||||
'<th id="headerName" class="hidden column-name">' +
|
||||
'<input type="checkbox" id="select_all_files" class="select-all">' +
|
||||
|
@ -701,7 +701,7 @@ describe('OCA.Sharing.FileList tests', function() {
|
|||
// dummy file list
|
||||
var $div = $(
|
||||
'<div>' +
|
||||
'<table id="filestable">' +
|
||||
'<table id="filestable" class="list-container view-grid">' +
|
||||
'<thead></thead>' +
|
||||
'<tbody id="fileList"></tbody>' +
|
||||
'</table>' +
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<p></p>
|
||||
</div>
|
||||
|
||||
<table id="filestable">
|
||||
<table id="filestable" class="list-container view-grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="headerSelection" class="hidden column-selection">
|
||||
|
|
|
@ -48,7 +48,7 @@ describe('OCA.Trashbin.FileList tests', function () {
|
|||
'</div>' +
|
||||
// dummy table
|
||||
// TODO: at some point this will be rendered by the fileList class itself!
|
||||
'<table id="filestable">' +
|
||||
'<table id="filestable" class="list-container view-grid">' +
|
||||
'<thead><tr><th id="headerName" class="hidden">' +
|
||||
'<input type="checkbox" id="select_all_trash" class="select-all">' +
|
||||
'<span class="name">Name</span>' +
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
:root {
|
||||
--color-main-text: $color-main-text;
|
||||
--color-main-background: $color-main-background;
|
||||
--color-main-background-translucent: $color-main-background-translucent;
|
||||
|
||||
--color-background-dark: $color-background-dark;
|
||||
--color-background-darker: $color-background-darker;
|
||||
|
|
|
@ -297,6 +297,7 @@ img, object, video, button, textarea, input, select, div[contenteditable='true']
|
|||
@include icon-black-white('toggle', 'actions', 1, true);
|
||||
@include icon-black-white('toggle-background', 'actions', 1, true);
|
||||
@include icon-black-white('toggle-pictures', 'actions', 1, true);
|
||||
@include icon-black-white('toggle-filelist', 'actions', 1, true);
|
||||
@include icon-black-white('triangle-e', 'actions', 1, true);
|
||||
@include icon-black-white('triangle-n', 'actions', 1, true);
|
||||
@include icon-black-white('triangle-s', 'actions', 1, true);
|
||||
|
|
|
@ -167,7 +167,7 @@ body {
|
|||
height: 44px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background-color: var(--color-main-background);
|
||||
background-color: var(--color-main-background-translucent);
|
||||
z-index: 60;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
|
@ -697,12 +697,15 @@ code {
|
|||
}
|
||||
|
||||
/* ---- DIALOGS ---- */
|
||||
|
||||
#oc-dialog-filepicker-content {
|
||||
position: relative;
|
||||
|
||||
.dirtree {
|
||||
width: 96%;
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
padding-left: 12px;
|
||||
padding-right: 44px;
|
||||
box-sizing: border-box;
|
||||
|
||||
div:first-child a {
|
||||
background-image: url('../img/places/home.svg?v=1');
|
||||
|
@ -722,6 +725,28 @@ code {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Grid view toggle */
|
||||
#picker-view-toggle {
|
||||
position: absolute;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 22px;
|
||||
opacity: .5;
|
||||
right: 0;
|
||||
top: 0;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
// keyboard focus
|
||||
#picker-showgridview:focus + #picker-view-toggle {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.filelist-container {
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
|
@ -771,9 +796,54 @@ code {
|
|||
.filesize {
|
||||
text-align: right;
|
||||
}
|
||||
&.view-grid {
|
||||
$grid-size: 120px;
|
||||
$grid-pad: 10px;
|
||||
$name-height: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
tbody {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, $grid-size);
|
||||
justify-content: space-around;
|
||||
row-gap: 15px;
|
||||
margin: 15px 0;
|
||||
|
||||
tr {
|
||||
display: block;
|
||||
position: relative;
|
||||
border-radius: var(--border-radius);
|
||||
padding: $grid-pad;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: $grid-size - 2 * $grid-pad;
|
||||
|
||||
td {
|
||||
border: none;
|
||||
padding: 0;
|
||||
|
||||
&.filename {
|
||||
padding: #{$grid-size - 2 * $grid-pad} 0 0 0;
|
||||
background-position: center top;
|
||||
background-size: contain;
|
||||
line-height: $name-height;
|
||||
height: $name-height;
|
||||
}
|
||||
&.filesize {
|
||||
line-height: $name-height;
|
||||
text-align: left;
|
||||
}
|
||||
&.date {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.filepicker_element_selected {
|
||||
background-color: lightblue;
|
||||
background-color: var(--color-background-darker);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
// DEPRECATED, please use CSS4 vars
|
||||
$color-main-text: #222 !default; // Not #000 for better readability
|
||||
$color-main-background: #fff !default;
|
||||
$color-main-background-translucent: rgba($color-main-background, .97) !default;
|
||||
|
||||
// used for different active/disabled states
|
||||
$color-background-dark: nc-darken($color-main-background, 7%) !default;
|
||||
|
|
|
@ -208,6 +208,7 @@ var OCdialogs = {
|
|||
|
||||
this.filepicker.loading = true;
|
||||
this.filepicker.filesClient = (OCA.Sharing && OCA.Sharing.PublicApp && OCA.Sharing.PublicApp.fileList)? OCA.Sharing.PublicApp.fileList.filesClient: OC.Files.getClient();
|
||||
|
||||
$.when(this._getFilePickerTemplate()).then(function($tmpl) {
|
||||
self.filepicker.loading = false;
|
||||
var dialogName = 'oc-dialog-filepicker-content';
|
||||
|
@ -237,6 +238,11 @@ var OCdialogs = {
|
|||
|
||||
$('body').append(self.$filePicker);
|
||||
|
||||
self.$showGridView = $('input#picker-showgridview');
|
||||
self.$showGridView.on('change', _.bind(self._onGridviewChange, self));
|
||||
|
||||
self._getGridSettings();
|
||||
|
||||
self.$filePicker.ready(function() {
|
||||
self.$filelist = self.$filePicker.find('.filelist tbody');
|
||||
self.$dirTree = self.$filePicker.find('.dirtree');
|
||||
|
@ -779,6 +785,31 @@ var OCdialogs = {
|
|||
//}
|
||||
return dialogDeferred.promise();
|
||||
},
|
||||
// get the gridview setting and set the input accordingly
|
||||
_getGridSettings: function() {
|
||||
var self = this;
|
||||
$.get(OC.generateUrl('/apps/files/api/v1/showgridview'), function(response) {
|
||||
self.$showGridView.checked = response.gridview;
|
||||
self.$showGridView.next('#picker-view-toggle')
|
||||
.removeClass('icon-toggle-filelist icon-toggle-pictures')
|
||||
.addClass(response.gridview ? 'icon-toggle-filelist' : 'icon-toggle-pictures')
|
||||
$('.list-container').toggleClass('view-grid', response.gridview);
|
||||
});
|
||||
},
|
||||
_onGridviewChange: function() {
|
||||
var show = this.$showGridView.is(':checked');
|
||||
// only save state if user is logged in
|
||||
if (OC.currentUser) {
|
||||
$.post(OC.generateUrl('/apps/files/api/v1/showgridview'), {
|
||||
show: show
|
||||
});
|
||||
}
|
||||
this.$showGridView.next('#picker-view-toggle')
|
||||
.removeClass('icon-toggle-filelist icon-toggle-pictures')
|
||||
.addClass(show ? 'icon-toggle-filelist' : 'icon-toggle-pictures')
|
||||
|
||||
$('.list-container').toggleClass('view-grid', show);
|
||||
},
|
||||
_getFilePickerTemplate: function() {
|
||||
var defer = $.Deferred();
|
||||
if(!this.$filePickerTemplate) {
|
||||
|
@ -899,6 +930,8 @@ var OCdialogs = {
|
|||
if (entry.type === 'file') {
|
||||
var urlSpec = {
|
||||
file: dir + '/' + entry.name,
|
||||
x: 100,
|
||||
y: 100
|
||||
};
|
||||
var img = new Image();
|
||||
var previewUrl = OC.generateUrl('/core/preview.png?') + $.param(urlSpec);
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
<div id="{dialog_name}" title="{title}">
|
||||
<span class="dirtree breadcrumb"></span>
|
||||
<input type="checkbox" class="hidden-visually" id="picker-showgridview" checked="checked" />
|
||||
<label id="picker-view-toggle" for="picker-showgridview" class="button icon-toggle-filelist"></label>
|
||||
<div class="filelist-container">
|
||||
<div class="emptycontent">
|
||||
<div class="icon-folder"></div>
|
||||
<h2>{emptytext}</h2>
|
||||
</div>
|
||||
<table id="filestable" class="filelist">
|
||||
<table id="filestable" class="filelist list-container view-grid">
|
||||
<tbody>
|
||||
<tr data-entryname="{filename}" data-type="{type}">
|
||||
<td class="filename"
|
||||
|
|
Loading…
Reference in New Issue