aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files/src/store
diff options
context:
space:
mode:
authorskjnldsv <skjnldsv@protonmail.com>2024-06-12 17:51:19 +0200
committerskjnldsv <skjnldsv@protonmail.com>2024-06-12 17:57:14 +0200
commit343b690d8081c760e4d7edff502095d6c4120605 (patch)
tree580e14590d4ab06927ac28cb2f59359866892079 /apps/files/src/store
parent1d7893dca899fbcec44c82f049a9c10a085f7153 (diff)
downloadnextcloud-server-343b690d8081c760e4d7edff502095d6c4120605.tar.gz
nextcloud-server-343b690d8081c760e4d7edff502095d6c4120605.zip
fix(files): fetch nodes if we have multiple of the same fileid in the store
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
Diffstat (limited to 'apps/files/src/store')
-rw-r--r--apps/files/src/store/files.ts47
1 files changed, 44 insertions, 3 deletions
diff --git a/apps/files/src/store/files.ts b/apps/files/src/store/files.ts
index bf09ec7f88a..0b541024018 100644
--- a/apps/files/src/store/files.ts
+++ b/apps/files/src/store/files.ts
@@ -2,14 +2,28 @@
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-import type { Folder, Node } from '@nextcloud/files'
+
import type { FilesStore, RootsStore, RootOptions, Service, FilesState, FileSource } from '../types'
+import type { FileStat, ResponseDataDetailed } from 'webdav'
+import type { Folder, Node } from '@nextcloud/files'
+import { davGetDefaultPropfind, davResultToNode, davRootPath } from '@nextcloud/files'
import { defineStore } from 'pinia'
import { subscribe } from '@nextcloud/event-bus'
import logger from '../logger'
import Vue from 'vue'
+import { client } from '../services/WebdavClient.ts'
+
+const fetchNode = async (node: Node): Promise<Node> => {
+ const propfindPayload = davGetDefaultPropfind()
+ const result = await client.stat(`${davRootPath}${node.path}`, {
+ details: true,
+ data: propfindPayload,
+ }) as ResponseDataDetailed<FileStat>
+ return davResultToNode(result.data)
+}
+
export const useFilesStore = function(...args) {
const store = defineStore('files', {
state: (): FilesState => ({
@@ -32,6 +46,13 @@ export const useFilesStore = function(...args) {
.filter(Boolean),
/**
+ * Get files or folders by their file ID
+ * Multiple nodes can have the same file ID but different sources
+ * (e.g. in a shared context)
+ */
+ getNodesById: (state) => (fileId: number): Node[] => Object.values(state.files).filter(node => node.fileid === fileId),
+
+ /**
* Get the root folder of a service
*/
getRoot: (state) => (service: Service): Folder|undefined => state.roots[service],
@@ -73,8 +94,28 @@ export const useFilesStore = function(...args) {
this.updateNodes([node])
},
- onUpdatedNode(node: Node) {
- this.updateNodes([node])
+ async onUpdatedNode(node: Node) {
+ if (!node.fileid) {
+ logger.error('Trying to update/set a node without fileid', { node })
+ return
+ }
+
+ // If we have multiple nodes with the same file ID, we need to update all of them
+ const nodes = this.getNodesById(node.fileid)
+ if (nodes.length > 1) {
+ await Promise.all(nodes.map(fetchNode)).then(this.updateNodes)
+ logger.debug(nodes.length + ' nodes updated in store', { fileid: node.fileid })
+ return
+ }
+
+ // If we have only one node with the file ID, we can update it directly
+ if (node.source === nodes[0].source) {
+ this.updateNodes([node])
+ return
+ }
+
+ // Otherwise, it means we receive an event for a node that is not in the store
+ fetchNode(node).then(n => this.updateNodes([n]))
},
},
})