22 * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
33 * SPDX-License-Identifier: AGPL-3.0-or-later
44 */
5- import type { Folder , Node } from '@nextcloud/files'
5+
66import type { FilesStore , RootsStore , RootOptions , Service , FilesState , FileSource } from '../types'
7+ import type { FileStat , ResponseDataDetailed } from 'webdav'
8+ import type { Folder , Node } from '@nextcloud/files'
79
810import { defineStore } from 'pinia'
9- import { subscribe } from '@nextcloud/event-bus'
11+ import { subscribe , emit } from '@nextcloud/event-bus'
12+ import { davGetDefaultPropfind , davResultToNode , davRootPath } from '@nextcloud/files'
1013import logger from '../logger'
1114import Vue from 'vue'
1215
16+ import { client } from '../services/WebdavClient.ts'
17+
18+ window . emitEvent = emit
19+
20+ const fetchNode = async ( node : Node ) : Promise < Node > => {
21+ const propfindPayload = davGetDefaultPropfind ( )
22+ const result = await client . stat ( `${ davRootPath } ${ node . path } ` , {
23+ details : true ,
24+ data : propfindPayload ,
25+ } ) as ResponseDataDetailed < FileStat >
26+ return davResultToNode ( result . data )
27+ }
28+
1329export const useFilesStore = function ( ...args ) {
1430 const store = defineStore ( 'files' , {
1531 state : ( ) : FilesState => ( {
@@ -31,6 +47,13 @@ export const useFilesStore = function(...args) {
3147 . map ( source => state . files [ source ] )
3248 . filter ( Boolean ) ,
3349
50+ /**
51+ * Get files or folders by their file ID
52+ * Multiple nodes can have the same file ID but different sources
53+ * (e.g. in a shared context)
54+ */
55+ getNodesById : ( state ) => ( fileId : number ) : Node [ ] => Object . values ( state . files ) . filter ( node => node . fileid === fileId ) ,
56+
3457 /**
3558 * Get the root folder of a service
3659 */
@@ -73,8 +96,28 @@ export const useFilesStore = function(...args) {
7396 this . updateNodes ( [ node ] )
7497 } ,
7598
76- onUpdatedNode ( node : Node ) {
77- this . updateNodes ( [ node ] )
99+ async onUpdatedNode ( node : Node ) {
100+ if ( ! node . fileid ) {
101+ logger . error ( 'Trying to update/set a node without fileid' , { node } )
102+ return
103+ }
104+
105+ // If we have multiple nodes with the same file ID, we need to update all of them
106+ const nodes = this . getNodesById ( node . fileid )
107+ if ( nodes . length > 1 ) {
108+ await Promise . all ( nodes . map ( fetchNode ) ) . then ( this . updateNodes )
109+ logger . debug ( nodes . length + ' nodes updated in store' , { fileid : node . fileid } )
110+ return
111+ }
112+
113+ // If we have only one node with the file ID, we can update it directly
114+ if ( node . source === nodes [ 0 ] . source ) {
115+ this . updateNodes ( [ node ] )
116+ return
117+ }
118+
119+ // Otherwise, it means we receive an event for a node that is not in the store
120+ fetchNode ( node ) . then ( n => this . updateNodes ( [ n ] ) )
78121 } ,
79122 } ,
80123 } )
0 commit comments