Skip to content

Feature: Implement the fundamental for rich progress #10814

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Dec 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[*.cs]
indent_style = tab
indent_size = 4
tab_width = 4
94 changes: 47 additions & 47 deletions src/BackgroundTasks/UpdateTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,51 @@

namespace BackgroundTasks
{
public sealed class UpdateTask : IBackgroundTask
{
public async void Run(IBackgroundTaskInstance taskInstance)
{
var deferral = taskInstance.GetDeferral();

// Refresh jump list to update string resources
try { await RefreshJumpList(); } catch { }

// Delete previous version log files
try { DeleteLogFiles(); } catch { }

deferral.Complete();
}

private void DeleteLogFiles()
{
File.Delete(Path.Combine(ApplicationData.Current.LocalFolder.Path, "debug.log"));
File.Delete(Path.Combine(ApplicationData.Current.LocalFolder.Path, "debug_fulltrust.log"));
}

private async Task RefreshJumpList()
{
if (JumpList.IsSupported())
{
var instance = await JumpList.LoadCurrentAsync();
// Disable automatic jumplist. It doesn't work with Files UWP.
instance.SystemGroupKind = JumpListSystemGroupKind.None;

var jumpListItems = instance.Items.ToList();

// Clear all items to avoid localization issues
instance.Items.Clear();

foreach (var temp in jumpListItems)
{
var jumplistItem = JumpListItem.CreateWithArguments(temp.Arguments, temp.DisplayName);
jumplistItem.Description = jumplistItem.Arguments;
jumplistItem.GroupName = "ms-resource:///Resources/JumpListRecentGroupHeader";
jumplistItem.Logo = new Uri("ms-appx:///Assets/FolderIcon.png");
instance.Items.Add(jumplistItem);
}

await instance.SaveAsync();
}
}
}
public sealed class UpdateTask : IBackgroundTask
{
public async void Run(IBackgroundTaskInstance taskInstance)
{
var deferral = taskInstance.GetDeferral();

// Refresh jump list to update string resources
try { await RefreshJumpList(); } catch { }

// Delete previous version log files
try { DeleteLogFiles(); } catch { }

deferral.Complete();
}

private void DeleteLogFiles()
{
File.Delete(Path.Combine(ApplicationData.Current.LocalFolder.Path, "debug.log"));
File.Delete(Path.Combine(ApplicationData.Current.LocalFolder.Path, "debug_fulltrust.log"));
}

private async Task RefreshJumpList()
{
if (JumpList.IsSupported())
{
var instance = await JumpList.LoadCurrentAsync();
// Disable automatic jumplist. It doesn't work with Files UWP.
instance.SystemGroupKind = JumpListSystemGroupKind.None;

var jumpListItems = instance.Items.ToList();

// Clear all items to avoid localization issues
instance.Items.Clear();

foreach (var temp in jumpListItems)
{
var jumplistItem = JumpListItem.CreateWithArguments(temp.Arguments, temp.DisplayName);
jumplistItem.Description = jumplistItem.Arguments;
jumplistItem.GroupName = "ms-resource:///Resources/JumpListRecentGroupHeader";
jumplistItem.Logo = new Uri("ms-appx:///Assets/FolderIcon.png");
instance.Items.Add(jumplistItem);
}

await instance.SaveAsync();
}
}
}
}
24 changes: 12 additions & 12 deletions src/Files.App.Storage/WindowsStorage/WindowsStorageFolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,18 +149,18 @@ private static Windows.Storage.NameCollisionOption GetWindowsNameCollisionOption
};
}

private static Windows.Storage.CreationCollisionOption GetWindowsCreationCollisionOption(
CreationCollisionOption options)
{
return options switch
{
CreationCollisionOption.GenerateUniqueName => Windows.Storage.CreationCollisionOption.GenerateUniqueName,
CreationCollisionOption.ReplaceExisting => Windows.Storage.CreationCollisionOption.ReplaceExisting,
CreationCollisionOption.OpenIfExists => Windows.Storage.CreationCollisionOption.OpenIfExists,
CreationCollisionOption.FailIfExists => Windows.Storage.CreationCollisionOption.FailIfExists,
_ => throw new ArgumentOutOfRangeException(nameof(options))
};
}
private static Windows.Storage.CreationCollisionOption GetWindowsCreationCollisionOption(
CreationCollisionOption options)
{
return options switch
{
CreationCollisionOption.GenerateUniqueName => Windows.Storage.CreationCollisionOption.GenerateUniqueName,
CreationCollisionOption.ReplaceExisting => Windows.Storage.CreationCollisionOption.ReplaceExisting,
CreationCollisionOption.OpenIfExists => Windows.Storage.CreationCollisionOption.OpenIfExists,
CreationCollisionOption.FailIfExists => Windows.Storage.CreationCollisionOption.FailIfExists,
_ => throw new ArgumentOutOfRangeException(nameof(options))
};
}

/// <inheritdoc/>
public override async Task<ILocatableFolder?> GetParentAsync(CancellationToken cancellationToken = default)
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ public static void SaveSessionTabs() // Enumerates through all tabs and gets the
{
IUserSettingsService userSettingsService = Ioc.Default.GetRequiredService<IUserSettingsService>();
IBundlesSettingsService bundlesSettingsService = Ioc.Default.GetRequiredService<IBundlesSettingsService>();

bundlesSettingsService.FlushSettings();

userSettingsService.PreferencesSettingsService.LastSessionTabList = MainPageViewModel.AppInstances.DefaultIfEmpty().Select(tab =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public float PercentageUsed
get => percentageUsed;
set
{
if (!SetProperty(ref percentageUsed, value))
if (!SetProperty(ref percentageUsed, value))
return;

if (Type == DriveType.Fixed)
Expand Down
22 changes: 20 additions & 2 deletions src/Files.App/Filesystem/Archive/ArchiveCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,14 @@ public class ArchiveCreator : IArchiveCreator
public ArchiveCompressionLevels CompressionLevel { get; init; } = ArchiveCompressionLevels.Normal;
public ArchiveSplittingSizes SplittingSize { get; init; } = ArchiveSplittingSizes.None;

public IProgress<float> Progress { get; set; } = new Progress<float>();
public IProgress<FileSystemProgress> Progress { get; set; } = new Progress<FileSystemProgress>();
private readonly FileSystemProgress fsProgress;

public ArchiveCreator()
{
fsProgress = new(Progress, true, Shared.Enums.FileSystemStatusCode.InProgress);
fsProgress.Report();
}

private string ArchiveExtension => FileFormat switch
{
Expand Down Expand Up @@ -90,6 +97,7 @@ public async Task<bool> RunCreationAsync()
EventSynchronization = EventSynchronizationStrategy.AlwaysAsynchronous,
};
compressor.Compressing += Compressor_Compressing;
compressor.CompressionFinished += Compressor_CompressionFinished;

try
{
Expand Down Expand Up @@ -121,6 +129,16 @@ public async Task<bool> RunCreationAsync()
}
}

private void Compressor_Compressing(object? _, ProgressEventArgs e) => Progress.Report(e.PercentDone);
private void Compressor_CompressionFinished(object? sender, EventArgs e)
{
fsProgress.Percentage = null;
fsProgress.ReportStatus(Shared.Enums.FileSystemStatusCode.Success);
}

private void Compressor_Compressing(object? _, ProgressEventArgs e)
{
fsProgress.Percentage = e.PercentDone;
fsProgress.Report();
}
}
}
2 changes: 1 addition & 1 deletion src/Files.App/Filesystem/Archive/IArchiveCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public interface IArchiveCreator
ArchiveCompressionLevels CompressionLevel { get; }
ArchiveSplittingSizes SplittingSize { get; }

IProgress<float> Progress { get; set; }
IProgress<FileSystemProgress> Progress { get; set; }

Task<bool> RunCreationAsync();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using Files.App.Helpers;
using Files.Shared.Enums;
using System;

namespace Files.App.Filesystem
{
public class FileSystemProgress
{
private readonly IProgress<FileSystemProgress>? progress;
private readonly IntervalSampler sampler;
private FileSystemStatusCode? status;
private bool criticalReport;
private bool enumerationCompleted;

public FileSystemStatusCode? Status
{
get => status;
set
{
if (status != value)
{
criticalReport = true;
}
status = value;
}
}
public string? FileName { get; set; }
public long TotalSize { get; set; }
public long ProcessedSize { get; set; }
public long ItemsCount { get; set; }
public long ProcessedItemsCount { get; set; }
public DateTimeOffset StartTime { get; }
public DateTimeOffset CompletedTime { get; private set; }
public bool EnumerationCompleted
{
get => enumerationCompleted;
set
{
if (enumerationCompleted != value)
{
criticalReport = true;
}
enumerationCompleted = value;
}
}
/// <summary>
/// Only used when detailed count isn't available.
/// </summary>
public float? Percentage { get; set; }

public FileSystemProgress(
IProgress<FileSystemProgress>? progress,
bool enumerationCompleted = false,
FileSystemStatusCode? status = null,
long itemsCount = 0,
long totalSize = 0,
int samplerInterval = 100)
{
this.StartTime = DateTimeOffset.Now;
this.progress = progress;
this.sampler = new(samplerInterval);
this.EnumerationCompleted = enumerationCompleted;
this.Status = status;
this.ItemsCount = itemsCount;
this.TotalSize = totalSize;
}

public void Report(float? percentage = null)
{
Percentage = percentage;
if (((EnumerationCompleted && (ProcessedItemsCount == ItemsCount || ProcessedSize == TotalSize)) ||
(percentage is float f && MathF.Abs(f - 100f) <= float.Epsilon)) &&
status is FileSystemStatusCode.InProgress or null)
{
status = FileSystemStatusCode.Success;
CompletedTime = DateTimeOffset.Now;
}

if (status is FileSystemStatusCode.Success)
CompletedTime = DateTimeOffset.Now;

if (progress is not null && (criticalReport || sampler.CheckNow()))
{
progress.Report(this);
criticalReport = false;
}
}

public void ReportStatus(FileSystemStatusCode status)
{
Status = status;
Report();
}
}
}
Loading