fix update message display

This commit is contained in:
IsWaffle 2023-08-03 18:02:38 -04:00
parent e291158ada
commit 5cca94d2bf
9 changed files with 145 additions and 54 deletions

View File

@ -20,6 +20,17 @@
<Style Selector="Grid.show"> <Style Selector="Grid.show">
<Setter Property="Opacity" Value="1"/> <Setter Property="Opacity" Value="1"/>
</Style> </Style>
<Style Selector="ProgressBar">
<Setter Property="IsVisible" Value="False"/>
</Style>
<Style Selector="ProgressBar.checking">
<Setter Property="IsIndeterminate" Value="True"/>
<Setter Property="IsVisible" Value="True"/>
</Style>
<Style Selector="ProgressBar.updating">
<Setter Property="IsIndeterminate" Value="false"/>
<Setter Property="IsVisible" Value="True"/>
</Style>
</UserControl.Styles> </UserControl.Styles>
<Grid ColumnDefinitions="10,*,AUTO,AUTO,10" RowDefinitions="10,AUTO,AUTO,10" <Grid ColumnDefinitions="10,*,AUTO,AUTO,10" RowDefinitions="10,AUTO,AUTO,10"
@ -35,18 +46,19 @@
<Button Grid.Column="2" Grid.Row="2" Content="Not now" <Button Grid.Column="2" Grid.Row="2" Content="Not now"
Classes="outlined" Classes="outlined"
IsVisible="{Binding !Updating, RelativeSource={RelativeSource AncestorType=UserControl}}" IsVisible="{Binding UpdateAvailable, RelativeSource={RelativeSource AncestorType=UserControl}}"
Command="{Binding NotNowCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" Command="{Binding NotNowCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
/> />
<Button Grid.Column="3" Grid.Row="2" Content="Update" <Button Grid.Column="3" Grid.Row="2" Content="Update"
Classes="yellow" Margin="10 0 0 0" Classes="yellow" Margin="10 0 0 0"
IsVisible="{Binding !Updating, RelativeSource={RelativeSource AncestorType=UserControl}}" IsVisible="{Binding UpdateAvailable, RelativeSource={RelativeSource AncestorType=UserControl}}"
Command="{Binding UpdateInstallerCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" Command="{Binding UpdateInstallerCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
/> />
<ProgressBar Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="3" <ProgressBar Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="3"
Value="{Binding DownloadProgress, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="{Binding DownloadProgress, RelativeSource={RelativeSource AncestorType=UserControl}}"
IsVisible="{Binding Updating, RelativeSource={RelativeSource AncestorType=UserControl}}" Classes.updating="{Binding Updating, RelativeSource={RelativeSource AncestorType=UserControl}}"
Classes.checking="{Binding IndeterminateProgress, RelativeSource={RelativeSource AncestorType=UserControl}}"
/> />
</Grid> </Grid>

View File

@ -26,6 +26,22 @@ public partial class UpdateInfoCard : UserControl
public static readonly StyledProperty<bool> UpdatingProperty = public static readonly StyledProperty<bool> UpdatingProperty =
AvaloniaProperty.Register<UpdateInfoCard, bool>(nameof(Updating)); AvaloniaProperty.Register<UpdateInfoCard, bool>(nameof(Updating));
public bool UpdateAvailable
{
get => GetValue(UpdateAvailableProperty);
set => SetValue(UpdateAvailableProperty, value);
}
public static readonly StyledProperty<bool> UpdateAvailableProperty =
AvaloniaProperty.Register<UpdateInfoCard, bool>(nameof(UpdateAvailable));
public bool IndeterminateProgress
{
get => GetValue(IndeterminateProgressProperty);
set => SetValue(IndeterminateProgressProperty, value);
}
public static readonly StyledProperty<bool> IndeterminateProgressProperty =
AvaloniaProperty.Register<UpdateInfoCard, bool>(nameof(IndeterminateProgress));
public string InfoText public string InfoText
{ {
get => GetValue(InfoTextProperty); get => GetValue(InfoTextProperty);

View File

@ -20,18 +20,32 @@ public class InstallerUpdateInfo : ReactiveObject
set => this.RaiseAndSetIfChanged(ref _updateInfoText, value); set => this.RaiseAndSetIfChanged(ref _updateInfoText, value);
} }
private bool _updateAvailable; private bool _showCard = false;
public bool ShowCard
{
get => _showCard;
set => this.RaiseAndSetIfChanged(ref _showCard, value);
}
private bool _updating = false;
public bool Updating
{
get => _updating;
set => this.RaiseAndSetIfChanged(ref _updating, value);
}
private bool _updateAvailable = false;
public bool UpdateAvailable public bool UpdateAvailable
{ {
get => _updateAvailable; get => _updateAvailable;
set => this.RaiseAndSetIfChanged(ref _updateAvailable, value); set => this.RaiseAndSetIfChanged(ref _updateAvailable, value);
} }
private bool _updating; private bool _checkingForUpdates = false;
public bool Updating public bool CheckingForUpdates
{ {
get => _updating; get => _checkingForUpdates;
set => this.RaiseAndSetIfChanged(ref _updating, value); set => this.RaiseAndSetIfChanged(ref _checkingForUpdates, value);
} }
private int _downloadProgress; private int _downloadProgress;
@ -44,6 +58,7 @@ public class InstallerUpdateInfo : ReactiveObject
public async Task UpdateInstaller() public async Task UpdateInstaller()
{ {
Updating = true; Updating = true;
UpdateAvailable = false;
var updater = new FileInfo(Path.Join(DownloadCacheHelper.CachePath, "update.ps1")); var updater = new FileInfo(Path.Join(DownloadCacheHelper.CachePath, "update.ps1"));
FileHelper.StreamAssemblyResourceOut("update.ps1", updater.FullName); FileHelper.StreamAssemblyResourceOut("update.ps1", updater.FullName);
@ -84,11 +99,37 @@ public class InstallerUpdateInfo : ReactiveObject
return file.FullName; return file.FullName;
} }
private void EndCheck(string infoText, bool updateAvailable)
{
UpdateInfoText = infoText;
if (!updateAvailable)
{
Task.Run(async () =>
{
// delay card dismiss
await Task.Delay(TimeSpan.FromSeconds(2));
ShowCard = updateAvailable;
});
}
else
{
ShowCard = updateAvailable;
}
CheckingForUpdates = false;
UpdateAvailable = updateAvailable;
}
public async Task CheckForUpdates(Version? currentVersion) public async Task CheckForUpdates(Version? currentVersion)
{ {
if (currentVersion == null) if (currentVersion == null)
return; return;
UpdateInfoText = "Checking for installer updates";
ShowCard = true;
CheckingForUpdates = true;
try try
{ {
var repo = new RepositoryApi(Configuration.Default); var repo = new RepositoryApi(Configuration.Default);
@ -96,31 +137,39 @@ public class InstallerUpdateInfo : ReactiveObject
var releases = await repo.RepoListReleasesAsync("CWX", "SPT-AKI-Installer"); var releases = await repo.RepoListReleasesAsync("CWX", "SPT-AKI-Installer");
if (releases == null || releases.Count == 0) if (releases == null || releases.Count == 0)
{
EndCheck("No updates available", false);
return; return;
}
var latest = releases.FindAll(x => !x.Prerelease)[0]; var latest = releases.FindAll(x => !x.Prerelease)[0];
if (latest == null) if (latest == null)
{
EndCheck("No updates available", false);
return; return;
}
var latestVersion = new Version(latest.TagName); var latestVersion = new Version(latest.TagName);
if (latestVersion == null || latestVersion <= currentVersion) if (latestVersion == null || latestVersion <= currentVersion)
{
EndCheck("No updates available", false);
return; return;
}
UpdateAvailable = true;
_newVersion = latestVersion; _newVersion = latestVersion;
UpdateInfoText = $"A newer installer is available, version {latestVersion}";
NewInstallerUrl = latest.Assets[0].BrowserDownloadUrl; NewInstallerUrl = latest.Assets[0].BrowserDownloadUrl;
EndCheck($"Update available, version {latestVersion}", true);
return; return;
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Logger.Error(ex, "Failed to check for updates"); EndCheck(ex.Message, false);
Log.Error(ex, "Failed to check for updates");
} }
return; return;

View File

@ -9,8 +9,8 @@
<PackageIcon>icon.ico</PackageIcon> <PackageIcon>icon.ico</PackageIcon>
<ApplicationIcon>Assets\icon.ico</ApplicationIcon> <ApplicationIcon>Assets\icon.ico</ApplicationIcon>
<Configurations>Debug;Release;TEST</Configurations> <Configurations>Debug;Release;TEST</Configurations>
<AssemblyVersion>2.7</AssemblyVersion> <AssemblyVersion>2.8</AssemblyVersion>
<FileVersion>2.7</FileVersion> <FileVersion>2.8</FileVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -3,7 +3,7 @@
namespace SPTInstaller.ViewModels; namespace SPTInstaller.ViewModels;
public class DetailedPreChecksViewModel : PreChecksViewModel public class DetailedPreChecksViewModel : PreChecksViewModel
{ {
public DetailedPreChecksViewModel(IScreen host) : base(host, null) public DetailedPreChecksViewModel(IScreen host) : base(host)
{ {
} }
} }

View File

@ -2,10 +2,8 @@
using Gitea.Client; using Gitea.Client;
using ReactiveUI; using ReactiveUI;
using Serilog; using Serilog;
using SPTInstaller.Models;
using System.Globalization; using System.Globalization;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks;
namespace SPTInstaller.ViewModels; namespace SPTInstaller.ViewModels;
@ -13,7 +11,6 @@ public class MainWindowViewModel : ReactiveObject, IActivatableViewModel, IScree
{ {
public RoutingState Router { get; } = new(); public RoutingState Router { get; } = new();
public ViewModelActivator Activator { get; } = new(); public ViewModelActivator Activator { get; } = new();
public InstallerUpdateInfo UpdateInfo { get; } = new();
private string _title; private string _title;
public string Title public string Title
@ -26,9 +23,7 @@ public class MainWindowViewModel : ReactiveObject, IActivatableViewModel, IScree
{ {
Configuration.Default.BasePath = "https://dev.sp-tarkov.com/api/v1"; Configuration.Default.BasePath = "https://dev.sp-tarkov.com/api/v1";
Version? version = Assembly.GetExecutingAssembly().GetName()?.Version; Title = $"SPT Installer {"v" + Assembly.GetExecutingAssembly().GetName()?.Version?.ToString() ?? "--unknown version--"}";
Title = $"SPT Installer {"v" + version?.ToString() ?? "--unknown version--"}";
Log.Information($"========= {Title} Started ========="); Log.Information($"========= {Title} Started =========");
Log.Information(Environment.OSVersion.VersionString); Log.Information(Environment.OSVersion.VersionString);
@ -37,12 +32,7 @@ public class MainWindowViewModel : ReactiveObject, IActivatableViewModel, IScree
Log.Information("System Language: {iso} - {name}", uiCulture.TwoLetterISOLanguageName, uiCulture.DisplayName); Log.Information("System Language: {iso} - {name}", uiCulture.TwoLetterISOLanguageName, uiCulture.DisplayName);
Task.Run(async () => Router.Navigate.Execute(new PreChecksViewModel(this));
{
await UpdateInfo.CheckForUpdates(version);
});
Router.Navigate.Execute(new PreChecksViewModel(this, DismissUpdateCommand));
} }
public void CloseCommand() public void CloseCommand()
@ -60,15 +50,4 @@ public class MainWindowViewModel : ReactiveObject, IActivatableViewModel, IScree
desktopApp.MainWindow.WindowState = Avalonia.Controls.WindowState.Minimized; desktopApp.MainWindow.WindowState = Avalonia.Controls.WindowState.Minimized;
} }
} }
public void DismissUpdateCommand()
{
UpdateInfo.UpdateAvailable = false;
}
public async Task UpdateInstallerCommand()
{
Router.Navigate.Execute(new MessageViewModel(this, Result.FromSuccess("Please wait while the update is installed"), false));
await UpdateInfo.UpdateInstaller();
}
} }

View File

@ -1,4 +1,6 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics.Metrics;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using ReactiveUI; using ReactiveUI;
@ -11,26 +13,39 @@ namespace SPTInstaller.ViewModels;
public class PreChecksViewModel : ViewModelBase public class PreChecksViewModel : ViewModelBase
{ {
private string _installPath;
private bool _allowInstall;
public ObservableCollection<PreCheckBase> PreChecks { get; set; } = new(ServiceHelper.GetAll<PreCheckBase>()); public ObservableCollection<PreCheckBase> PreChecks { get; set; } = new(ServiceHelper.GetAll<PreCheckBase>());
public ICommand StartInstallCommand { get; set; } public ICommand StartInstallCommand { get; set; }
public ICommand ShowDetailedViewCommand { get; set; } public ICommand ShowDetailedViewCommand { get; set; }
public ICommand UpdateInstallerCommand { get; set; }
public ICommand DismissUpdateCommand { get; set; }
public InstallerUpdateInfo UpdateInfo { get; set; } = new InstallerUpdateInfo();
private string _installPath;
public string InstallPath public string InstallPath
{ {
get => _installPath; get => _installPath;
set => this.RaiseAndSetIfChanged(ref _installPath, value); set => this.RaiseAndSetIfChanged(ref _installPath, value);
} }
private bool _allowInstall;
public bool AllowInstall public bool AllowInstall
{ {
get => _allowInstall; get => _allowInstall;
set => this.RaiseAndSetIfChanged(ref _allowInstall, value); set => this.RaiseAndSetIfChanged(ref _allowInstall, value);
} }
public PreChecksViewModel(IScreen host, Action? dismissUpdateCard) : base(host) private bool _allowDetailsButton = false;
public bool AllowDetailsButton
{
get => _allowDetailsButton;
set => this.RaiseAndSetIfChanged(ref _allowDetailsButton, value);
}
public PreChecksViewModel(IScreen host) : base(host)
{ {
var data = ServiceHelper.Get<InternalData?>(); var data = ServiceHelper.Get<InternalData?>();
var installer = ServiceHelper.Get<InstallController?>(); var installer = ServiceHelper.Get<InstallController?>();
@ -55,20 +70,37 @@ public class PreChecksViewModel : ViewModelBase
StartInstallCommand = ReactiveCommand.Create(() => StartInstallCommand = ReactiveCommand.Create(() =>
{ {
dismissUpdateCard?.Invoke(); UpdateInfo.ShowCard = false;
NavigateTo(new InstallViewModel(HostScreen)); NavigateTo(new InstallViewModel(HostScreen));
}); });
ShowDetailedViewCommand = ReactiveCommand.Create(() => ShowDetailedViewCommand = ReactiveCommand.Create(() =>
{ {
dismissUpdateCard?.Invoke(); UpdateInfo.ShowCard = false;
Log.Logger.Information("Opening Detailed PreCheck View"); Log.Logger.Information("Opening Detailed PreCheck View");
NavigateTo(new DetailedPreChecksViewModel(HostScreen)); NavigateTo(new DetailedPreChecksViewModel(HostScreen));
}); });
UpdateInstallerCommand = ReactiveCommand.Create(async () =>
{
AllowDetailsButton = false;
AllowInstall = false;
await UpdateInfo.UpdateInstaller();
});
DismissUpdateCommand = ReactiveCommand.Create(() =>
{
UpdateInfo.ShowCard = false;
});
Task.Run(async () => Task.Run(async () =>
{ {
var result = await installer.RunPreChecks(); var result = await installer.RunPreChecks();
await UpdateInfo.CheckForUpdates(Assembly.GetExecutingAssembly().GetName()?.Version);
AllowDetailsButton = true;
AllowInstall = result.Succeeded; AllowInstall = result.Succeeded;
}); });
} }

View File

@ -33,15 +33,5 @@
/> />
<rxui:RoutedViewHost Router="{Binding Router}" Grid.Row="1"/> <rxui:RoutedViewHost Router="{Binding Router}" Grid.Row="1"/>
<cc:UpdateInfoCard Grid.Row="1" Padding="10"
VerticalAlignment="Top" HorizontalAlignment="Left"
InfoText="{Binding UpdateInfo.UpdateInfoText}"
ShowUpdateCard="{Binding UpdateInfo.UpdateAvailable}"
NotNowCommand="{Binding DismissUpdateCommand}"
UpdateInstallerCommand="{Binding UpdateInstallerCommand}"
Updating="{Binding UpdateInfo.Updating}"
DownloadProgress="{Binding UpdateInfo.DownloadProgress}"
/>
</Grid> </Grid>
</Window> </Window>

View File

@ -46,7 +46,20 @@
</ItemsControl> </ItemsControl>
<Button Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="3" HorizontalAlignment="Center" <Button Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="3" HorizontalAlignment="Center"
Content="Detailed View" Content="Detailed View"
IsEnabled="{Binding AllowDetailsButton}"
Command="{Binding ShowDetailedViewCommand}" Command="{Binding ShowDetailedViewCommand}"
/> />
<cc:UpdateInfoCard Grid.Row="1" Grid.RowSpan="4" Padding="10"
VerticalAlignment="Top" HorizontalAlignment="Left"
InfoText="{Binding UpdateInfo.UpdateInfoText}"
ShowUpdateCard="{Binding UpdateInfo.ShowCard}"
NotNowCommand="{Binding DismissUpdateCommand}"
UpdateInstallerCommand="{Binding UpdateInstallerCommand}"
Updating="{Binding UpdateInfo.Updating}"
DownloadProgress="{Binding UpdateInfo.DownloadProgress}"
IndeterminateProgress="{Binding UpdateInfo.CheckingForUpdates}"
UpdateAvailable="{Binding UpdateInfo.UpdateAvailable}"
/>
</Grid> </Grid>
</UserControl> </UserControl>