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+ import type { ContentsWithRoot , Folder , Node } from '@nextcloud/files'
66import type { ComputedRef , Ref } from 'vue'
7- import type { FileStat , ResponseDataDetailed , SearchResult } from 'webdav'
87
9- import { davGetClient , davGetDefaultPropfind , davGetRecentSearch , davResultToNode , davRootPath , getFavoriteNodes } from '@nextcloud/files'
10- import { join } from 'path'
11- import { onMounted , ref , shallowRef , watch } from 'vue'
8+ import { davGetClient , davRootPath , getFavoriteNodes } from '@nextcloud/files'
129import { CancelablePromise } from 'cancelable-promise'
10+ import { join } from 'node:path'
11+ import { onMounted , ref , shallowRef , watch } from 'vue'
12+ import { getFile , getNodes , getRecentNodes } from '../utils/dav'
1313
1414/**
1515 * Handle file loading using WebDAV
@@ -27,48 +27,6 @@ export const useDAVFiles = function(
2727 */
2828 const client = davGetClient ( )
2929
30- const resultToNode = ( result : FileStat ) => davResultToNode ( result )
31-
32- const getRecentNodes = ( ) : CancelablePromise < Node [ ] > => {
33- const controller = new AbortController ( )
34- // unix timestamp in seconds, two weeks ago
35- const lastTwoWeek = Math . round ( Date . now ( ) / 1000 ) - ( 60 * 60 * 24 * 14 )
36- return new CancelablePromise ( async ( resolve , reject , onCancel ) => {
37- onCancel ( ( ) => controller . abort ( ) )
38- try {
39- const { data } = await client . search ( '/' , {
40- signal : controller . signal ,
41- details : true ,
42- data : davGetRecentSearch ( lastTwoWeek ) ,
43- } ) as ResponseDataDetailed < SearchResult >
44- const nodes = data . results . map ( resultToNode )
45- resolve ( nodes )
46- } catch ( error ) {
47- reject ( error )
48- }
49- } )
50- }
51-
52- const getNodes = ( ) : CancelablePromise < Node [ ] > => {
53- const controller = new AbortController ( )
54- return new CancelablePromise ( async ( resolve , reject , onCancel ) => {
55- onCancel ( ( ) => controller . abort ( ) )
56- try {
57- const results = await client . getDirectoryContents ( join ( davRootPath , currentPath . value ) , {
58- signal : controller . signal ,
59- details : true ,
60- data : davGetDefaultPropfind ( ) ,
61- } ) as ResponseDataDetailed < FileStat [ ] >
62- let nodes = results . data . map ( resultToNode )
63- // Hack for the public endpoint which always returns folder itself
64- nodes = nodes . filter ( ( file ) => file . path !== currentPath . value )
65- resolve ( nodes )
66- } catch ( error ) {
67- reject ( error )
68- }
69- } )
70- }
71-
7230 /**
7331 * All files in current view and path
7432 */
@@ -77,49 +35,33 @@ export const useDAVFiles = function(
7735 /**
7836 * The current folder
7937 */
80- const folder = shallowRef < Folder > ( )
81- watch ( [ currentPath ] , async ( ) => {
82- folder . value = ( files . value . find ( ( { path } ) => path === currentPath . value ) ?? await getFile ( currentPath . value ) ) as Folder
83- } , { immediate : true } )
38+ const folder = shallowRef < Folder | null > ( null )
8439
8540 /**
8641 * Loading state of the files
8742 */
8843 const isLoading = ref ( true )
8944
9045 /**
91- * The cancelable promise
46+ * The cancelable promise used internally to cancel on fast navigation
9247 */
93- const promise = ref < null | CancelablePromise < unknown > > ( null )
48+ const promise = ref < null | CancelablePromise < Node [ ] | ContentsWithRoot > > ( null )
9449
9550 /**
9651 * Create a new directory in the current path
52+ * The directory will be added to the current file list
9753 * @param name Name of the new directory
9854 * @return {Promise<Folder> } The created directory
9955 */
10056 async function createDirectory ( name : string ) : Promise < Folder > {
10157 const path = join ( currentPath . value , name )
10258
10359 await client . createDirectory ( join ( davRootPath , path ) )
104- const directory = await getFile ( path ) as Folder
60+ const directory = await getFile ( client , path ) as Folder
10561 files . value = [ ...files . value , directory ]
10662 return directory
10763 }
10864
109- /**
110- * Get information for one file
111- *
112- * @param path The path of the file or folder
113- * @param rootPath DAV root path, defaults to '/files/USERID'
114- */
115- async function getFile ( path : string , rootPath : string = davRootPath ) {
116- const { data } = await client . stat ( join ( rootPath , path ) , {
117- details : true ,
118- data : davGetDefaultPropfind ( ) ,
119- } ) as ResponseDataDetailed < FileStat >
120- return resultToNode ( data )
121- }
122-
12365 /**
12466 * Force reload files using the DAV client
12567 */
@@ -132,11 +74,18 @@ export const useDAVFiles = function(
13274 if ( currentView . value === 'favorites' ) {
13375 promise . value = getFavoriteNodes ( client , currentPath . value )
13476 } else if ( currentView . value === 'recent' ) {
135- promise . value = getRecentNodes ( )
77+ promise . value = getRecentNodes ( client )
78+ } else {
79+ promise . value = getNodes ( client , currentPath . value )
80+ }
81+ const content = await promise . value
82+ if ( 'folder' in content ) {
83+ folder . value = content . folder
84+ files . value = content . contents
13685 } else {
137- promise . value = getNodes ( )
86+ folder . value = null
87+ files . value = content
13888 }
139- files . value = await promise . value as Node [ ]
14089
14190 promise . value = null
14291 isLoading . value = false
@@ -157,7 +106,6 @@ export const useDAVFiles = function(
157106 files,
158107 folder,
159108 loadFiles : loadDAVFiles ,
160- getFile,
161109 createDirectory,
162110 }
163111}
0 commit comments