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;
private readonly AlertOverlayLayer _alertLayer;
/// The live chat message buffer — the same collection the
/// owns; here so XAML can bind it and the
/// left panel can subscribe to its changes.
public ObservableCollection ChatMessages => _chatLayer.Messages;
/// The Add → YouTube Chat menu item: enabled only while no chat layer exists
/// anywhere — one chat overlay per layout.
public bool CanAddYouTubeChat
=> StagedScene != null
&& !Scenes.Any(s => s.Elements.OfType().Any(e => e.Type == SourceType.ChatBox));
/// The Add → Stream Alerts menu item: one alert zone per layout
/// (multiple zones would double-play every event).
public bool CanAddAlerts
=> StagedScene != null
&& !Scenes.Any(s => s.Elements.OfType().Any(e => e.Type == SourceType.AlertBox));
public bool ShowChatInactiveMessage => !IsLive;
private void OnChatMessageReceived(ChatMessage message)
{
_chatLayer.OnMessageReceived(message, Scenes);
_alertLayer.OnMessageReceived(message, Scenes);
}
private void UpdateChatBoxPreview(Source chatBox, IReadOnlyList? messages = null)
=> _chatLayer.UpdatePreview(chatBox, messages);
private VideoFrame? RenderChatBox(Source chatBox)
=> _chatLayer.RenderFrame(chatBox);
private void UpdateAlertBoxPreview(Source alertBox)
=> _alertLayer.UpdatePreview(alertBox);
private VideoFrame? RenderAlertBox(Source alertBox)
=> _alertLayer.RenderFrame(alertBox);
private void StartMockChatPreview()
=> _chatLayer.StartMockPreview(Scenes);
private void StopMockChatPreview()
=> _chatLayer.StopMockPreview();
private void UpdateActiveChatBoxPreviews()
=> _chatLayer.UpdateConfiguredBoxes(Scenes);
private void UpdateActiveAlertBoxPreviews()
=> _alertLayer.UpdateConfiguredBoxes(Scenes);
}