@@ -27,11 +27,10 @@ import RealmSwift
2727import SwiftUI
2828
2929class NCFiles : NCCollectionViewCommon {
30- internal var isRoot : Bool = true
3130 internal var fileNameBlink : String ?
3231 internal var fileNameOpen : String ?
3332 internal var matadatasHash : String = " "
34- internal var reloadDataSourceInProgress : Bool = false
33+ internal var semaphoreReloadDataSource = DispatchSemaphore ( value : 1 )
3534
3635 required init ? ( coder aDecoder: NSCoder ) {
3736 super. init ( coder: aDecoder)
@@ -50,7 +49,14 @@ class NCFiles: NCCollectionViewCommon {
5049 override func viewDidLoad( ) {
5150 super. viewDidLoad ( )
5251
53- if isRoot {
52+ if self . serverUrl. isEmpty {
53+
54+ ///
55+ /// Set ServerURL when start (isEmpty)
56+ ///
57+ self . serverUrl = utilityFileSystem. getHomeServer ( session: session)
58+ self . titleCurrentFolder = getNavigationTitle ( )
59+
5460 NotificationCenter . default. addObserver ( forName: NSNotification . Name ( rawValue: NCGlobal . shared. notificationCenterChangeUser) , object: nil , queue: nil ) { notification in
5561
5662 if let userInfo = notification. userInfo, let account = userInfo [ " account " ] as? String {
@@ -88,10 +94,6 @@ class NCFiles: NCCollectionViewCommon {
8894 }
8995
9096 override func viewWillAppear( _ animated: Bool ) {
91- if isRoot {
92- serverUrl = utilityFileSystem. getHomeServer ( session: session)
93- titleCurrentFolder = getNavigationTitle ( )
94- }
9597 super. viewWillAppear ( animated)
9698
9799 reloadDataSource ( )
@@ -122,12 +124,16 @@ class NCFiles: NCCollectionViewCommon {
122124 // MARK: - DataSource
123125
124126 override func reloadDataSource( ) {
125- guard !isSearchingMode,
126- !reloadDataSourceInProgress
127+ guard !isSearchingMode
127128 else {
128129 return super. reloadDataSource ( )
129130 }
130- reloadDataSourceInProgress = true
131+
132+ // Watchdog: this is only a fail safe "dead lock", I don't think the timeout will ever be called but at least nothing gets stuck, if after 5 sec. (which is a long time in this routine), the semaphore is still locked
133+ //
134+ if self . semaphoreReloadDataSource. wait ( timeout: . now( ) + 5 ) == . timedOut {
135+ self . semaphoreReloadDataSource. signal ( )
136+ }
131137
132138 var predicate = self . defaultPredicate
133139 let predicateDirectory = NSPredicate ( format: " account == %@ AND serverUrl == %@ " , session. account, self . serverUrl)
@@ -145,14 +151,16 @@ class NCFiles: NCCollectionViewCommon {
145151 self . dataSource = NCCollectionViewDataSource ( metadatas: metadatas, layoutForView: layoutForView)
146152
147153 if metadatas. isEmpty {
148- reloadDataSourceInProgress = false
154+ self . semaphoreReloadDataSource . signal ( )
149155 return super. reloadDataSource ( )
150156 }
151157
152158 self . dataSource. caching ( metadatas: metadatas, dataSourceMetadatas: dataSourceMetadatas) { updated in
153- self . reloadDataSourceInProgress = false
154- if updated || self . isNumberOfItemsInAllSectionsNull || self . numberOfItemsInAllSections != metadatas. count {
155- super. reloadDataSource ( )
159+ self . semaphoreReloadDataSource. signal ( )
160+ DispatchQueue . main. async {
161+ if updated || self . isNumberOfItemsInAllSectionsNull || self . numberOfItemsInAllSections != metadatas. count {
162+ super. reloadDataSource ( )
163+ }
156164 }
157165 }
158166 }
@@ -178,6 +186,26 @@ class NCFiles: NCCollectionViewCommon {
178186 return false
179187 }
180188
189+ ///
190+ /// Recommended files
191+ ///
192+ if self . serverUrl == self . utilityFileSystem. getHomeServer ( session: self . session) ,
193+ NCCapabilities . shared. getCapabilities ( account: self . session. account) . capabilityRecommendations {
194+ let options = NKRequestOptions ( queue: NextcloudKit . shared. nkCommonInstance. backgroundQueue)
195+
196+ NextcloudKit . shared. getRecommendedFiles ( account: self . session. account, options: options) { _, recommendations, _, error in
197+ if error == . success,
198+ let recommendations,
199+ !recommendations. isEmpty {
200+ Task . detached {
201+ await self . createRecommendations ( recommendations)
202+ }
203+ } else {
204+ NotificationCenter . default. postOnMainThread ( name: NCGlobal . shared. notificationCenterReloadRecommendedFiles, userInfo: nil )
205+ }
206+ }
207+ }
208+
181209 DispatchQueue . global ( ) . async {
182210 self . networkReadFolder { metadatas, isChanged, error in
183211 DispatchQueue . main. async {
@@ -340,6 +368,33 @@ class NCFiles: NCCollectionViewCommon {
340368 }
341369 }
342370
371+ private func createRecommendations( _ recommendations: [ NKRecommendation ] ) async {
372+ let home = self . utilityFileSystem. getHomeServer ( session: self . session)
373+ var recommendationsToInsert : [ NKRecommendation ] = [ ]
374+
375+ for recommendation in recommendations {
376+ var metadata = database. getResultMetadataFromFileId ( recommendation. id)
377+ if metadata == nil || metadata? . fileName != recommendation. name {
378+ let serverUrlFileName = home + recommendation. directory + recommendation. name
379+ let results = await NCNetworking . shared. readFileOrFolder ( serverUrlFileName: serverUrlFileName, depth: " 0 " , showHiddenFiles: NCKeychain ( ) . showHiddenFiles, account: session. account)
380+
381+ if results. error == . success, let file = results. files? . first {
382+ let isDirectoryE2EE = self . utilityFileSystem. isDirectoryE2EE ( file: file)
383+ let metadataConverted = self . database. convertFileToMetadata ( file, isDirectoryE2EE: isDirectoryE2EE)
384+ metadata = metadataConverted
385+
386+ self . database. addMetadata ( metadataConverted)
387+ recommendationsToInsert. append ( recommendation)
388+ }
389+ } else {
390+ recommendationsToInsert. append ( recommendation)
391+ }
392+ }
393+
394+ self . database. createRecommendedFiles ( account: session. account, recommendations: recommendationsToInsert)
395+ NotificationCenter . default. postOnMainThread ( name: NCGlobal . shared. notificationCenterReloadRecommendedFiles, userInfo: nil )
396+ }
397+
343398 // MARK: - NCAccountSettingsModelDelegate
344399
345400 override func accountSettingsDidDismiss( tableAccount: tableAccount ? , controller: NCMainTabBarController ? ) {
@@ -349,9 +404,9 @@ class NCFiles: NCCollectionViewCommon {
349404 appDelegate. openLogin ( selector: NCGlobal . shared. introLogin)
350405 } else if let account = tableAccount? . account, account != currentAccount {
351406 NCAccount ( ) . changeAccount ( account, userProfile: nil , controller: controller) { }
352- } else if isRoot {
353- titleCurrentFolder = getNavigationTitle ( )
354- navigationItem. title = titleCurrentFolder
407+ } else if self . serverUrl == self . utilityFileSystem . getHomeServer ( session : self . session ) {
408+ self . titleCurrentFolder = getNavigationTitle ( )
409+ navigationItem. title = self . titleCurrentFolder
355410 }
356411
357412 setNavigationLeftItems ( )
0 commit comments