Add image viewer window

This commit is contained in:
Stone_Red
2026-07-17 16:22:22 +02:00
parent d77e6cf8bf
commit 831ffe46d2
5 changed files with 127 additions and 2 deletions
+4 -1
View File
@@ -797,7 +797,10 @@ public sealed class MainWindowViewModel : ViewModelBase
Avalonia.Threading.Dispatcher.UIThread.Post(() =>
{
serverVm.Channels.Add(channelVm);
if (!serverVm.Channels.Any(c => c.Name == channel.Name))
{
serverVm.Channels.Add(channelVm);
}
serverVm.SelectedChannel = channelVm;
foreach (MessageModel msg in joinResult.History)
+29
View File
@@ -0,0 +1,29 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
x:Class="Decho.Views.ImageViewerWindow"
Title="Image"
MinWidth="100"
MinHeight="100"
MaxWidth="1400"
MaxHeight="1000"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterOwner"
Background="{DynamicResource UiTheme03}">
<Border Padding="8">
<Grid RowDefinitions="*,Auto">
<Image x:Name="ImageView"
Stretch="Uniform"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
<Button Grid.Row="1"
Content="Close"
HorizontalAlignment="Right"
Width="80"
Margin="0 8 0 0"
Click="OnCloseClick" />
</Grid>
</Border>
</Window>
@@ -0,0 +1,34 @@
using Avalonia.Controls;
using Avalonia.Media.Imaging;
namespace Decho.Views;
public sealed partial class ImageViewerWindow : Window
{
public ImageViewerWindow()
{
InitializeComponent();
}
public ImageViewerWindow(Bitmap bitmap, string fileName)
{
InitializeComponent();
Title = fileName;
ImageView.Source = bitmap;
Opened += (_, _) =>
{
SizeToContent = SizeToContent.Manual;
if (Width > MaxWidth) Width = MaxWidth;
if (Height > MaxHeight) Height = MaxHeight;
MaxHeight = double.MaxValue;
MaxWidth = double.MaxValue;
};
}
private void OnCloseClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
Close();
}
}
+3 -1
View File
@@ -37,7 +37,9 @@
<Image Loaded="OnAttachmentImageLoaded"
MaxHeight="300"
MaxWidth="400"
HorizontalAlignment="Left" />
HorizontalAlignment="Left"
Cursor="Hand"
PointerPressed="OnAttachmentImagePointerPressed" />
<TextBlock Text="{Binding FileName}"
FontSize="11"
Opacity="0.7" />
+57
View File
@@ -321,4 +321,61 @@ public partial class MessageItemView : UserControl
// Ignore if temp file cannot be deleted
}
}
private async void OnAttachmentImagePointerPressed(object? sender, Avalonia.Input.PointerPressedEventArgs e)
{
if (sender is not Image image)
{
return;
}
if (image.DataContext is not AttachmentDto att)
{
return;
}
if (att.Kind != AttachmentKind.Image)
{
return;
}
if (DataContext is not MessageViewModel msg)
{
return;
}
if (msg.ImageCache.TryGetValue(att.Url, out Bitmap? cached))
{
ImageViewerWindow viewer = new ImageViewerWindow(cached, att.FileName);
if (TopLevel.GetTopLevel(this) is Window parent)
{
await viewer.ShowDialog(parent);
}
return;
}
MainWindowViewModel? mainVm = this.GetMainWindowViewModel();
if (mainVm is null)
{
return;
}
byte[]? bytes = await mainVm.ConnectionService.DownloadImageBytesAsync(
msg.ServerUrl ?? "", msg.Model.ChannelName, att.Url);
if (bytes is null || bytes.Length == 0)
{
return;
}
using MemoryStream stream = new MemoryStream(bytes);
Bitmap bitmap = new Bitmap(stream);
msg.ImageCache[att.Url] = bitmap;
ImageViewerWindow viewerWindow = new ImageViewerWindow(bitmap, att.FileName);
if (TopLevel.GetTopLevel(this) is Window parentWindow)
{
await viewerWindow.ShowDialog(parentWindow);
}
}
}