releases/VideoDownloader.App/MainWindow.xaml

1324 lines
102 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<Window x:Class="VideoDownloader.App.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
xmlns:vm="clr-namespace:VideoDownloader.App.ViewModels"
xmlns:local="clr-namespace:VideoDownloader.App"
xmlns:feat="clr-namespace:VideoDownloader.App.Browser.Features"
mc:Ignorable="d"
FontFamily="{DynamicResource UiFont}"
Title="Video Downloader" Height="820" Width="1300"
Background="{DynamicResource WindowBgGradient}"
WindowStartupLocation="CenterScreen"
UseLayoutRounding="True"
ToolTipService.InitialShowDelay="400"
ToolTipService.ShowDuration="8000"
AutomationProperties.Name="Video Downloader 메인 창"
WindowStyle="None" ResizeMode="CanResize">
<!-- 보더리스: WindowChrome 이 실제 엣지 리사이즈 + 올바른 최대화(작업표시줄 존중) + DWM 그림자 담당 -->
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0"
ResizeBorderThickness="6"
GlassFrameThickness="1"
CornerRadius="0"
UseAeroCaptionButtons="False"
NonClientFrameEdges="None"/>
</WindowChrome.WindowChrome>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
<!-- §E 다운로드 필터 탭(세그먼트 라디오) -->
<Style x:Key="FilterTabStyle" TargetType="RadioButton">
<Setter Property="Foreground" Value="{DynamicResource TextMuted}"/>
<Setter Property="FontSize" Value="11"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Border x:Name="bd" Background="Transparent" CornerRadius="6,6,0,0" Padding="6,4"
BorderBrush="Transparent" BorderThickness="0,0,0,2" SnapsToDevicePixels="True">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource CardBgHover}"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="bd" Property="BorderBrush" Value="{DynamicResource AccentBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource TextPrimary}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate DataType="{x:Type vm:DownloadItemViewModel}">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1" CornerRadius="{StaticResource CornerRadius.Card}" Padding="13" Margin="0,0,0,10">
<!-- UC-D14 카드 우클릭 컨텍스트 메뉴 -->
<Border.ContextMenu>
<ContextMenu x:Name="CardContextMenu">
<MenuItem Header="URL 복사" Click="CardCopyUrl_Click"/>
<MenuItem Header="제목·경로 복사" Click="CardCopyInfo_Click"/>
<Separator/>
<MenuItem Header="목록에서 제거" Click="CardDismiss_Click"/>
<Separator/>
<!-- UC-D24 우선순위 -->
<MenuItem Header="우선순위 높임" Click="CardPriorityUp_Click"/>
<MenuItem Header="우선순위 낮춤" Click="CardPriorityDown_Click"/>
</ContextMenu>
</Border.ContextMenu>
<StackPanel>
<DockPanel>
<Border DockPanel.Dock="Right" Background="{DynamicResource GlassBg}"
BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1"
CornerRadius="6" Padding="8,2" VerticalAlignment="Center">
<!-- UC-D29 미디어 종류 배지(감지 종류 그대로 표시) + UC-A11 색 무의존 아이콘 -->
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="SuccessIcon" Text="&#xE73E;" Style="{StaticResource FluentIcon}"
FontSize="11" Foreground="{DynamicResource SuccessBrush}" Margin="0,0,5,0"
Visibility="{Binding Status, Converter={x:Static local:StatusToVisibilityConverter.Done}}"
AutomationProperties.Name="다운로드 완료"/>
<TextBlock Text="{Binding FormatTag}" FontSize="10" FontWeight="Bold"
x:Name="MediaKindBadge" Foreground="{DynamicResource AccentTextBrush}"/>
</StackPanel>
</Border>
<TextBlock Text="{Binding Title}" Foreground="{DynamicResource TextPrimary}"
FontSize="13" FontWeight="SemiBold" TextTrimming="CharacterEllipsis"
VerticalAlignment="Center" AutomationProperties.Name="{Binding Title}"/>
</DockPanel>
<!-- 소셜(YouTube/Instagram/X) 카드: 화질 선택 -->
<DockPanel Margin="0,9,0,2" Visibility="{Binding IsSocial, Converter={StaticResource BoolToVis}}">
<Button DockPanel.Dock="Right" Click="CardFetchFormats_Click" Margin="7,0,0,0"
VerticalAlignment="Center" ToolTip="이 영상에서 사용 가능한 화질 조회">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource CardActionButton}">
<Setter Property="Content" Value="불러오기"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsFetchingFormats}" Value="True">
<Setter Property="Content" Value="…"/>
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="다운로드 중"><Setter Property="IsEnabled" Value="False"/></DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="병합 중"><Setter Property="IsEnabled" Value="False"/></DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="리먹스 중"><Setter Property="IsEnabled" Value="False"/></DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="완료"><Setter Property="IsEnabled" Value="False"/></DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<ComboBox Style="{StaticResource DarkComboBox}"
ItemsSource="{Binding Formats}" DisplayMemberPath="Label"
SelectedItem="{Binding SelectedFormat}"
VerticalAlignment="Center"/>
</DockPanel>
<DockPanel Margin="0,11,0,6">
<!-- UC-D05/D04/D19 속도·남은 시간·총 크기 (등폭 숫자 — 흔들리지 않음) -->
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" VerticalAlignment="Center" Margin="8,0,0,0">
<TextBlock Text="{Binding SpeedText}" Style="{StaticResource Type.Mono}" MinWidth="58" TextAlignment="Right"
AutomationProperties.Name="다운로드 속도"/>
<TextBlock Text="{Binding RemainingText}" Style="{StaticResource Type.Mono}" MinWidth="58" TextAlignment="Right" Margin="6,0,0,0"
AutomationProperties.Name="남은 시간"/>
<TextBlock Text="{Binding TotalSizeText}" Style="{StaticResource Type.Mono}" MinWidth="64" TextAlignment="Right" Margin="6,0,0,0"
AutomationProperties.Name="총 크기"/>
</StackPanel>
<Grid VerticalAlignment="Center">
<ProgressBar Value="{Binding Progress}" Maximum="100" AutomationProperties.Name="{Binding Progress, StringFormat=진행률 {0}%}">
<ProgressBar.Style>
<Style TargetType="ProgressBar" BasedOn="{StaticResource AccentProgressBar}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsIndeterminate}" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ProgressBar.Style>
</ProgressBar>
<ProgressBar>
<ProgressBar.Style>
<Style TargetType="ProgressBar" BasedOn="{StaticResource IndeterminateBar}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsIndeterminate}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ProgressBar.Style>
</ProgressBar>
</Grid>
</DockPanel>
<!-- UC-D10 세그먼트 진행 막대 그리드 (완료=파랑/진행=강조/대기=트랙) -->
<ItemsControl x:Name="SegmentMapHost" ItemsSource="{Binding SegmentMap}" Margin="0,4,0,0"
Visibility="{Binding SegmentMap.Count, Converter={StaticResource InverseCountToVisibility}}">
<ItemsPanelTemplate>
<UniformGrid Rows="1"/>
</ItemsPanelTemplate>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Height="4" CornerRadius="2" Margin="0,0,2,0"
Background="{Binding Converter={x:Static local:SegmentFillConverter.Instance}, Mode=OneWay}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<DockPanel Margin="0,4,0,0">
<TextBlock Text="{Binding Status}" FontSize="11" VerticalAlignment="Center"
AutomationProperties.LiveSetting="Polite">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{DynamicResource TextSecondary}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="대기">
<Setter Property="Foreground" Value="{DynamicResource PendingBrush}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="오류">
<Setter Property="Foreground" Value="{DynamicResource ErrorBrush}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="완료">
<Setter Property="Foreground" Value="{DynamicResource SuccessBrush}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
<Button Style="{StaticResource CardActionButton}" Content="받기" Click="CardDownload_Click" Margin="0,0,6,0"
AutomationProperties.Name="다운로드 시작" TabIndex="30"/>
<Button Content="취소" Click="CardCancel_Click" Margin="0,0,6,0" AutomationProperties.Name="다운로드 취소">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource CardActionButton}">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="다운로드 중"><Setter Property="IsEnabled" Value="True"/></DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="병합 중"><Setter Property="IsEnabled" Value="True"/></DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="리먹스 중"><Setter Property="IsEnabled" Value="True"/></DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Style="{StaticResource CardActionButton}" Content="재시도" Click="CardRetry_Click" Margin="0,0,6,0"
AutomationProperties.Name="다운로드 재시도"/>
<Button Style="{StaticResource CardActionButton}" Content="폴더" Click="CardFolder_Click"
AutomationProperties.HelpText="저장 폴더에서 이 파일을 선택해 엽니다"/>
</StackPanel>
</DockPanel>
<!-- UC-D15 카드 상세 펼침: 출처 URL·형식·재시도 횟수·최종 파일명 -->
<Expander x:Name="CardDetailExpander" Header="상세 정보" FontSize="11" Margin="0,6,0,0"
Foreground="{DynamicResource TextMuted}" AutomationProperties.Name="다운로드 상세 정보 펼치기">
<StackPanel Margin="0,4,0,0">
<TextBlock Style="{StaticResource Type.Caption}" Text="{Binding Url, StringFormat=출처: {0}}" TextTrimming="CharacterEllipsis"/>
<TextBlock Style="{StaticResource Type.Caption}">
<Run Text="재시도: "/><Run Text="{Binding RetryCount, Mode=OneWay}"/><Run Text="회 · 우선순위 "/><Run Text="{Binding Priority, Mode=OneWay}"/>
</TextBlock>
<TextBlock Style="{StaticResource Type.Caption}" Text="{Binding FinalFileName, StringFormat=저장 파일: {0}, TargetNullValue=저장 파일: (미정)}" TextTrimming="CharacterEllipsis"/>
</StackPanel>
</Expander>
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
<StackPanel.Style>
<Style TargetType="StackPanel">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="오류">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<TextBlock Text="&#xE7BA;" Style="{StaticResource FluentIcon}" Foreground="{DynamicResource ErrorBrush}" FontSize="13" Margin="0,0,6,0"/>
<TextBlock Text="{Binding Error}" Foreground="{DynamicResource ErrorBrush}" FontSize="11" TextWrapping="Wrap" MaxWidth="260"
AutomationProperties.LiveSetting="Assertive"/>
<!-- UC-D27 오류 메시지 복사 -->
<Button x:Name="CopyErrorButton" Style="{StaticResource CardActionButton}" Content="오류 복사"
Click="CardCopyError_Click" Margin="8,0,0,0" VerticalAlignment="Center"
AutomationProperties.Name="오류 메시지 복사"/>
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
<!-- UC-D30 사이트별 묶음 헤더(PageUrl 호스트 기준 그룹) — 코드에서 GroupStyle 에 장착 -->
<DataTemplate x:Key="SiteGroupHeaderTemplate">
<TextBlock x:Name="SiteGroupHeader" Text="{Binding Name}" FontWeight="SemiBold" FontSize="11.5"
Foreground="{DynamicResource TextMuted}" Margin="2,8,0,4"/>
</DataTemplate>
</Window.Resources>
<Grid x:Name="MainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- ===== 상단 툴바 (슬림, 전체가 드래그 핸들) ===== -->
<Border x:Name="ToolbarRow" Grid.Row="0" Background="{DynamicResource PanelBg}"
BorderBrush="{DynamicResource AccentFadeBrush}" BorderThickness="0,0,0,2" Padding="20,9,0,9"
PreviewMouseLeftButtonDown="TitleBar_PreviewMouseLeftButtonDown">
<DockPanel>
<!-- 브랜드 -->
<StackPanel DockPanel.Dock="Left" Orientation="Horizontal"
VerticalAlignment="Center" Margin="0,0,12,0">
<Border Width="26" Height="26" CornerRadius="7" Background="{DynamicResource AccentGradient}">
<TextBlock Text="&#xE896;" Style="{StaticResource FluentIcon}" Foreground="White" FontSize="14"/>
</Border>
<TextBlock Text="Video Downloader" Foreground="{DynamicResource TextPrimary}"
FontWeight="SemiBold" FontSize="13.5" VerticalAlignment="Center" Margin="9,0,0,0"/>
</StackPanel>
<!-- 네비게이션 (Fluent 아이콘) — UC-A06 TabIndex 순서 지정 -->
<StackPanel DockPanel.Dock="Left" Orientation="Horizontal" VerticalAlignment="Center">
<Button Name="NavBack" Style="{StaticResource IconButton}" Content="&#xE76B;" ToolTip="뒤로 (Alt+←)" Margin="0,0,3,0" Click="NavBack_Click"
TabIndex="1" AutomationProperties.Name="뒤로 가기" AutomationProperties.HelpText="한 페이지 뒤로 이동"/>
<Button Name="NavForward" Style="{StaticResource IconButton}" Content="&#xE76C;" ToolTip="앞으로 (Alt+→)" Margin="0,0,3,0" Click="NavForward_Click"
TabIndex="2" AutomationProperties.Name="앞으로 가기"/>
<Button Name="NavRefresh" Style="{StaticResource IconButton}" Content="&#xE72C;" ToolTip="새로고침 (F5)" Margin="0,0,3,0" Click="NavRefresh_Click"
TabIndex="3" AutomationProperties.Name="새로 고침"/>
<Button Name="NavHome" Style="{StaticResource IconButton}" Content="&#xE80F;" ToolTip="홈" Click="NavHome_Click"
TabIndex="4" AutomationProperties.Name="홈으로 가기"/>
<!-- UC-L08 컴팩트 모드 토글 -->
<Button Name="CompactModeBtn" Style="{StaticResource IconButton}" Content="&#xEE49;" ToolTip="컴팩트 모드 (Ctrl+Shift+M)" Margin="3,0,0,0" Click="CompactModeBtn_Click"
TabIndex="5" AutomationProperties.Name="컴팩트 모드 전환" AutomationProperties.HelpText="툴바와 탭을 숨겨 영상에 집중합니다"/>
</StackPanel>
<!-- 우측 액션 + 캡션 (Fluent 아이콘 + 툴팁) -->
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" VerticalAlignment="Center" Margin="10,0,0,0"
KeyboardNavigation.TabNavigation="Cycle">
<Button Name="BookmarksBtn" Style="{StaticResource IconButton}" Content="&#xE734;" ToolTip="즐겨찾기" Margin="0,0,2,0" Click="ToggleBookmarks"
TabIndex="10" AutomationProperties.Name="즐겨찾기"/>
<Button Name="HistoryBtn" Style="{StaticResource IconButton}" Content="&#xE823;" ToolTip="방문 기록" Margin="0,0,2,0" Click="ToggleHistory"
TabIndex="11" AutomationProperties.Name="방문 기록"/>
<Button Name="TabSearchBtn" Style="{StaticResource IconButton}" Content="&#xE721;" ToolTip="탭 검색 (Ctrl+Shift+A)" Margin="0,0,2,0" Click="ToggleTabSearch"
TabIndex="12" AutomationProperties.Name="탭 검색"/>
<!-- UC-N19 다운로드 진행 개수 배지 -->
<Grid Margin="0,0,2,0">
<Button Name="DownloadsBtn" Style="{StaticResource IconButton}" Content="&#xE896;" ToolTip="다운로드 (Ctrl+J)" Click="ToggleDownloads"
TabIndex="13" AutomationProperties.Name="다운로드 목록"/>
<Border Name="DownloadsBtnBadge" CornerRadius="8" Background="{DynamicResource PendingBrush}" Padding="5,1"
HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,2,2,0" Visibility="Collapsed"
AutomationProperties.Name="진행 중 다운로드 수">
<TextBlock Name="DownloadsBtnBadgeText" Text="" FontSize="9" Foreground="Black"/>
</Border>
</Grid>
<!-- T3-14 추적 방지 실드 -->
<Grid Margin="0,0,2,0">
<Button Name="ShieldBtn" Style="{StaticResource IconButton}" Content="&#xE72E;" ToolTip="추적 방지" Click="Shield_Click"
TabIndex="14" AutomationProperties.Name="추적 방지 실드"/>
<Border Name="ShieldBadge" CornerRadius="8" Background="#FF4CAF50" Padding="5,1"
HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,2,2,0" Visibility="Collapsed">
<TextBlock Name="ShieldBadgeText" Text="" FontSize="9" Foreground="White"/>
</Border>
</Grid>
<Button Name="PlaylistBtn" Style="{StaticResource IconButton}" Content="&#xE8D6;" ToolTip="미디어 재생목록" Margin="0,0,2,0" Click="TogglePlaylistPanel"
TabIndex="15" AutomationProperties.Name="미디어 재생목록"/>
<!-- UC-M01 라이브러리 뷰 -->
<Button Name="LibraryBtn" Style="{StaticResource IconButton}" Content="&#xE8F1;" ToolTip="라이브러리" Margin="0,0,2,0" Click="LibraryBtn_Click"
TabIndex="16" AutomationProperties.Name="라이브러리" AutomationProperties.HelpText="받은 파일을 그리드·목록으로 봅니다"/>
<!-- UC-N08 툴바 QR 페어링 -->
<Button Name="PairingBtn" Style="{StaticResource IconButton}" Content="&#xE8C7;" ToolTip="기기 연결 (QR 페어링)" Margin="0,0,2,0" Click="PairingBtn_Click"
TabIndex="17" AutomationProperties.Name="기기 연결 QR 페어링"/>
<Button Style="{StaticResource IconButton}" Content="&#xE8B7;" ToolTip="저장 폴더 열기" Margin="0,0,2,0" Click="OpenFolder_Click"
TabIndex="18" AutomationProperties.Name="저장 폴더 열기"/>
<Button Name="LinkBtn" Style="{StaticResource IconButton}" Content="&#xE71B;" ToolTip="링크로 받기 (YouTube·Instagram·X)" Margin="0,0,2,0" Click="ToggleLink"
TabIndex="19" AutomationProperties.Name="링크로 받기"/>
<Button x:Name="PrivateBtn" Style="{StaticResource IconButton}" Content="&#xE72E;" ToolTip="개인정보 보호 모드(InPrivate)" Margin="0,0,2,0" Click="TogglePrivate_Click"
TabIndex="20" AutomationProperties.Name="개인정보 보호 모드"/>
<!-- UC-N09 업데이트 가능 배지 -->
<Grid Margin="0,0,8,0">
<Button Style="{StaticResource IconButton}" Content="&#xE713;" ToolTip="설정" Click="Settings_Click"
TabIndex="21" AutomationProperties.Name="설정"/>
<Border Name="UpdateBadge" CornerRadius="8" Background="{DynamicResource SuccessBrush}" Width="9" Height="9"
HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,3,3,0" Visibility="Collapsed"
AutomationProperties.Name="새 버전 알림"/>
</Grid>
<Button Style="{StaticResource PrimaryButton}" ToolTip="주소로 이동 (Enter)" Height="32" Click="Go_Click"
TabIndex="9" AutomationProperties.Name="주소로 이동">
<!-- UC-A08 Alt 접근 키 -->
<AccessText Text="이동(_G)"/>
</Button>
<!-- 구분선 (좌우 대칭 여백) -->
<Border Width="1" Background="{DynamicResource BorderSubtle}" Margin="10,8"/>
<!-- 윈도우 캡션 컨트롤 (고정폭, 서로 밀착) -->
<Button Style="{StaticResource CaptionButton}" Content="&#xE921;" ToolTip="최소화" Click="Minimize_Click"
AutomationProperties.Name="창 최소화"/>
<Button Name="MaxRestoreBtn" Style="{StaticResource CaptionButton}" Content="&#xE922;" ToolTip="최대화" Click="MaxRestore_Click"
AutomationProperties.Name="창 최대화"/>
<Button Style="{StaticResource CloseButton}" Content="&#xE8BB;" ToolTip="닫기" Click="Close_Click"
AutomationProperties.Name="창 닫기"/>
</StackPanel>
<!-- 주소창 -->
<Border Background="{DynamicResource GlassBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="8" Height="32" VerticalAlignment="Center">
<Grid>
<TextBox Name="AddressBox" Style="{StaticResource DarkTextBox}"
PreviewKeyDown="AddressBox_PreviewKeyDown" TextChanged="AddressBox_TextChanged"
GotKeyboardFocus="AddressBox_GotKeyboardFocus"
BorderThickness="0" Background="Transparent"
Padding="14,0" FontSize="13" VerticalContentAlignment="Center"
TabIndex="8" AutomationProperties.Name="주소 입력창"
AutomationProperties.HelpText="URL 또는 검색어를 입력하고 Enter 를 누릅니다">
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Header="붙여넣고 이동" Click="PasteAndGo_Click" InputGestureText="UC-K07"/>
<MenuItem Header="붙여넣기" Command="ApplicationCommands.Paste"/>
<MenuItem Header="복사" Command="ApplicationCommands.Copy"/>
<Separator/>
<MenuItem Header="파라미터 제거 후 복사" Click="CopyCleanUrl_Click" InputGestureText="T3-15"/>
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
<!-- T3-15 주소창 진행 바 -->
<ProgressBar Name="NavProgress" Height="2" VerticalAlignment="Bottom" MinHeight="2"
Minimum="0" Maximum="100" IsIndeterminate="True" Visibility="Collapsed"
Foreground="{DynamicResource AccentBrush}" Background="Transparent" BorderThickness="0"/>
<!-- UC-N06 클립보드 URL 감지 제안 배지 -->
<Button Name="ClipboardHint" Visibility="Collapsed" Click="ClipboardHint_Click"
HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,8,0" Cursor="Hand"
Background="Transparent" BorderThickness="0" Padding="0"
AutomationProperties.Name="클립보드 링크 받기 제안">
<Border Background="{DynamicResource AccentFadeBrush}" CornerRadius="9" Padding="9,3">
<TextBlock Text="&#xE71B; 링크 붙여넣고 받기" FontSize="10.5" Foreground="{DynamicResource TextPrimary}"/>
</Border>
</Button>
</Grid>
</Border>
</DockPanel>
</Border>
<!-- ===== 북마크바 (T1-6, Ctrl+Shift+B 토글) ===== -->
<Border x:Name="BookmarkBar" Grid.Row="1" Background="{DynamicResource PanelBg}"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="0,0,0,1" Padding="8,3"
Visibility="Collapsed">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<ItemsControl x:Name="BookmarkBarList" ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Style="{StaticResource FlatButton}" Click="BookmarkBar_Click"
Padding="10,4" Margin="2,1" ToolTip="{Binding Url}">
<TextBlock Text="{Binding Title}" TextTrimming="CharacterEllipsis"
MaxWidth="130" FontSize="12"/>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Border>
<!-- ===== 탭 스트립 (Phase A) ===== -->
<Border x:Name="TabStripRow" Grid.Row="2" Background="{DynamicResource PanelBg}"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="0,0,0,1" Padding="8,4,8,0"
MouseWheel="TabStrip_MouseWheel" AllowDrop="True"
DragOver="TabList_DragOver" Drop="TabList_Drop" DragLeave="TabList_DragLeave">
<DockPanel>
<!-- UC-B18/B20 현재 작업공간 표시 + 클릭 전환 -->
<StackPanel DockPanel.Dock="Left" Orientation="Horizontal" VerticalAlignment="Center" Margin="0,0,8,3">
<TextBlock x:Name="WorkspaceIndicator" Text="작업" FontSize="11" FontWeight="SemiBold"
Foreground="{DynamicResource AccentTextBrush}" VerticalAlignment="Center" Margin="0,0,6,0"
AutomationProperties.Name="현재 작업공간"/>
<ComboBox x:Name="WorkspaceSwitcher" Style="{StaticResource DarkComboBox}" FontSize="11"
MinWidth="86" SelectionChanged="WorkspaceSwitcher_SelectionChanged"
AutomationProperties.Name="작업공간 전환"/>
</StackPanel>
<Button x:Name="NewTabBtn" DockPanel.Dock="Right" Style="{StaticResource IconButton}"
Content="&#xE710;" FontSize="13" ToolTip="새 탭 (Ctrl+T)" Click="NewTab_Click"
Margin="4,0,2,3" VerticalAlignment="Center"
AutomationProperties.Name="새 탭" AutomationProperties.HelpText="새 브라우저 탭을 엽니다"/>
<!-- UC-B21 새 탭 보조 메뉴(최근 페이지·즐겨찾기) -->
<Button x:Name="NewTabMoreBtn" DockPanel.Dock="Right" Style="{StaticResource IconButton}"
Content="&#xE712;" FontSize="10" ToolTip="최근 페이지·즐겨찾기로 열기" Click="NewTabMore_Click"
Margin="2,0,0,3" VerticalAlignment="Center"
AutomationProperties.Name="새 탭 보조 메뉴"/>
<!-- UC-B13 닫은 탭 아카이브 -->
<Button x:Name="ArchiveBtn" DockPanel.Dock="Right" Style="{StaticResource IconButton}"
Content="&#xE81C;" FontSize="12" ToolTip="닫은 탭 아카이브" Click="ArchiveBtn_Click"
Margin="2,0,0,3" VerticalAlignment="Center"
AutomationProperties.Name="닫은 탭 아카이브"/>
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Disabled"
VerticalAlignment="Bottom">
<Grid>
<!-- UC-B08 드래그 삽입 위치 표시기 -->
<Rectangle x:Name="TabInsertIndicator" Width="3" Fill="{DynamicResource AccentBrush}"
RadiusX="2" RadiusY="2" HorizontalAlignment="Left" Visibility="Collapsed"/>
<ItemsControl x:Name="TabList" AllowDrop="True">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,4,0" MinWidth="130" MaxWidth="220">
<Border x:Name="TabBg" CornerRadius="8,8,0,0"
Background="{DynamicResource GlassBg}"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1,1,1,0"
Padding="10,7,4,7" MouseLeftButtonUp="Tab_Click"
MouseMove="TabBg_MouseMove"
PreviewMouseDown="Tab_PreviewMouseDown"
MouseRightButtonUp="Tab_ContextMenu"
ToolTipOpening="Tab_ToolTipOpening"
AllowDrop="True" Drop="TabItem_Drop" DragOver="TabItem_DragOver">
<DockPanel>
<!-- UC-B02 사용자 지정 색 + 그룹색 표시줄 -->
<Border DockPanel.Dock="Left" Width="3" CornerRadius="2" Margin="0,0,7,0"
Visibility="{Binding CustomColor, Converter={x:Static feat:StringToBrushConverter.VisibleIf}}">
<Border.Background>
<SolidColorBrush Color="{Binding CustomColor, Converter={x:Static feat:StringToBrushConverter.Conv}}"/>
</Border.Background>
</Border>
<!-- UC-B07 탭 번호 배지 -->
<Border x:Name="TabIndexBadge" DockPanel.Dock="Left" CornerRadius="7"
Background="{DynamicResource GlassBg}" Padding="5,1" Margin="0,0,6,0"
VerticalAlignment="Center" Visibility="Collapsed"
AutomationProperties.Name="탭 번호">
<TextBlock x:Name="TabIndexText" Text="1" FontSize="9.5"
Foreground="{DynamicResource TextMuted}"/>
</Border>
<!-- UC-B06 잠자기(zzz) · B01 잠금 아이콘 -->
<TextBlock x:Name="SuspendIcon" Text="&#xE7F8;" Style="{StaticResource FluentIcon}"
FontSize="10" Margin="0,0,6,0" VerticalAlignment="Center"
Foreground="{DynamicResource TextMuted}" Visibility="Collapsed"
AutomationProperties.Name="잠자기 탭"/>
<TextBlock x:Name="LockIcon" Text="&#xE72E;" Style="{StaticResource FluentIcon}"
FontSize="9" Margin="0,0,5,0" VerticalAlignment="Center"
Foreground="{DynamicResource TextMuted}" Visibility="Collapsed"
AutomationProperties.Name="잠긴 탭"/>
<Button DockPanel.Dock="Right" Style="{StaticResource CardActionButton}"
Content="&#xE711;" FontSize="9" Padding="5,3" Margin="4,0,0,0"
Click="TabClose_Click" ToolTip="탭 닫기 (Ctrl+W)"
VerticalAlignment="Center"
AutomationProperties.Name="탭 닫기"/>
<TextBlock x:Name="AudioIcon" Text="&#xE767;" Style="{StaticResource FluentIcon}"
FontSize="11" Margin="0,0,6,0" VerticalAlignment="Center"
Visibility="Collapsed" Cursor="Hand"
MouseLeftButtonUp="TabAudio_Click"/>
<TextBlock Text="{Binding Title}" Style="{StaticResource TabTitleStyle}"/>
</DockPanel>
</Border>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsActive}" Value="True">
<Setter TargetName="TabBg" Property="Background" Value="{DynamicResource CardBg}"/>
<Setter TargetName="TabBg" Property="BorderBrush" Value="{DynamicResource AccentFadeBrush}"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsAudioPlaying}" Value="True">
<Setter TargetName="AudioIcon" Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsMuted}" Value="True">
<Setter TargetName="AudioIcon" Property="Text" Value="&#xE74F;"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsPinned}" Value="True">
<Setter TargetName="TabBg" Property="Background" Value="{DynamicResource AccentFadeBrush}"/>
</DataTrigger>
<!-- UC-B06 잠자기 탭 시각 구분 -->
<DataTrigger Binding="{Binding IsSuspended}" Value="True">
<Setter TargetName="SuspendIcon" Property="Visibility" Value="Visible"/>
<Setter TargetName="TabBg" Property="Opacity" Value="0.55"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsLocked}" Value="True">
<Setter TargetName="LockIcon" Property="Visibility" Value="Visible"/>
</DataTrigger>
<!-- UC-B03 그룹 접힘 → 제목만 흐리게 남김 -->
<DataTrigger Binding="{Binding IsGroupCollapsed}" Value="True">
<Setter TargetName="TabBg" Property="Opacity" Value="0.45"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</ScrollViewer>
</DockPanel>
</Border>
<!-- ===== 본문 ===== -->
<Grid x:Name="ContentRoot" Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="SideStripCol" Width="0"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition x:Name="SplitCol" Width="0"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition x:Name="RightCol" Width="420" MinWidth="56" MaxWidth="900"/>
</Grid.ColumnDefinitions>
<!-- T2-5 세로 탭 사이드 호스트 -->
<Border x:Name="TabSideHost" Grid.Column="0" Background="{DynamicResource PanelBg}"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="0,0,1,0"
ClipToBounds="True" MinWidth="170" MaxWidth="330"/>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" ClipToBounds="True" Background="Black">
<Grid x:Name="TabHost" Background="Black"/>
</Border>
<!-- 페이지 내 검색 바 (T1-3): WebView2(airspace) 아래에 도킹 -->
<Border x:Name="FindBar" Grid.Row="1" Visibility="Collapsed"
Background="{DynamicResource PanelBg}" BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="0,1,0,0" Padding="12,6">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<CheckBox x:Name="FindCaseBox" Style="{StaticResource DarkCheckBox}" Content="Aa"
ToolTip="대소문자 구분" Margin="0,0,8,0" VerticalAlignment="Center"
Checked="FindOption_Changed" Unchecked="FindOption_Changed"/>
<CheckBox x:Name="FindWordBox" Style="{StaticResource DarkCheckBox}" Content="단어"
ToolTip="전체 단어 일치" Margin="0,0,10,0" VerticalAlignment="Center"
Checked="FindOption_Changed" Unchecked="FindOption_Changed"/>
<Border Background="{DynamicResource GlassBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="7" Width="230">
<TextBox x:Name="FindBox" Style="{StaticResource DarkTextBox}" BorderThickness="0"
Background="Transparent" Padding="10,4" FontSize="12.5"
VerticalContentAlignment="Center"
TextChanged="FindBox_TextChanged" PreviewKeyDown="FindBox_PreviewKeyDown"/>
</Border>
<Button Style="{StaticResource IconButton}" Content="&#xE74A;" ToolTip="이전 매치 (Shift+F3)"
Margin="6,0,0,0" Click="FindPrev_Click"/>
<Button Style="{StaticResource IconButton}" Content="&#xE74B;" ToolTip="다음 매치 (F3)"
Margin="2,0,0,0" Click="FindNext_Click"/>
<TextBlock x:Name="FindStatus" Text="" Foreground="{DynamicResource TextMuted}" FontSize="11.5"
VerticalAlignment="Center" Margin="10,0,4,0" MinWidth="52"/>
<Button Style="{StaticResource IconButton}" Content="&#xE711;" ToolTip="닫기 (Esc)"
Click="FindClose_Click"/>
</StackPanel>
</Border>
</Grid>
<!-- 리사이즈 핸들 (펼침 상태에서만 노출). 드래그로 우측 패널 폭 변경. -->
<!-- T2-3 분할 화면: 드래그 스플리터 + 우측 탭 호스트 -->
<GridSplitter x:Name="SplitSplitter" Grid.Column="2" Width="7"
HorizontalAlignment="Center" VerticalAlignment="Stretch"
ResizeBehavior="PreviousAndNext" ResizeDirection="Columns"
Background="Transparent" Cursor="SizeWE" Visibility="Collapsed"/>
<Border x:Name="SplitRightHost" Grid.Column="3" ClipToBounds="True" Background="Black"
Visibility="Collapsed"/>
<GridSplitter x:Name="RightSplitter" Grid.Column="4" Width="7"
HorizontalAlignment="Center" VerticalAlignment="Stretch"
ResizeBehavior="PreviousAndNext" ResizeDirection="Columns"
Background="Transparent" Cursor="SizeWE"
DragCompleted="RightSplitter_DragCompleted"
MouseDoubleClick="RightSplitter_DoubleClick"
AutomationProperties.Name="패널 폭 조절" AutomationProperties.HelpText="더블 클릭하면 기본 폭으로 되돌립니다">
<GridSplitter.Template>
<ControlTemplate TargetType="GridSplitter">
<Border x:Name="handle" Background="Transparent">
<Rectangle Width="1" HorizontalAlignment="Center" Fill="{DynamicResource BorderSubtle}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="handle" Property="Background" Value="{DynamicResource AccentFadeBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</GridSplitter.Template>
</GridSplitter>
<!-- 범용 우측 패널: 헤더(토글 버튼, 항상 노출) + 본문(펼침 시). 접기/펼치기·폭·상태 저장. -->
<Border Grid.Column="5" Background="{DynamicResource PanelBg}"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1,0,0,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" Margin="10,12,10,8" LastChildFill="True">
<Button x:Name="PanelToggle" DockPanel.Dock="Right" Style="{StaticResource IconButton}"
Click="PanelToggle_Click" ToolTip="패널 접기"
VerticalAlignment="Center" Margin="4,0,0,0" Content="&#xE76C;"
AutomationProperties.Name="다운로드 패널 접기"/>
<!-- UC-D16 대기 현황 요약(예: 3 대기 · 1 실패) -->
<TextBlock x:Name="QueueSummaryText" DockPanel.Dock="Right" Text="" FontSize="10.5"
Foreground="{DynamicResource TextMuted}" VerticalAlignment="Center" Margin="0,0,8,0"
AutomationProperties.Name="다운로드 대기 현황" AutomationProperties.LiveSetting="Polite"/>
<Border x:Name="PanelCountBadge" DockPanel.Dock="Right" Background="{DynamicResource GlassBg}"
CornerRadius="9" Padding="9,2" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,8,0">
<TextBlock Text="{Binding Items.Count}" Foreground="{DynamicResource TextSecondary}" FontSize="11"/>
</Border>
<TextBlock x:Name="PanelTitle" Text="다운로드" Foreground="{DynamicResource TextPrimary}"
FontWeight="SemiBold" FontSize="13.5" VerticalAlignment="Center"/>
</DockPanel>
<!-- §E 다운로드 관리자 도구 모음 -->
<StackPanel x:Name="PanelToolbar" Grid.Row="1" Margin="10,0,10,8">
<!-- UC-D02 상태 필터 탭 -->
<UniformGrid x:Name="DownloadFilterTabs" Columns="4" Margin="0,0,0,6">
<RadioButton x:Name="FilterAll" Style="{StaticResource FilterTabStyle}" Content="전체" IsChecked="True"
Checked="DownloadFilter_Changed" GroupName="dlfilter" AutomationProperties.Name="전체 다운로드 보기"/>
<RadioButton x:Name="FilterActive" Style="{StaticResource FilterTabStyle}" Content="진행"
Checked="DownloadFilter_Changed" GroupName="dlfilter" AutomationProperties.Name="진행 중 다운로드 보기"/>
<RadioButton x:Name="FilterDone" Style="{StaticResource FilterTabStyle}" Content="완료"
Checked="DownloadFilter_Changed" GroupName="dlfilter" AutomationProperties.Name="완료된 다운로드 보기"/>
<RadioButton x:Name="FilterFailed" Style="{StaticResource FilterTabStyle}" Content="실패"
Checked="DownloadFilter_Changed" GroupName="dlfilter" AutomationProperties.Name="실패한 다운로드 보기"/>
</UniformGrid>
<DockPanel>
<!-- UC-D06/D07 모두 일시정지/재개 -->
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
<Button Style="{StaticResource CardActionButton}" Content="&#xE769; 모두 일시정지" Click="PauseAllDownloads_Click" Margin="0,0,5,0"
AutomationProperties.Name="모두 일시정지"/>
<Button Style="{StaticResource CardActionButton}" Content="&#xE768; 모두 재개" Click="ResumeAllDownloads_Click" Margin="0,0,5,0"
AutomationProperties.Name="모두 재개"/>
<Button Style="{StaticResource CardActionButton}" Content="CSV" Click="ExportDownloads_Click"
ToolTip="다운로드 목록 CSV 내보내기" AutomationProperties.Name="목록 CSV 내보내기"/>
</StackPanel>
<!-- UC-D03 목록 검색 -->
<TextBox x:Name="DownloadSearchBox" Style="{StaticResource DarkTextBox}" FontSize="12"
Padding="8,5" TextChanged="DownloadSearchBox_TextChanged"
AutomationProperties.Name="다운로드 검색"/>
</DockPanel>
<!-- UC-D18 전체 속도 + UC-D17 스파크라인 -->
<DockPanel Margin="0,6,0,0">
<TextBlock x:Name="GlobalSpeedText" DockPanel.Dock="Right" Text="" Style="{StaticResource Type.Mono}"
AutomationProperties.Name="전체 다운로드 속도"/>
<Polyline x:Name="SpeedSparkline" Points="0,12 12,12 24,12 36,12 48,12 60,12 72,12 84,12 96,12 108,12 120,12"
Stroke="{DynamicResource AccentBrush}" StrokeThickness="1.5" HorizontalAlignment="Left"
VerticalAlignment="Center" Height="14" MinWidth="120" MaxWidth="200"
AutomationProperties.Name="속도 추이 스파크라인"/>
</DockPanel>
</StackPanel>
<Grid Grid.Row="2" x:Name="PanelBody">
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0,60,0,0"
Visibility="{Binding Items.Count, Converter={StaticResource InverseCountToVisibility}}">
<Border Width="54" Height="54" CornerRadius="14" Background="{DynamicResource GlassBg}"
BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" HorizontalAlignment="Center">
<TextBlock Text="&#xE8B2;" Style="{StaticResource FluentIcon}" FontSize="24" Foreground="{DynamicResource TextMuted}"/>
</Border>
<TextBlock Text="영상을 재생하면 여기에 나타납니다" Foreground="{DynamicResource TextSecondary}"
FontSize="13" FontWeight="Medium" HorizontalAlignment="Center" Margin="0,14,0,2"/>
<TextBlock Text="탐지 즉시 자동으로 목록에 추가돼요" Foreground="{DynamicResource TextMuted}"
FontSize="11.5" HorizontalAlignment="Center"/>
</StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="16,2,16,16">
<ItemsControl x:Name="DownloadCards" ItemsSource="{Binding Items}"/>
</ScrollViewer>
</Grid>
</Grid>
</Border>
</Grid>
<!-- ===== 상태 표시줄 ===== -->
<Border x:Name="StatusBar" Grid.Row="4" Background="{DynamicResource PanelBg}"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="0,1,0,0" Padding="16,5">
<DockPanel>
<!-- UC-N20 상태바 우측 보조 정보(줌·서버) -->
<StackPanel x:Name="StatusRight" DockPanel.Dock="Right" Orientation="Horizontal" VerticalAlignment="Center">
<!-- UC-K14 현재 줌 배율 -->
<Button x:Name="ZoomIndicator" Style="{StaticResource CardActionButton}" Content="100%"
Click="ZoomIndicator_Click" ToolTip="줌 배율 — 클릭하면 100%로 초기화" Margin="0,0,8,0"
AutomationProperties.Name="현재 줌 배율"/>
<!-- UC-N07 원격 접속 서버 상태 -->
<TextBlock x:Name="ServerStatusIcon" Text="&#xE9D9;" Style="{StaticResource FluentIcon}" FontSize="11"
Foreground="{DynamicResource TextMuted}" Margin="0,0,6,0"
ToolTip="원격 접속 꺼짐" AutomationProperties.Name="원격 접속 서버 상태"/>
<!-- UC-N14 알림 센터 -->
<Button x:Name="NotificationCenter" Style="{StaticResource CardActionButton}" Content="&#xEA8F;"
FontFamily="{DynamicResource IconFont}" Click="NotificationCenter_Click" ToolTip="알림 센터"
Margin="0,0,6,0" AutomationProperties.Name="알림 센터"/>
<!-- UC-K04 단축키 도움말 -->
<Button x:Name="ShortcutHelpBtn" Style="{StaticResource CardActionButton}" Content="&#xE8A5;" FontFamily="{DynamicResource IconFont}"
Click="ShortcutHelpBtn_Click" ToolTip="단축키 목록" AutomationProperties.Name="단축키 목록 보기"/>
</StackPanel>
<!-- UC-N01 전체 다운로드 진행률 -->
<ProgressBar x:Name="AggregateProgress" DockPanel.Dock="Right" Width="90" Height="4" Minimum="0" Maximum="100"
Style="{StaticResource AccentProgressBar}" Margin="0,0,10,0" VerticalAlignment="Center"
AutomationProperties.Name="전체 다운로드 진행률"/>
<!-- UC-N13 상태 텍스트 클릭 복사 · UC-A03 LiveSetting -->
<TextBlock Name="StatusText" Style="{StaticResource StatusTextStyle}" Text="준비"
Cursor="Hand" MouseLeftButtonUp="CopyStatus_Click"
AutomationProperties.Name="상태 메시지" AutomationProperties.LiveSetting="Polite"/>
</DockPanel>
</Border>
<!-- ===== UC-N02 토스트 호스트(우하단) ===== -->
<StackPanel x:Name="ToastHost" Grid.Row="3" HorizontalAlignment="Right" VerticalAlignment="Bottom"
Margin="0,0,16,14" IsHitTestVisible="True" Panel.ZIndex="40"/>
<!-- ===== UC-N04/N05 치명 오류 배너(상단 고정) ===== -->
<Border x:Name="ErrorBanner" Grid.Row="3" VerticalAlignment="Top" Margin="16,8,16,0"
Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource ErrorBrush}" BorderThickness="1"
CornerRadius="10" Padding="12,8" Visibility="Collapsed" Panel.ZIndex="41">
<DockPanel>
<Button DockPanel.Dock="Right" Style="{StaticResource CardActionButton}" Content="&#xE711;" Click="ErrorBanner_Close"
AutomationProperties.Name="오류 배너 닫기"/>
<Expander x:Name="ErrorDetailExpander" Header="오류가 발생했습니다 — 펼쳐서 상세 보기"
Foreground="{DynamicResource ErrorBrush}" FontSize="12"
AutomationProperties.LiveSetting="Assertive">
<TextBox x:Name="ErrorDetailText" Style="{StaticResource DarkTextBox}" IsReadOnly="True" FontSize="11"
TextWrapping="Wrap" MaxHeight="120" Margin="0,6,0,0"/>
</Expander>
</DockPanel>
</Border>
<!-- ===== UC-N16 첫 실행 온보딩 ===== -->
<Border x:Name="Onboarding" Grid.Row="3" Background="#CC000000" Visibility="Collapsed" Panel.ZIndex="50">
<Border Style="{StaticResource EmptyStateStyle}" Background="{DynamicResource CardBg}" MaxWidth="460"
VerticalAlignment="Center" HorizontalAlignment="Center" Padding="28">
<StackPanel>
<TextBlock Text="Video Downloader 에 오세요" Style="{StaticResource Type.H1}" Margin="0,0,0,8"/>
<TextBlock Style="{StaticResource Type.Body}"
Text="영상을 재생하면 자동으로 감지해 오른쪽 패널에 카드가 생깁니다. 받기 버튼으로 저장하고, 휴대폰 QR 페어링으로 밖에서도 볼 수 있어요."/>
<TextBlock Style="{StaticResource Type.Caption}" Margin="0,10,0,0"
Text="Ctrl+K 명령 팔레트 · F12 개발자 도구 · Ctrl+Shift+A 탭 검색"/>
<Button Style="{StaticResource PrimaryButton}" Content="시작하기" HorizontalAlignment="Right"
Margin="0,16,0,0" Click="Onboarding_Close" AutomationProperties.Name="온보딩 닫기"/>
</StackPanel>
</Border>
</Border>
<!-- ===== 즐겨찾기 플라이아웃 ===== -->
<Popup Name="BookmarksPopup" PlacementTarget="{Binding ElementName=BookmarksBtn}"
Placement="Bottom" HorizontalOffset="-10" VerticalOffset="6"
StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="8" Width="320" MaxHeight="460"
Effect="{StaticResource PopupShadow}">
<StackPanel KeyboardNavigation.TabNavigation="Cycle">
<DockPanel Margin="6,4,6,6">
<TextBlock Text="즐겨찾기" Foreground="{DynamicResource TextPrimary}" FontWeight="SemiBold" VerticalAlignment="Center"/>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Style="{StaticResource CardActionButton}" Content="+ 현재 페이지 추가" Click="AddBookmark_Click" Margin="0,0,6,0"/>
<!-- UC-K16 관리 창 -->
<Button Style="{StaticResource CardActionButton}" Content="관리" Click="BookmarkManager_Click"
AutomationProperties.Name="즐겨찾기 관리 창 열기"/>
</StackPanel>
</DockPanel>
<!-- UC-M18 즐겨찾기 검색 -->
<TextBox x:Name="BookmarkSearchBox" Style="{StaticResource DarkTextBox}" FontSize="12" Padding="8,5"
Margin="6,0,6,6" TextChanged="BookmarkSearchBox_TextChanged"
AutomationProperties.Name="즐겨찾기 검색"/>
<Border Background="{DynamicResource BorderSubtle}" Height="1" Margin="0,0,0,4"/>
<ItemsControl Name="BookmarksList" MaxHeight="360">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DockPanel Margin="0,1">
<Button DockPanel.Dock="Right" Style="{StaticResource CardActionButton}" Content="✕"
Click="RemoveBookmark_Click" Padding="8,5" Margin="6,0,0,0" VerticalAlignment="Center"
AutomationProperties.Name="즐겨찾기에서 삭제"/>
<!-- UC-M17 즐겨찾기 편집 -->
<Button DockPanel.Dock="Right" Style="{StaticResource CardActionButton}" Content="편집"
Click="EditBookmark_Click" Margin="6,0,0,0" VerticalAlignment="Center"/>
<!-- UC-M16 폴더로 이동 -->
<Button DockPanel.Dock="Right" Style="{StaticResource CardActionButton}" Content="&#xE8B7;"
FontFamily="{DynamicResource IconFont}" Click="BookmarkFolder_Click" Margin="6,0,0,0" VerticalAlignment="Center"
ToolTip="폴더로 이동" AutomationProperties.Name="즐겨찾기 폴더 지정"/>
<Button Style="{StaticResource FlatButton}" Click="OpenBookmark_Click" HorizontalAlignment="Stretch">
<StackPanel>
<TextBlock Text="{Binding Title}" TextTrimming="CharacterEllipsis" FontSize="12.5" FontWeight="Medium"/>
<TextBlock Text="{Binding Url}" Foreground="{DynamicResource TextMuted}" FontSize="10.5" TextTrimming="CharacterEllipsis"/>
</StackPanel>
</Button>
</DockPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
</Popup>
<!-- ===== 히스토리 플라이아웃 ===== -->
<Popup Name="HistoryPopup" PlacementTarget="{Binding ElementName=HistoryBtn}"
Placement="Bottom" HorizontalOffset="-10" VerticalOffset="6"
StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="8" Width="340" MaxHeight="480"
Effect="{StaticResource PopupShadow}">
<StackPanel KeyboardNavigation.TabNavigation="Cycle">
<DockPanel Margin="6,4,6,6">
<TextBlock Text="방문 기록" Foreground="{DynamicResource TextPrimary}" FontWeight="SemiBold" VerticalAlignment="Center"/>
<Button DockPanel.Dock="Right" Style="{StaticResource CardActionButton}" Content="🗑 전체 삭제" Click="ClearHistory_Click" HorizontalAlignment="Right"/>
</DockPanel>
<!-- UC-M21 기록 검색 -->
<TextBox x:Name="HistorySearchBox" Style="{StaticResource DarkTextBox}" FontSize="12" Padding="8,5"
Margin="6,0,6,6" TextChanged="HistorySearchBox_TextChanged"
AutomationProperties.Name="방문 기록 검색"/>
<Border Background="{DynamicResource BorderSubtle}" Height="1" Margin="0,0,0,4"/>
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="380">
<ItemsControl Name="HistoryList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- UC-M20 날짜별 묶음 헤더(같은 날 첫 항목 위에 표시) -->
<StackPanel>
<TextBlock x:Name="GroupHeader" Text="{Binding GroupKey}" FontSize="10.5" FontWeight="SemiBold"
Foreground="{DynamicResource AccentTextBrush}" Margin="2,6,0,3"
Visibility="{Binding ShowGroupKey, Converter={StaticResource BoolToVis}}"/>
<DockPanel>
<!-- UC-K17 이 항목만 삭제 -->
<Button DockPanel.Dock="Right" Style="{StaticResource CardActionButton}" Content="✕"
Click="DeleteHistory_Click" Padding="8,5" Margin="6,0,0,0" VerticalAlignment="Center"
AutomationProperties.Name="이 방문 기록만 삭제"/>
<Button Style="{StaticResource FlatButton}" Click="OpenHistory_Click" HorizontalAlignment="Stretch" Margin="0,1">
<StackPanel>
<DockPanel>
<TextBlock DockPanel.Dock="Right" Text="{Binding VisitedAt, StringFormat=HH:mm}" Foreground="{DynamicResource TextMuted}" FontSize="10.5" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Title}" TextTrimming="CharacterEllipsis" FontSize="12.5" FontWeight="Medium"/>
</DockPanel>
<TextBlock Text="{Binding Url}" Foreground="{DynamicResource TextMuted}" FontSize="10.5" TextTrimming="CharacterEllipsis"/>
</StackPanel>
</Button>
</DockPanel>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>
</Border>
</Popup>
<!-- ===== 주소창 자동완성 제안 ===== -->
<Popup Name="AddressPopup" PlacementTarget="{Binding ElementName=AddressBox}"
Placement="Bottom" StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade"
Width="560" MaxHeight="380">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="10" Padding="4">
<ListBox Name="AddressSuggestions" Style="{StaticResource SuggestList}"
ItemContainerStyle="{StaticResource SuggestItem}"
PreviewMouseLeftButtonUp="AddressSuggestion_Click">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Title}" TextTrimming="CharacterEllipsis" FontSize="12.5" FontWeight="Medium"/>
<TextBlock Text="{Binding Url}" Foreground="{DynamicResource TextMuted}" FontSize="10.5" TextTrimming="CharacterEllipsis"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</Popup>
<!-- ===== 다운로드 플라이아웃 (T1-5) ===== -->
<!-- T3-12 노트 패널 -->
<Popup Name="NotesPopup" PlacementTarget="{Binding ElementName=AddressBox}"
Placement="Bottom" HorizontalOffset="-40" VerticalOffset="6"
StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="10" Width="420" MaxHeight="460"
Effect="{StaticResource PopupShadow}">
<StackPanel KeyboardNavigation.TabNavigation="Cycle">
<DockPanel Margin="6,2,6,8">
<TextBlock Text="노트" Foreground="{DynamicResource TextPrimary}" FontWeight="SemiBold" VerticalAlignment="Center"/>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Style="{StaticResource CardActionButton}" Content="현재 페이지 추가" Click="NotesAddPage_Click" Margin="0,0,6,0"/>
<!-- UC-K19 노트 편집 저장 -->
<Button x:Name="NotesSaveBtn" Style="{StaticResource CardActionButton}" Content="저장(Ctrl+S)" Click="NotesSave_Click" Margin="0,0,6,0"
AutomationProperties.Name="노트 저장"/>
<Button Style="{StaticResource CardActionButton}" Content="삭제" Click="NotesDelete_Click"/>
</StackPanel>
</DockPanel>
<!-- UC-M22 노트 검색 -->
<TextBox x:Name="NotesSearchBox" Style="{StaticResource DarkTextBox}" FontSize="12" Padding="8,5"
Margin="6,0,6,6" TextChanged="NotesSearchBox_TextChanged"
AutomationProperties.Name="노트 검색"/>
<ListBox Name="NotesList" Background="Transparent" BorderThickness="0" Height="340"
Foreground="{DynamicResource TextPrimary}" FontSize="12"/>
</StackPanel>
</Border>
</Popup>
<!-- T3-14 추적 방지 실드 팝업 -->
<Popup Name="ShieldPopup" PlacementTarget="{Binding ElementName=ShieldBtn}"
Placement="Bottom" HorizontalOffset="-10" VerticalOffset="6"
StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="10" Width="320" MaxHeight="360">
<StackPanel>
<TextBlock Text="추적 방지 — 차단된 요청" Foreground="{DynamicResource TextPrimary}"
FontWeight="SemiBold" Margin="6,4,6,8"/>
<ListBox Name="ShieldDomainStats" Background="Transparent" BorderThickness="0"
Foreground="{DynamicResource TextSecondary}" FontSize="12"/>
</StackPanel>
</Border>
</Popup>
<Popup Name="DownloadsPopup" PlacementTarget="{Binding ElementName=DownloadsBtn}"
Placement="Bottom" HorizontalOffset="-10" VerticalOffset="6"
StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="10" Width="420" MaxHeight="460">
<StackPanel>
<DockPanel Margin="6,2,6,8">
<TextBlock Text="다운로드" Foreground="{DynamicResource TextPrimary}" FontWeight="SemiBold" VerticalAlignment="Center"/>
<Button DockPanel.Dock="Right" Style="{StaticResource CardActionButton}" Content="완료 항목 지우기"
Click="DownloadsClear_Click" HorizontalAlignment="Right"/>
</DockPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="380">
<ItemsControl Name="DownloadsList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="{DynamicResource GlassBg}" BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1" CornerRadius="8" Padding="10" Margin="0,0,0,8">
<StackPanel>
<DockPanel>
<TextBlock DockPanel.Dock="Right" Text="{Binding SpeedText}" Foreground="{DynamicResource TextMuted}"
FontSize="11" VerticalAlignment="Center" Margin="8,0,0,0"/>
<TextBlock Text="{Binding FileName}" Foreground="{DynamicResource TextPrimary}"
FontSize="12.5" FontWeight="Medium" TextTrimming="CharacterEllipsis"/>
</DockPanel>
<ProgressBar Value="{Binding Percent}" Maximum="100" Height="6" Margin="0,7,0,6"
Style="{StaticResource AccentProgressBar}"/>
<DockPanel>
<TextBlock Text="{Binding State}" Foreground="{DynamicResource TextSecondary}" FontSize="11" VerticalAlignment="Center"/>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
<Button Style="{StaticResource CardActionButton}" Content="일시정지" Click="DlPause_Click" Margin="0,0,5,0"/>
<Button Style="{StaticResource CardActionButton}" Content="재개" Click="DlResume_Click" Margin="0,0,5,0"/>
<Button Style="{StaticResource CardActionButton}" Content="취소" Click="DlCancel_Click"/>
</StackPanel>
</DockPanel>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<TextBlock Text="페이지 내 파일 다운로드가 여기 표시됩니다" Foreground="{DynamicResource TextMuted}"
FontSize="11" HorizontalAlignment="Center" Margin="0,4,0,0"
x:Name="DownloadsEmptyHint"/>
</StackPanel>
</Border>
</Popup>
<!-- ===== 탭 검색 팝업 (T2-8, Ctrl+Shift+A) ===== -->
<Popup Name="TabSearchPopup" PlacementTarget="{Binding ElementName=AddressBox}"
Placement="Center" StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade"
Width="520">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="10">
<StackPanel>
<Border Background="{DynamicResource GlassBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="8" Margin="2,0,2,8">
<TextBox Name="TabSearchBox" Style="{StaticResource DarkTextBox}" BorderThickness="0"
Background="Transparent" Padding="12,9" FontSize="13"
TextChanged="TabSearchBox_TextChanged" PreviewKeyDown="TabSearchBox_PreviewKeyDown"/>
</Border>
<ListBox Name="TabSearchResults" Style="{StaticResource SuggestList}"
ItemContainerStyle="{StaticResource SuggestItem}" MaxHeight="320"
PreviewMouseLeftButtonUp="TabSearchResult_Click">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<DockPanel>
<TextBlock DockPanel.Dock="Right" Text="{Binding IsClosed, Converter={x:Static feat:BoolToClosedConverter.Instance}}"
Foreground="{DynamicResource TextMuted}" FontSize="10.5" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Title}" TextTrimming="CharacterEllipsis" FontSize="12.5" FontWeight="Medium"/>
</DockPanel>
<TextBlock Text="{Binding Url}" Foreground="{DynamicResource TextMuted}" FontSize="10.5" TextTrimming="CharacterEllipsis"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Border>
</Popup>
<!-- ===== 명령 팔레트 (T2-1, Ctrl+K) ===== -->
<Popup Name="PalettePopup" PlacementTarget="{Binding ElementName=AddressBox}"
Placement="Center" StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade"
Width="560">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="10">
<StackPanel>
<Border Background="{DynamicResource GlassBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="8" Margin="2,0,2,8">
<TextBox Name="PaletteBox" Style="{StaticResource DarkTextBox}" BorderThickness="0"
Background="Transparent" Padding="12,10" FontSize="13.5"
TextChanged="PaletteBox_TextChanged" PreviewKeyDown="PaletteBox_PreviewKeyDown"/>
</Border>
<ListBox Name="PaletteResults" Style="{StaticResource SuggestList}"
ItemContainerStyle="{StaticResource SuggestItem}" MaxHeight="360"
PreviewMouseLeftButtonUp="PaletteResult_Click">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" TextTrimming="CharacterEllipsis"
FontSize="12.5" Padding="4,2"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Border>
</Popup>
<!-- ===== 미디어 재생목록 플라이아웃 (T2-10) ===== -->
<Popup Name="PlaylistPopup" PlacementTarget="{Binding ElementName=PlaylistBtn}"
Placement="Bottom" HorizontalOffset="-10" VerticalOffset="6"
StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="10" Width="440" MaxHeight="470"
Effect="{StaticResource PopupShadow}">
<StackPanel KeyboardNavigation.TabNavigation="Cycle">
<DockPanel Margin="6,2,6,6">
<TextBlock Text="미디어 재생목록" Foreground="{DynamicResource TextPrimary}" FontWeight="SemiBold" VerticalAlignment="Center"/>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" HorizontalAlignment="Right">
<!-- UC-M11 셔플 -->
<Button x:Name="PlaylistShuffle" Style="{StaticResource CardActionButton}" Content="&#xE8B1; 셔플" Click="PlaylistShuffle_Click" Margin="0,0,5,0"
AutomationProperties.Name="재생목록 셔플"/>
<!-- UC-M12 반복 모드 -->
<Button x:Name="PlaylistLoop" Style="{StaticResource CardActionButton}" Content="반복 끔" Click="PlaylistLoop_Click" Margin="0,0,5,0"
AutomationProperties.Name="반복 모드 전환"/>
<Button Style="{StaticResource CardActionButton}" Content="▶ 재생" Click="PlaylistPlayAll_Click" Margin="0,0,5,0"/>
<!-- UC-M13 재생목록 파일 저장/불러오기 -->
<Button Style="{StaticResource CardActionButton}" Content="내보내기" Click="PlaylistExport_Click" Margin="0,0,5,0"
AutomationProperties.Name="재생목록 내보내기"/>
<Button Style="{StaticResource CardActionButton}" Content="불러오기" Click="PlaylistImport_Click"
AutomationProperties.Name="재생목록 불러오기"/>
</StackPanel>
</DockPanel>
<!-- UC-M15 재생목록 검색 -->
<TextBox x:Name="PlaylistSearchBox" Style="{StaticResource DarkTextBox}" FontSize="12" Padding="8,5"
Margin="6,0,6,6" TextChanged="PlaylistSearchBox_TextChanged"
AutomationProperties.Name="재생목록 검색"/>
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="340">
<ItemsControl Name="PlaylistList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="{DynamicResource GlassBg}" BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1" CornerRadius="8" Padding="10" Margin="0,0,0,7">
<DockPanel>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
<!-- UC-M14 순서 변경 -->
<Button x:Name="PlaylistMoveUp" Style="{StaticResource CardActionButton}" Content="▲" Click="PlaylistMoveUp_Click" Margin="0,0,5,0"
AutomationProperties.Name="한 칸 위로"/>
<Button x:Name="PlaylistMoveDown" Style="{StaticResource CardActionButton}" Content="▼" Click="PlaylistMoveDown_Click" Margin="0,0,5,0"
AutomationProperties.Name="한 칸 아래로"/>
<Button Style="{StaticResource CardActionButton}" Content="▶" Click="PlaylistPlay_Click" Margin="0,0,5,0"/>
<Button Style="{StaticResource CardActionButton}" Content="✕" Click="PlaylistRemove_Click"/>
</StackPanel>
<StackPanel>
<TextBlock Text="{Binding Title}" Foreground="{DynamicResource TextPrimary}" FontSize="12.5"
FontWeight="Medium" TextTrimming="CharacterEllipsis"/>
<TextBlock Foreground="{DynamicResource TextMuted}" FontSize="10.5" TextTrimming="CharacterEllipsis">
<Run Text="{Binding Kind}"/><Run Text=" · "/><Run Text="{Binding AddedAt, StringFormat=MM-dd HH:mm}"/>
</TextBlock>
</StackPanel>
</DockPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<TextBlock x:Name="PlaylistEmptyHint" Text="영상을 재생하면 자동으로 쌓입니다" Foreground="{DynamicResource TextMuted}"
FontSize="11" HorizontalAlignment="Center" Margin="0,4,0,0"/>
</StackPanel>
</Border>
</Popup>
<!-- ===== 링크로 받기 플라이아웃 (YouTube/Instagram/X URL 붙여넣기) ===== -->
<Popup Name="LinkPopup" PlacementTarget="{Binding ElementName=LinkBtn}"
Placement="Bottom" HorizontalOffset="-10" VerticalOffset="6"
StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="10" Width="380"
Effect="{StaticResource PopupShadow}">
<StackPanel KeyboardNavigation.TabNavigation="Cycle">
<TextBlock Text="링크로 받기" Foreground="{DynamicResource TextPrimary}" FontWeight="SemiBold" Margin="6,2,6,4"/>
<TextBlock Text="YouTube·Instagram·X 등 영상 링크를 붙여넣고 받기를 누르세요" Foreground="{DynamicResource TextMuted}" FontSize="11" Margin="6,0,6,10" TextWrapping="Wrap"/>
<DockPanel>
<Button DockPanel.Dock="Right" Style="{StaticResource PrimaryButton}" Content="받기" Margin="8,0,0,0" Click="LinkDownload_Click"/>
<Border Background="{DynamicResource GlassBg}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" CornerRadius="8">
<TextBox Name="LinkBox" Style="{StaticResource DarkTextBox}" BorderThickness="0" Background="Transparent"
Padding="12,8" PreviewKeyDown="LinkBox_PreviewKeyDown"/>
</Border>
</DockPanel>
</StackPanel>
</Border>
</Popup>
<!-- ===== UC-M01 라이브러리 플라이아웃(받은 파일 그리드/리스트) ===== -->
<Popup Name="LibraryPopup" PlacementTarget="{Binding ElementName=LibraryBtn}"
Placement="Bottom" HorizontalOffset="-10" VerticalOffset="6"
StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="10" Width="520" MaxHeight="500"
Effect="{StaticResource PopupShadow}">
<StackPanel KeyboardNavigation.TabNavigation="Cycle">
<DockPanel Margin="6,2,6,6">
<TextBlock Text="라이브러리" Style="{StaticResource Type.H1}" FontSize="15" VerticalAlignment="Center"/>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" HorizontalAlignment="Right">
<!-- UC-M02 그리드/리스트 전환 -->
<Button x:Name="LibraryViewToggle" Style="{StaticResource CardActionButton}" Content="&#xE8FD; 그리드" Click="LibraryViewToggle_Click"
Margin="0,0,6,0" AutomationProperties.Name="라이브러리 보기 전환"/>
<!-- UC-M04 정렬 메뉴 -->
<Menu x:Name="LibrarySortMenu" Background="Transparent">
<MenuItem Header="정렬" Foreground="{DynamicResource TextSecondary}">
<MenuItem Header="이름순" Click="LibrarySort_Click" Tag="name"/>
<MenuItem Header="최근 추가순" Click="LibrarySort_Click" Tag="date"/>
<MenuItem Header="크기순" Click="LibrarySort_Click" Tag="size"/>
</MenuItem>
</Menu>
</StackPanel>
</DockPanel>
<!-- UC-M03 라이브러리 검색 -->
<TextBox x:Name="LibrarySearchBox" Style="{StaticResource DarkTextBox}" FontSize="12" Padding="8,5"
Margin="6,0,6,6" TextChanged="LibrarySearchBox_TextChanged"
AutomationProperties.Name="라이브러리 검색"/>
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="360">
<ItemsControl x:Name="LibraryList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="{DynamicResource GlassBg}" BorderBrush="{DynamicResource BorderSubtle}"
BorderThickness="1" CornerRadius="8" Padding="10" Margin="0,0,0,7"
MouseLeftButtonDown="LibraryItem_DoubleClick">
<DockPanel>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" VerticalAlignment="Center">
<!-- UC-M07 더블클릭 재생 + 버튼 -->
<Button Style="{StaticResource CardActionButton}" Content="▶ 재생" Click="LibraryPlay_Click" Margin="0,0,5,0"
AutomationProperties.Name="파일 재생"/>
<!-- UC-M09 폴더 열기 -->
<Button Style="{StaticResource CardActionButton}" Content="폴더" Click="LibraryOpenFolder_Click" Margin="0,0,5,0"
AutomationProperties.Name="포함 폴더 열기"/>
<!-- UC-M08 삭제 -->
<Button Style="{StaticResource CardActionButton}" Content="삭제" Click="LibraryDelete_Click"
AutomationProperties.Name="파일 삭제"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<!-- UC-M06 썸네일 -->
<Border x:Name="LibraryThumbnail" Width="52" Height="32" CornerRadius="5"
Background="{DynamicResource TrackBrush}" VerticalAlignment="Center" Margin="0,0,10,0">
<TextBlock Text="&#xE8B2;" Style="{StaticResource FluentIcon}" FontSize="14"
Foreground="{DynamicResource TextMuted}"/>
</Border>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="{Binding Name}" Foreground="{DynamicResource TextPrimary}" FontSize="12.5"
FontWeight="Medium" TextTrimming="CharacterEllipsis" MaxWidth="230"/>
<!-- UC-M05 추가일 표시 -->
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="AddedDateText" Text="{Binding AddedAt, StringFormat=yyyy-MM-dd 추가}"
Foreground="{DynamicResource TextMuted}" FontSize="10.5"/>
<TextBlock Text="{Binding SizeText, StringFormat=' · {0}'}"
Foreground="{DynamicResource TextMuted}" FontSize="10.5"/>
</StackPanel>
</StackPanel>
</StackPanel>
</DockPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<!-- UC-M10 빈 상태 안내 -->
<TextBlock x:Name="LibraryEmptyHint" Text="아직 받은 파일이 없습니다. 재생 중인 영상을 받으면 여기에 쌓입니다"
Style="{StaticResource Type.Caption}" HorizontalAlignment="Center" Margin="0,8,0,0"/>
</StackPanel>
</Border>
</Popup>
<!-- ===== UC-B13 닫은 탭 아카이브 팝업 ===== -->
<Popup x:Name="ArchivePopup" PlacementTarget="{Binding ElementName=ArchiveBtn}"
Placement="Bottom" HorizontalOffset="-10" VerticalOffset="6"
StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="10" Width="380" MaxHeight="440"
Effect="{StaticResource PopupShadow}">
<StackPanel KeyboardNavigation.TabNavigation="Cycle">
<DockPanel Margin="6,2,6,6">
<TextBlock Text="닫은 탭 아카이브" Foreground="{DynamicResource TextPrimary}" FontWeight="SemiBold" VerticalAlignment="Center"/>
<!-- UC-B15 전체 비우기 -->
<Button DockPanel.Dock="Right" Style="{StaticResource CardActionButton}" Content="전체 비우기" Click="ArchiveClear_Click"
HorizontalAlignment="Right" AutomationProperties.Name="아카이브 전체 비우기"/>
</DockPanel>
<!-- UC-B14 아카이브 검색 -->
<TextBox x:Name="ArchiveSearchBox" Style="{StaticResource DarkTextBox}" FontSize="12" Padding="8,5"
Margin="6,0,6,6" TextChanged="ArchiveSearchBox_TextChanged"
AutomationProperties.Name="아카이브 검색"/>
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="320">
<ItemsControl x:Name="ArchiveList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- UC-B16 항목 클릭 복구 -->
<Button Style="{StaticResource FlatButton}" Click="ArchiveRestore_Click" HorizontalAlignment="Stretch" Margin="0,1">
<StackPanel>
<TextBlock Text="{Binding Title}" TextTrimming="CharacterEllipsis" FontSize="12.5" FontWeight="Medium"/>
<TextBlock Text="{Binding Url}" Foreground="{DynamicResource TextMuted}" FontSize="10.5" TextTrimming="CharacterEllipsis"/>
</StackPanel>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>
</Border>
</Popup>
<!-- ===== UC-K04 단축키 도움말 팝업 ===== -->
<Popup x:Name="ShortcutHelpPopup" PlacementTarget="{Binding ElementName=AddressBox}"
Placement="Center" StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade" Width="420">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="14"
Effect="{StaticResource PopupShadow}">
<StackPanel KeyboardNavigation.TabNavigation="Cycle">
<TextBlock Text="단축키" Style="{StaticResource Type.H1}" FontSize="15" Margin="0,0,0,10"/>
<ItemsControl x:Name="ShortcutHelpList" MaxHeight="360">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DockPanel Margin="0,3">
<Border DockPanel.Dock="Right" Background="{DynamicResource GlassBg}" CornerRadius="5" Padding="8,2"
BorderBrush="{DynamicResource BorderSubtle}" BorderThickness="1">
<TextBlock Text="{Binding Gesture}" FontFamily="{DynamicResource MonoFont}" FontSize="11"
Foreground="{DynamicResource AccentTextBrush}"/>
</Border>
<TextBlock Text="{Binding Label}" FontSize="12" Foreground="{DynamicResource TextSecondary}" VerticalAlignment="Center"/>
</DockPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
</Popup>
<!-- ===== UC-N14 알림 센터 팝업 ===== -->
<Popup x:Name="NotificationCenterPopup" PlacementTarget="{Binding ElementName=NotificationCenter}"
Placement="Top" HorizontalOffset="-10" VerticalOffset="-6"
StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="12" Padding="10" Width="340" MaxHeight="400"
Effect="{StaticResource PopupShadow}">
<StackPanel>
<TextBlock Text="알림" Foreground="{DynamicResource TextPrimary}" FontWeight="SemiBold" Margin="6,2,6,8"/>
<ListBox x:Name="NotificationCenterList" Background="Transparent" BorderThickness="0" MaxHeight="330"
Foreground="{DynamicResource TextSecondary}" FontSize="12"/>
</StackPanel>
</Border>
</Popup>
<!-- ===== UC-B23 탭 볼륨 팝업(오디오 아이콘 클릭) ===== -->
<Popup x:Name="TabVolumePopup" Placement="MousePoint"
StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade">
<Border Background="{DynamicResource CardBg}" BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1" CornerRadius="10" Padding="12" Width="220"
Effect="{StaticResource PopupShadow}">
<StackPanel>
<DockPanel Margin="0,0,0,6">
<TextBlock Text="탭 볼륨" Foreground="{DynamicResource TextPrimary}" FontWeight="SemiBold"/>
<TextBlock x:Name="TabVolumeValue" Text="100%" DockPanel.Dock="Right" HorizontalAlignment="Right"
Foreground="{DynamicResource TextMuted}" FontSize="11"/>
</DockPanel>
<Slider x:Name="TabVolumeSlider" Minimum="0" Maximum="100" Value="100" ValueChanged="TabVolumeSlider_ValueChanged"
AutomationProperties.Name="탭 볼륨 조절"/>
</StackPanel>
</Border>
</Popup>
</Grid>
</Window>