summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorJohn Molakvoæ <skjnldsv@users.noreply.github.com>2024-07-05 10:43:30 +0200
committerGitHub <noreply@github.com>2024-07-05 10:43:30 +0200
commita98a0eb7cd8dc33b906a5c1aa981fcdc96c23da9 (patch)
tree04ee6bb527d89abd84efebce8b8a325ab93316de /apps
parent5d2d582a2b317756da3e5247171683795fed6612 (diff)
parentd30d7de56f2fe7632479bce55e76bc3ef4530bf7 (diff)
downloadnextcloud-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.vue24
-rw-r--r--apps/files/src/components/FileEntryGrid.vue12
-rw-r--r--apps/files/src/components/FileEntryMixin.ts26
-rw-r--r--apps/files/src/components/FilesListVirtual.vue85
-rw-r--r--apps/files/src/components/VirtualList.vue8
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() {