@@ -11,8 +11,18 @@ namespace Files.App.Filesystem.Archive
11
11
{
12
12
public class ArchiveCreator : IArchiveCreator
13
13
{
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
+
14
20
private string archivePath = string . Empty ;
15
- public string ArchivePath => archivePath ;
21
+ public string ArchivePath
22
+ {
23
+ get => archivePath ;
24
+ set => archivePath = value ;
25
+ }
16
26
17
27
public string Directory { get ; init ; } = string . Empty ;
18
28
public string FileName { get ; init ; } = string . Empty ;
@@ -24,13 +34,24 @@ public class ArchiveCreator : IArchiveCreator
24
34
public ArchiveCompressionLevels CompressionLevel { get ; init ; } = ArchiveCompressionLevels . Normal ;
25
35
public ArchiveSplittingSizes SplittingSize { get ; init ; } = ArchiveSplittingSizes . None ;
26
36
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 ;
29
50
30
51
public ArchiveCreator ( )
31
52
{
32
53
fsProgress = new ( Progress , true , Shared . Enums . FileSystemStatusCode . InProgress ) ;
33
- fsProgress . Report ( ) ;
54
+ fsProgress . Report ( 0 ) ;
34
55
}
35
56
36
57
private string ArchiveExtension => FileFormat switch
@@ -75,16 +96,15 @@ public ArchiveCreator()
75
96
_ => throw new ArgumentOutOfRangeException ( nameof ( SplittingSize ) ) ,
76
97
} ;
77
98
99
+ public string GetArchivePath ( string suffix = "" )
100
+ {
101
+ return Path . Combine ( Directory , $ "{ FileName } { suffix } { ArchiveExtension } ") ;
102
+ }
103
+
78
104
public async Task < bool > RunCreationAsync ( )
79
105
{
80
- var path = Path . Combine ( Directory , FileName + ArchiveExtension ) ;
81
106
string [ ] sources = Sources . ToArray ( ) ;
82
107
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
-
88
108
var compressor = new SevenZipCompressor
89
109
{
90
110
ArchiveFormat = SevenZipArchiveFormat ,
@@ -104,41 +124,51 @@ public async Task<bool> RunCreationAsync()
104
124
var files = sources . Where ( source => File . Exists ( source ) ) . ToArray ( ) ;
105
125
var directories = sources . Where ( source => System . IO . Directory . Exists ( source ) ) ;
106
126
127
+ itemsAmount = files . Length + directories . Count ( ) ;
128
+
107
129
foreach ( string directory in directories )
108
130
{
109
- await compressor . CompressDirectoryAsync ( directory , path , Password ) ;
131
+ await compressor . CompressDirectoryAsync ( directory , archivePath , Password ) ;
110
132
compressor . CompressionMode = CompressionMode . Append ;
111
133
}
112
134
113
135
if ( files . Any ( ) )
114
136
{
115
137
if ( string . IsNullOrEmpty ( Password ) )
116
- await compressor . CompressFilesAsync ( path , files ) ;
138
+ await compressor . CompressFilesAsync ( archivePath , files ) ;
117
139
else
118
- await compressor . CompressFilesEncryptedAsync ( path , Password , files ) ;
140
+ await compressor . CompressFilesEncryptedAsync ( archivePath , Password , files ) ;
119
141
}
120
142
121
143
return true ;
122
144
}
123
145
catch ( Exception ex )
124
146
{
125
147
var logger = Ioc . Default . GetService < ILogger > ( ) ;
126
- logger ? . Warn ( ex , $ "Error compressing folder: { path } ") ;
148
+ logger ? . Warn ( ex , $ "Error compressing folder: { archivePath } ") ;
127
149
128
150
return false ;
129
151
}
130
152
}
131
153
132
154
private void Compressor_CompressionFinished ( object ? sender , EventArgs e )
133
155
{
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
+ }
136
166
}
137
167
138
168
private void Compressor_Compressing ( object ? _ , ProgressEventArgs e )
139
169
{
140
- fsProgress . Percentage = e . PercentDone ;
141
- fsProgress . Report ( ) ;
170
+ fsProgress . Percentage + = e . PercentDelta / itemsAmount ;
171
+ fsProgress . Report ( fsProgress . Percentage ) ;
142
172
}
143
173
}
144
174
}
0 commit comments