mirror of
https://github.com/MaxiFan/TunnelX.git
synced 2026-05-17 21:14:37 +03:00
8283b9d6d1
Co-authored-by: Cursor <cursoragent@cursor.com>
874 lines
53 KiB
XML
874 lines
53 KiB
XML
<Window x:Class="AppTunnel.MainWindow"
|
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:conv="clr-namespace:AppTunnel.Converters"
|
|
xmlns:views="clr-namespace:AppTunnel.Views"
|
|
xmlns:vm="clr-namespace:AppTunnel.ViewModels"
|
|
xmlns:model="clr-namespace:AppTunnel.Models"
|
|
Title="TunnelX — Split Traffic Per App"
|
|
Width="620" Height="760"
|
|
MinWidth="580" MinHeight="680"
|
|
WindowStartupLocation="CenterScreen"
|
|
WindowStyle="None"
|
|
AllowsTransparency="True"
|
|
Background="Transparent"
|
|
FlowDirection="RightToLeft"
|
|
MouseLeftButtonDown="OnTitleBarMouseDown">
|
|
|
|
<Window.Resources>
|
|
<conv:BoolToColorConverter x:Key="BoolToColor"/>
|
|
<conv:StringToColorConverter x:Key="StringToColor"/>
|
|
<conv:InverseBoolConverter x:Key="InverseBool"/>
|
|
<conv:BoolToVisibilityConverter x:Key="BoolToVis"/>
|
|
<conv:InverseBoolToVisibilityConverter x:Key="InverseBoolToVis"/>
|
|
<conv:TextToFlowDirectionConverter x:Key="TextToFlowDirection"/>
|
|
</Window.Resources>
|
|
|
|
<!-- Main Container with rounded corners and shadow -->
|
|
<Border x:Name="OuterBorder" Background="{StaticResource BackgroundBrush}"
|
|
CornerRadius="12"
|
|
BorderBrush="{StaticResource CardBrush}"
|
|
BorderThickness="1"
|
|
Cursor="Arrow"
|
|
SizeChanged="OnOuterBorderSizeChanged">
|
|
<Border.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="20" Opacity="0.5" ShadowDepth="0"/>
|
|
</Border.Effect>
|
|
|
|
<Grid>
|
|
<Grid Margin="0" FlowDirection="LeftToRight">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<!-- ═══ MAIN CONTENT ═══ -->
|
|
<Grid Grid.Column="0" FlowDirection="RightToLeft">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="*"/>
|
|
<RowDefinition Height="Auto"/>
|
|
</Grid.RowDefinitions>
|
|
|
|
<!-- ═══ CUSTOM TITLE BAR ═══ -->
|
|
<Border Grid.Row="0" Background="{StaticResource SurfaceBrush}"
|
|
BorderBrush="#12FFFFFF"
|
|
BorderThickness="0,0,0,1"
|
|
CornerRadius="12,0,0,0" Padding="14,8">
|
|
<Grid FlowDirection="LeftToRight">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<!-- Logo & Title -->
|
|
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center">
|
|
<!-- Tx Icon SVG -->
|
|
<Viewbox Width="30" Height="30" Margin="0,0,10,0">
|
|
<Canvas Width="48" Height="48">
|
|
<Rectangle Width="48" Height="48" RadiusX="8" RadiusY="8" Fill="{StaticResource PrimaryBrush}"/>
|
|
<TextBlock Text="Tx" FontSize="24" FontWeight="Bold"
|
|
Foreground="White" Canvas.Left="6" Canvas.Top="8"
|
|
FontFamily="Segoe UI"/>
|
|
</Canvas>
|
|
</Viewbox>
|
|
<StackPanel VerticalAlignment="Bottom" Margin="0,0,0,1">
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock Text="Tunnel" FontSize="17" FontWeight="Bold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"/>
|
|
<TextBlock Text="X" FontSize="17" FontWeight="Bold"
|
|
Foreground="{StaticResource AccentBrush}"/>
|
|
</StackPanel>
|
|
<TextBlock Text="Per-app split tunneling" FontSize="9"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
Margin="0,-3,0,0"/>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
|
|
<!-- Connection Status + Compact Health Chips -->
|
|
<StackPanel Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center">
|
|
<Border HorizontalAlignment="Center"
|
|
CornerRadius="12"
|
|
Padding="12,5"
|
|
Background="#121212"
|
|
BorderBrush="#20FFFFFF"
|
|
BorderThickness="1">
|
|
<StackPanel Orientation="Horizontal">
|
|
<Ellipse Width="9" Height="9" VerticalAlignment="Center" Margin="0,0,8,0"
|
|
Fill="{Binding StatusColor, Converter={StaticResource StringToColor}}"/>
|
|
<TextBlock Text="{Binding StatusText}"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
FontSize="12"
|
|
FontWeight="SemiBold"
|
|
VerticalAlignment="Center"
|
|
MaxWidth="210"
|
|
TextTrimming="CharacterEllipsis"/>
|
|
</StackPanel>
|
|
</Border>
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,5,0,0"
|
|
FlowDirection="LeftToRight">
|
|
<Border Background="#12FFFFFF" CornerRadius="8" Padding="7,2" Margin="0,0,4,0">
|
|
<TextBlock Text="{Binding HeaderCoreText}" FontSize="9"
|
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
|
</Border>
|
|
<Border Background="#12FFFFFF" CornerRadius="8" Padding="7,2" Margin="0,0,4,0">
|
|
<TextBlock Text="{Binding HeaderRouteText}" FontSize="9"
|
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
|
</Border>
|
|
<Border Background="#12FFFFFF" CornerRadius="8" Padding="7,2">
|
|
<TextBlock Text="{Binding HeaderLeakText}" FontSize="9"
|
|
Foreground="{Binding HeaderLeakColor, Converter={StaticResource StringToColor}}"/>
|
|
</Border>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
|
|
<!-- Details Button -->
|
|
<Button Grid.Column="2" Content="جزئیات"
|
|
Click="OnShowLogClick"
|
|
Background="#121212"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
BorderBrush="#20FFFFFF"
|
|
BorderThickness="1"
|
|
Padding="11,6"
|
|
Margin="0,0,8,0"
|
|
FontSize="11"
|
|
Cursor="Hand"
|
|
VerticalAlignment="Center">
|
|
<Button.Style>
|
|
<Style TargetType="Button">
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="8" Padding="{TemplateBinding Padding}">
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
<Style.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Background" Value="#22FFFFFF"/>
|
|
</Trigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</Button.Style>
|
|
</Button>
|
|
|
|
<!-- Window Controls: Minimize → Close (standard Windows order) -->
|
|
<StackPanel Grid.Column="3" Orientation="Horizontal">
|
|
<Button Content="—" Click="OnMinimizeClick"
|
|
ToolTip="کوچک کردن به System Tray"
|
|
Style="{StaticResource WindowControlButton}"
|
|
Width="36" Height="28" FontSize="16" Padding="0,-4,0,0"/>
|
|
<Button Content="✕" Click="OnCloseClick"
|
|
ToolTip="خروج از برنامه"
|
|
Style="{StaticResource WindowControlButton}"
|
|
Width="36" Height="28" FontSize="14" Margin="4,0,0,0"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- ═══ MAIN CONTENT ═══ -->
|
|
<Grid Grid.Row="1">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="*"/>
|
|
<RowDefinition Height="Auto"/>
|
|
</Grid.RowDefinitions>
|
|
|
|
<TabControl Grid.Row="0" Style="{StaticResource ModernTabControl}" Margin="8,6,8,6">
|
|
|
|
<!-- ███ TAB 1: CONNECTION ███ -->
|
|
<TabItem Style="{StaticResource ModernTabItem}" ToolTip="وضعیت اتصال VPN و کنترل اتصال">
|
|
<TabItem.Header>
|
|
<StackPanel>
|
|
<TextBlock Text="⚡" FontSize="13" HorizontalAlignment="Center"/>
|
|
<TextBlock Text="اتصال VPN" FontSize="11" FontWeight="Medium" TextAlignment="Center"/>
|
|
</StackPanel>
|
|
</TabItem.Header>
|
|
<views:ConnectionTabView/>
|
|
</TabItem>
|
|
<TabItem Style="{StaticResource ModernTabItem}" ToolTip="انتخاب برنامههایی که باید از تونل عبور کنند">
|
|
<TabItem.Header>
|
|
<StackPanel>
|
|
<TextBlock Text="📱" FontSize="13" HorizontalAlignment="Center"/>
|
|
<TextBlock Text="برنامهها" FontSize="11" FontWeight="Medium" TextAlignment="Center"/>
|
|
</StackPanel>
|
|
</TabItem.Header>
|
|
<views:AppsTabView/>
|
|
</TabItem>
|
|
|
|
<TabItem Style="{StaticResource ModernTabItem}" ToolTip="تنظیمات عمومی تونل و DNS">
|
|
<TabItem.Header>
|
|
<StackPanel>
|
|
<TextBlock Text="⚙" FontSize="13" HorizontalAlignment="Center"/>
|
|
<TextBlock Text="تنظیمات" FontSize="11" FontWeight="Medium" TextAlignment="Center"/>
|
|
</StackPanel>
|
|
</TabItem.Header>
|
|
<views:SettingsTabView/>
|
|
</TabItem>
|
|
|
|
<!-- ███ TAB 3: ROUTING RULES ███ -->
|
|
<TabItem Style="{StaticResource ModernTabItem}" ToolTip="قوانین Include و Exclude مسیرها">
|
|
<TabItem.Header>
|
|
<StackPanel>
|
|
<TextBlock Text="🧭" FontSize="13" HorizontalAlignment="Center"/>
|
|
<TextBlock Text="قوانین مسیر" FontSize="11" FontWeight="Medium" TextAlignment="Center"/>
|
|
</StackPanel>
|
|
</TabItem.Header>
|
|
|
|
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="0,10,0,0">
|
|
<StackPanel HorizontalAlignment="Stretch" Margin="16,0">
|
|
|
|
<Border Background="#121212" BorderBrush="#18FFFFFF" BorderThickness="1"
|
|
CornerRadius="10" Padding="12,8" Margin="0,0,0,10">
|
|
<StackPanel>
|
|
<TextBlock Text="قوانین مسیر"
|
|
FontSize="13"
|
|
FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"/>
|
|
<TextBlock Text="مقصدهای مستقیم و مقصدهای اجباری تونل را اینجا مدیریت کنید."
|
|
TextWrapping="Wrap"
|
|
FontSize="10"
|
|
Margin="0,2,0,0"
|
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="10"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<StackPanel Grid.Column="0">
|
|
<!-- Info Card -->
|
|
<Border Style="{StaticResource CardPanel}" Margin="0,0,0,8" BorderBrush="#2247A3F3">
|
|
<StackPanel>
|
|
<TextBlock Text="🚫 مستقیم بماند" FontSize="13" FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}" Margin="0,0,0,4"/>
|
|
<TextBlock TextWrapping="Wrap" Foreground="{StaticResource TextSecondaryBrush}" FontSize="10"
|
|
Text="این مقصدها از تونل عبور نمیکنند."/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Tip for Excludes -->
|
|
<Border Background="#1247A3F3" BorderBrush="#2647A3F3" BorderThickness="1"
|
|
CornerRadius="9" Padding="10,7" Margin="0,0,0,8">
|
|
<StackPanel>
|
|
<StackPanel Orientation="Horizontal" Margin="0,0,0,3">
|
|
<TextBlock Text="💡" FontSize="11" Margin="0,0,5,0"/>
|
|
<TextBlock Text="نمونه کاربرد" FontSize="10" FontWeight="SemiBold"
|
|
Foreground="#47A3F3"/>
|
|
</StackPanel>
|
|
<TextBlock Text="سایتهای داخلی یا سرورهای بازی را مستقیم نگه دارید."
|
|
TextWrapping="Wrap" FontSize="10" LineHeight="15"
|
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Add Entry -->
|
|
<Border Style="{StaticResource CardPanel}" Margin="0,0,0,8">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBox Grid.Column="0" Style="{StaticResource ModernTextBox}"
|
|
Text="{Binding ExcludeInput, UpdateSourceTrigger=PropertyChanged}"
|
|
Tag="دامنه یا آیپی (مثلاً google.com یا 1.2.3.4)"
|
|
FlowDirection="LeftToRight"
|
|
FontSize="12" Padding="9,6"
|
|
Margin="0,0,7,0">
|
|
<TextBox.InputBindings>
|
|
<KeyBinding Key="Enter" Command="{Binding AddExcludeCommand}"/>
|
|
</TextBox.InputBindings>
|
|
</TextBox>
|
|
<Button Grid.Column="1" Style="{StaticResource PrimaryButton}"
|
|
Content="افزودن"
|
|
Command="{Binding AddExcludeCommand}"
|
|
FontSize="11" Padding="12,6"/>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Exclude List -->
|
|
<Border Style="{StaticResource CardPanel}" BorderBrush="#2247A3F3">
|
|
<DockPanel>
|
|
<TextBlock DockPanel.Dock="Top" FontSize="12" FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}" Margin="0,0,0,6"
|
|
Text="آدرسهای مستقیم"/>
|
|
<ListView ItemsSource="{Binding ExcludedDestinations}"
|
|
Background="Transparent"
|
|
BorderThickness="0"
|
|
FlowDirection="LeftToRight"
|
|
Cursor="Arrow"
|
|
PreviewMouseWheel="OnNestedScrollPreviewMouseWheel"
|
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
|
<ListView.ItemTemplate>
|
|
<DataTemplate>
|
|
<Border Background="#11FFFFFF" CornerRadius="7"
|
|
Padding="9,5" Margin="0,2" Cursor="Arrow">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="🚫"
|
|
VerticalAlignment="Center" Margin="0,0,8,0"/>
|
|
<TextBlock Grid.Column="1" Text="{Binding}"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
FontSize="12" VerticalAlignment="Center"
|
|
FlowDirection="LeftToRight"/>
|
|
<Button Grid.Column="2" Style="{StaticResource DangerButton}"
|
|
Content="حذف" FontSize="10" Padding="7,3"
|
|
Command="{Binding DataContext.RemoveExcludeCommand,
|
|
RelativeSource={RelativeSource AncestorType=Window}}"
|
|
CommandParameter="{Binding}"/>
|
|
</Grid>
|
|
</Border>
|
|
</DataTemplate>
|
|
</ListView.ItemTemplate>
|
|
<ListView.ItemContainerStyle>
|
|
<Style TargetType="ListViewItem">
|
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
|
<Setter Property="Padding" Value="0"/>
|
|
<Setter Property="Margin" Value="0"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="ListViewItem">
|
|
<ContentPresenter/>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
</ListView.ItemContainerStyle>
|
|
</ListView>
|
|
</DockPanel>
|
|
</Border>
|
|
|
|
</StackPanel>
|
|
|
|
<Border Grid.Column="1" Width="1" Background="#18FFFFFF" Margin="0,2"/>
|
|
|
|
<StackPanel Grid.Column="2">
|
|
|
|
<!-- Include Info -->
|
|
<Border Style="{StaticResource CardPanel}" Margin="0,0,0,8" BorderBrush="#2233C481">
|
|
<StackPanel>
|
|
<TextBlock Text="✅ از تونل عبور کند" FontSize="13" FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}" Margin="0,0,0,4"/>
|
|
<TextBlock TextWrapping="Wrap" Foreground="{StaticResource TextSecondaryBrush}" FontSize="10"
|
|
Text="این مقصدها همیشه از تونل عبور میکنند."/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Add Include Entry -->
|
|
<Border Style="{StaticResource CardPanel}" Margin="0,0,0,8">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBox Grid.Column="0" Style="{StaticResource ModernTextBox}"
|
|
Text="{Binding IncludeInput, UpdateSourceTrigger=PropertyChanged}"
|
|
Tag="دامنه یا آیپی (مثلاً example.com یا 1.2.3.4)"
|
|
FlowDirection="LeftToRight"
|
|
FontSize="12" Padding="9,6"
|
|
Margin="0,0,7,0">
|
|
<TextBox.InputBindings>
|
|
<KeyBinding Key="Enter" Command="{Binding AddIncludeCommand}"/>
|
|
</TextBox.InputBindings>
|
|
</TextBox>
|
|
<Button Grid.Column="1" Style="{StaticResource PrimaryButton}"
|
|
Content="افزودن"
|
|
Command="{Binding AddIncludeCommand}"
|
|
FontSize="11" Padding="12,6"/>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Include List -->
|
|
<Border Style="{StaticResource CardPanel}" BorderBrush="#2233C481">
|
|
<DockPanel>
|
|
<TextBlock DockPanel.Dock="Top" FontSize="12" FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}" Margin="0,0,0,6"
|
|
Text="آدرسهای اجباری"/>
|
|
<ListView ItemsSource="{Binding IncludedDestinations}"
|
|
Background="Transparent"
|
|
BorderThickness="0"
|
|
FlowDirection="LeftToRight"
|
|
Cursor="Arrow"
|
|
PreviewMouseWheel="OnNestedScrollPreviewMouseWheel"
|
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
|
<ListView.ItemTemplate>
|
|
<DataTemplate>
|
|
<Border Background="#11FFFFFF" CornerRadius="7"
|
|
Padding="9,5" Margin="0,2" Cursor="Arrow">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="✅"
|
|
VerticalAlignment="Center" Margin="0,0,8,0"/>
|
|
<TextBlock Grid.Column="1" Text="{Binding}"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
FontSize="12" VerticalAlignment="Center"
|
|
FlowDirection="LeftToRight"/>
|
|
<Button Grid.Column="2" Style="{StaticResource DangerButton}"
|
|
Content="حذف" FontSize="10" Padding="7,3"
|
|
Command="{Binding DataContext.RemoveIncludeCommand,
|
|
RelativeSource={RelativeSource AncestorType=Window}}"
|
|
CommandParameter="{Binding}"/>
|
|
</Grid>
|
|
</Border>
|
|
</DataTemplate>
|
|
</ListView.ItemTemplate>
|
|
<ListView.ItemContainerStyle>
|
|
<Style TargetType="ListViewItem">
|
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
|
<Setter Property="Padding" Value="0"/>
|
|
<Setter Property="Margin" Value="0"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="ListViewItem">
|
|
<ContentPresenter/>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
</ListView.ItemContainerStyle>
|
|
</ListView>
|
|
</DockPanel>
|
|
</Border>
|
|
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</TabItem>
|
|
|
|
<!-- ███ TAB 5: TRAFFIC MONITOR ███ -->
|
|
<TabItem Style="{StaticResource ModernTabItem}" ToolTip="نمایش ترافیک، تاریخچه و آمار اتصال">
|
|
<TabItem.Header>
|
|
<StackPanel>
|
|
<TextBlock Text="📊" FontSize="13" HorizontalAlignment="Center"/>
|
|
<TextBlock Text="ترافیک/تاریخچه" FontSize="10.5" FontWeight="Medium" TextAlignment="Center"/>
|
|
</StackPanel>
|
|
</TabItem.Header>
|
|
|
|
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="0,12,0,0">
|
|
<StackPanel HorizontalAlignment="Stretch" Margin="16,0">
|
|
|
|
<!-- Summary Card -->
|
|
<Border Style="{StaticResource CardPanel}" BorderBrush="#22E8803A">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<StackPanel Grid.Column="0" HorizontalAlignment="Center">
|
|
<TextBlock Text="⏱ مدت" FontSize="11"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding ConnectionDuration}" FontSize="20"
|
|
FontWeight="Bold" Foreground="{StaticResource AccentBrush}"
|
|
HorizontalAlignment="Center" Margin="0,6,0,0"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
|
|
<StackPanel Grid.Column="1" HorizontalAlignment="Center">
|
|
<TextBlock Text="🌐 IP" FontSize="11"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding VpnIp}" FontSize="14"
|
|
FontWeight="SemiBold" Foreground="{StaticResource SuccessBrush}"
|
|
HorizontalAlignment="Center" Margin="0,6,0,0"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
|
|
<StackPanel Grid.Column="2" HorizontalAlignment="Center">
|
|
<TextBlock Text="📊 تونل" FontSize="11"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding TotalTraffic}" FontSize="14"
|
|
FontWeight="SemiBold" Foreground="{StaticResource WarningBrush}"
|
|
HorizontalAlignment="Center" Margin="0,6,0,0"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
|
|
<StackPanel Grid.Column="3" HorizontalAlignment="Center">
|
|
<TextBlock Text="📡 خارج تونل" FontSize="11"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding DirectTraffic}" FontSize="14"
|
|
FontWeight="SemiBold" Foreground="{StaticResource TextPrimaryBrush}"
|
|
HorizontalAlignment="Center" Margin="0,6,0,0"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Split Tunnel Health -->
|
|
<Border Style="{StaticResource CardPanel}" BorderBrush="#2233C481">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<StackPanel Grid.Column="0" HorizontalAlignment="Center">
|
|
<TextBlock Text="Leak" FontSize="10" Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding HealthLeakText}" FontSize="13" FontWeight="SemiBold"
|
|
Foreground="{Binding HeaderLeakColor, Converter={StaticResource StringToColor}}"
|
|
HorizontalAlignment="Center" FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="1" HorizontalAlignment="Center">
|
|
<TextBlock Text="DNS" FontSize="10" Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding HealthDnsText}" FontSize="13" FontWeight="SemiBold"
|
|
Foreground="{StaticResource AccentBrush}"
|
|
HorizontalAlignment="Center" FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2" HorizontalAlignment="Center">
|
|
<TextBlock Text="IPv6" FontSize="10" Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding HealthIpv6Text}" FontSize="13" FontWeight="SemiBold"
|
|
Foreground="{StaticResource WarningBrush}"
|
|
HorizontalAlignment="Center" FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="3" HorizontalAlignment="Center">
|
|
<TextBlock Text="Route" FontSize="10" Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding HealthRoutesText}" FontSize="13" FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
HorizontalAlignment="Center" FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<Expander Header="📜 تاریخچه اتصالات"
|
|
IsExpanded="False"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
Background="#121212"
|
|
BorderBrush="#18FFFFFF"
|
|
Padding="10,6"
|
|
Margin="0,0,0,8">
|
|
<views:HistoryTabView/>
|
|
</Expander>
|
|
|
|
<!-- Per-App Traffic -->
|
|
<Border Style="{StaticResource CardPanel}" BorderBrush="#2247A3F3">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionHeader}"
|
|
Text="مصرف تونل به تفکیک برنامه"/>
|
|
<Grid Margin="0,6,0,8">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<Border Grid.Column="0" Background="#11FFFFFF" CornerRadius="8" Padding="10,7">
|
|
<StackPanel Orientation="Horizontal" FlowDirection="LeftToRight">
|
|
<TextBlock Text="اپهای تونل: " FontSize="11"
|
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
|
<TextBlock Text="{Binding AppTrafficTotal}" FontSize="11" FontWeight="SemiBold"
|
|
Foreground="{StaticResource AccentBrush}"/>
|
|
</StackPanel>
|
|
</Border>
|
|
<Border Grid.Column="2" Background="#11FFFFFF" CornerRadius="8" Padding="10,7">
|
|
<StackPanel Orientation="Horizontal" FlowDirection="LeftToRight">
|
|
<TextBlock Text="سایر تونل: " FontSize="11"
|
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
|
<TextBlock Text="{Binding OtherTunnelTraffic}" FontSize="11" FontWeight="SemiBold"
|
|
Foreground="{StaticResource WarningBrush}"/>
|
|
</StackPanel>
|
|
</Border>
|
|
</Grid>
|
|
|
|
<ItemsControl ItemsSource="{Binding TunnelApps}" Cursor="Arrow">
|
|
<ItemsControl.ItemTemplate>
|
|
<DataTemplate>
|
|
<Border Background="#11FFFFFF" CornerRadius="8"
|
|
Padding="12,10" Margin="0,3" Cursor="Arrow">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<Image Grid.Column="0" Source="{Binding Icon}"
|
|
Width="24" Height="24" Margin="0,0,10,0"/>
|
|
|
|
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
|
<TextBlock Text="{Binding DisplayName}"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
FontSize="13"/>
|
|
<StackPanel Orientation="Horizontal" Margin="0,2,0,0"
|
|
FlowDirection="LeftToRight">
|
|
<TextBlock Text="↑ " Foreground="{StaticResource WarningBrush}"
|
|
FontSize="10"/>
|
|
<TextBlock Text="{Binding BytesSent, StringFormat={}{0:N0} B ↑}"
|
|
Foreground="{StaticResource WarningBrush}"
|
|
FontSize="10" Margin="0,0,10,0"/>
|
|
<TextBlock Text="{Binding BytesReceived, StringFormat={}{0:N0} B ↓}"
|
|
Foreground="{StaticResource SuccessBrush}"
|
|
FontSize="10"/>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
|
|
<TextBlock Grid.Column="2" Text="{Binding TrafficDisplay}"
|
|
Foreground="{StaticResource AccentBrush}"
|
|
FontSize="14" FontWeight="SemiBold"
|
|
VerticalAlignment="Center"
|
|
FlowDirection="LeftToRight"/>
|
|
</Grid>
|
|
</Border>
|
|
</DataTemplate>
|
|
</ItemsControl.ItemTemplate>
|
|
</ItemsControl>
|
|
|
|
<!-- Empty state -->
|
|
<TextBlock Text="هنوز برنامهای اضافه نشده. از تب «برنامهها» اضافه کنید."
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
FontSize="13" HorizontalAlignment="Center"
|
|
Margin="0,20">
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Visibility" Value="Collapsed"/>
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding TunnelApps.Count}" Value="0">
|
|
<Setter Property="Visibility" Value="Visible"/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</TabItem>
|
|
|
|
</TabControl>
|
|
|
|
</Grid>
|
|
|
|
<!-- ═══ FOOTER ═══ -->
|
|
<Border Grid.Row="2"
|
|
Background="#121212"
|
|
BorderBrush="#18FFFFFF"
|
|
BorderThickness="0,1,0,0"
|
|
CornerRadius="0,0,0,12"
|
|
Padding="12,6">
|
|
<Grid VerticalAlignment="Center" FlowDirection="RightToLeft">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="12"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<StackPanel Grid.Column="0"
|
|
Orientation="Horizontal"
|
|
FlowDirection="RightToLeft"
|
|
HorizontalAlignment="Right"
|
|
VerticalAlignment="Center">
|
|
<TextBlock Text="ساخته شده توسط Maxifan"
|
|
FontSize="10"
|
|
FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
VerticalAlignment="Center"/>
|
|
<Border Background="#18E8803A"
|
|
CornerRadius="8"
|
|
Padding="7,2"
|
|
Margin="8,0,0,0"
|
|
VerticalAlignment="Center">
|
|
<TextBlock Text="{Binding AppVersion}"
|
|
FontSize="9"
|
|
Foreground="{StaticResource AccentBrush}"
|
|
VerticalAlignment="Center"/>
|
|
</Border>
|
|
<TextBlock Text="TunnelX"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
FontSize="10"
|
|
TextTrimming="CharacterEllipsis"
|
|
VerticalAlignment="Center"
|
|
Margin="8,0,0,0"/>
|
|
</StackPanel>
|
|
|
|
<StackPanel Grid.Column="3"
|
|
Orientation="Horizontal"
|
|
HorizontalAlignment="Left"
|
|
VerticalAlignment="Center"
|
|
FlowDirection="RightToLeft">
|
|
<Button Content="بروزرسانی"
|
|
Command="{Binding OpenLatestReleaseCommand}"
|
|
Visibility="{Binding IsUpdateAvailable, Converter={StaticResource BoolToVis}}"
|
|
Style="{StaticResource PrimaryButton}"
|
|
Padding="10,4"
|
|
FontSize="10"
|
|
Margin="0,0,0,0"
|
|
VerticalAlignment="Center"
|
|
ToolTip="دانلود نسخه جدید از صفحه Releases در GitHub"/>
|
|
<Button Content="راهنما"
|
|
Click="OnShowHelpClick"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Padding="9,4"
|
|
FontSize="10"
|
|
Margin="8,0,0,0"
|
|
VerticalAlignment="Center"
|
|
ToolTip="راهنما و عیبیابی"/>
|
|
<Button Content="GitHub"
|
|
Command="{Binding OpenGitHubCommand}"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Padding="9,4"
|
|
FontSize="10"
|
|
Margin="8,0,0,0"
|
|
VerticalAlignment="Center"
|
|
ToolTip="باز کردن صفحه GitHub پروژه TunnelX"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
|
|
</Grid> <!-- end main content column -->
|
|
|
|
<!-- ═══ LOG PANEL (RIGHT SIDE) ═══ -->
|
|
<Border x:Name="LogPanel" Grid.Column="1" Visibility="Collapsed"
|
|
Background="{StaticResource SurfaceBrush}"
|
|
BorderBrush="{StaticResource CardBrush}" BorderThickness="1,0,0,0">
|
|
<Grid Width="350">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="*"/>
|
|
</Grid.RowDefinitions>
|
|
|
|
<!-- Log Header -->
|
|
<Border Grid.Row="0" Padding="12,10" Background="#11FFFFFF">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="🔍 جزئیات عملکرد" FontSize="13" FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}" VerticalAlignment="Center"/>
|
|
<ComboBox x:Name="LogFilterCombo"
|
|
Grid.Column="1"
|
|
SelectedIndex="0"
|
|
SelectionChanged="OnLogFilterChanged"
|
|
Margin="0,0,6,0"
|
|
MinWidth="86"
|
|
Style="{StaticResource DarkComboBox}">
|
|
<ComboBoxItem Content="همه" Tag="All"/>
|
|
<ComboBoxItem Content="خطا" Tag="Error"/>
|
|
<ComboBoxItem Content="هشدار" Tag="Warn"/>
|
|
<ComboBoxItem Content="DNS" Tag="Dns"/>
|
|
<ComboBoxItem Content="Route" Tag="Route"/>
|
|
</ComboBox>
|
|
<StackPanel Grid.Column="2" Orientation="Horizontal">
|
|
<Button Content="🗑" ToolTip="پاک کردن" Click="OnLogClearClick"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Padding="8,4" FontSize="12" Margin="0,0,4,0"/>
|
|
<Button Content="⚠" ToolTip="کپی آخرین خطا یا هشدار" Click="OnLogCopyLastErrorClick"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Padding="8,4" FontSize="12" Margin="0,0,4,0"/>
|
|
<Button Content="📋" ToolTip="کپی کردن" Click="OnLogCopyClick"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Padding="8,4" FontSize="12"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Log Content -->
|
|
<TextBox x:Name="LogTextBox" Grid.Row="1"
|
|
Background="{StaticResource SurfaceBrush}"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
BorderThickness="0"
|
|
FontFamily="Consolas"
|
|
FontSize="11"
|
|
Padding="8"
|
|
IsReadOnly="True"
|
|
TextWrapping="Wrap"
|
|
FlowDirection="LeftToRight"
|
|
VerticalScrollBarVisibility="Auto"/>
|
|
</Grid>
|
|
</Border>
|
|
|
|
</Grid>
|
|
|
|
<!-- Toast Notification Overlay -->
|
|
<Border x:Name="ToastPanel"
|
|
Background="#E0303030" CornerRadius="8"
|
|
Padding="14,8" Margin="0,0,0,16"
|
|
HorizontalAlignment="Center" VerticalAlignment="Bottom"
|
|
Visibility="Collapsed"
|
|
IsHitTestVisible="False">
|
|
<Border.Effect>
|
|
<DropShadowEffect Color="Black" BlurRadius="12" Opacity="0.4" ShadowDepth="2"/>
|
|
</Border.Effect>
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock x:Name="ToastIcon" Text="✅" FontSize="14" VerticalAlignment="Center" Margin="0,0,8,0"/>
|
|
<TextBlock x:Name="ToastMessage" Text="" FontSize="12"
|
|
Foreground="{StaticResource TextPrimaryBrush}" VerticalAlignment="Center"/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Startup Loading Overlay — dismissed quickly while app discovery continues in the background. -->
|
|
<Border x:Name="LoadingOverlay" CornerRadius="12"
|
|
Background="{StaticResource BackgroundBrush}"
|
|
FlowDirection="LeftToRight">
|
|
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
|
|
<!-- Logo -->
|
|
<Viewbox Width="60" Height="60" HorizontalAlignment="Center" Margin="0,0,0,20">
|
|
<Canvas Width="48" Height="48">
|
|
<Rectangle Width="48" Height="48" RadiusX="8" RadiusY="8"
|
|
Fill="{StaticResource PrimaryBrush}"/>
|
|
<TextBlock Text="Tx" FontSize="24" FontWeight="Bold"
|
|
Foreground="White" Canvas.Left="6" Canvas.Top="8"
|
|
FontFamily="Segoe UI"/>
|
|
</Canvas>
|
|
</Viewbox>
|
|
<!-- App name -->
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,6">
|
|
<TextBlock Text="Tunnel" FontSize="24" FontWeight="Bold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"/>
|
|
<TextBlock Text="X" FontSize="24" FontWeight="Bold"
|
|
Foreground="{StaticResource AccentBrush}"/>
|
|
</StackPanel>
|
|
<TextBlock Text="Split Traffic Per App" FontSize="11"
|
|
HorizontalAlignment="Center"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
Margin="0,0,0,28"/>
|
|
<!-- Indeterminate progress bar -->
|
|
<ProgressBar IsIndeterminate="True" Width="220" Height="3"
|
|
BorderThickness="0"
|
|
Foreground="{StaticResource AccentBrush}"
|
|
Background="#22FFFFFF"/>
|
|
<!-- Status text -->
|
|
<TextBlock x:Name="LoadingStatusText"
|
|
Text="در حال بارگذاری..."
|
|
FontSize="11" HorizontalAlignment="Center"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
Margin="0,14,0,0"/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
</Grid>
|
|
</Border>
|
|
</Window>
|