Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(files): Refresh grid view layout #46307

Merged
merged 2 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 0 additions & 24 deletions apps/files/src/components/FileEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,10 @@ export default defineComponent({
],

props: {
isMtimeAvailable: {
type: Boolean,
default: false,
},
isSizeAvailable: {
type: Boolean,
default: false,
},
compact: {
type: Boolean,
default: false,
},
},

setup() {
Expand Down Expand Up @@ -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')
Expand Down
12 changes: 12 additions & 0 deletions apps/files/src/components/FileEntryGrid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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}`"
Expand All @@ -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'
Expand All @@ -80,6 +91,7 @@ export default defineComponent({
FileEntryCheckbox,
FileEntryName,
FileEntryPreview,
NcDateTime,
},

mixins: [
Expand Down
26 changes: 24 additions & 2 deletions apps/files/src/components/FileEntryMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ export default defineComponent({
type: Number,
default: 0,
},
isMtimeAvailable: {
type: Boolean,
default: false,
},
compact: {
type: Boolean,
default: false,
},
},

data() {
Expand Down Expand Up @@ -148,8 +156,22 @@ export default defineComponent({
},
},

isRenaming() {
skjnldsv marked this conversation as resolved.
Show resolved Hide resolved
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))`,
}
},
},

Expand Down
85 changes: 55 additions & 30 deletions apps/files/src/components/FilesListVirtual.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
Expand Down
8 changes: 4 additions & 4 deletions apps/files/src/components/VirtualList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
4 changes: 2 additions & 2 deletions dist/files-main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files-main.js.map

Large diffs are not rendered by default.

Loading