LANCommander/LANCommander.Launcher/Views/ShellView.axaml.cs

97 lines
3 KiB
C#
Raw Permalink Normal View History

2026-04-07 23:10:45 -05:00
using System;
using Avalonia.Controls;
2026-05-26 00:14:13 -05:00
using Avalonia.Input;
2026-04-07 23:10:45 -05:00
using Avalonia.Threading;
using LANCommander.Launcher.Services;
using LANCommander.Launcher.ViewModels;
2026-05-26 00:14:13 -05:00
using Microsoft.Extensions.DependencyInjection;
2026-04-07 23:10:45 -05:00
namespace LANCommander.Launcher.Views;
2026-04-07 23:10:45 -05:00
public partial class ShellView : UserControl
{
private ChatWindow? _chatWindow;
2026-05-09 19:42:41 -05:00
private ShellViewModel? _previousVm;
private System.ComponentModel.PropertyChangedEventHandler? _chatPropertyChangedHandler;
private EventHandler<(string threadTitle, string senderName)>? _chatMessageReceivedHandler;
2026-04-07 23:10:45 -05:00
public ShellView()
{
InitializeComponent();
2026-05-26 00:14:13 -05:00
KeyDown += OnKeyDown;
2026-04-07 23:10:45 -05:00
DataContextChanged += (_, _) =>
{
2026-05-09 19:42:41 -05:00
if (_previousVm != null)
_previousVm.OpenChatRequested -= OnOpenChatRequested;
2026-04-07 23:10:45 -05:00
if (DataContext is ShellViewModel vm)
2026-05-09 19:42:41 -05:00
{
2026-04-07 23:10:45 -05:00
vm.OpenChatRequested += OnOpenChatRequested;
2026-05-09 19:42:41 -05:00
_previousVm = vm;
}
2026-04-07 23:10:45 -05:00
};
}
2026-05-26 00:14:13 -05:00
private void OnKeyDown(object? sender, KeyEventArgs e)
{
if (e.Key == Key.Escape && !e.Handled)
{
var nav = App.Services.GetService<INavigationService>();
if (nav is { CanGoBack: true })
{
nav.GoBack();
e.Handled = true;
}
}
}
2026-04-07 23:10:45 -05:00
private void OnOpenChatRequested(object? sender, System.EventArgs e)
{
if (DataContext is not ShellViewModel vm)
return;
if (_chatWindow == null)
{
_chatWindow = new ChatWindow
{
DataContext = vm.Chat,
};
// Wire scroll-to-bottom when new messages arrive in the active thread
2026-05-09 19:42:41 -05:00
_chatPropertyChangedHandler = (_, args) =>
2026-04-07 23:10:45 -05:00
{
if (args.PropertyName == nameof(ChatWindowViewModel.SelectedThread))
_chatWindow?.ScrollToBottom();
};
2026-05-09 19:42:41 -05:00
vm.Chat.PropertyChanged += _chatPropertyChangedHandler;
2026-04-07 23:10:45 -05:00
// When a message arrives while the window is inactive, activate it
2026-05-09 19:42:41 -05:00
_chatMessageReceivedHandler = (_, _) =>
2026-04-07 23:10:45 -05:00
{
if (!_chatWindow.IsVisible)
return; // only activate, don't show — the notification handles that
Dispatcher.UIThread.InvokeAsync(_chatWindow.Activate);
};
2026-05-09 19:42:41 -05:00
vm.Chat.MessageReceivedWhileInactive += _chatMessageReceivedHandler;
_chatWindow.Closed += (_, _) =>
{
if (_chatPropertyChangedHandler != null)
vm.Chat.PropertyChanged -= _chatPropertyChangedHandler;
if (_chatMessageReceivedHandler != null)
vm.Chat.MessageReceivedWhileInactive -= _chatMessageReceivedHandler;
_chatPropertyChangedHandler = null;
_chatMessageReceivedHandler = null;
_chatWindow = null;
};
2026-04-07 23:10:45 -05:00
}
if (_chatWindow.IsVisible)
_chatWindow.Activate();
else
_chatWindow.Show();
}
}