85893ea709
The first true decomposition of the 4105-line god-object, not another partial shuffle. MainViewModel.Chat.cs 194 -> 44 lines of thin delegation; all chat behavior now lives in a self-contained Services/ChatOverlayLayer.cs (199): - Owns the message buffer (Messages), ChatBoxRenderer, fade + mock-preview timers, per-source preview renders, and the live-output RenderFrame path. - The VM keeps only the binding surface: ChatMessages delegates to _chatLayer.Messages (so XAML ItemsSource + LeftPanel CollectionChanged hold), CanAddYouTubeChat / ShowChatInactiveMessage stay computed on the VM (OnPropertyChanged raised from VM setters + XAML-bound), and thin forwards. - Scenes handed in as args (no Func seam), so the layer owns no scene graph. An AI reading ChatOverlayLayer.cs now sees the entire chat feature in one self-contained unit. Zero behavior change; build 0 warnings; 246 pass, only the 2 known failures. Docs: ViewModels/index.md tracker updated in same commit.
45 lines
1.5 KiB
C#
45 lines
1.5 KiB
C#
using System.Collections.ObjectModel;
|
|
using System.Linq;
|
|
using ytLive.Helpers;
|
|
using ytLive.Models;
|
|
using ytLive.Services;
|
|
|
|
namespace ytLive.ViewModels;
|
|
|
|
public partial class MainViewModel : ViewModelBase
|
|
{
|
|
|
|
private readonly ChatOverlayLayer _chatLayer;
|
|
|
|
/// <summary>The live chat message buffer — the same collection the
|
|
/// <see cref="ChatOverlayLayer"/> owns; here so XAML can bind it and the
|
|
/// left panel can subscribe to its changes.</summary>
|
|
public ObservableCollection<ChatMessage> ChatMessages => _chatLayer.Messages;
|
|
|
|
/// <summary>The Add → YouTube Chat menu item: enabled only while no chat layer exists
|
|
/// anywhere — one chat overlay per layout.</summary>
|
|
public bool CanAddYouTubeChat
|
|
=> StagedScene != null
|
|
&& !Scenes.Any(s => s.Elements.OfType<Source>().Any(e => e.Type == SourceType.ChatBox));
|
|
|
|
public bool ShowChatInactiveMessage => !IsLive;
|
|
|
|
private void OnChatMessageReceived(ChatMessage message)
|
|
=> _chatLayer.OnMessageReceived(message, Scenes);
|
|
|
|
private void UpdateChatBoxPreview(Source chatBox, IReadOnlyList<ChatMessage>? messages = null)
|
|
=> _chatLayer.UpdatePreview(chatBox, messages);
|
|
|
|
private VideoFrame? RenderChatBox(Source chatBox)
|
|
=> _chatLayer.RenderFrame(chatBox);
|
|
|
|
private void StartMockChatPreview()
|
|
=> _chatLayer.StartMockPreview(Scenes);
|
|
|
|
private void StopMockChatPreview()
|
|
=> _chatLayer.StopMockPreview();
|
|
|
|
private void UpdateActiveChatBoxPreviews()
|
|
=> _chatLayer.UpdateConfiguredBoxes(Scenes);
|
|
}
|