@@ -11,8 +11,18 @@ namespace Files.App.Filesystem.Archive
1111{
1212 public class ArchiveCreator : IArchiveCreator
1313 {
14+ // Represents the total number of items to be processed.
15+ // It is used to calculate a weighted progress with this formula:
16+ // Progress = [OldProgress + (ProgressDelta / ItemsAmount)]
17+ private int itemsAmount = 1 ;
18+ private int processedItems = 0 ;
19+
1420 private string archivePath = string . Empty ;
15- public string ArchivePath => archivePath ;
21+ public string ArchivePath
22+ {
23+ get => archivePath ;
24+ set => archivePath = value ;
25+ }
1626
1727 public string Directory { get ; init ; } = string . Empty ;
1828 public string FileName { get ; init ; } = string . Empty ;
@@ -24,13 +34,24 @@ public class ArchiveCreator : IArchiveCreator
2434 public ArchiveCompressionLevels CompressionLevel { get ; init ; } = ArchiveCompressionLevels . Normal ;
2535 public ArchiveSplittingSizes SplittingSize { get ; init ; } = ArchiveSplittingSizes . None ;
2636
27- public IProgress < FileSystemProgress > Progress { get ; set ; } = new Progress < FileSystemProgress > ( ) ;
28- private readonly FileSystemProgress fsProgress ;
37+ private IProgress < FileSystemProgress > progress = new Progress < FileSystemProgress > ( ) ;
38+ public IProgress < FileSystemProgress > Progress
39+ {
40+ get => progress ;
41+ set
42+ {
43+ progress = value ;
44+ fsProgress = new ( Progress , true , Shared . Enums . FileSystemStatusCode . InProgress ) ;
45+ fsProgress . Report ( 0 ) ;
46+ }
47+ }
48+
49+ private FileSystemProgress fsProgress ;
2950
3051 public ArchiveCreator ( )
3152 {
3253 fsProgress = new ( Progress , true , Shared . Enums . FileSystemStatusCode . InProgress ) ;
33- fsProgress . Report ( ) ;
54+ fsProgress . Report ( 0 ) ;
3455 }
3556
3657 private string ArchiveExtension => FileFormat switch
@@ -75,16 +96,15 @@ public ArchiveCreator()
7596 _ => throw new ArgumentOutOfRangeException ( nameof ( SplittingSize ) ) ,
7697 } ;
7798
99+ public string GetArchivePath ( string suffix = "" )
100+ {
101+ return Path . Combine ( Directory , $ "{ FileName } { suffix } { ArchiveExtension } ") ;
102+ }
103+
78104 public async Task < bool > RunCreationAsync ( )
79105 {
80- var path = Path . Combine ( Directory , FileName + ArchiveExtension ) ;
81106 string [ ] sources = Sources . ToArray ( ) ;
82107
83- int index = 1 ;
84- while ( File . Exists ( path ) || System . IO . Directory . Exists ( path ) )
85- path = Path . Combine ( Directory , $ "{ FileName } ({ ++ index } ){ ArchiveExtension } ") ;
86- archivePath = path ;
87-
88108 var compressor = new SevenZipCompressor
89109 {
90110 ArchiveFormat = SevenZipArchiveFormat ,
@@ -104,41 +124,51 @@ public async Task<bool> RunCreationAsync()
104124 var files = sources . Where ( source => File . Exists ( source ) ) . ToArray ( ) ;
105125 var directories = sources . Where ( source => System . IO . Directory . Exists ( source ) ) ;
106126
127+ itemsAmount = files . Length + directories . Count ( ) ;
128+
107129 foreach ( string directory in directories )
108130 {
109- await compressor . CompressDirectoryAsync ( directory , path , Password ) ;
131+ await compressor . CompressDirectoryAsync ( directory , archivePath , Password ) ;
110132 compressor . CompressionMode = CompressionMode . Append ;
111133 }
112134
113135 if ( files . Any ( ) )
114136 {
115137 if ( string . IsNullOrEmpty ( Password ) )
116- await compressor . CompressFilesAsync ( path , files ) ;
138+ await compressor . CompressFilesAsync ( archivePath , files ) ;
117139 else
118- await compressor . CompressFilesEncryptedAsync ( path , Password , files ) ;
140+ await compressor . CompressFilesEncryptedAsync ( archivePath , Password , files ) ;
119141 }
120142
121143 return true ;
122144 }
123145 catch ( Exception ex )
124146 {
125147 var logger = Ioc . Default . GetService < ILogger > ( ) ;
126- logger ? . Warn ( ex , $ "Error compressing folder: { path } ") ;
148+ logger ? . Warn ( ex , $ "Error compressing folder: { archivePath } ") ;
127149
128150 return false ;
129151 }
130152 }
131153
132154 private void Compressor_CompressionFinished ( object ? sender , EventArgs e )
133155 {
134- fsProgress . Percentage = null ;
135- fsProgress . ReportStatus ( Shared . Enums . FileSystemStatusCode . Success ) ;
156+ if ( ++ processedItems == itemsAmount )
157+ {
158+ fsProgress . Percentage = null ;
159+ fsProgress . ReportStatus ( Shared . Enums . FileSystemStatusCode . Success ) ;
160+ }
161+ else
162+ {
163+ fsProgress . Percentage = processedItems * 100 / itemsAmount ;
164+ fsProgress . Report ( fsProgress . Percentage ) ;
165+ }
136166 }
137167
138168 private void Compressor_Compressing ( object ? _ , ProgressEventArgs e )
139169 {
140- fsProgress . Percentage = e . PercentDone ;
141- fsProgress . Report ( ) ;
170+ fsProgress . Percentage + = e . PercentDelta / itemsAmount ;
171+ fsProgress . Report ( fsProgress . Percentage ) ;
142172 }
143173 }
144174}
0 commit comments