diff --git a/PalCalc.SaveReader/SaveFile/LevelSaveFile.cs b/PalCalc.SaveReader/SaveFile/LevelSaveFile.cs index 1956b629..a05e42df 100644 --- a/PalCalc.SaveReader/SaveFile/LevelSaveFile.cs +++ b/PalCalc.SaveReader/SaveFile/LevelSaveFile.cs @@ -63,6 +63,8 @@ private LevelSaveData BuildResult(PalDB db, List characte // references a container ID not in this list. the cause is not known, but I've seen "effective" // container sizes from 1 to 40. there's no clear answer to "where" this container is (or its // pals), so we won't bother referencing it + // + // (might be due to butchered pals? https://github.com/tylercamp/palcalc/issues/12#issuecomment-2101688781) logger.Warning("unrecognized pal container id '{id}', skipping", gvasInstance.ContainerId); continue; } diff --git a/PalCalc.UI/App.xaml.cs b/PalCalc.UI/App.xaml.cs index 7a4cbf72..00974889 100644 --- a/PalCalc.UI/App.xaml.cs +++ b/PalCalc.UI/App.xaml.cs @@ -17,7 +17,8 @@ namespace PalCalc.UI /// public partial class App : Application { - public static string Version => "v1.0.1"; + public static string Version => "v1.0.3"; + public static string RepositoryUrl => "https://github.com/tylercamp/palcalc/"; private static ILogger logger; diff --git a/PalCalc.UI/MainWindow.xaml b/PalCalc.UI/MainWindow.xaml index c140e765..74a02803 100644 --- a/PalCalc.UI/MainWindow.xaml +++ b/PalCalc.UI/MainWindow.xaml @@ -81,9 +81,13 @@ - - - + + + + + An update is available! + + diff --git a/PalCalc.UI/MainWindow.xaml.cs b/PalCalc.UI/MainWindow.xaml.cs index 79d054c5..06a13560 100644 --- a/PalCalc.UI/MainWindow.xaml.cs +++ b/PalCalc.UI/MainWindow.xaml.cs @@ -61,5 +61,10 @@ private void AboutButton_Click(object sender, RoutedEventArgs e) window.Owner = this; window.ShowDialog(); } + + private void DownloadUpdateLink_RequestNavigate(object sender, RequestNavigateEventArgs e) + { + ViewModel.TryDownloadLatestVersion(); + } } } diff --git a/PalCalc.UI/ViewModel/MainWindowViewModel.cs b/PalCalc.UI/ViewModel/MainWindowViewModel.cs index a31d2913..640af013 100644 --- a/PalCalc.UI/ViewModel/MainWindowViewModel.cs +++ b/PalCalc.UI/ViewModel/MainWindowViewModel.cs @@ -13,6 +13,8 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Net; +using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -149,6 +151,8 @@ public MainWindowViewModel(Dispatcher dispatcher) if (settings.SelectedGameIdentifier != null) SaveSelection.TrySelectSaveGame(settings.SelectedGameIdentifier); dispatcher.BeginInvoke(UpdateFromSaveProperties, DispatcherPriority.Background); + + CheckForUpdates(); } private void SaveSelection_CustomSaveAdded(ManualSavesLocationViewModel manualSaves, ISaveGame save) @@ -450,6 +454,57 @@ public bool IsEditable public Visibility ProgressBarVisibility => string.IsNullOrEmpty(SolverStatusMsg) ? Visibility.Collapsed : Visibility.Visible; + [ObservableProperty] + private Visibility updatesMessageVisibility = Visibility.Collapsed; + + private string VersionFromUrl(string url) => url.Split('/').Last(); + private string latestVersionUrl; + + private void CheckForUpdates() + { + Task.Run(async () => + { + try + { + var latestReleaseUrl = $"{App.RepositoryUrl}/releases/latest"; + using (var client = new HttpClient(new HttpClientHandler() { AllowAutoRedirect = false })) + using (var response = await client.GetAsync(latestReleaseUrl)) + { + if (response.StatusCode == HttpStatusCode.Found) + { + var location = response.Headers?.Location; + if (location != null) + { + latestVersionUrl = location.AbsoluteUri; + var latestVersion = VersionFromUrl(latestVersionUrl); + if (latestVersion != App.Version) + { + dispatcher.BeginInvoke(() => UpdatesMessageVisibility = Visibility.Visible); + } + } + else + { + logger.Warning("releases response did not include redirect URL, unable to determine latest version"); + } + } + else + { + logger.Warning("did not receive FOUND status code, unable to determine latest version"); + } + } + } + catch (Exception e) + { + logger.Warning(e, "error fetching latest version"); + } + }); + } + + public void TryDownloadLatestVersion() + { + Process.Start(new ProcessStartInfo { FileName = latestVersionUrl, UseShellExecute = true }); + } + public PalDB DB => db; } }