Skip to content

Commit 494ca6b

Browse files
Fix: Fixed issue where progress was not updated when creating an archive (#11811)
1 parent 03286c5 commit 494ca6b

File tree

3 files changed

+57
-20
lines changed

3 files changed

+57
-20
lines changed

src/Files.App/Filesystem/Archive/ArchiveCreator.cs

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

src/Files.App/Filesystem/Archive/IArchiveCreator.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace Files.App.Filesystem.Archive
66
{
77
public interface IArchiveCreator
88
{
9-
string ArchivePath { get; }
9+
string ArchivePath { get; set; }
1010

1111
string Directory { get; }
1212
string FileName { get; }
@@ -20,6 +20,8 @@ public interface IArchiveCreator
2020

2121
IProgress<FileSystemProgress> Progress { get; set; }
2222

23+
string GetArchivePath(string suffix = "");
24+
2325
Task<bool> RunCreationAsync();
2426
}
2527
}

src/Files.App/Helpers/ArchiveHelpers.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,12 @@ public static (string[] Sources, string directory, string fileName) GetCompressD
7070

7171
public static async Task CompressArchiveAsync(IArchiveCreator creator)
7272
{
73-
var archivePath = creator.ArchivePath;
73+
var archivePath = creator.GetArchivePath();
74+
75+
int index = 1;
76+
while (File.Exists(archivePath) || System.IO.Directory.Exists(archivePath))
77+
archivePath = creator.GetArchivePath($" ({++index})");
78+
creator.ArchivePath = archivePath;
7479

7580
CancellationTokenSource compressionToken = new();
7681
PostedStatusBanner banner = OngoingTasksViewModel.PostOperationBanner

0 commit comments

Comments
 (0)