diff options
author | skjnldsv <skjnldsv@protonmail.com> | 2024-06-12 17:51:19 +0200 |
---|---|---|
committer | skjnldsv <skjnldsv@protonmail.com> | 2024-06-12 17:57:14 +0200 |
commit | 343b690d8081c760e4d7edff502095d6c4120605 (patch) | |
tree | 580e14590d4ab06927ac28cb2f59359866892079 /apps/files/src/store | |
parent | 1d7893dca899fbcec44c82f049a9c10a085f7153 (diff) | |
download | nextcloud-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.ts | 47 |
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])) }, }, }) |