1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { FileSource, PathsStore, PathOptions, ServicesState } from '../types'
import { defineStore } from 'pinia'
import { FileType, Folder, Node, getNavigation } from '@nextcloud/files'
import { subscribe } from '@nextcloud/event-bus'
import Vue from 'vue'
import logger from '../logger'
import { useFilesStore } from './files'
export const usePathsStore = function(...args) {
const files = useFilesStore(...args)
const store = defineStore('paths', {
state: () => ({
paths: {} as ServicesState,
} as PathsStore),
getters: {
getPath: (state) => {
return (service: string, path: string): FileSource|undefined => {
if (!state.paths[service]) {
return undefined
}
return state.paths[service][path]
}
},
},
actions: {
addPath(payload: PathOptions) {
// If it doesn't exists, init the service state
if (!this.paths[payload.service]) {
Vue.set(this.paths, payload.service, {})
}
// Now we can set the provided path
Vue.set(this.paths[payload.service], payload.path, payload.source)
},
onCreatedNode(node: Node) {
const service = getNavigation()?.active?.id || 'files'
if (!node.fileid) {
logger.error('Node has no fileid', { node })
return
}
// Only add path if it's a folder
if (node.type === FileType.Folder) {
this.addPath({
service,
path: node.path,
source: node.source,
})
}
// Update parent folder children if exists
// If the folder is the root, get it and update it
if (node.dirname === '/') {
const root = files.getRoot(service)
if (!root._children) {
Vue.set(root, '_children', [])
}
root._children.push(node.source)
return
}
// If the folder doesn't exists yet, it will be
// fetched later and its children updated anyway.
if (this.paths[service][node.dirname]) {
const parentSource = this.paths[service][node.dirname]
const parentFolder = files.getNode(parentSource) as Folder
logger.debug('Path already exists, updating children', { parentFolder, node })
if (!parentFolder) {
logger.error('Parent folder not found', { parentSource })
return
}
if (!parentFolder._children) {
Vue.set(parentFolder, '_children', [])
}
parentFolder._children.push(node.source)
return
}
logger.debug('Parent path does not exists, skipping children update', { node })
},
},
})
const pathsStore = store(...args)
// Make sure we only register the listeners once
if (!pathsStore._initialized) {
// TODO: watch folders to update paths?
subscribe('files:node:created', pathsStore.onCreatedNode)
// subscribe('files:node:deleted', pathsStore.onDeletedNode)
// subscribe('files:node:moved', pathsStore.onMovedNode)
pathsStore._initialized = true
}
return pathsStore
}
|