2121 *
2222 */
2323import type { ContentsWithRoot , Node } from '@nextcloud/files'
24- import type { FileStat , ResponseDataDetailed } from 'webdav'
24+ import type { FileStat , ResponseDataDetailed , SearchResult } from 'webdav'
2525
2626import { getCurrentUser } from '@nextcloud/auth'
2727import { Folder , Permission , davGetRecentSearch , davGetClient , davResultToNode , davRootPath , davRemoteURL } from '@nextcloud/files'
28+ import { getBaseUrl } from '@nextcloud/router'
29+ import { CancelablePromise } from 'cancelable-promise'
2830import { useUserConfigStore } from '../store/userconfig.ts'
2931import { pinia } from '../store/index.ts'
3032
3133const client = davGetClient ( )
3234
3335const lastTwoWeeksTimestamp = Math . round ( ( Date . now ( ) / 1000 ) - ( 60 * 60 * 24 * 14 ) )
3436
37+ /**
38+ * Helper to map a WebDAV result to a Nextcloud node
39+ * The search endpoint already includes the dav remote URL so we must not include it in the source
40+ *
41+ * @param stat the WebDAV result
42+ */
43+ const resultToNode = ( stat : FileStat ) => davResultToNode ( stat , davRootPath , getBaseUrl ( ) )
44+
3545/**
3646 * Get recently changed nodes
3747 *
@@ -51,28 +61,41 @@ export const getContents = async (path = '/'): Promise<ContentsWithRoot> => {
5161 || store . userConfig . show_hidden // If configured to show hidden files we can early return
5262 || ! node . dirname . split ( '/' ) . some ( ( dir ) => dir . startsWith ( '.' ) ) // otherwise only include the file if non of the parent directories is hidden
5363
54- const contentsResponse = await client . getDirectoryContents ( path , {
55- details : true ,
56- data : davGetRecentSearch ( lastTwoWeeksTimestamp ) ,
57- headers : {
58- // Patched in WebdavClient.ts
59- method : 'SEARCH' ,
60- // Somehow it's needed to get the correct response
61- 'Content-Type' : 'application/xml; charset=utf-8' ,
62- } ,
63- deep : true ,
64- } ) as ResponseDataDetailed < FileStat [ ] >
64+ const abort = new AbortController ( )
65+
66+ return new CancelablePromise ( async ( resolve , reject , cancel ) => {
67+ cancel ( ( ) => abort . abort ( ) )
68+
69+ let contentsResponse : ResponseDataDetailed < SearchResult >
70+ try {
71+ contentsResponse = await client . search ( '/' , {
72+ details : true ,
73+ data : davGetRecentSearch ( lastTwoWeeksTimestamp ) ,
74+ signal : abort . signal ,
75+ } ) as ResponseDataDetailed < SearchResult >
76+ } catch ( e ) {
77+ reject ( e )
78+ return
79+ }
80+
81+ if ( abort . signal . aborted ) {
82+ reject ( )
83+ return
84+ }
6585
66- const contents = contentsResponse . data
86+ const contents = contentsResponse . data . results
87+ . map ( resultToNode )
88+ . filter ( filterHidden )
6789
68- return {
69- folder : new Folder ( {
70- id : 0 ,
71- source : `${ davRemoteURL } ${ davRootPath } ` ,
72- root : davRootPath ,
73- owner : getCurrentUser ( ) ?. uid || null ,
74- permissions : Permission . READ ,
75- } ) ,
76- contents : contents . map ( ( r ) => davResultToNode ( r ) ) . filter ( filterHidden ) ,
77- }
90+ resolve ( {
91+ contents,
92+ folder : new Folder ( {
93+ id : 0 ,
94+ source : `${ davRemoteURL } ${ davRootPath } ` ,
95+ root : davRootPath ,
96+ owner : getCurrentUser ( ) ?. uid || null ,
97+ permissions : Permission . READ ,
98+ } ) ,
99+ } )
100+ } )
78101}
0 commit comments