Add Url property to HyperLink; simplify converter link handling; add http/https scheme guard

Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-02-24 15:58:26 +00:00
parent f6ded3fc8c
commit 3daf49cb52
2 changed files with 34 additions and 18 deletions

View File

@@ -1,12 +1,9 @@
using System; using System;
using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using Avalonia.Controls.Documents; using Avalonia.Controls.Documents;
using Avalonia.Data.Converters; using Avalonia.Data.Converters;
using Avalonia.Media; using Avalonia.Media;
using CommunityToolkit.Mvvm.Input;
using DiscordChatExporter.Gui.Utils.Extensions;
using DiscordChatExporter.Gui.Views.Controls; using DiscordChatExporter.Gui.Views.Controls;
using Markdig; using Markdig;
using Markdig.Syntax; using Markdig.Syntax;
@@ -82,18 +79,16 @@ public class MarkdownToInlinesConverter : IValueConverter
break; break;
} }
case LinkInline link when link.Url is not null: case LinkInline link when !string.IsNullOrWhiteSpace(link.Url):
{ {
var text = string.Concat(
link.OfType<LiteralInline>().Select(l => l.Content.ToString())
);
var url = link.Url;
inlines.Add( inlines.Add(
new InlineUIContainer( new InlineUIContainer(
new HyperLink new HyperLink
{ {
Text = text, Text = string.Concat(
Command = new RelayCommand(() => Process.StartShellExecute(url)), link.OfType<LiteralInline>().Select(l => l.Content.ToString())
),
Url = link.Url,
} }
) )
); );

View File

@@ -1,7 +1,10 @@
using System.Windows.Input; using System;
using System.Diagnostics;
using System.Windows.Input;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using DiscordChatExporter.Gui.Utils.Extensions;
namespace DiscordChatExporter.Gui.Views.Controls; namespace DiscordChatExporter.Gui.Views.Controls;
@@ -16,6 +19,12 @@ public partial class HyperLink : UserControl
public static readonly StyledProperty<object?> CommandParameterProperty = public static readonly StyledProperty<object?> CommandParameterProperty =
Button.CommandParameterProperty.AddOwner<HyperLink>(); Button.CommandParameterProperty.AddOwner<HyperLink>();
// If Url is set and Command is not set, clicking will open this URL in the default browser.
public static readonly StyledProperty<string?> UrlProperty = AvaloniaProperty.Register<
HyperLink,
string?
>(nameof(Url));
public HyperLink() => InitializeComponent(); public HyperLink() => InitializeComponent();
public string? Text public string? Text
@@ -36,14 +45,26 @@ public partial class HyperLink : UserControl
set => SetValue(CommandParameterProperty, value); set => SetValue(CommandParameterProperty, value);
} }
public string? Url
{
get => GetValue(UrlProperty);
set => SetValue(UrlProperty, value);
}
private void TextBlock_OnPointerReleased(object? sender, PointerReleasedEventArgs args) private void TextBlock_OnPointerReleased(object? sender, PointerReleasedEventArgs args)
{ {
if (Command is null) if (Command is not null)
return; {
if (Command.CanExecute(CommandParameter))
if (!Command.CanExecute(CommandParameter)) Command.Execute(CommandParameter);
return; }
else if (
Command.Execute(CommandParameter); !string.IsNullOrWhiteSpace(Url)
&& Uri.TryCreate(Url, UriKind.Absolute, out var uri)
&& (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
)
{
Process.StartShellExecute(uri.AbsoluteUri);
}
} }
} }