Skip to content
Open
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
8 changes: 5 additions & 3 deletions apps/files/src/components/FileEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ import FileEntryCheckbox from './FileEntry/FileEntryCheckbox.vue'
import FileEntryName from './FileEntry/FileEntryName.vue'
import FileEntryPreview from './FileEntry/FileEntryPreview.vue'
import { useFileActions } from '../composables/useFileActions.ts'
import { useFileListLayout } from '../composables/useFileListLayout.ts'
import { useFileListWidth } from '../composables/useFileListWidth.ts'
import { useRouteParameters } from '../composables/useRouteParameters.ts'
import { useActionsMenuStore } from '../store/actionsmenu.ts'
Expand Down Expand Up @@ -162,6 +163,7 @@ export default defineComponent({
const renamingStore = useRenamingStore()
const selectionStore = useSelectionStore()
const { isNarrow } = useFileListWidth()
const layout = useFileListLayout()
const {
fileId: currentRouteFileId,
} = useRouteParameters()
Expand All @@ -182,6 +184,7 @@ export default defineComponent({
activeView,
currentRouteFileId,
isNarrow,
layout,

activeStore,
actionsMenuStore,
Expand Down Expand Up @@ -215,11 +218,10 @@ export default defineComponent({
},

columns() {
// Hide columns if the list is too small
if (this.isNarrow || this.compact) {
if (this.compact) {
return []
}
return this.activeView?.columns || []
return this.layout.columns
},

mime() {
Expand Down
63 changes: 55 additions & 8 deletions apps/files/src/components/FileEntry/FileEntryActions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
import ArrowLeftIcon from 'vue-material-design-icons/ArrowLeft.vue'
import CustomElementRender from '../CustomElementRender.vue'
import { useFileListWidth } from '../../composables/useFileListWidth.ts'
import { INLINE_ACTION_WIDTH, reportInlineActionsWidth, useFileListLayout } from '../../composables/useFileListLayout.ts'
import actionsMixins from '../../mixins/actionsMixin.ts'
import { useActiveStore } from '../../store/active.ts'
import { executeAction } from '../../utils/actionUtils.ts'
Expand Down Expand Up @@ -178,16 +178,22 @@ export default defineComponent({
setup() {
// The file list is guaranteed to be shown with active view - thus we can set the `loaded` flag
const activeStore = useActiveStore()
const { isNarrow } = useFileListWidth()
const layout = useFileListLayout()
const enabledFileActions = inject<IFileAction[]>('enabledFileActions', [])
return {
activeStore,
enabledFileActions,
isNarrow,
layout,
t,
}
},

data() {
return {
resizeObserver: null as ResizeObserver | null,
}
},

computed: {
isActive() {
return this.activeStore.activeNode?.source === this.source.source
Expand All @@ -206,9 +212,9 @@ export default defineComponent({
}
},

// Enabled action that are displayed inline
enabledInlineActions() {
if (this.isNarrow || this.gridMode) {
// Enabled actions that can be displayed inline
inlineCapableActions() {
if (this.gridMode) {
return []
}
return this.enabledFileActions.filter((action) => {
Expand All @@ -221,9 +227,17 @@ export default defineComponent({
})
},

// Enabled actions that are displayed inline
enabledInlineActions() {
if (!this.layout.inlineActions) {
return []
}
return this.inlineCapableActions
},

// Enabled action that are displayed inline with a custom render function
enabledRenderActions() {
if (this.gridMode) {
if (!this.layout.inlineActions || this.gridMode) {
return []
}
return this.enabledFileActions.filter((action) => typeof action.renderInline === 'function')
Expand Down Expand Up @@ -287,6 +301,10 @@ export default defineComponent({
openedMenu() {
this.openedSubmenu = null
},

inlineCapableActions() {
this.reportInlineActionsWidth()
},
},

created() {
Expand All @@ -301,10 +319,39 @@ export default defineComponent({
})
},

mounted() {
if (this.gridMode) {
return
}
// Inline rendered actions (e.g. tags) are rendered asynchronously and change the cell size
this.resizeObserver = new ResizeObserver(() => this.reportInlineActionsWidth())
this.resizeObserver.observe(this.$el)
this.reportInlineActionsWidth()
},

beforeUnmount() {
this.resizeObserver?.disconnect()
},

methods: {
/**
* Report the width needed by the inline actions of this row to the files list layout
*/
reportInlineActionsWidth() {
if (this.gridMode || !this.$el) {
return
}

const renderActionsWidth = [...this.$el.querySelectorAll<HTMLElement>(':scope > .files-list__row-action--inline')]
.filter((element) => element.offsetWidth > 0)
.reduce((total, element) => total + element.offsetWidth + parseFloat(getComputedStyle(element).marginInlineEnd || '0'), 0)

reportInlineActionsWidth(this.inlineCapableActions.length * INLINE_ACTION_WIDTH + renderActionsWidth)
},

actionDisplayName(action: IFileAction) {
try {
if ((this.gridMode || (this.isNarrow && action.inline)) && typeof action.title === 'function') {
if ((this.gridMode || (!this.layout.inlineActions && action.inline)) && typeof action.title === 'function') {
// if an inline action is rendered in the menu for
// lack of space we use the title first if defined
const title = action.title(this.actionContext)
Expand Down
12 changes: 3 additions & 9 deletions apps/files/src/components/FilesListTableFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import type { IColumn, INode, IView } from '@nextcloud/files'
import { formatFileSize } from '@nextcloud/files'
import { t } from '@nextcloud/l10n'
import { computed } from 'vue'
import { useFileListWidth } from '../composables/useFileListWidth.ts'
import { useFileListLayout } from '../composables/useFileListLayout.ts'
import { useActiveStore } from '../store/active.ts'

const props = defineProps<{
Expand All @@ -78,17 +78,11 @@ const props = defineProps<{
}>()

const activeStore = useActiveStore()
const { isNarrow } = useFileListWidth()
const layout = useFileListLayout()

const currentFolder = computed(() => activeStore.activeFolder)

const columns = computed(() => {
// Hide columns if the list is too small
if (isNarrow.value) {
return []
}
return props.currentView?.columns || []
})
const columns = computed(() => layout.value.columns)

const totalSize = computed(() => {
// If we have the size already, let's use it
Expand Down
12 changes: 4 additions & 8 deletions apps/files/src/components/FilesListTableHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwit
import FilesListTableHeaderActions from './FilesListTableHeaderActions.vue'
import FilesListTableHeaderButton from './FilesListTableHeaderButton.vue'
import { useFilesSorting } from '../composables/filesSorting.ts'
import { useFileListWidth } from '../composables/useFileListWidth.ts'
import { useFileListLayout } from '../composables/useFileListLayout.ts'
import { useRouteParameters } from '../composables/useRouteParameters.ts'
import { useActiveStore } from '../store/active.ts'
import { useFilesStore } from '../store/files.ts'
Expand Down Expand Up @@ -168,27 +168,23 @@ export default defineComponent({
const selectionStore = useSelectionStore()
const { directory } = useRouteParameters()

const { isNarrow } = useFileListWidth()
const layout = useFileListLayout()

return {
activeStore,
filesStore,
selectionStore,

directory,
isNarrow,
layout,

...useFilesSorting(),
}
},

computed: {
columns() {
// Hide columns if the list is too small
if (this.isNarrow) {
return []
}
return this.activeStore.activeView?.columns || []
return this.layout.columns
},

dir() {
Expand Down
32 changes: 19 additions & 13 deletions apps/files/src/components/FilesListVirtual.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ import { showError } from '@nextcloud/dialogs'
import { FileType, Folder, getSidebar, Permission, View } from '@nextcloud/files'
import { t } from '@nextcloud/l10n'
import { useHotKey } from '@nextcloud/vue/composables/useHotKey'
import { computed, defineComponent } from 'vue'
import { computed, defineComponent, provide, watch } from 'vue'
import FileEntry from './FileEntry.vue'
import FileEntryGrid from './FileEntryGrid.vue'
import FileListFilterChips from './FileListFilter/FileListFilterChips.vue'
Expand All @@ -80,6 +80,7 @@ import FilesListTableHeader from './FilesListTableHeader.vue'
import VirtualList from './VirtualList.vue'
import { useEnabledFileActions } from '../composables/useFileActions.ts'
import { useFileListHeaders } from '../composables/useFileListHeaders.ts'
import { FileListLayoutKey, getFileListLayout, resetInlineActionsWidth, useInlineActionsWidth } from '../composables/useFileListLayout.ts'
import { useFileListWidth } from '../composables/useFileListWidth.ts'
import { useRouteParameters } from '../composables/useRouteParameters.ts'
import { useActiveStore } from '../store/active.ts'
Expand Down Expand Up @@ -125,20 +126,9 @@ export default defineComponent({
const activeStore = useActiveStore()
const userConfigStore = useUserConfigStore()

const { isNarrow, isWide } = useFileListWidth()
const { width, isNarrow, isWide } = useFileListWidth()
const { fileId, openDetails, openFile } = useRouteParameters()

const isMimeAvailable = computed(() => {
if (!userConfigStore.userConfig.show_mime_column) {
return false
}
if (!isWide.value) {
return false // only show on wide screens
}
return props.nodes
.some((node: INode) => node.mime !== undefined || node.mime !== 'application/octet-stream')
})

const isMtimeAvailable = computed(() => {
// Hide mtime column on narrow screens
if (isNarrow.value) {
Expand All @@ -155,6 +145,22 @@ export default defineComponent({
return props.nodes.some((node: INode) => node.size !== undefined)
})

const inlineActionsWidth = useInlineActionsWidth()
watch(() => [props.currentFolder, props.currentView], resetInlineActionsWidth, { immediate: true })

const layout = computed(() => getFileListLayout(width.value, {
inlineActions: true,
mime: userConfigStore.userConfig.show_mime_column
&& isWide.value // only show on wide screens
&& props.nodes.some((node: INode) => node.mime !== undefined || node.mime !== 'application/octet-stream'),
size: isSizeAvailable.value,
mtime: isMtimeAvailable.value,
columns: isNarrow.value ? [] : (props.currentView.columns ?? []),
}, inlineActionsWidth.value))
provide(FileListLayoutKey, layout)

const isMimeAvailable = computed(() => layout.value.mime)

return {
fileId,
headers: useFileListHeaders(),
Expand Down
Loading
Loading