diff options
author | John Molakvoæ <skjnldsv@users.noreply.github.com> | 2024-07-05 10:43:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-05 10:43:30 +0200 |
commit | a98a0eb7cd8dc33b906a5c1aa981fcdc96c23da9 (patch) | |
tree | 04ee6bb527d89abd84efebce8b8a325ab93316de /apps | |
parent | 5d2d582a2b317756da3e5247171683795fed6612 (diff) | |
parent | d30d7de56f2fe7632479bce55e76bc3ef4530bf7 (diff) | |
download | nextcloud-server-a98a0eb7cd8dc33b906a5c1aa981fcdc96c23da9.tar.gz nextcloud-server-a98a0eb7cd8dc33b906a5c1aa981fcdc96c23da9.zip |
Merge pull request #46307 from nextcloud/artonge/feat/improve_grid_view
Diffstat (limited to 'apps')
-rw-r--r-- | apps/files/src/components/FileEntry.vue | 24 | ||||
-rw-r--r-- | apps/files/src/components/FileEntryGrid.vue | 12 | ||||
-rw-r--r-- | apps/files/src/components/FileEntryMixin.ts | 26 | ||||
-rw-r--r-- | apps/files/src/components/FilesListVirtual.vue | 85 | ||||
-rw-r--r-- | apps/files/src/components/VirtualList.vue | 8 |
5 files changed, 95 insertions, 60 deletions
diff --git a/apps/files/src/components/FileEntry.vue b/apps/files/src/components/FileEntry.vue index 02ddb47f93e..fdc800b3464 100644 --- a/apps/files/src/components/FileEntry.vue +++ b/apps/files/src/components/FileEntry.vue @@ -121,18 +121,10 @@ export default defineComponent({ ], props: { - isMtimeAvailable: { - type: Boolean, - default: false, - }, isSizeAvailable: { type: Boolean, default: false, }, - compact: { - type: Boolean, - default: false, - }, }, setup() { @@ -204,23 +196,7 @@ export default defineComponent({ color: `color-mix(in srgb, var(--color-main-text) ${ratio}%, var(--color-text-maxcontrast))`, } }, - mtimeOpacity() { - const maxOpacityTime = 31 * 24 * 60 * 60 * 1000 // 31 days - const mtime = this.source.mtime?.getTime?.() - if (!mtime) { - return {} - } - - // 1 = today, 0 = 31 days ago - const ratio = Math.round(Math.min(100, 100 * (maxOpacityTime - (Date.now() - mtime)) / maxOpacityTime)) - if (ratio < 0) { - return {} - } - return { - color: `color-mix(in srgb, var(--color-main-text) ${ratio}%, var(--color-text-maxcontrast))`, - } - }, mtimeTitle() { if (this.source.mtime) { return moment(this.source.mtime).format('LLL') diff --git a/apps/files/src/components/FileEntryGrid.vue b/apps/files/src/components/FileEntryGrid.vue index 1ec4f173a0e..ed8175fcda7 100644 --- a/apps/files/src/components/FileEntryGrid.vue +++ b/apps/files/src/components/FileEntryGrid.vue @@ -46,6 +46,15 @@ @click.native="execDefaultAction" /> </td> + <!-- Mtime --> + <td v-if="!compact && isMtimeAvailable" + :style="mtimeOpacity" + class="files-list__row-mtime" + data-cy-files-list-row-mtime + @click="openDetailsIfAvailable"> + <NcDateTime v-if="source.mtime" :timestamp="source.mtime" :ignore-seconds="true" /> + </td> + <!-- Actions --> <FileEntryActions ref="actions" :class="`files-list__row-actions-${uniqueId}`" @@ -60,6 +69,8 @@ <script lang="ts"> import { defineComponent } from 'vue' +import NcDateTime from '@nextcloud/vue/dist/Components/NcDateTime.js' + import { useNavigation } from '../composables/useNavigation' import { useActionsMenuStore } from '../store/actionsmenu.ts' import { useDragAndDropStore } from '../store/dragging.ts' @@ -80,6 +91,7 @@ export default defineComponent({ FileEntryCheckbox, FileEntryName, FileEntryPreview, + NcDateTime, }, mixins: [ diff --git a/apps/files/src/components/FileEntryMixin.ts b/apps/files/src/components/FileEntryMixin.ts index d3ae1511936..243b963c7b2 100644 --- a/apps/files/src/components/FileEntryMixin.ts +++ b/apps/files/src/components/FileEntryMixin.ts @@ -37,6 +37,14 @@ export default defineComponent({ type: Number, default: 0, }, + isMtimeAvailable: { + type: Boolean, + default: false, + }, + compact: { + type: Boolean, + default: false, + }, }, data() { @@ -148,8 +156,22 @@ export default defineComponent({ }, }, - isRenaming() { - return this.renamingStore.renamingNode === this.source + mtimeOpacity() { + const maxOpacityTime = 31 * 24 * 60 * 60 * 1000 // 31 days + + const mtime = this.source.mtime?.getTime?.() + if (!mtime) { + return {} + } + + // 1 = today, 0 = 31 days ago + const ratio = Math.round(Math.min(100, 100 * (maxOpacityTime - (Date.now() - mtime)) / maxOpacityTime)) + if (ratio < 0) { + return {} + } + return { + color: `color-mix(in srgb, var(--color-main-text) ${ratio}%, var(--color-text-maxcontrast))`, + } }, }, diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue index 7c74f2d2d7e..9fd056c3aaf 100644 --- a/apps/files/src/components/FilesListVirtual.vue +++ b/apps/files/src/components/FilesListVirtual.vue @@ -316,7 +316,7 @@ export default defineComponent({ --checkbox-padding: calc((var(--row-height) - var(--checkbox-size)) / 2); --checkbox-size: 24px; - --clickable-area: 44px; + --clickable-area: var(--default-clickable-area); --icon-preview-size: 32px; overflow: auto; @@ -687,39 +687,56 @@ export default defineComponent({ // Grid mode tbody.files-list__tbody.files-list__tbody--grid { --half-clickable-area: calc(var(--clickable-area) / 2); - --row-width: 160px; - // We use half of the clickable area as visual balance margin - --row-height: calc(var(--row-width) - var(--half-clickable-area)); - --icon-preview-size: calc(var(--row-width) - var(--clickable-area)); + --item-padding: 16px; + --icon-preview-size: 208px; + --name-height: 32px; + --mtime-height: 16px; + --row-width: calc(var(--icon-preview-size)); + --row-height: calc(var(--icon-preview-size) + var(--name-height) + var(--mtime-height)); --checkbox-padding: 0px; display: grid; grid-template-columns: repeat(auto-fill, var(--row-width)); - grid-gap: 15px; - row-gap: 15px; + gap: 22px; align-content: center; align-items: center; justify-content: space-around; justify-items: center; + margin: 16px; + width: calc(100% - 32px); tr { + display: flex; + flex-direction: column; width: var(--row-width); - height: calc(var(--row-height) + var(--clickable-area)); + height: var(--row-height); border: none; - border-radius: var(--border-radius); + padding: var(--item-padding); + box-sizing: content-box } // Checkbox in the top left .files-list__row-checkbox { position: absolute; z-index: 9; - top: 0; - left: 0; + top: calc(var(--item-padding)/2); + left: calc(var(--item-padding)/2); overflow: hidden; - width: var(--clickable-area); - height: var(--clickable-area); - border-radius: var(--half-clickable-area); + --checkbox-container-size: 44px; + width: var(--checkbox-container-size); + height: var(--checkbox-container-size); + + // Add a background to the checkbox so we do not see the image through it. + .checkbox-radio-switch__content::after { + content: ''; + width: 16px; + height: 16px; + position: absolute; + left: 14px; + z-index: -1; + background: var(--color-main-background); + } } // Star icon in the top right @@ -735,36 +752,44 @@ tbody.files-list__tbody.files-list__tbody--grid { } .files-list__row-name { - display: grid; - justify-content: stretch; - width: 100%; - height: 100%; - grid-auto-rows: var(--row-height) var(--clickable-area); + display: flex; + flex-direction: column; + width: var(--icon-preview-size); + height: calc(var(--icon-preview-size) + var(--name-height)); + // Ensure that the name outline is visible. + overflow: visible; span.files-list__row-icon { - width: 100%; - height: 100%; - // Visual balance, we use half of the clickable area - // as a margin around the preview - padding-top: var(--half-clickable-area); + width: var(--icon-preview-size); + height: var(--icon-preview-size); + } + + .files-list__row-icon-preview { + border-radius: 0; } a.files-list__row-name-link { - // Minus action menu - width: calc(100% - var(--clickable-area)); - height: var(--clickable-area); + height: var(--name-height); } .files-list__row-name-text { margin: 0; - padding-right: 0; + // Ensure that the outline is not too close to the text. + margin-left: -4px; + padding: 0px 4px; } } + .files-list__row-mtime { + width: var(--icon-preview-size); + height: var(--mtime-height); + font-size: calc(var(--default-font-size) - 4px); + } + .files-list__row-actions { position: absolute; - right: 0; - bottom: 0; + right: calc(var(--half-clickable-area) / 2); + bottom: calc(var(--mtime-height) / 2); width: var(--clickable-area); height: var(--clickable-area); } diff --git a/apps/files/src/components/VirtualList.vue b/apps/files/src/components/VirtualList.vue index daaa64056ac..0ca2d869d17 100644 --- a/apps/files/src/components/VirtualList.vue +++ b/apps/files/src/components/VirtualList.vue @@ -127,13 +127,13 @@ export default Vue.extend({ itemHeight() { // Align with css in FilesListVirtual - // 138px + 44px (name) + 15px (grid gap) - return this.gridMode ? (138 + 44 + 15) : 55 + // 208px + 32px (name) + 16px (mtime) + 16px (padding) + 22px (grid gap) + return this.gridMode ? (208 + 32 + 16 + 16 + 22) : 55 }, // Grid mode only itemWidth() { - // 160px + 15px grid gap - return 160 + 15 + // 208px + 16px padding + 22px grid gap + return 208 + 16 + 22 }, rowCount() { |