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