aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/files/src/components/FilesListVirtual.vue20
-rw-r--r--apps/files/src/services/RouterService.ts37
-rw-r--r--apps/files/src/views/FilesList.vue4
-rw-r--r--apps/files_sharing/src/components/FileListFilterAccount.vue41
-rw-r--r--package.json1
5 files changed, 78 insertions, 25 deletions
diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue
index 9a35e9ff855..782e2bd3587 100644
--- a/apps/files/src/components/FilesListVirtual.vue
+++ b/apps/files/src/components/FilesListVirtual.vue
@@ -4,7 +4,7 @@
-->
<template>
<VirtualList ref="table"
- :data-component="userConfig.grid_view ? FileEntryGrid : FileEntry"
+ :data-component="fileEntryComponent"
:data-key="'source'"
:data-sources="nodes"
:grid-mode="userConfig.grid_view"
@@ -132,8 +132,6 @@ export default defineComponent({
data() {
return {
- FileEntry,
- FileEntryGrid,
headers: getFileListHeaders(),
scrollToIndex: 0,
openFileId: null as number|null,
@@ -141,6 +139,13 @@ export default defineComponent({
},
computed: {
+ /**
+ * The Vue component to use for file list entries
+ */
+ fileEntryComponent() {
+ return this.userConfig.grid_view ? FileEntryGrid : FileEntry
+ },
+
userConfig(): UserConfig {
return this.userConfigStore.userConfig
},
@@ -218,6 +223,11 @@ export default defineComponent({
},
methods: {
+ reset() {
+ this.scrollToIndex = 0
+ this.openFileId = null
+ },
+
// Open the file sidebar if we have the room for it
// but don't open the sidebar for the current folder
openSidebarForFile(fileId) {
@@ -236,6 +246,10 @@ export default defineComponent({
if (fileId) {
const index = this.nodes.findIndex(node => node.fileid === fileId)
if (warn && index === -1 && fileId !== this.currentFolder.fileid) {
+ logger.error('File to scroll to not found', {
+ folder: this.currentFolder,
+ fileId,
+ })
showError(this.t('files', 'File not found'))
}
this.scrollToIndex = Math.max(0, index)
diff --git a/apps/files/src/services/RouterService.ts b/apps/files/src/services/RouterService.ts
index 84516465495..65113eb32d7 100644
--- a/apps/files/src/services/RouterService.ts
+++ b/apps/files/src/services/RouterService.ts
@@ -4,14 +4,47 @@
*/
import type { Route } from 'vue-router'
import type VueRouter from 'vue-router'
-import type { Dictionary, Location } from 'vue-router/types/router'
+import type { Dictionary, Location } from 'vue-router/types/router.d.ts'
+import { TypedEventTarget } from 'typescript-event-target'
-export default class RouterService {
+interface NavigationEventData {
+ name: Route['name']
+ params: Route['params']
+ query: Route['query']
+}
+
+class NavigationEvent extends CustomEvent<NavigationEventData> {
+
+ constructor({ name, params, query }: Route) {
+ super('navigation', {
+ detail: {
+ name,
+ // Do not let API users mess with internal state of our VueRouter (e.g. if they use Vue it could conflict)
+ params: structuredClone(params),
+ query: structuredClone(query),
+ },
+ })
+ }
+
+}
+
+interface RouterEventMap {
+ navigation: NavigationEvent
+}
+
+export default class RouterService extends TypedEventTarget<RouterEventMap> {
private _router: VueRouter
constructor(router: VueRouter) {
+ super()
this._router = router
+ this._router.beforeEach((to, from, next) => {
+ // emit event
+ this.dispatchTypedEvent('navigation', new NavigationEvent(to))
+ // continue
+ next()
+ })
}
get name(): string | null | undefined {
diff --git a/apps/files/src/views/FilesList.vue b/apps/files/src/views/FilesList.vue
index a127fd4c35c..bca95d0d25a 100644
--- a/apps/files/src/views/FilesList.vue
+++ b/apps/files/src/views/FilesList.vue
@@ -397,7 +397,7 @@ export default defineComponent({
showCustomEmptyView() {
return !this.loading && this.isEmptyDir && this.currentView?.emptyView !== undefined
- }
+ },
},
watch: {
@@ -657,7 +657,7 @@ export default defineComponent({
filterDirContent() {
let nodes = this.dirContents
for (const filter of this.filtersStore.sortedFilters) {
- nodes = filter.filter(nodes)
+ nodes = filter.filter(nodes) as Node[]
}
this.dirContentsFiltered = nodes
},
diff --git a/apps/files_sharing/src/components/FileListFilterAccount.vue b/apps/files_sharing/src/components/FileListFilterAccount.vue
index 68383735532..e0c77c1a900 100644
--- a/apps/files_sharing/src/components/FileListFilterAccount.vue
+++ b/apps/files_sharing/src/components/FileListFilterAccount.vue
@@ -40,9 +40,7 @@ import type { IAccountData } from '../filters/AccountFilter.ts'
import { translate as t } from '@nextcloud/l10n'
import { mdiAccountMultiple } from '@mdi/js'
-import { useBrowserLocation } from '@vueuse/core'
-import { computed, ref, watch } from 'vue'
-import { useNavigation } from '../../../files/src/composables/useNavigation.ts'
+import { computed, onMounted, ref, watch } from 'vue'
import FileListFilter from '../../../files/src/components/FileListFilter/FileListFilter.vue'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
@@ -50,6 +48,7 @@ import NcActionInput from '@nextcloud/vue/dist/Components/NcActionInput.js'
import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js'
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
import { ShareType } from '@nextcloud/sharing'
+import { getNavigation, View } from '@nextcloud/files'
interface IUserSelectData {
id: string
@@ -61,12 +60,12 @@ const emit = defineEmits<{
(event: 'update:accounts', value: IAccountData[]): void
}>()
-const { currentView } = useNavigation()
-const currentLocation = useBrowserLocation()
const accountFilter = ref('')
const availableAccounts = ref<IUserSelectData[]>([])
const selectedAccounts = ref<IUserSelectData[]>([])
+const currentView = ref<View | null>(null)
+
/**
* Currently shown accounts (filtered)
*/
@@ -107,14 +106,21 @@ watch(selectedAccounts, () => {
/**
* Update the accounts owning nodes or have nodes shared to them
- * @param path The path inside the current view to load for accounts
*/
-async function updateAvailableAccounts(path: string = '/') {
+async function updateAvailableAccounts() {
availableAccounts.value = []
+ // Skip while loading
if (!currentView.value) {
return
}
+ const path: string = [window.OCP.Files.Router.query.dir].flat()[0] || '/'
+
+ // Skip for tags as they do not have an owner
+ if (currentView.value.id === 'tags' && path === '/') {
+ return
+ }
+
const { contents } = await currentView.value.getContents(path)
const available = new Map<string, IUserSelectData>()
for (const node of contents) {
@@ -152,6 +158,16 @@ async function updateAvailableAccounts(path: string = '/') {
availableAccounts.value = [...available.values()]
}
+(window.OCP.Files.Router as unknown as EventTarget).addEventListener('navigation', () => {
+ currentView.value = getNavigation().active
+ updateAvailableAccounts()
+})
+
+onMounted(() => {
+ currentView.value = getNavigation().active
+ updateAvailableAccounts()
+})
+
/**
* Reset this filter
*/
@@ -160,17 +176,6 @@ function resetFilter() {
accountFilter.value = ''
}
defineExpose({ resetFilter, toggleAccount })
-
-// When the current view changes or the current directory,
-// then we need to rebuild the available accounts
-watch([currentView, currentLocation], () => {
- if (currentView.value) {
- // we have no access to the files router here...
- const path = (currentLocation.value.search ?? '?dir=/').match(/(?<=&|\?)dir=([^&#]+)/)?.[1]
- resetFilter()
- updateAvailableAccounts(decodeURIComponent(path ?? '/'))
- }
-}, { immediate: true })
</script>
<style scoped lang="scss">
diff --git a/package.json b/package.json
index 47e06c8c48c..0b93ccf45df 100644
--- a/package.json
+++ b/package.json
@@ -98,6 +98,7 @@
"snap.js": "^2.0.9",
"strengthify": "github:nextcloud/strengthify#0.5.9",
"throttle-debounce": "^5.0.2",
+ "typescript-event-target": "^1.1.1",
"underscore": "1.13.6",
"url-search-params-polyfill": "^8.1.1",
"v-click-outside": "^3.2.0",