using System.ComponentModel; using System.Runtime.CompilerServices; using Microsoft.Web.WebView2.Wpf; namespace VideoDownloader.Browser.Tabs; /// 탭 하나의 상태. View(WebView2 컨트롤)는 앱 레이어에서 주입한다(단위 테스트에선 null). public sealed class TabItem : INotifyPropertyChanged { public Guid Id { get; } = Guid.NewGuid(); /// 탭에 연결된 WebView2 컨트롤. 닫힌 탭 재오픈 시 재생성될 수 있음. public WebView2? View { get; set; } /// CoreWebView2 (초기화 전 null) public Microsoft.Web.WebView2.Core.CoreWebView2? Core => View?.CoreWebView2; private string _title = "새 탭"; public string Title { get => _title; set => Set(ref _title, value); } private string _url = ""; public string Url { get => _url; set => Set(ref _url, value); } private bool _isPinned; public bool IsPinned { get => _isPinned; set => Set(ref _isPinned, value); } private bool _isActive; public bool IsActive { get => _isActive; set => Set(ref _isActive, value); } private bool _isAudioPlaying; public bool IsAudioPlaying { get => _isAudioPlaying; set => Set(ref _isAudioPlaying, value); } private bool _isMuted; public bool IsMuted { get => _isMuted; set => Set(ref _isMuted, value); } private bool _isSuspended; public bool IsSuspended { get => _isSuspended; set => Set(ref _isSuspended, value); } private bool _isLoading; public bool IsLoading { get => _isLoading; set => Set(ref _isLoading, value); } private string? _groupName; // T2-11 탭 그룹 public string? GroupName { get => _groupName; set => Set(ref _groupName, value); } private string? _groupColor; public string? GroupColor { get => _groupColor; set => Set(ref _groupColor, value); } /// UC-B01 탭 잠금 — 실수로 닫는 것 방지(닫기 무시, 컨텍스트 메뉴로 해제). private bool _isLocked; public bool IsLocked { get => _isLocked; set => Set(ref _isLocked, value); } /// UC-B02 사용자 지정 탭 색(#RRGGBB) — 탭 좌측 표시줄에 표시. private string? _customColor; public string? CustomColor { get => _customColor; set => Set(ref _customColor, value); } /// UC-B03 그룹 접음 — 같은 그룹 탭을 스트립에서 접어 표시. private bool _isGroupCollapsed; public bool IsGroupCollapsed { get => _isGroupCollapsed; set => Set(ref _isGroupCollapsed, value); } /// 마지막 활성 시각(탭 절전 판정용) public DateTime LastActivated { get; set; } = DateTime.UtcNow; /// 닫힌 시점의 인덱스(닫힌 탭 복원용). 열려 있는 동안은 무의미. internal int ClosedIndex { get; set; } = -1; // ---- 탭별 일시 상태(호스트 앱이 사용) ---- /// SourceChanged → 타이틀 확정 사이의 히스토리 기록 대기 URL. public string? PendingHistoryUrl { get; set; } /// 소셜 카드 제목 갱신 대기 URL. public string? PendingSocialUrl { get; set; } /// 탭별 페이지 내 검색 세션 (CoreWebView2 바인딩). public FindSession? FindSession { get; set; } /// T2-4 리더 모드 진입 여부. public bool IsReader { get; set; } /// T3-3 InPrivate(사생활 보호) 탭 여부. public bool IsPrivate { get; set; } /// 리더 진입 전 원본 URL(복귀용). public string? ReaderOriginalUrl { get; set; } public event PropertyChangedEventHandler? PropertyChanged; private void Set(ref T field, T value, [CallerMemberName] string? name = null) { if (EqualityComparer.Default.Equals(field, value)) return; field = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } } /// 세션 스냅샷(T1-10): 탭 URL 순서 + 활성 인덱스 + 핀 여부. public sealed record SessionSnapshot(List Urls, int ActiveIndex, List Pinned);