mirror of
https://github.com/nextcloud/server.git
synced 2026-02-20 00:12:30 -05:00
fix(files): fetch nodes if we have multiple of the same fileid in the store
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
This commit is contained in:
parent
e1248947fb
commit
6f6f1ad2ed
1 changed files with 45 additions and 4 deletions
|
|
@ -19,14 +19,28 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import type { Folder, Node } from '@nextcloud/files'
|
||||
import type { FilesStore, RootsStore, RootOptions, Service, FilesState, FileSource } from '../types'
|
||||
|
||||
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 => ({
|
||||
|
|
@ -48,6 +62,13 @@ export const useFilesStore = function(...args) {
|
|||
.map(source => state.files[source])
|
||||
.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
|
||||
*/
|
||||
|
|
@ -90,8 +111,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]))
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue