Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 42 additions & 18 deletions Services/DialogService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ public class DialogService : IDialogService
{
private readonly Func<XamlRoot?> _xamlRootFactory;

// Wrap and cap plain messages so short notices do not expand to the dialog's max width.
private static TextBlock CreateMessageText(string message) => new()
{
Text = message,
TextWrapping = TextWrapping.Wrap,
MaxWidth = 280,
};

public DialogService(Func<XamlRoot?> xamlRootFactory)
{
_xamlRootFactory = xamlRootFactory;
Expand Down Expand Up @@ -655,20 +663,11 @@ void UpdateLanAddressText()
public async Task<bool> ShowConfirmationAsync(string title, string message, string? confirmText = null,
string? cancelText = null, bool isDanger = false)
{
confirmText ??= L.Dialog_OK;
cancelText ??= L.Dialog_Cancel;
var content = new TextBlock
{
Text = message,
TextWrapping = TextWrapping.Wrap,
MaxWidth = 280
};

var dialog = CreateDialog();
dialog.Title = title;
dialog.Content = content;
dialog.PrimaryButtonText = confirmText;
dialog.CloseButtonText = cancelText;
dialog.Content = CreateMessageText(message);
dialog.PrimaryButtonText = confirmText ?? L.Dialog_OK;
dialog.CloseButtonText = cancelText ?? L.Dialog_Cancel;
dialog.DefaultButton = isDanger ? ContentDialogButton.None : ContentDialogButton.Primary;

if (isDanger && Application.Current.Resources.TryGetValue("DangerAccentButtonStyle", out var style) &&
Expand Down Expand Up @@ -728,7 +727,7 @@ public async Task ShowErrorAsync(string title, string message, XamlRoot? xamlRoo
{
var dialog = CreateDialog(xamlRoot);
dialog.Title = title;
dialog.Content = message;
dialog.Content = CreateMessageText(message);
dialog.CloseButtonText = L.Dialog_OK;
await dialog.ShowAsync();
}
Expand Down Expand Up @@ -1005,6 +1004,19 @@ public async Task ShowShareLinkDialogAsync(string serverName, string link)

// ── App update confirm ────────────────────────────────────────────────

/// <summary>
/// Content width of the update dialog's notes list, inside ContentDialog's own padding.
/// Sized so a typical changelog line still fits on one row; longer ones wrap onto the
/// hanging indent that <see cref="BuildNoteLine"/> sets up, which is why it can stay
/// well below what the longest line would need. It also has to cover the bullet column
/// and <see cref="ScrollBarGutter"/>, neither of which holds text, so trimming it back
/// toward the bare text width costs a good dozen characters a line.
/// </summary>
private const double UpdateContentWidth = 392;

/// <summary>Right gutter kept clear inside the notes list for the overlay scrollbar.</summary>
private const double ScrollBarGutter = 14;

public async Task<bool> ShowUpdateConfirmDialogAsync(
Version newVersion, IReadOnlyList<string> notes)
{
Expand All @@ -1021,7 +1033,7 @@ public async Task<bool> ShowUpdateConfirmDialogAsync(
// ContentDialog clips tall content instead of letting the notes list scroll.
// Fixed width keeps the dialog compact — without it the longest note line
// stretches it toward ContentDialog's max width.
var root = new Grid { Width = 380 };
var root = new Grid { Width = UpdateContentWidth };
root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); // notes header
root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); // notes list

Expand All @@ -1038,17 +1050,25 @@ public async Task<bool> ShowUpdateConfirmDialogAsync(
Grid.SetRow(notesHeader, 0);
root.Children.Add(notesHeader);

var list = new StackPanel { Spacing = 4 };
var list = new StackPanel { Spacing = 6 };
foreach (var line in notes)
list.Children.Add(BuildNoteLine(line));

var scroller = new ScrollViewer
{
Content = list,
MaxHeight = 220,
MaxHeight = 240,
VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
HorizontalScrollMode = ScrollMode.Disabled,
HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
// WinUI scrollbars are overlays: they paint on top of the content rather
// than taking layout space, so without this gutter the expanded mouse
// scrollbar covers the last dozen pixels of every note line. Whether it
// overlays at all depends on the "always show scrollbars" accessibility
// setting, so reserving the space is the only way to get the same result
// under both. The gutter is unconditional because whether the list will
// overflow is not known until after layout.
Padding = new Thickness(0, 0, ScrollBarGutter, 0),
};
Grid.SetRow(scroller, 1);
root.Children.Add(scroller);
Expand All @@ -1072,15 +1092,19 @@ private static Grid BuildNoteLine(string text)
var bullet = new TextBlock
{
Text = "•",
FontSize = 13,
FontSize = 14,
LineHeight = 20,
Opacity = 0.65,
VerticalAlignment = VerticalAlignment.Top,
};

var body = new TextBlock
{
Text = text,
FontSize = 13,
FontSize = 14,
// Default leading is tight for CJK once a line wraps; 20 keeps a wrapped note
// readable without spacing the list out.
LineHeight = 20,
TextWrapping = TextWrapping.Wrap,
};
Grid.SetColumn(body, 1);
Expand Down
Loading