mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-12-12 07:36:59 +00:00
UI: Improve "Show Changelog" button in the updater
Now it no longer causes the dialog to disappear (which then promptly re-appears so you can click yes/no to accept/deny the update)
This commit is contained in:
parent
e8751e1c40
commit
862a686c5e
4 changed files with 164 additions and 43 deletions
|
|
@ -88,14 +88,10 @@ namespace Ryujinx.Ava.Systems
|
||||||
{
|
{
|
||||||
if (showVersionUpToDate)
|
if (showVersionUpToDate)
|
||||||
{
|
{
|
||||||
UserResult userResult = await ContentDialogHelper.CreateUpdaterUpToDateInfoDialog(
|
await ContentDialogHelper.CreateUpdaterUpToDateInfoDialog(
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
|
||||||
string.Empty);
|
string.Empty,
|
||||||
|
_versionResponse.ReleaseUrlFormat.Format(currentVersion));
|
||||||
if (userResult is UserResult.Ok)
|
|
||||||
{
|
|
||||||
OpenHelper.OpenUrl(_versionResponse.ReleaseUrlFormat.Format(currentVersion));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Application, "Up to date.");
|
Logger.Info?.Print(LogClass.Application, "Up to date.");
|
||||||
|
|
|
||||||
|
|
@ -60,14 +60,10 @@ namespace Ryujinx.Ava.Systems
|
||||||
{
|
{
|
||||||
if (showVersionUpToDate)
|
if (showVersionUpToDate)
|
||||||
{
|
{
|
||||||
UserResult userResult = await ContentDialogHelper.CreateUpdaterUpToDateInfoDialog(
|
await ContentDialogHelper.CreateUpdaterUpToDateInfoDialog(
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
|
||||||
string.Empty);
|
string.Empty,
|
||||||
|
changelogUrl: _versionResponse.ReleaseUrlFormat.Format(currentVersion));
|
||||||
if (userResult is UserResult.Ok)
|
|
||||||
{
|
|
||||||
OpenHelper.OpenUrl(_versionResponse.ReleaseUrlFormat.Format(currentVersion));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Application, "Up to date.");
|
Logger.Info?.Print(LogClass.Application, "Up to date.");
|
||||||
|
|
@ -106,22 +102,18 @@ namespace Ryujinx.Ava.Systems
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Application, $"Version found: {newVersionString.Replace("→", "->")}");
|
Logger.Info?.Print(LogClass.Application, $"Version found: {newVersionString.Replace("→", "->")}");
|
||||||
|
|
||||||
RequestUserToUpdate:
|
|
||||||
// Show a message asking the user if they want to update
|
// Show a message asking the user if they want to update
|
||||||
UserResult shouldUpdate = await ContentDialogHelper.CreateUpdaterChoiceDialog(
|
UserResult shouldUpdate = await ContentDialogHelper.CreateUpdaterChoiceDialog(
|
||||||
LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
|
LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
|
||||||
LocaleManager.Instance[LocaleKeys.RyujinxUpdaterMessage],
|
LocaleManager.Instance[LocaleKeys.RyujinxUpdaterMessage],
|
||||||
newVersionString);
|
newVersionString,
|
||||||
|
ReleaseInformation.GetChangelogUrl(currentVersion, newVersion));
|
||||||
|
|
||||||
switch (shouldUpdate)
|
switch (shouldUpdate)
|
||||||
{
|
{
|
||||||
case UserResult.Yes:
|
case UserResult.Yes:
|
||||||
await UpdateRyujinx(_versionResponse.ArtifactUrl);
|
await UpdateRyujinx(_versionResponse.ArtifactUrl);
|
||||||
break;
|
break;
|
||||||
// Secondary button maps to no, which in this case is the show changelog button.
|
|
||||||
case UserResult.No:
|
|
||||||
OpenHelper.OpenUrl(ReleaseInformation.GetChangelogUrl(currentVersion, newVersion));
|
|
||||||
goto RequestUserToUpdate;
|
|
||||||
default:
|
default:
|
||||||
_running = false;
|
_running = false;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ using FluentAvalonia.Core;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
@ -103,6 +104,25 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
return await ShowContentDialog(title, content, primaryButton, secondaryButton, closeButton, primaryButtonResult, deferResetEvent, deferCloseAction);
|
return await ShowContentDialog(title, content, primaryButton, secondaryButton, closeButton, primaryButtonResult, deferResetEvent, deferCloseAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async static Task<UserResult> ShowTextDialogWithButton(
|
||||||
|
string title,
|
||||||
|
string primaryText,
|
||||||
|
string secondaryText,
|
||||||
|
string primaryButton,
|
||||||
|
string secondaryButton,
|
||||||
|
string closeButton,
|
||||||
|
int iconSymbol,
|
||||||
|
string buttonText,
|
||||||
|
Action onClick,
|
||||||
|
UserResult primaryButtonResult = UserResult.Ok,
|
||||||
|
ManualResetEvent deferResetEvent = null,
|
||||||
|
TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> deferCloseAction = null)
|
||||||
|
{
|
||||||
|
Grid content = CreateTextDialogContentWithButton(primaryText, secondaryText, iconSymbol, buttonText, onClick);
|
||||||
|
|
||||||
|
return await ShowContentDialog(title, content, primaryButton, secondaryButton, closeButton, primaryButtonResult, deferResetEvent, deferCloseAction);
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task<UserResult> ShowDeferredContentDialog(
|
public static async Task<UserResult> ShowDeferredContentDialog(
|
||||||
Window window,
|
Window window,
|
||||||
string title,
|
string title,
|
||||||
|
|
@ -173,43 +193,109 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
MinHeight = 80,
|
MinHeight = 80,
|
||||||
};
|
};
|
||||||
|
|
||||||
SymbolIcon icon = new()
|
content.Children.Add(new SymbolIcon
|
||||||
{
|
{
|
||||||
Symbol = (Symbol)symbol,
|
Symbol = (Symbol)symbol,
|
||||||
Margin = new Thickness(10),
|
Margin = new Thickness(10),
|
||||||
FontSize = 40,
|
FontSize = 40,
|
||||||
FlowDirection = FlowDirection.LeftToRight,
|
FlowDirection = FlowDirection.LeftToRight,
|
||||||
VerticalAlignment = VerticalAlignment.Center,
|
VerticalAlignment = VerticalAlignment.Center,
|
||||||
};
|
GridColumn = 0,
|
||||||
|
GridRow = 0,
|
||||||
|
GridRowSpan = 2
|
||||||
|
});
|
||||||
|
|
||||||
Grid.SetColumn(icon, 0);
|
content.Children.Add(new TextBlock
|
||||||
Grid.SetRowSpan(icon, 2);
|
|
||||||
Grid.SetRow(icon, 0);
|
|
||||||
|
|
||||||
TextBlock primaryLabel = new()
|
|
||||||
{
|
{
|
||||||
Text = primaryText,
|
Text = primaryText,
|
||||||
Margin = new Thickness(5),
|
Margin = new Thickness(5),
|
||||||
TextWrapping = TextWrapping.Wrap,
|
TextWrapping = TextWrapping.Wrap,
|
||||||
MaxWidth = 450,
|
MaxWidth = 450,
|
||||||
};
|
GridColumn = 1,
|
||||||
|
GridRow = 0
|
||||||
|
});
|
||||||
|
|
||||||
TextBlock secondaryLabel = new()
|
content.Children.Add(new TextBlock
|
||||||
{
|
{
|
||||||
Text = secondaryText,
|
Text = secondaryText,
|
||||||
Margin = new Thickness(5),
|
Margin = new Thickness(5),
|
||||||
TextWrapping = TextWrapping.Wrap,
|
TextWrapping = TextWrapping.Wrap,
|
||||||
MaxWidth = 450,
|
MaxWidth = 450,
|
||||||
|
GridColumn = 1,
|
||||||
|
GridRow = 1
|
||||||
|
});
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Grid CreateTextDialogContentWithButton(string primaryText, string secondaryText, int symbol, string buttonName, Action onClick)
|
||||||
|
{
|
||||||
|
Grid content = new()
|
||||||
|
{
|
||||||
|
RowDefinitions = [new(), new(), new(GridLength.Star), new()],
|
||||||
|
ColumnDefinitions = [new(GridLength.Auto), new()],
|
||||||
|
|
||||||
|
MinHeight = 80,
|
||||||
};
|
};
|
||||||
|
|
||||||
Grid.SetColumn(primaryLabel, 1);
|
content.Children.Add(new SymbolIcon
|
||||||
Grid.SetColumn(secondaryLabel, 1);
|
{
|
||||||
Grid.SetRow(primaryLabel, 0);
|
Symbol = (Symbol)symbol,
|
||||||
Grid.SetRow(secondaryLabel, 1);
|
Margin = new Thickness(10),
|
||||||
|
FontSize = 40,
|
||||||
|
FlowDirection = FlowDirection.LeftToRight,
|
||||||
|
VerticalAlignment = VerticalAlignment.Center,
|
||||||
|
GridColumn = 0,
|
||||||
|
GridRow = 0,
|
||||||
|
GridRowSpan = 2
|
||||||
|
});
|
||||||
|
|
||||||
content.Children.Add(icon);
|
StackPanel buttonContent = new()
|
||||||
content.Children.Add(primaryLabel);
|
{
|
||||||
content.Children.Add(secondaryLabel);
|
Orientation = Orientation.Horizontal,
|
||||||
|
Spacing = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
buttonContent.Children.Add(new TextBlock
|
||||||
|
{
|
||||||
|
Text = buttonName,
|
||||||
|
Margin = new Thickness(2)
|
||||||
|
});
|
||||||
|
|
||||||
|
buttonContent.Children.Add(new SymbolIcon
|
||||||
|
{
|
||||||
|
FlowDirection = FlowDirection.LeftToRight,
|
||||||
|
Symbol = Symbol.Open
|
||||||
|
});
|
||||||
|
|
||||||
|
content.Children.Add(new TextBlock
|
||||||
|
{
|
||||||
|
Text = primaryText,
|
||||||
|
Margin = new Thickness(5),
|
||||||
|
TextWrapping = TextWrapping.Wrap,
|
||||||
|
MaxWidth = 450,
|
||||||
|
GridColumn = 1,
|
||||||
|
GridRow = 0
|
||||||
|
});
|
||||||
|
|
||||||
|
content.Children.Add(new TextBlock
|
||||||
|
{
|
||||||
|
Text = secondaryText,
|
||||||
|
Margin = new Thickness(5),
|
||||||
|
TextWrapping = TextWrapping.Wrap,
|
||||||
|
MaxWidth = 450,
|
||||||
|
GridColumn = 1,
|
||||||
|
GridRow = 1
|
||||||
|
});
|
||||||
|
|
||||||
|
content.Children.Add(new Button
|
||||||
|
{
|
||||||
|
Content = buttonContent,
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
|
Command = Commands.Create(onClick),
|
||||||
|
GridRow = 2,
|
||||||
|
GridColumnSpan = 2,
|
||||||
|
});
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
@ -282,15 +368,20 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
LocaleManager.Instance[LocaleKeys.InputDialogOk],
|
LocaleManager.Instance[LocaleKeys.InputDialogOk],
|
||||||
(int)Symbol.Important);
|
(int)Symbol.Important);
|
||||||
|
|
||||||
internal static async Task<UserResult> CreateUpdaterUpToDateInfoDialog(string primary, string secondaryText)
|
internal static async Task CreateUpdaterUpToDateInfoDialog(string primary, string secondaryText,
|
||||||
=> await ShowTextDialog(
|
string changelogUrl)
|
||||||
|
{
|
||||||
|
await ShowTextDialogWithButton(
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterTitle],
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterTitle],
|
||||||
primary,
|
primary,
|
||||||
secondaryText,
|
secondaryText,
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterShowChangelogMessage],
|
string.Empty,
|
||||||
string.Empty,
|
string.Empty,
|
||||||
LocaleManager.Instance[LocaleKeys.InputDialogOk],
|
LocaleManager.Instance[LocaleKeys.InputDialogOk],
|
||||||
(int)Symbol.Important);
|
(int)Symbol.Important,
|
||||||
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterShowChangelogMessage],
|
||||||
|
() => OpenHelper.OpenUrl(changelogUrl));
|
||||||
|
}
|
||||||
|
|
||||||
internal static async Task CreateWarningDialog(string primary, string secondaryText)
|
internal static async Task CreateWarningDialog(string primary, string secondaryText)
|
||||||
=> await ShowTextDialog(
|
=> await ShowTextDialog(
|
||||||
|
|
@ -340,7 +431,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
return response == UserResult.Yes;
|
return response == UserResult.Yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<UserResult> CreateUpdaterChoiceDialog(string title, string primary, string secondaryText)
|
internal static async Task<UserResult> CreateUpdaterChoiceDialog(string title, string primary, string secondaryText, string changelogUrl)
|
||||||
{
|
{
|
||||||
if (_isChoiceDialogOpen)
|
if (_isChoiceDialogOpen)
|
||||||
{
|
{
|
||||||
|
|
@ -349,14 +440,16 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
|
|
||||||
_isChoiceDialogOpen = true;
|
_isChoiceDialogOpen = true;
|
||||||
|
|
||||||
UserResult response = await ShowTextDialog(
|
UserResult response = await ShowTextDialogWithButton(
|
||||||
title,
|
title,
|
||||||
primary,
|
primary,
|
||||||
secondaryText,
|
secondaryText,
|
||||||
LocaleManager.Instance[LocaleKeys.InputDialogYes],
|
LocaleManager.Instance[LocaleKeys.InputDialogYes],
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterShowChangelogMessage],
|
string.Empty,
|
||||||
LocaleManager.Instance[LocaleKeys.InputDialogNo],
|
LocaleManager.Instance[LocaleKeys.InputDialogNo],
|
||||||
(int)Symbol.Help,
|
(int)Symbol.Help,
|
||||||
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterShowChangelogMessage],
|
||||||
|
() => OpenHelper.OpenUrl(changelogUrl),
|
||||||
UserResult.Yes);
|
UserResult.Yes);
|
||||||
|
|
||||||
_isChoiceDialogOpen = false;
|
_isChoiceDialogOpen = false;
|
||||||
|
|
|
||||||
40
src/Ryujinx/UI/Helpers/ControlExtensions.cs
Normal file
40
src/Ryujinx/UI/Helpers/ControlExtensions.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Helpers
|
||||||
|
{
|
||||||
|
public static class ControlExtensions
|
||||||
|
{
|
||||||
|
extension(Control ctrl)
|
||||||
|
{
|
||||||
|
public int GridRow
|
||||||
|
{
|
||||||
|
get => Grid.GetRow(ctrl);
|
||||||
|
set => Grid.SetRow(ctrl, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GridColumn
|
||||||
|
{
|
||||||
|
get => Grid.GetColumn(ctrl);
|
||||||
|
set => Grid.SetColumn(ctrl, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GridRowSpan
|
||||||
|
{
|
||||||
|
get => Grid.GetRowSpan(ctrl);
|
||||||
|
set => Grid.SetRowSpan(ctrl, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GridColumnSpan
|
||||||
|
{
|
||||||
|
get => Grid.GetColumnSpan(ctrl);
|
||||||
|
set => Grid.SetColumnSpan(ctrl, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GridIsSharedSizeScope
|
||||||
|
{
|
||||||
|
get => Grid.GetIsSharedSizeScope(ctrl);
|
||||||
|
set => Grid.SetIsSharedSizeScope(ctrl, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue