From fe9fe2a10f6e9664823c5bfdb50a9b7224b17c87 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Mon, 10 Feb 2025 19:28:46 -0600 Subject: [PATCH 1/7] UI: Added option to check for updates in the background --- src/Ryujinx/Assets/locales.json | 115 +++++++++++++++--- .../UI/ViewModels/SettingsViewModel.cs | 4 + .../UI/Views/Settings/SettingsUIView.axaml | 24 +++- .../UI/Views/Settings/SettingsUIView.axaml.cs | 1 - src/Ryujinx/UI/Windows/MainWindow.axaml.cs | 26 +++- src/Ryujinx/Updater.cs | 59 ++++----- .../Configuration/ConfigurationFileFormat.cs | 9 +- .../ConfigurationState.Migration.cs | 4 +- .../Configuration/ConfigurationState.Model.cs | 7 ++ .../Configuration/ConfigurationState.cs | 2 +- .../Utilities/Configuration/UI/UpdaterType.cs | 13 ++ 11 files changed, 204 insertions(+), 60 deletions(-) create mode 100644 src/Ryujinx/Utilities/Configuration/UI/UpdaterType.cs diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index ab114a8936..ad7b4286f9 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -3350,26 +3350,101 @@ { "ID": "SettingsTabGeneralCheckUpdatesOnLaunch", "Translations": { - "ar_SA": "التحقق من وجود تحديثات عند التشغيل", - "de_DE": "Beim Start nach Updates suchen", - "el_GR": "Έλεγχος για Ενημερώσεις στην Εκκίνηση", - "en_US": "Check for Updates on Launch", - "es_ES": "Buscar actualizaciones al iniciar", - "fr_FR": "Vérifier les mises à jour au démarrage", - "he_IL": "בדוק אם קיימים עדכונים בהפעלה", - "it_IT": "Controlla aggiornamenti all'avvio", - "ja_JP": "起動時にアップデートを確認する", - "ko_KR": "시작 시, 업데이트 확인", - "no_NO": "Se etter oppdateringer ved oppstart", - "pl_PL": "Sprawdzaj aktualizacje przy uruchomieniu", - "pt_BR": "Verificar se há atualizações ao iniciar", - "ru_RU": "Проверять наличие обновлений при запуске", - "sv_SE": "Leta efter uppdatering vid uppstart", - "th_TH": "ตรวจหาการอัปเดตเมื่อเปิดโปรแกรม", - "tr_TR": "Her Açılışta Güncellemeleri Denetle", - "uk_UA": "Перевіряти наявність оновлень під час запуску", - "zh_CN": "启动时检查更新", - "zh_TW": "啟動時檢查更新" + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Check for Updates:", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGeneralCheckUpdatesOnLaunchOff", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Off", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGeneralCheckUpdatesOnLaunchPromptAtStartup", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Prompt", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGeneralCheckUpdatesOnLaunchBackground", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Background", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 0b3f8dcc6f..b3df13e7f8 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -13,6 +13,7 @@ using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.Utilities.Configuration; using Ryujinx.Ava.Utilities.Configuration.System; +using Ryujinx.Ava.Utilities.Configuration.UI; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.GraphicsDriver; @@ -121,6 +122,7 @@ public float CustomResolutionScale public bool RememberWindowState { get; set; } public bool ShowTitleBar { get; set; } public int HideCursor { get; set; } + public int UpdateCheckerType { get; set; } public bool EnableDockedMode { get; set; } public bool EnableKeyboard { get; set; } public bool EnableMouse { get; set; } @@ -476,6 +478,7 @@ public void LoadCurrentConfiguration() RememberWindowState = config.RememberWindowState; ShowTitleBar = config.ShowTitleBar; HideCursor = (int)config.HideCursor.Value; + UpdateCheckerType = (int)config.UpdateCheckerType.Value; GameDirectories.Clear(); GameDirectories.AddRange(config.UI.GameDirs.Value); @@ -582,6 +585,7 @@ public void SaveSettings() config.RememberWindowState.Value = RememberWindowState; config.ShowTitleBar.Value = ShowTitleBar; config.HideCursor.Value = (HideCursorMode)HideCursor; + config.UpdateCheckerType.Value = (UpdaterType)UpdateCheckerType; if (GameDirectoryChanged) { diff --git a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml index 77f9b7bf55..d71a7d7951 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml @@ -6,6 +6,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" + xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common" mc:Ignorable="d" x:DataType="viewModels:SettingsViewModel"> @@ -30,18 +31,33 @@ ToolTip.Tip="{ext:Locale ToggleDiscordTooltip}" Text="{ext:Locale SettingsTabGeneralEnableDiscordRichPresence}" /> - - - - + + + + + + + + + + + + + + + AddDirButton(GameDirPathBox, ViewModel.GameDirectories, true)); AddAutoloadDirButton.Command = diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs index 669e338df5..7354555410 100644 --- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs @@ -19,6 +19,7 @@ using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Ava.Utilities.Configuration; +using Ryujinx.Ava.Utilities.Configuration.UI; using Ryujinx.Common; using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; @@ -400,10 +401,29 @@ private async Task CheckLaunchState() await Dispatcher.UIThread.InvokeAsync(async () => await UserErrorDialog.ShowUserErrorDialog(UserError.NoKeys)); } - if (ConfigurationState.Instance.CheckUpdatesOnStart && !CommandLineState.HideAvailableUpdates && Updater.CanUpdate()) + if (!Updater.CanUpdate() || CommandLineState.HideAvailableUpdates) + return; + + switch (ConfigurationState.Instance.UpdateCheckerType.Value) { - await Updater.BeginUpdateAsync() - .Catch(task => Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}")); + case UpdaterType.PromptAtStartup: + await Updater.BeginUpdateAsync() + .Catch(task => Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}")); + break; + case UpdaterType.CheckInBackground: + if ((await Updater.CheckVersionAsync()).TryGet(out (Version Current, Version Incoming) versions)) + { + string newVersionString = ReleaseInformation.IsCanaryBuild + ? $"Canary {versions.Current} -> Canary {versions.Incoming}" + : $"{versions.Current} -> {versions.Incoming}"; + + if (versions.Current < versions.Incoming) + NotificationHelper.ShowInformation( + title: "Update Available", + text: newVersionString, + onClick: () => _ = Updater.BeginUpdateAsync()); + } + break; } } diff --git a/src/Ryujinx/Updater.cs b/src/Ryujinx/Updater.cs index f8b4b2beb9..56c4acea28 100644 --- a/src/Ryujinx/Updater.cs +++ b/src/Ryujinx/Updater.cs @@ -43,7 +43,18 @@ internal static class Updater private const int ConnectionCount = 4; private static string _buildVer; - private static string _platformExt; + + private static readonly string _platformExt = + RunningPlatform.IsMacOS + ? "macos_universal.app.tar.gz" + : RunningPlatform.IsWindows + ? "win_x64.zip" + : RunningPlatform.IsX64Linux + ? "linux_x64.tar.gz" + : RunningPlatform.IsArmLinux + ? "linux_arm64.tar.gz" + : throw new PlatformNotSupportedException(); + private static string _buildUrl; private static long _buildSize; private static bool _updateSuccessful; @@ -51,30 +62,8 @@ internal static class Updater private static readonly string[] _windowsDependencyDirs = []; - public static async Task BeginUpdateAsync(bool showVersionUpToDate = false) + public static async Task> CheckVersionAsync(bool showVersionUpToDate = false) { - if (_running) - { - return; - } - - _running = true; - - // Detect current platform - if (OperatingSystem.IsMacOS()) - { - _platformExt = "macos_universal.app.tar.gz"; - } - else if (OperatingSystem.IsWindows()) - { - _platformExt = "win_x64.zip"; - } - else if (OperatingSystem.IsLinux()) - { - string arch = RuntimeInformation.OSArchitecture == Architecture.Arm64 ? "arm64" : "x64"; - _platformExt = $"linux_{arch}.tar.gz"; - } - if (!Version.TryParse(Program.Version, out Version currentVersion)) { Logger.Error?.Print(LogClass.Application, $"Failed to convert the current {RyujinxApp.FullAppName} version!"); @@ -85,7 +74,7 @@ await ContentDialogHelper.CreateWarningDialog( _running = false; - return; + return default; } Logger.Info?.Print(LogClass.Application, "Checking for updates."); @@ -123,7 +112,7 @@ await ContentDialogHelper.CreateWarningDialog( _running = false; - return; + return default; } break; @@ -149,7 +138,7 @@ await ContentDialogHelper.CreateWarningDialog( _running = false; - return; + return default; } } catch (Exception exception) @@ -161,7 +150,7 @@ await ContentDialogHelper.CreateErrorDialog( _running = false; - return; + return default; } if (!Version.TryParse(_buildVer, out Version newVersion)) @@ -174,9 +163,23 @@ await ContentDialogHelper.CreateWarningDialog( _running = false; + return (currentVersion, null); + } + + return (currentVersion, newVersion); + } + + public static async Task BeginUpdateAsync(bool showVersionUpToDate = false) + { + if (_running) + { return; } + _running = true; + + (Version currentVersion, Version newVersion) = (await CheckVersionAsync(showVersionUpToDate)).OrDefault(); + if (newVersion <= currentVersion) { if (showVersionUpToDate) diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs index 95364873b5..d7235ef27f 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs @@ -15,7 +15,7 @@ public class ConfigurationFileFormat /// /// The current version of the file format /// - public const int CurrentVersion = 64; + public const int CurrentVersion = 65; /// /// Version of the configuration file format @@ -163,9 +163,14 @@ public class ConfigurationFileFormat public bool EnableDiscordIntegration { get; set; } /// - /// Checks for updates when Ryujinx starts when enabled + /// DEPRECATED: Checks for updates when Ryujinx starts when enabled /// public bool CheckUpdatesOnStart { get; set; } + + /// + /// Checks for updates when Ryujinx starts when enabled, either prompting when an update is found or just showing a notification. + /// + public UpdaterType UpdateCheckerType { get; set; } /// /// Show "Confirm Exit" Dialog diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs index 36f42d8b3c..d82e557916 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs @@ -45,6 +45,7 @@ in _migrations.OrderBy(x => x.Key)) EnableDiscordIntegration.Value = cff.EnableDiscordIntegration; CheckUpdatesOnStart.Value = cff.CheckUpdatesOnStart; + UpdateCheckerType.Value = cff.UpdateCheckerType; ShowConfirmExit.Value = cff.ShowConfirmExit; RememberWindowState.Value = cff.RememberWindowState; ShowTitleBar.Value = cff.ShowTitleBar; @@ -431,7 +432,8 @@ in _migrations.OrderBy(x => x.Key)) }), (62, static cff => cff.RainbowSpeed = 1f), (63, static cff => cff.MatchSystemTime = false), - (64, static cff => cff.LoggingEnableAvalonia = false) + (64, static cff => cff.LoggingEnableAvalonia = false), + (65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off) ); } } diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs index 8fbe20e055..b511b32dd6 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs @@ -1,6 +1,7 @@ using ARMeilleure; using Gommon; using Ryujinx.Ava.Utilities.Configuration.System; +using Ryujinx.Ava.Utilities.Configuration.UI; using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Hid; @@ -767,6 +768,11 @@ void Apply(DirtyHack hack, int value = 0) /// Checks for updates when Ryujinx starts when enabled /// public ReactiveObject CheckUpdatesOnStart { get; private set; } + + /// + /// Checks for updates when Ryujinx starts when enabled, either prompting when an update is found or just showing a notification. + /// + public ReactiveObject UpdateCheckerType { get; private set; } /// /// Show "Confirm Exit" Dialog @@ -804,6 +810,7 @@ private ConfigurationState() Hacks = new HacksSection(); EnableDiscordIntegration = new ReactiveObject(); CheckUpdatesOnStart = new ReactiveObject(); + UpdateCheckerType = new ReactiveObject(); ShowConfirmExit = new ReactiveObject(); RememberWindowState = new ReactiveObject(); ShowTitleBar = new ReactiveObject(); diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs index f8fbc90d81..6374b4680c 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs @@ -175,7 +175,7 @@ public void LoadDefault() System.SystemTimeOffset.Value = 0; System.EnableDockedMode.Value = true; EnableDiscordIntegration.Value = true; - CheckUpdatesOnStart.Value = true; + UpdateCheckerType.Value = UpdaterType.PromptAtStartup; ShowConfirmExit.Value = true; RememberWindowState.Value = true; ShowTitleBar.Value = !OperatingSystem.IsWindows(); diff --git a/src/Ryujinx/Utilities/Configuration/UI/UpdaterType.cs b/src/Ryujinx/Utilities/Configuration/UI/UpdaterType.cs new file mode 100644 index 0000000000..2ab17a497e --- /dev/null +++ b/src/Ryujinx/Utilities/Configuration/UI/UpdaterType.cs @@ -0,0 +1,13 @@ +using Ryujinx.Common.Utilities; +using System.Text.Json.Serialization; + +namespace Ryujinx.Ava.Utilities.Configuration.UI +{ + [JsonConverter(typeof(TypedStringEnumConverter))] + public enum UpdaterType + { + Off, + PromptAtStartup, + CheckInBackground + } +} From 1eb78872d803e2022e47796cfd00ecc703b4bc7e Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Mon, 10 Feb 2025 19:51:28 -0600 Subject: [PATCH 2/7] misc: chore: annoyed I missed this, it's very obvious --- src/Ryujinx/Utilities/Configuration/ConfigurationState.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs index 6374b4680c..7e4b794455 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs @@ -56,6 +56,7 @@ public ConfigurationFileFormat ToFileFormat() DockedMode = System.EnableDockedMode, EnableDiscordIntegration = EnableDiscordIntegration, CheckUpdatesOnStart = CheckUpdatesOnStart, + UpdateCheckerType = UpdateCheckerType, ShowConfirmExit = ShowConfirmExit, RememberWindowState = RememberWindowState, ShowTitleBar = ShowTitleBar, From 13388e972a105096161f619e8659ac7bb03ebaf1 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Mon, 10 Feb 2025 20:00:59 -0600 Subject: [PATCH 3/7] UI: RPC: add image asset for Bluey: The Video Game --- src/Ryujinx.Common/TitleIDs.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Ryujinx.Common/TitleIDs.cs b/src/Ryujinx.Common/TitleIDs.cs index 28d332a616..76d873f608 100644 --- a/src/Ryujinx.Common/TitleIDs.cs +++ b/src/Ryujinx.Common/TitleIDs.cs @@ -219,6 +219,7 @@ public static string GetDiscordGameAsset(string titleId) //Misc Games "010056e00853a000", // A Hat in Time "0100fd1014726000", // Baldurs Gate: Dark Alliance + "01008c2019598000", // Bluey: The Video Game "0100c6800b934000", // Brawlhalla "0100dbf01000a000", // Burnout Paradise Remastered "0100744001588000", // Cars 3: Driven to Win From 1024aa87577d8a46f2112ee9552b2767b5a025db Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Mon, 10 Feb 2025 22:13:58 -0600 Subject: [PATCH 4/7] UI: Change the background updater notification to a persistent button on the status bar when not in a game --- src/Ryujinx/Assets/locales.json | 27 ++++++++++++++++++- .../UI/ViewModels/MainWindowViewModel.cs | 8 ++++++ .../UI/Views/Main/MainStatusBarView.axaml | 19 +++++++++++-- src/Ryujinx/UI/Windows/MainWindow.axaml.cs | 9 +------ 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index ad7b4286f9..cba9b2ce9c 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -17747,6 +17747,31 @@ "zh_TW": "更新已停用!" } }, + { + "ID": "UpdaterBackgroundStatusBarButtonText", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Update Available!", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "ControllerSettingsRotate90", "Translations": { @@ -23873,4 +23898,4 @@ } } ] -} \ No newline at end of file +} diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 113c00a5a9..2273470303 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -7,6 +7,7 @@ using Avalonia.Platform.Storage; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; using DynamicData; using DynamicData.Binding; using FluentAvalonia.UI.Controls; @@ -104,6 +105,13 @@ public partial class MainWindowViewModel : BaseModel [ObservableProperty] private bool _isSubMenuOpen; [ObservableProperty] private ApplicationContextMenu _listAppContextMenu; [ObservableProperty] private ApplicationContextMenu _gridAppContextMenu; + [ObservableProperty] private bool _updateAvailable; + + public static AsyncRelayCommand UpdateCommand => Commands.Create(async () => + { + if (Updater.CanUpdate(true)) + await Updater.BeginUpdateAsync(true); + }); private bool _showLoadProgress; private bool _isGameRunning; diff --git a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml index a0259c723c..7c3199386d 100644 --- a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml +++ b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml @@ -23,7 +23,7 @@ Background="{DynamicResource ThemeContentBackgroundColor}" DockPanel.Dock="Bottom" IsVisible="{Binding ShowMenuAndStatusBar}" - ColumnDefinitions="Auto,Auto,*,Auto,Auto"> + ColumnDefinitions="Auto,Auto,*,Auto,Auto,Auto"> - + + + + diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs index 7354555410..2b6de9d750 100644 --- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs @@ -413,15 +413,8 @@ await Updater.BeginUpdateAsync() case UpdaterType.CheckInBackground: if ((await Updater.CheckVersionAsync()).TryGet(out (Version Current, Version Incoming) versions)) { - string newVersionString = ReleaseInformation.IsCanaryBuild - ? $"Canary {versions.Current} -> Canary {versions.Incoming}" - : $"{versions.Current} -> {versions.Incoming}"; - if (versions.Current < versions.Incoming) - NotificationHelper.ShowInformation( - title: "Update Available", - text: newVersionString, - onClick: () => _ = Updater.BeginUpdateAsync()); + Dispatcher.UIThread.Post(() => RyujinxApp.MainWindow.ViewModel.UpdateAvailable = true); } break; } From daa648dc408005c5b38153ec189ee9b0fd34560a Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Mon, 10 Feb 2025 22:25:04 -0600 Subject: [PATCH 5/7] UI: Correct visibility for new background update button --- src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml index 7c3199386d..78fefc3465 100644 --- a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml +++ b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml @@ -286,6 +286,7 @@ IsVisible="{Binding EnableNonGameRunningControls}" Orientation="Horizontal"> - + RyujinxApp.MainWindow.ViewModel.UpdateAvailable = true); + Dispatcher.UIThread.Post(() => RyujinxApp.MainWindow.ViewModel.UpdateAvailable = versions.Current < versions.Incoming); } break; } diff --git a/src/Ryujinx/Updater.cs b/src/Ryujinx/Updater.cs index 56c4acea28..338e9de430 100644 --- a/src/Ryujinx/Updater.cs +++ b/src/Ryujinx/Updater.cs @@ -163,7 +163,7 @@ await ContentDialogHelper.CreateWarningDialog( _running = false; - return (currentVersion, null); + return default; } return (currentVersion, newVersion); @@ -178,7 +178,11 @@ public static async Task BeginUpdateAsync(bool showVersionUpToDate = false) _running = true; - (Version currentVersion, Version newVersion) = (await CheckVersionAsync(showVersionUpToDate)).OrDefault(); + Optional<(Version, Version)> versionTuple = await CheckVersionAsync(showVersionUpToDate); + + if (_running is false || !versionTuple.HasValue) return; + + (Version currentVersion, Version newVersion) = versionTuple.Value; if (newVersion <= currentVersion) {