66using System . Reactive ;
77using System . Threading . Tasks ;
88using Avalonia . Media ;
9+ using Avalonia . Threading ;
910using DazContentInstaller . Database ;
1011using DazContentInstaller . Extensions ;
1112using DazContentInstaller . Models ;
@@ -155,33 +156,40 @@ private void ClearLoadedArchives()
155156 public async Task LoadAssetLibrariesAsync ( )
156157 {
157158 await using var dbContext = await _dbContextFactory . CreateDbContextAsync ( ) ;
158- var libraries = await dbContext . AssetLibraries . ToListAsync ( ) ;
159159 AssetLibraries . Clear ( ) ;
160- AssetLibraries . AddRange ( libraries ) ;
161- CurrentSelectedAssetLibrary = libraries . OrderByDescending ( d => d . IsDefault ) . FirstOrDefault ( ) ;
160+ await Task . Run ( async ( ) =>
161+ {
162+ await foreach ( var library in dbContext . AssetLibraries . AsAsyncEnumerable ( ) )
163+ AssetLibraries . Add ( library ) ;
164+ } ) ;
165+
166+ CurrentSelectedAssetLibrary = AssetLibraries . OrderByDescending ( d => d . IsDefault ) . FirstOrDefault ( ) ;
162167 }
163168
164169 public async Task LoadInstalledArchivesAsync ( )
165170 {
166171 InstalledArchivesTree . Clear ( ) ;
172+ DisplayedInstalledArchives . Clear ( ) ;
173+ InstalledAssetsCount = 0 ;
167174
168- await using var dbContext = await _dbContextFactory . CreateDbContextAsync ( ) ;
169- var archivesQuery = dbContext . Archives
170- . Where ( d => d . Status == ArchiveStatus . Installed ) ;
171-
172- if ( CurrentSelectedAssetLibrary is not null )
173- archivesQuery = archivesQuery . Where ( d => d . AssetLibraryId == CurrentSelectedAssetLibrary . Id ) ;
174-
175- var archives = await archivesQuery
176- . Include ( d => d . AssetFiles )
177- . OrderBy ( d => d . ArchiveName )
178- . ToListAsync ( ) ;
179-
180- InstalledAssetsCount = archives . Count ;
181- foreach ( var archive in archives )
182- InstalledArchivesTree . LoadArchive ( archive ) ;
175+ await Task . Run ( async ( ) =>
176+ {
177+ await using var dbContext = await _dbContextFactory . CreateDbContextAsync ( ) ;
178+ var archivesQuery = dbContext . Archives
179+ . Where ( d => d . Status == ArchiveStatus . Installed ) ;
180+ if ( CurrentSelectedAssetLibrary is not null )
181+ archivesQuery = archivesQuery . Where ( d => d . AssetLibraryId == CurrentSelectedAssetLibrary . Id ) ;
183182
184- FilterInstalledAssetsTree ( InstalledAssetsSearch ) ;
183+ await foreach ( var archive in archivesQuery . OrderBy ( d => d . ArchiveName . ToLower ( ) ) . AsAsyncEnumerable ( ) )
184+ {
185+ var files = await dbContext . AssetFiles . Where ( d => d . ArchiveId == archive . Id ) . ToListAsync ( ) ;
186+ archive . AssetFiles = files ;
187+
188+ var node = InstalledArchivesTree . LoadArchive ( archive ) ;
189+ DisplayedInstalledArchives . Add ( node ) ;
190+ InstalledAssetsCount = InstalledArchivesTree . Count ;
191+ }
192+ } ) ;
185193 }
186194
187195 private void RemoveLoadedArchive ( LoadedArchive loadedArchiveOld )
@@ -197,49 +205,53 @@ private async Task InstallArchives()
197205 var archivesToInstall =
198206 SelectedArchives . Count > 0 ? SelectedArchives . ToList ( ) : LoadedArchives . ToList ( ) ;
199207
200- StatusProgress = 0 ;
201208 IProgress < string > messageProgress = new Progress < string > ( s => StatusText = s ) ;
202- StatusBarColor = Brushes . DodgerBlue ;
203209 IProgress < double > percentageProgress = new Progress < double > ( s => StatusProgress = ( int ) s ) ;
210+ StatusProgress = 0 ;
211+ StatusBarColor = Brushes . DodgerBlue ;
204212
205- await using var dbContext = await _dbContextFactory . CreateDbContextAsync ( ) ;
206-
207- var archivesToInstallNames = archivesToInstall . Select ( GetLoadedArchiveName ) . ToArray ( ) ;
208- var existingArchives = await dbContext . Archives
209- . Where ( a => archivesToInstallNames . Contains ( a . ArchiveName ) )
210- . Include ( a => a . AssetFiles )
211- . ToListAsync ( ) ;
212-
213- existingArchives = existingArchives . Where ( e => archivesToInstall . Any ( a =>
214- a . ContainedFiles . Count == e . AssetFiles . Count && GetLoadedArchiveName ( a ) . Equals ( e . ArchiveName ) ) ) . ToList ( ) ;
215-
216- var loadedArchivesToSkip = archivesToInstall
217- . IntersectBy ( existingArchives . Select ( d => d . ArchiveName ) , GetLoadedArchiveName ) . ToList ( ) ;
218- loadedArchivesToSkip . ForEach ( d => d . ArchiveStatus = ArchiveStatus . Duplicate ) ;
219-
220- archivesToInstall = archivesToInstall . Except ( loadedArchivesToSkip ) . ToList ( ) ;
221- using var installer = new DazArchiveInstaller ( archivesToInstall , _settingsService . CurrentSettings ) ;
222-
223- await foreach ( var archive in installer . InstallArchivesAsync ( CurrentSelectedAssetLibrary . Path , messageProgress ,
224- percentageProgress ) )
213+ await Task . Run ( async ( ) =>
225214 {
226- var dbArchive = new Archive
215+ await using var dbContext = await _dbContextFactory . CreateDbContextAsync ( ) ;
216+
217+ var archivesToInstallNames = archivesToInstall . Select ( GetLoadedArchiveName ) . ToArray ( ) ;
218+ var existingArchives = await dbContext . Archives
219+ . Where ( a => archivesToInstallNames . Contains ( a . ArchiveName ) )
220+ . Include ( a => a . AssetFiles )
221+ . ToListAsync ( ) ;
222+
223+ existingArchives = existingArchives . Where ( e => archivesToInstall . Any ( a =>
224+ a . ContainedFiles . Count == e . AssetFiles . Count && GetLoadedArchiveName ( a ) . Equals ( e . ArchiveName ) ) )
225+ . ToList ( ) ;
226+
227+ var loadedArchivesToSkip = archivesToInstall
228+ . IntersectBy ( existingArchives . Select ( d => d . ArchiveName ) , GetLoadedArchiveName ) . ToList ( ) ;
229+ loadedArchivesToSkip . ForEach ( d => d . ArchiveStatus = ArchiveStatus . Duplicate ) ;
230+
231+ archivesToInstall = archivesToInstall . Except ( loadedArchivesToSkip ) . ToList ( ) ;
232+ using var installer = new DazArchiveInstaller ( archivesToInstall , _settingsService . CurrentSettings ) ;
233+ await foreach ( var archive in installer . InstallArchivesAsync ( CurrentSelectedAssetLibrary . Path ,
234+ messageProgress ,
235+ percentageProgress ) )
227236 {
228- ArchiveName = archive . Name ,
229- ArchiveSize = archive . FileSizeBytes ,
230- Status = ArchiveStatus . Installed ,
231- CustomAssetsBasePath = archive . CustomAssetBaseDirectory ,
232- AssetLibraryId = CurrentSelectedAssetLibrary . Id
233- } ;
234-
235- dbArchive . AssetFiles . AddRange ( archive . ContainedFiles ) ;
236- dbContext . Archives . Add ( dbArchive ) ;
237- await dbContext . SaveChangesAsync ( ) ;
238-
239- LoadedArchives . Remove ( archive ) ;
240- await LoadInstalledArchivesAsync ( ) ;
241- }
237+ var dbArchive = new Archive
238+ {
239+ ArchiveName = archive . Name ,
240+ ArchiveSize = archive . FileSizeBytes ,
241+ Status = ArchiveStatus . Installed ,
242+ CustomAssetsBasePath = archive . CustomAssetBaseDirectory ,
243+ AssetLibraryId = CurrentSelectedAssetLibrary . Id
244+ } ;
245+
246+ dbArchive . AssetFiles . AddRange ( archive . ContainedFiles ) ;
247+ dbContext . Archives . Add ( dbArchive ) ;
248+ await dbContext . SaveChangesAsync ( ) ;
249+
250+ Dispatcher . UIThread . Post ( ( ) => LoadedArchives . Remove ( archive ) ) ;
251+ }
252+ } ) ;
242253
254+ await LoadInstalledArchivesAsync ( ) ;
243255 messageProgress . Report ( $ "Installed { archivesToInstall . Count } archives") ;
244256 percentageProgress . Report ( 100 ) ;
245257 StatusBarColor = Brushes . Green ;
@@ -267,41 +279,49 @@ private async Task UninstallArchiveAsync()
267279 if ( archives . Count < 1 )
268280 return ;
269281
270- var archiveIds = archives . Select ( a => a . Id ) . ToArray ( ) ;
271- var deleteFileExceptions = await dbContext . AssetFiles
272- . Where ( f => ! archiveIds . Contains ( f . ArchiveId ) && f . InstalledPath != null )
273- . ToListAsync ( ) ;
282+ await Task . Run ( async ( ) =>
283+ {
284+ IProgress < string > messageProgress = new Progress < string > ( s => StatusText = s ) ;
285+ IProgress < double > percentageProgress = new Progress < double > ( s => StatusProgress = ( int ) s ) ;
286+ StatusBarColor = Brushes . DodgerBlue ;
287+ StatusProgress = 0 ;
274288
275- deleteFileExceptions = deleteFileExceptions
276- . Where ( e => archives . SelectMany ( a => a . AssetFiles )
277- . Any ( f => f . InstalledPath ! . Equals ( e . InstalledPath , StringComparison . OrdinalIgnoreCase ) ) )
278- . Distinct ( ) . ToList ( ) ;
289+ messageProgress . Report ( $ "Reading { selectedInstallArchiveIds . Length } archives to uninstall...") ;
279290
280- IProgress < string > messageProgress = new Progress < string > ( s => StatusText = s ) ;
281- IProgress < double > percentageProgress = new Progress < double > ( s => StatusProgress = ( int ) s ) ;
282- StatusBarColor = Brushes . DodgerBlue ;
283- StatusProgress = 0 ;
284- var increment = Math . Ceiling ( 100D / archives . Count ) ;
291+ var archiveIds = archives . Select ( a => a . Id ) . ToArray ( ) ;
292+ var deleteFileExceptions = await dbContext . AssetFiles
293+ . Where ( f => ! archiveIds . Contains ( f . ArchiveId ) && f . InstalledPath != null )
294+ . ToListAsync ( ) ;
285295
286- var index = 0 ;
287- foreach ( var archive in archives )
288- {
289- index ++ ;
290- var uninstaller = new DazArchiveUninstaller ( archive ) ;
291- await uninstaller . UninstallArchiveAsync ( deleteFileExceptions . Select ( d => d . InstalledPath ! ) . ToHashSet ( ) ) ;
296+ deleteFileExceptions = deleteFileExceptions
297+ . Where ( e => archives . SelectMany ( a => a . AssetFiles )
298+ . Any ( f => f . InstalledPath ! . Equals ( e . InstalledPath , StringComparison . OrdinalIgnoreCase ) ) )
299+ . Distinct ( ) . ToList ( ) ;
292300
293- dbContext . Archives . Remove ( archive ) ;
294- await dbContext . SaveChangesAsync ( ) ;
301+ var increment = Math . Ceiling ( 100D / archives . Count ) ;
295302
296- messageProgress . Report ( $ "Uninstalled { archive . ArchiveName } ") ;
297- percentageProgress . Report ( index * increment ) ;
298- await Task . Yield ( ) ;
299- }
303+ var index = 0 ;
304+
305+ foreach ( var archive in archives )
306+ {
307+ index ++ ;
308+ var uninstaller = new DazArchiveUninstaller ( archive ) ;
309+ await uninstaller . UninstallArchiveAsync ( deleteFileExceptions . Select ( d => d . InstalledPath ! ) . ToHashSet ( ) ) ;
310+
311+ dbContext . Archives . Remove ( archive ) ;
312+ await dbContext . SaveChangesAsync ( ) ;
313+
314+ messageProgress . Report ( $ "Uninstalled { archive . ArchiveName } ") ;
315+ percentageProgress . Report ( index * increment ) ;
316+ await Task . Yield ( ) ;
317+ }
318+
319+ messageProgress . Report ( $ "Uninstalled { archives . Count } archives") ;
320+ percentageProgress . Report ( 100 ) ;
321+ StatusBarColor = Brushes . Green ;
322+ } ) ;
300323
301324 await LoadInstalledArchivesAsync ( ) ;
302- messageProgress . Report ( $ "Uninstalled { archives . Count } archives") ;
303- percentageProgress . Report ( 100 ) ;
304- StatusBarColor = Brushes . Green ;
305325 }
306326
307327 public async Task LoadArchiveFilesAsync ( List < string > filePaths )
@@ -311,20 +331,27 @@ public async Task LoadArchiveFilesAsync(List<string> filePaths)
311331 StatusBarColor = Brushes . DodgerBlue ;
312332
313333 var index = 0 ;
314- foreach ( var path in filePaths )
315- {
316- index ++ ;
317- var existingStatusProgress = index * 100 ;
318- IProgress < string > messageProgress = new Progress < string > ( s => StatusText = s ) ;
319- var percentageProgress = new Progress < int > ( p => StatusProgress = existingStatusProgress + p ) ;
320-
321- using var loader = new DazArchiveLoader ( path ) ;
322- var result = await loader . LoadArchiveAsync ( messageProgress , percentageProgress ) ;
323334
324- LoadedArchives . AddRange ( result . Where ( d => d . ContainedFiles . Count > 0 ) ) ;
325- UpdateInstallButton ( ) ;
326- messageProgress . Report ( $ "Finished loading { Path . GetFileName ( path ) } ") ;
327- }
335+ await Task . Run ( async ( ) =>
336+ {
337+ foreach ( var path in filePaths )
338+ {
339+ index ++ ;
340+ var existingStatusProgress = index * 100 ;
341+ IProgress < string > messageProgress = new Progress < string > ( s => StatusText = s ) ;
342+ var percentageProgress = new Progress < int > ( p => StatusProgress = existingStatusProgress + p ) ;
343+
344+ using var loader = new DazArchiveLoader ( path ) ;
345+ var result = await loader . LoadArchiveAsync ( messageProgress , percentageProgress ) ;
346+
347+ Dispatcher . UIThread . Post ( ( ) =>
348+ {
349+ LoadedArchives . AddRange ( result . Where ( d => d . ContainedFiles . Count > 0 ) ) ;
350+ UpdateInstallButton ( ) ;
351+ } ) ;
352+ messageProgress . Report ( $ "Finished loading { Path . GetFileName ( path ) } ") ;
353+ }
354+ } ) ;
328355
329356 StatusBarMax = 100 ;
330357 StatusBarColor = Brushes . Green ;
@@ -336,6 +363,7 @@ private void FilterInstalledAssetsTree(string? searchTerm)
336363 if ( string . IsNullOrWhiteSpace ( searchTerm ) )
337364 {
338365 DisplayedInstalledArchives . AddRange ( InstalledArchivesTree ) ;
366+
339367 return ;
340368 }
341369
0 commit comments