Add support for rendering message embeds

This commit is contained in:
Stone_Red
2026-07-19 19:55:43 +02:00
parent ccbeb94aee
commit 7fab3543eb
8 changed files with 67 additions and 12 deletions
+23
View File
@@ -0,0 +1,23 @@
using Avalonia.Data.Converters;
using System.Globalization;
namespace Decho.Converters;
public static class StringConverters
{
public static readonly IValueConverter IsNotNullOrEmpty = new IsNotNullOrEmptyConverter();
private sealed class IsNotNullOrEmptyConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
return value is string s && !string.IsNullOrEmpty(s);
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}
+4 -1
View File
@@ -10,7 +10,8 @@ public sealed class MessageModel(
string channelName, string channelName,
string? serverUrl = null, string? serverUrl = null,
List<AttachmentDto>? attachments = null, List<AttachmentDto>? attachments = null,
ReplyRefDto? replyTo = null) ReplyRefDto? replyTo = null,
List<EmbedDto>? embeds = null)
{ {
public string Id { get; } = id; public string Id { get; } = id;
@@ -27,4 +28,6 @@ public sealed class MessageModel(
public List<AttachmentDto> Attachments { get; } = attachments ?? []; public List<AttachmentDto> Attachments { get; } = attachments ?? [];
public ReplyRefDto? ReplyTo { get; } = replyTo; public ReplyRefDto? ReplyTo { get; } = replyTo;
public List<EmbedDto> Embeds { get; } = embeds ?? [];
} }
+2 -1
View File
@@ -334,6 +334,7 @@ internal sealed class ChannelService : IChannelService
dto.ChannelName, dto.ChannelName,
entry.Server.ServerUrl, entry.Server.ServerUrl,
attachments, attachments,
dto.ReplyTo); dto.ReplyTo,
dto.Embeds);
} }
} }
+2 -8
View File
@@ -1,6 +1,3 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Decho.Models; using Decho.Models;
using EchoHub.Client.Config; using EchoHub.Client.Config;
@@ -9,10 +6,6 @@ using EchoHub.Client.UI.Dialogs;
using EchoHub.Core.Constants; using EchoHub.Core.Constants;
using EchoHub.Core.DTOs; using EchoHub.Core.DTOs;
using MsBox.Avalonia;
using MsBox.Avalonia.Base;
using MsBox.Avalonia.Enums;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
@@ -167,7 +160,8 @@ public sealed class ConnectionService : IConnectionService
dto.ChannelName, dto.ChannelName,
entry.Server.ServerUrl, entry.Server.ServerUrl,
attachments, attachments,
dto.ReplyTo); dto.ReplyTo,
dto.Embeds ?? []);
} }
internal ServerConnection? GetConnection(string serverUrl) internal ServerConnection? GetConnection(string serverUrl)
+1 -1
View File
@@ -45,4 +45,4 @@ public interface IChannelService
Task SendUrlAsync(string serverUrl, string channelName, string url, string? size); Task SendUrlAsync(string serverUrl, string channelName, string url, string? size);
Task<List<MessageModel>> GetHistoryAsync(string serverUrl, string channelName, int count = 50, int offset = 0); Task<List<MessageModel>> GetHistoryAsync(string serverUrl, string channelName, int count = 50, int offset = 0);
} }
+4
View File
@@ -54,6 +54,10 @@ public sealed class MessageViewModel(MessageModel model) : ViewModelBase
public bool HasAttachments => Attachments.Count > 0; public bool HasAttachments => Attachments.Count > 0;
public IReadOnlyList<EmbedDto> Embeds => Model.Embeds;
public bool HasEmbeds => Embeds.Count > 0;
public bool ShowContent => !string.IsNullOrEmpty(Content); public bool ShowContent => !string.IsNullOrEmpty(Content);
public string TimeText public string TimeText
+30
View File
@@ -2,6 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Decho.ViewModels" xmlns:vm="using:Decho.ViewModels"
xmlns:dto="using:EchoHub.Core.DTOs" xmlns:dto="using:EchoHub.Core.DTOs"
xmlns:conv="using:Decho.Converters"
x:Class="Decho.Views.MessageItemView" x:Class="Decho.Views.MessageItemView"
x:DataType="vm:MessageViewModel"> x:DataType="vm:MessageViewModel">
<Grid Margin="5" ColumnDefinitions="Auto, *"> <Grid Margin="5" ColumnDefinitions="Auto, *">
@@ -67,6 +68,35 @@
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
</ItemsControl> </ItemsControl>
<ItemsControl ItemsSource="{Binding Embeds}"
IsVisible="{Binding HasEmbeds}"
Margin="0 4 0 0">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="dto:EmbedDto">
<Border BorderThickness="3 0 0 0"
BorderBrush="{Binding ThemeColor, TargetNullValue=Gray}"
CornerRadius="4"
Background="{DynamicResource UiTheme01}"
Padding="10"
Margin="0 2 0 2">
<StackPanel Spacing="2">
<TextBlock Text="{Binding SiteName}"
FontSize="11"
Opacity="0.6"
IsVisible="{Binding SiteName, Converter={x:Static conv:StringConverters.IsNotNullOrEmpty}}" />
<TextBlock Text="{Binding Title}"
FontWeight="Bold"
TextWrapping="Wrap" />
<TextBlock Text="{Binding Description}"
FontSize="12"
Opacity="0.8"
TextWrapping="Wrap"
IsVisible="{Binding Description, Converter={x:Static conv:StringConverters.IsNotNullOrEmpty}}" />
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel> </StackPanel>
</Grid> </Grid>
</UserControl> </UserControl>
+1 -1
View File
@@ -267,7 +267,7 @@ public partial class MessageItemView : UserControl
} }
catch catch
{ {
// Image failed to load filename is shown as fallback // Image failed to load filename is shown as fallback
} }
} }