Skip to content

Commit

Permalink
Add ETA to update view
Browse files Browse the repository at this point in the history
Closes #205
  • Loading branch information
AlexMacocian committed Aug 7, 2023
1 parent 664d94a commit c55cec2
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 13 deletions.
35 changes: 35 additions & 0 deletions Daybreak/Converters/TimespanToETAConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Globalization;
using System.Windows.Data;

namespace Daybreak.Converters;

public sealed class TimespanToETAConverter : IValueConverter
{
private const char PluralAppend = 's';

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return GetETAString(value);
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}

private static string GetETAString(object obj)
{
if (obj is not TimeSpan timeSpan)
{
return string.Empty;
}

if ((int)timeSpan.TotalDays > 0)
{
return $"~{(int)timeSpan.TotalDays} day{((int)timeSpan.TotalDays > 1 ? PluralAppend : string.Empty)} remaining";
}

return $"{(int)timeSpan.Hours:D2}:{(int)timeSpan.Minutes:D2}:{(int)timeSpan.Seconds:D2} remaining";
}
}
2 changes: 1 addition & 1 deletion Daybreak/Daybreak.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<LangVersion>preview</LangVersion>
<ApplicationIcon>Daybreak.ico</ApplicationIcon>
<IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
<Version>0.9.8.93</Version>
<Version>0.9.8.94</Version>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<UserSecretsId>cfb2a489-db80-448d-a969-80270f314c46</UserSecretsId>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
Expand Down
11 changes: 8 additions & 3 deletions Daybreak/Models/Progress/DownloadStatus.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
namespace Daybreak.Models.Progress;
using System;

namespace Daybreak.Models.Progress;

public abstract class DownloadStatus : ActionStatus
{
public static readonly LoadStatus InitializingDownload = new DownloadStep("Initializing download");
public static LoadStatus Downloading(double progress) => new DownloadProgressStep("Downloading", progress);
public static LoadStatus Downloading(double progress, TimeSpan? eta) => new DownloadProgressStep("Downloading", progress, eta);
public static readonly LoadStatus DownloadCancelled = new DownloadStep("Download has been cancelled");
public static readonly LoadStatus DownloadFinished = new DownloadStep("Download finished. Starting installer");
public static readonly LoadStatus FailedDownload = new DownloadStep("Download failed. Please check logs for details");
Expand All @@ -22,9 +24,12 @@ internal DownloadStep(string name) : base(name)

public sealed class DownloadProgressStep : DownloadStep
{
internal DownloadProgressStep(string name, double progress) : base(name)
public TimeSpan? ETA { get; set; }

internal DownloadProgressStep(string name, double progress, TimeSpan? eta) : base(name)
{
this.Progress = progress;
this.ETA = eta;
}
}
}
13 changes: 11 additions & 2 deletions Daybreak/Services/Downloads/DownloadService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public async Task<bool> DownloadFile(string downloadUri, string destinationPath,
var downloaded = 0d;
var downloadedPerTimeframe = 0d;
var tickTime = DateTime.Now;
var startTime = DateTime.Now;
while (downloadStream.CanRead && (length = await downloadStream.ReadAsync(buffer)) > 0)
{
downloaded += length;
Expand All @@ -63,12 +64,20 @@ public async Task<bool> DownloadFile(string downloadUri, string destinationPath,
tickTime = DateTime.Now;
var downloadedInSecond = downloadedPerTimeframe * 1000d / StatusUpdateInterval;
this.averageDownloadSpeed.Record(downloadedInSecond);

var avgSpeed = downloaded / (tickTime - startTime).TotalSeconds;
var remainingSize = downloadSize - downloaded;
var secondsRemaining = remainingSize / avgSpeed;
downloadedPerTimeframe = 0d;
downloadStatus.CurrentStep = DownloadStatus.Downloading(downloaded / downloadSize);
downloadStatus.CurrentStep = DownloadStatus.Downloading(
downloaded / downloadSize,
double.IsFinite(secondsRemaining) ?
TimeSpan.FromSeconds(secondsRemaining) :
TimeSpan.Zero);
}
}

downloadStatus.CurrentStep = DownloadStatus.Downloading(1);
downloadStatus.CurrentStep = DownloadStatus.Downloading(1, TimeSpan.Zero);
downloadStatus.CurrentStep = DownloadStatus.DownloadFinished;
fileStream.Close();
this.logger.LogInformation("Downloaded file");
Expand Down
32 changes: 25 additions & 7 deletions Daybreak/Views/UpdateView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,46 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Views"
xmlns:buttons="clr-namespace:Daybreak.Controls.Buttons"
xmlns:converters="clr-namespace:Daybreak.Converters"
mc:Ignorable="d"
x:Name="_this"
xmlns:controls="clr-namespace:Daybreak.Controls"
Loaded="UpdateView_Loaded"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
<converters:TimespanToETAConverter x:Key="TimespanToETAConverter"></converters:TimespanToETAConverter>
</UserControl.Resources>
<Grid VerticalAlignment="Center" HorizontalAlignment="Center" Background="{StaticResource Daybreak.Brushes.Background}" MinHeight="200" MinWidth="400">
<Border BorderBrush="{StaticResource MahApps.Brushes.ThemeForeground}"
BorderThickness="1"/>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="{Binding ElementName=_this, Path=Description, Mode=OneWay}" Margin="10, 0, 10, 0" Foreground="{StaticResource MahApps.Brushes.ThemeForeground}"
TextWrapping="Wrap" HorizontalAlignment="Center" FontSize="16"></TextBlock>
<ProgressBar Minimum="0" Maximum="100" Value="{Binding ElementName=_this, Path=ProgressValue, Mode=OneWay}" Width="300" Height="20"></ProgressBar>
<buttons:HighlightButton Title="Ok" Background="{StaticResource MahApps.Brushes.ThemeBackground}" HorizontalAlignment="Center"
<Grid VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<StackPanel
Grid.Row="0">
<TextBlock Text="{Binding ElementName=_this, Path=Description, Mode=OneWay}" Margin="10, 0, 10, 0" Foreground="{StaticResource MahApps.Brushes.ThemeForeground}"
TextWrapping="Wrap" HorizontalAlignment="Center" FontSize="16" />
<ProgressBar Minimum="0" Maximum="100" Value="{Binding ElementName=_this, Path=ProgressValue, Mode=OneWay}" Width="300" Height="20" />
<WrapPanel HorizontalAlignment="Center"
Visibility="{Binding ElementName=_this, Path=EtaVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"
Margin="0, 10, 0, 10">
<TextBlock Text="ETA: " Margin="10, 0, 10, 0" Foreground="{StaticResource MahApps.Brushes.ThemeForeground}"
TextWrapping="Wrap" HorizontalAlignment="Center" FontSize="16" />
<TextBlock Text="{Binding ElementName=_this, Path=Eta, Mode=OneWay, Converter={StaticResource TimespanToETAConverter}}" Margin="10, 0, 10, 0" Foreground="{StaticResource MahApps.Brushes.ThemeForeground}"
TextWrapping="Wrap" HorizontalAlignment="Center" FontSize="16" />
</WrapPanel>
</StackPanel>
<buttons:HighlightButton Grid.Row="1"
Title="Ok" Background="{StaticResource MahApps.Brushes.ThemeBackground}" HorizontalAlignment="Center"
FontSize="16" Margin="10" Width="50" Height="25" Clicked="OpaqueButton_Clicked" Foreground="{StaticResource MahApps.Brushes.ThemeForeground}"
HighlightColor="{StaticResource MahApps.Brushes.Accent}"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
BorderBrush="{StaticResource MahApps.Brushes.ThemeForeground}"
BorderThickness="1"
Visibility="{Binding ElementName=_this, Path=ContinueButtonEnabled, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"></buttons:HighlightButton>
</StackPanel>
Visibility="{Binding ElementName=_this, Path=ContinueButtonEnabled, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}" />
</Grid>
</Grid>
</UserControl>
6 changes: 6 additions & 0 deletions Daybreak/Views/UpdateView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public partial class UpdateView : UserControl
private double progressValue;
[GenerateDependencyProperty]
private bool continueButtonEnabled;
[GenerateDependencyProperty]
private TimeSpan eta;
[GenerateDependencyProperty]
private bool etaVisible;

public UpdateView(
IApplicationUpdater applicationUpdater,
Expand All @@ -50,6 +54,8 @@ private void UpdateStatus_PropertyChanged(object sender, System.ComponentModel.P
if (this.updateStatus.CurrentStep is DownloadStatus.DownloadProgressStep downloadUpdateStep)
{
this.ProgressValue = downloadUpdateStep.Progress * 100;
this.Eta = downloadUpdateStep.ETA ?? TimeSpan.Zero;
this.EtaVisible = downloadUpdateStep.ETA is not null;
}
this.Description = this.updateStatus.CurrentStep.Description;
Expand Down

0 comments on commit c55cec2

Please sign in to comment.