mirror of
https://github.com/MaxiFan/TunnelX.git
synced 2026-05-19 08:04:41 +03:00
04d8d52ba9
Co-authored-by: Cursor <cursoragent@cursor.com>
985 lines
60 KiB
XML
985 lines
60 KiB
XML
<UserControl x:Class="AppTunnel.Views.ConnectionTabView"
|
|
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:models="clr-namespace:AppTunnel.Models">
|
|
|
|
<UserControl.Resources>
|
|
<conv:BoolToVisibilityConverter x:Key="BoolToVis"/>
|
|
<conv:InverseBoolToVisibilityConverter x:Key="InverseBoolToVis"/>
|
|
<conv:StringToColorConverter x:Key="StringToColor"/>
|
|
<conv:EnumToVisibilityConverter x:Key="EnumToVis"/>
|
|
</UserControl.Resources>
|
|
|
|
<ScrollViewer FlowDirection="{Binding AppFlowDirection}"
|
|
VerticalScrollBarVisibility="Auto"
|
|
HorizontalScrollBarVisibility="Disabled">
|
|
<StackPanel HorizontalAlignment="Stretch" Margin="16,8,16,4">
|
|
|
|
<!-- ══ DISCONNECTED STATE: Show connection form ══ -->
|
|
<StackPanel Visibility="{Binding IsConnected, Converter={StaticResource InverseBoolToVis}}">
|
|
|
|
<!-- OpenVPN connecting view -->
|
|
<Border Background="#33221812"
|
|
BorderBrush="{StaticResource WarningBrush}"
|
|
BorderThickness="1"
|
|
CornerRadius="12"
|
|
Padding="18,16"
|
|
Margin="0,0,0,10"
|
|
Visibility="{Binding IsOpenVpnConnectionPending, Converter={StaticResource BoolToVis}}">
|
|
<StackPanel>
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="12"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="12"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<Border Grid.Column="0"
|
|
Width="42"
|
|
Height="42"
|
|
CornerRadius="21"
|
|
Background="#22FFC107"
|
|
VerticalAlignment="Top">
|
|
<TextBlock Text="⏳"
|
|
FontSize="20"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"/>
|
|
</Border>
|
|
<StackPanel Grid.Column="2">
|
|
<TextBlock Text="در حال اتصال OpenVPN"
|
|
FontSize="15"
|
|
FontWeight="SemiBold"
|
|
Foreground="{StaticResource WarningBrush}"/>
|
|
<TextBlock Text="{Binding StatusText}"
|
|
TextWrapping="Wrap"
|
|
FontSize="11"
|
|
LineHeight="18"
|
|
Margin="0,5,0,0"
|
|
Foreground="{StaticResource TextPrimaryBrush}"/>
|
|
<TextBlock Text="تا قبل از بالا آمدن آداپتر، مسیرهای سیستم تغییر داده نمیشود. اگر اتصال طولانی شد، فایل .ovpn، نام کاربری/رمز یا نصب OpenVPN Community را بررسی کنید."
|
|
TextWrapping="Wrap"
|
|
FontSize="10"
|
|
LineHeight="17"
|
|
Margin="0,6,0,0"
|
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
|
</StackPanel>
|
|
<Button Grid.Column="4"
|
|
Style="{StaticResource DangerButton}"
|
|
Content="لغو اتصال"
|
|
Command="{Binding ConnectCommand}"
|
|
VerticalAlignment="Top"
|
|
Padding="14,7"/>
|
|
</Grid>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- ── Profile Card ── -->
|
|
<Border Style="{StaticResource CardPanel}"
|
|
Visibility="{Binding IsOpenVpnConnectionPending, Converter={StaticResource InverseBoolToVis}}">
|
|
<StackPanel>
|
|
<Grid Margin="0,0,0,12">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="10"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<StackPanel Grid.Column="0">
|
|
<TextBlock Text="کانفیگها و پروفایلها"
|
|
FontSize="16"
|
|
FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"/>
|
|
<TextBlock Text="یک کانفیگ را انتخاب کنید، ویرایش کنید یا کانفیگ جدید بسازید."
|
|
FontSize="11"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
Margin="0,4,0,0"/>
|
|
</StackPanel>
|
|
<Button Grid.Column="2"
|
|
Style="{StaticResource PrimaryButton}"
|
|
Content="افزودن کانفیگ جدید"
|
|
FontSize="12"
|
|
Padding="16,9"
|
|
Command="{Binding NewProfileCommand}"/>
|
|
</Grid>
|
|
|
|
<ListBox ItemsSource="{Binding Profiles}"
|
|
SelectedItem="{Binding SelectedProfile, Mode=TwoWay}"
|
|
Background="Transparent"
|
|
BorderThickness="0"
|
|
Padding="0"
|
|
PreviewMouseWheel="OnProfileListPreviewMouseWheel"
|
|
ScrollViewer.VerticalScrollBarVisibility="Disabled"
|
|
SelectionMode="Single">
|
|
<ListBox.ItemContainerStyle>
|
|
<Style TargetType="ListBoxItem">
|
|
<Setter Property="Padding" Value="0"/>
|
|
<Setter Property="Margin" Value="0,0,0,6"/>
|
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
|
<Setter Property="Background" Value="#121212"/>
|
|
<Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
|
|
<Setter Property="BorderThickness" Value="1"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="ListBoxItem">
|
|
<Border x:Name="ItemBorder"
|
|
Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="10"
|
|
Padding="10,8">
|
|
<ContentPresenter/>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="ItemBorder" Property="BorderBrush" Value="{StaticResource AccentBrush}"/>
|
|
<Setter TargetName="ItemBorder" Property="Background" Value="#181818"/>
|
|
</Trigger>
|
|
<Trigger Property="IsSelected" Value="True">
|
|
<Setter TargetName="ItemBorder" Property="BorderBrush" Value="{StaticResource PrimaryBrush}"/>
|
|
<Setter TargetName="ItemBorder" Property="Background" Value="#24180F"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
</ListBox.ItemContainerStyle>
|
|
<ListBox.ItemTemplate>
|
|
<DataTemplate>
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<StackPanel Grid.Column="0">
|
|
<StackPanel Orientation="Horizontal" FlowDirection="{Binding DataContext.AppFlowDirection, RelativeSource={RelativeSource AncestorType=UserControl}}">
|
|
<TextBlock Text="{Binding Name}"
|
|
FontSize="13"
|
|
FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
TextTrimming="CharacterEllipsis"/>
|
|
<Border Background="#18E8803A"
|
|
CornerRadius="8"
|
|
Padding="7,2"
|
|
Margin="8,0,0,0">
|
|
<TextBlock Text="{Binding TunnelTypeDisplay}"
|
|
FontSize="9"
|
|
Foreground="{StaticResource AccentBrush}"/>
|
|
</Border>
|
|
</StackPanel>
|
|
<StackPanel Orientation="Horizontal"
|
|
FlowDirection="LeftToRight"
|
|
Margin="0,5,0,0">
|
|
<TextBlock Text="{Binding EndpointDisplay}"
|
|
FontSize="10"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
TextTrimming="CharacterEllipsis"/>
|
|
<TextBlock Text=" • "
|
|
FontSize="10"
|
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
|
<TextBlock Text="{Binding ReadinessText}"
|
|
Foreground="{Binding ReadinessColor, Converter={StaticResource StringToColor}}"
|
|
FontSize="10"
|
|
FontWeight="SemiBold"/>
|
|
</StackPanel>
|
|
</StackPanel>
|
|
|
|
<StackPanel Grid.Column="2"
|
|
Orientation="Horizontal"
|
|
FlowDirection="{Binding DataContext.AppFlowDirection, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
|
VerticalAlignment="Center">
|
|
<Button Style="{StaticResource PrimaryButton}"
|
|
Content="فعال"
|
|
FontSize="10"
|
|
Padding="10,5"
|
|
Command="{Binding DataContext.SelectProfileCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
|
|
CommandParameter="{Binding}"
|
|
ToolTip="استفاده از این کانفیگ برای اتصال"/>
|
|
<Button Style="{StaticResource SecondaryButton}"
|
|
Content="ویرایش"
|
|
FontSize="10"
|
|
Padding="9,5"
|
|
Margin="5,0,0,0"
|
|
Command="{Binding DataContext.EditProfileCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
|
|
CommandParameter="{Binding}"/>
|
|
<Button Style="{StaticResource SecondaryButton}"
|
|
Content="کپی"
|
|
FontSize="10"
|
|
Padding="9,5"
|
|
Margin="5,0,0,0"
|
|
Command="{Binding DataContext.DuplicateProfileCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
|
|
CommandParameter="{Binding}"/>
|
|
<Button Style="{StaticResource DangerButton}"
|
|
Content="حذف"
|
|
FontSize="10"
|
|
Padding="9,5"
|
|
Margin="5,0,0,0"
|
|
Command="{Binding DataContext.DeleteProfileCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
|
|
CommandParameter="{Binding}"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</DataTemplate>
|
|
</ListBox.ItemTemplate>
|
|
</ListBox>
|
|
|
|
<Border Background="#151515"
|
|
BorderBrush="#22FFFFFF"
|
|
BorderThickness="1"
|
|
CornerRadius="12"
|
|
Padding="12,10"
|
|
Margin="0,10,0,0">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="10"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<StackPanel Grid.Column="0" VerticalAlignment="Center">
|
|
<StackPanel Orientation="Horizontal" FlowDirection="{Binding AppFlowDirection}">
|
|
<Ellipse Width="9" Height="9"
|
|
Fill="{Binding StatusColor, Converter={StaticResource StringToColor}}"
|
|
VerticalAlignment="Center"/>
|
|
<TextBlock Text="{Binding StatusText}"
|
|
FontSize="12"
|
|
FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
Margin="7,0,0,0"
|
|
VerticalAlignment="Center"
|
|
TextTrimming="CharacterEllipsis"/>
|
|
</StackPanel>
|
|
<TextBlock FontSize="10"
|
|
Text="{Binding SelectedProfileSummaryText}"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
Margin="0,4,0,0"
|
|
FontWeight="SemiBold"
|
|
TextTrimming="CharacterEllipsis"/>
|
|
</StackPanel>
|
|
|
|
<Button Grid.Column="2"
|
|
Command="{Binding ConnectCommand}"
|
|
Content="{Binding ConnectButtonText}"
|
|
MinWidth="160"
|
|
Height="44"
|
|
Padding="18,8"
|
|
ToolTip="{Binding ConnectButtonToolTip}">
|
|
<Button.Style>
|
|
<Style TargetType="Button">
|
|
<Setter Property="Background" Value="#10B981"/>
|
|
<Setter Property="Foreground" Value="White"/>
|
|
<Setter Property="BorderBrush" Value="Transparent"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="FontSize" Value="13"/>
|
|
<Setter Property="FontWeight" Value="Bold"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="12"
|
|
Padding="{TemplateBinding Padding}">
|
|
<ContentPresenter HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"/>
|
|
</Border>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
<Style.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter Property="Background" Value="#059669"/>
|
|
</Trigger>
|
|
<DataTrigger Binding="{Binding ConnectionState}" Value="{x:Static models:ConnectionState.Connecting}">
|
|
<Setter Property="Background" Value="#F97316"/>
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding ConnectionState}" Value="{x:Static models:ConnectionState.Error}">
|
|
<Setter Property="Background" Value="#DC2626"/>
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</Button.Style>
|
|
</Button>
|
|
</Grid>
|
|
</Border>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- ── Server Settings Card ── -->
|
|
<Border Style="{StaticResource CardPanel}"
|
|
Visibility="Collapsed">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionHeader}" Text="🌐 تنظیمات سرور"
|
|
Margin="0,0,0,4"/>
|
|
|
|
<!-- Tunnel Type selector -->
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="نوع اتصال"/>
|
|
<ComboBox Style="{StaticResource DarkComboBox}"
|
|
SelectedValue="{Binding CurrentTunnelType, Mode=TwoWay}"
|
|
SelectedValuePath="Tag"
|
|
Margin="0,0,0,8">
|
|
<ComboBoxItem Content="L2TP/IPsec"
|
|
Tag="{x:Static models:TunnelType.L2tpIpsec}"/>
|
|
<ComboBoxItem Content="V2Ray / Xray"
|
|
Tag="{x:Static models:TunnelType.V2Ray}"/>
|
|
<ComboBoxItem Content="OpenVPN"
|
|
Tag="{x:Static models:TunnelType.OpenVpn}"/>
|
|
<ComboBoxItem Content="SOCKS / Proxy"
|
|
Tag="{x:Static models:TunnelType.SocksProxy}"/>
|
|
</ComboBox>
|
|
|
|
<!-- L2TP fields (shown only when TunnelType = L2tpIpsec) -->
|
|
<StackPanel Visibility="{Binding CurrentTunnelType,
|
|
Converter={StaticResource EnumToVis},
|
|
ConverterParameter=L2tpIpsec}">
|
|
|
|
<!-- Row 1: Server + Username -->
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<StackPanel Grid.Column="0">
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="آدرس سرور"/>
|
|
<TextBox Style="{StaticResource ModernTextBox}"
|
|
Text="{Binding ServerAddress, UpdateSourceTrigger=PropertyChanged}"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2">
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="نام کاربری"/>
|
|
<TextBox Style="{StaticResource ModernTextBox}"
|
|
Text="{Binding Username, UpdateSourceTrigger=PropertyChanged}"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<!-- Row 2: Password + PSK -->
|
|
<Grid Margin="0,5,0,0">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<StackPanel Grid.Column="0">
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="رمز عبور"/>
|
|
<PasswordBox x:Name="PasswordField"
|
|
Style="{StaticResource ModernPasswordBox}"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2">
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="Pre-Shared Key"/>
|
|
<PasswordBox x:Name="PskField"
|
|
Style="{StaticResource ModernPasswordBox}"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
</StackPanel>
|
|
<!-- End L2TP fields -->
|
|
|
|
<!-- V2Ray fields (shown only when TunnelType = V2Ray) -->
|
|
<StackPanel Visibility="{Binding CurrentTunnelType,
|
|
Converter={StaticResource EnumToVis},
|
|
ConverterParameter=V2Ray}">
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="کانفیگ V2Ray"/>
|
|
<TextBox Style="{StaticResource ModernTextBox}"
|
|
Text="{Binding SelectedV2RayConfig,
|
|
Mode=TwoWay,
|
|
UpdateSourceTrigger=PropertyChanged}"
|
|
AcceptsReturn="True"
|
|
MinHeight="96"
|
|
FontFamily="Consolas"
|
|
FlowDirection="LeftToRight"
|
|
VerticalScrollBarVisibility="Auto"
|
|
TextWrapping="Wrap"/>
|
|
<Grid Margin="0,6,0,0">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="6"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="10"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<Button Grid.Column="0"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Content="پیست"
|
|
Command="{Binding PasteConfigCommand}"
|
|
FontSize="10"
|
|
Padding="10,5"
|
|
ToolTip="خواندن کانفیگ از کلیپبورد"/>
|
|
<Button Grid.Column="2"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Content="پاک کردن"
|
|
Command="{Binding ClearConfigCommand}"
|
|
FontSize="10"
|
|
Padding="10,5"/>
|
|
<TextBlock Grid.Column="4"
|
|
Text="{Binding ConfigCoreHint}"
|
|
FontSize="10"
|
|
FontWeight="SemiBold"
|
|
Foreground="{StaticResource AccentBrush}"
|
|
VerticalAlignment="Center"/>
|
|
<TextBlock Grid.Column="6"
|
|
Text="{Binding ConfigValidationText}"
|
|
FontSize="10"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
FlowDirection="LeftToRight"
|
|
TextTrimming="CharacterEllipsis"
|
|
VerticalAlignment="Center"/>
|
|
</Grid>
|
|
</StackPanel>
|
|
<!-- End V2Ray fields -->
|
|
|
|
<!-- OpenVPN fields (shown only when TunnelType = OpenVpn) -->
|
|
<StackPanel Visibility="{Binding CurrentTunnelType,
|
|
Converter={StaticResource EnumToVis},
|
|
ConverterParameter=OpenVpn}">
|
|
<Border Background="#11FFFFFF" CornerRadius="8" Padding="10,8" Margin="0,0,0,8">
|
|
<StackPanel>
|
|
<TextBlock Text="TunnelX فایل .ovpn را با OpenVPN Community اجرا میکند و مسیر/DNS پیشفرض OpenVPN را کنترل میکند تا فقط برنامههای انتخابی از تونل عبور کنند."
|
|
TextWrapping="Wrap"
|
|
FontSize="11"
|
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
|
<TextBlock Text="OpenVPN Connect بهتنهایی کافی نیست؛ اگر Community نصب نباشد، از دکمه دانلود پایین استفاده کنید."
|
|
TextWrapping="Wrap"
|
|
FontSize="10"
|
|
Margin="0,5,0,0"
|
|
Foreground="{StaticResource WarningBrush}"/>
|
|
</StackPanel>
|
|
</Border>
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="فایل OpenVPN (.ovpn)"/>
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="6"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBox Grid.Column="0"
|
|
Style="{StaticResource ModernTextBox}"
|
|
Text="{Binding SelectedOpenVpnConfigPath}"
|
|
IsReadOnly="True"
|
|
FlowDirection="LeftToRight"/>
|
|
<Button Grid.Column="2"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Content="انتخاب فایل"
|
|
Command="{Binding BrowseOpenVpnConfigCommand}"
|
|
FontSize="10"
|
|
Padding="12,6"/>
|
|
<Button Grid.Column="4"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Content="حذف فایل"
|
|
Command="{Binding ClearConfigCommand}"
|
|
FontSize="10"
|
|
Padding="12,6"/>
|
|
</Grid>
|
|
|
|
<Border Background="#11FFFFFF" CornerRadius="8" Padding="10,8" Margin="0,6,0,0">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0"
|
|
Text="{Binding OpenVpnPrerequisiteText}"
|
|
Foreground="{Binding OpenVpnPrerequisiteColor, Converter={StaticResource StringToColor}}"
|
|
FontSize="10"
|
|
TextWrapping="Wrap"
|
|
FlowDirection="{Binding AppFlowDirection}"/>
|
|
<Button Grid.Column="2"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Content="دانلود OpenVPN"
|
|
Command="{Binding OpenOpenVpnCommunityDownloadCommand}"
|
|
FontSize="10"
|
|
Padding="10,5"/>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<Grid Margin="0,6,0,0">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<StackPanel Grid.Column="1">
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="نام کاربری"/>
|
|
<TextBox Style="{StaticResource ModernTextBox}"
|
|
Text="{Binding OpenVpnUsername, UpdateSourceTrigger=PropertyChanged}"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="3">
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="رمز عبور"/>
|
|
<PasswordBox x:Name="OpenVpnPasswordField"
|
|
Style="{StaticResource ModernPasswordBox}"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<TextBlock Text="{Binding ConfigValidationText}"
|
|
FontSize="10"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
TextWrapping="Wrap"
|
|
Margin="0,6,0,0"/>
|
|
</StackPanel>
|
|
<!-- End OpenVPN fields -->
|
|
|
|
<!-- SOCKS/Proxy fields (shown only when TunnelType = SocksProxy) -->
|
|
<StackPanel Visibility="{Binding CurrentTunnelType,
|
|
Converter={StaticResource EnumToVis},
|
|
ConverterParameter=SocksProxy}">
|
|
<Border Background="#11FFFFFF" CornerRadius="8" Padding="10,8" Margin="0,0,0,8">
|
|
<StackPanel>
|
|
<TextBlock Text="برای سرورهای SOCKS5 یا HTTP Proxy، اطلاعات را جداگانه وارد کنید. TunnelX از همین پراکسی یک TUN داخلی میسازد تا اسپلیتتانلینگ برنامههای انتخابی مثل سایر نوعهای اتصال کار کند."
|
|
TextWrapping="Wrap"
|
|
FontSize="11"
|
|
Foreground="{StaticResource TextSecondaryBrush}"/>
|
|
<TextBlock Text="اگر پراکسی شما نام کاربری یا رمز ندارد، فیلدهای احراز هویت را خالی بگذارید."
|
|
TextWrapping="Wrap"
|
|
FontSize="10"
|
|
Margin="0,5,0,0"
|
|
Foreground="{StaticResource AccentBrush}"/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<StackPanel Grid.Column="0">
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="نوع پراکسی"/>
|
|
<ComboBox Style="{StaticResource DarkComboBox}"
|
|
SelectedValue="{Binding ProxyProtocol, Mode=TwoWay}"
|
|
SelectedValuePath="Tag">
|
|
<ComboBoxItem Content="SOCKS5"
|
|
Tag="{x:Static models:ProxyProtocol.Socks5}"/>
|
|
<ComboBoxItem Content="HTTP Proxy"
|
|
Tag="{x:Static models:ProxyProtocol.Http}"/>
|
|
</ComboBox>
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2">
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="پورت"/>
|
|
<TextBox Style="{StaticResource ModernTextBox}"
|
|
Text="{Binding ProxyPortText, UpdateSourceTrigger=PropertyChanged}"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="آدرس IP یا دامنه سرور" Margin="0,6,0,0"/>
|
|
<TextBox Style="{StaticResource ModernTextBox}"
|
|
Text="{Binding ProxyServerAddress, UpdateSourceTrigger=PropertyChanged}"
|
|
FlowDirection="LeftToRight"/>
|
|
|
|
<Grid Margin="0,6,0,0">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<StackPanel Grid.Column="0">
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="نام کاربری"/>
|
|
<TextBox Style="{StaticResource ModernTextBox}"
|
|
Text="{Binding ProxyUsername, UpdateSourceTrigger=PropertyChanged}"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="2">
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="رمز عبور"/>
|
|
<PasswordBox x:Name="ProxyPasswordField"
|
|
Style="{StaticResource ModernPasswordBox}"
|
|
FlowDirection="LeftToRight"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<TextBlock Text="{Binding ConfigValidationText}"
|
|
FontSize="10"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
TextWrapping="Wrap"
|
|
Margin="0,6,0,0"/>
|
|
</StackPanel>
|
|
<!-- End SOCKS/Proxy fields -->
|
|
|
|
<Border Background="#11FFFFFF" CornerRadius="8" Padding="10,8" Margin="0,8,0,0">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="8"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="🏓 سرور" FontSize="11"
|
|
FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
VerticalAlignment="Center"/>
|
|
<TextBlock Grid.Column="2" Text="{Binding ServerPingResult}"
|
|
FontSize="11"
|
|
Foreground="{StaticResource AccentBrush}"
|
|
FlowDirection="LeftToRight"
|
|
VerticalAlignment="Center"
|
|
TextTrimming="CharacterEllipsis"/>
|
|
<Button Grid.Column="4"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Content="{Binding ServerPingButtonText}"
|
|
Command="{Binding TestServerPingCommand}"
|
|
FontSize="11"
|
|
Padding="10,5"
|
|
ToolTip="قبل از اتصال، دسترسی و latency سرور را تست میکند"/>
|
|
</Grid>
|
|
</Border>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
</StackPanel>
|
|
<!-- End Disconnected State -->
|
|
|
|
<!-- ══ CONNECTED STATE: compact status dashboard ══ -->
|
|
<StackPanel Visibility="{Binding IsConnected, Converter={StaticResource BoolToVis}}">
|
|
|
|
<!-- Connection summary -->
|
|
<Grid Margin="0,4,0,0">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="0.95*"/>
|
|
<ColumnDefinition Width="6"/>
|
|
<ColumnDefinition Width="0.9*"/>
|
|
<ColumnDefinition Width="6"/>
|
|
<ColumnDefinition Width="1.45*"/>
|
|
<ColumnDefinition Width="6"/>
|
|
<ColumnDefinition Width="0.95*"/>
|
|
<ColumnDefinition Width="6"/>
|
|
<ColumnDefinition Width="0.95*"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<!-- Connected profile -->
|
|
<Border Grid.Column="0" Background="#1A6CCB5F" CornerRadius="10" Padding="10,8"
|
|
ToolTip="وضعیت و پروفایل فعال">
|
|
<StackPanel HorizontalAlignment="Center">
|
|
<TextBlock Text="✓" FontSize="15" FontWeight="Bold"
|
|
Foreground="{StaticResource SuccessBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding ConnectedBadgeText}" FontSize="11" FontWeight="SemiBold"
|
|
Foreground="{StaticResource SuccessBrush}"
|
|
HorizontalAlignment="Center"
|
|
Margin="0,2,0,0"/>
|
|
<TextBlock Text="{Binding ConnectedProfileName}" FontSize="10"
|
|
FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"
|
|
TextAlignment="Center"
|
|
TextTrimming="CharacterEllipsis"
|
|
MaxWidth="120"/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Duration -->
|
|
<Border Grid.Column="2" Background="#11FFFFFF" CornerRadius="10" Padding="10,8"
|
|
ToolTip="مدت زمان اتصال فعلی از لحظه برقراری اتصال">
|
|
<StackPanel HorizontalAlignment="Center">
|
|
<TextBlock Text="⏱" FontSize="14" HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding ConnectionDuration}" FontSize="14"
|
|
FontWeight="Bold" Foreground="{StaticResource AccentBrush}"
|
|
HorizontalAlignment="Center" Margin="0,2,0,0"
|
|
FlowDirection="LeftToRight"/>
|
|
<TextBlock Text="مدت" FontSize="9"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Connection / Exit IP -->
|
|
<Border Grid.Column="4" Background="#11FFFFFF" CornerRadius="10" Padding="10,8"
|
|
ToolTip="IP عمومیای که مقصدهای اینترنتی شما را با آن میبینند">
|
|
<StackPanel HorizontalAlignment="Center">
|
|
<TextBlock Text="🌐" FontSize="14" HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding ConnectionIpText}" FontSize="13"
|
|
FontWeight="SemiBold" Foreground="{StaticResource SuccessBrush}"
|
|
HorizontalAlignment="Center" Margin="0,2,0,0"
|
|
FlowDirection="LeftToRight"/>
|
|
<TextBlock Text="{Binding ConnectionIpLabel}" FontSize="9"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Tunnel Traffic -->
|
|
<Border Grid.Column="6" Background="#11FFFFFF" CornerRadius="10" Padding="10,8"
|
|
ToolTip="مجموع ترافیک ارسال و دریافت عبوری از تونل VPN (کل تونل)">
|
|
<StackPanel HorizontalAlignment="Center">
|
|
<TextBlock Text="📊" FontSize="14" HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding TotalTraffic}" FontSize="13"
|
|
FontWeight="SemiBold" Foreground="{StaticResource WarningBrush}"
|
|
HorizontalAlignment="Center" Margin="0,2,0,0"
|
|
FlowDirection="LeftToRight"/>
|
|
<TextBlock Text="تونل" FontSize="9"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Direct diagnostic -->
|
|
<Border Grid.Column="8" Background="#11FFFFFF" CornerRadius="10" Padding="10,8"
|
|
ToolTip="نمایش تشخیصی ترافیک خارج از تونل. این عدد در مصرف تونل و تاریخچه ثبت نمیشود.">
|
|
<StackPanel HorizontalAlignment="Center">
|
|
<TextBlock Text="📡" FontSize="14" HorizontalAlignment="Center"/>
|
|
<TextBlock Text="{Binding DirectTraffic}" FontSize="13"
|
|
FontWeight="SemiBold" Foreground="{StaticResource TextPrimaryBrush}"
|
|
HorizontalAlignment="Center" Margin="0,2,0,0"
|
|
FlowDirection="LeftToRight"/>
|
|
<TextBlock Text="خارج تونل" FontSize="9"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"/>
|
|
</StackPanel>
|
|
</Border>
|
|
</Grid>
|
|
|
|
<!-- Route, manual proxy, ping -->
|
|
<Grid Margin="0,6,0,0">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="6"/>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="6"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<Border Grid.Column="0" Background="#11FFFFFF" CornerRadius="10" Padding="12,12" MinHeight="136">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<StackPanel Grid.Column="0">
|
|
<TextBlock Text="🌐 عبور کل سیستم" FontSize="12" FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"/>
|
|
<TextBlock Text="{Binding RouteModeDescription}" FontSize="10"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
TextWrapping="Wrap"
|
|
LineHeight="17"
|
|
Margin="0,4,10,0"/>
|
|
</StackPanel>
|
|
<CheckBox Grid.Column="1"
|
|
Style="{StaticResource ToggleSwitch}"
|
|
IsChecked="{Binding IsFullRouteEnabled, Mode=TwoWay}"
|
|
VerticalAlignment="Center"
|
|
ToolTip="روشن: کل ویندوز از تونل. خاموش: فقط برنامهها و قوانین انتخابی."/>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<Border Grid.Column="2" Background="#11FFFFFF" CornerRadius="10" Padding="12,12" MinHeight="136"
|
|
ToolTip="اگر برنامهای خودکار وارد تونل نشد، این آدرس را در تنظیمات Proxy همان برنامه وارد کنید.">
|
|
<StackPanel>
|
|
<TextBlock Text="🧦 پروکسی دستی" FontSize="12" FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"/>
|
|
<TextBlock Text="{Binding MixedProxyInfo}" FontSize="11" FontWeight="SemiBold"
|
|
Foreground="{StaticResource AccentBrush}"
|
|
FlowDirection="LeftToRight"
|
|
Margin="0,5,0,0"/>
|
|
<TextBlock Text="این آدرس داخلی را در برنامههایی وارد کنید که تنظیم Proxy جداگانه دارند یا خودکار وارد تونل نمیشوند."
|
|
FontSize="10"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
TextWrapping="Wrap"
|
|
LineHeight="17"
|
|
Margin="0,4,0,0"/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<Border Grid.Column="4" Background="#11FFFFFF" CornerRadius="10" Padding="12,12" MinHeight="136">
|
|
<StackPanel>
|
|
<TextBlock Text="🏓 تست مسیر" FontSize="12" FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
Margin="0,0,0,3"/>
|
|
<TextBlock Text="یک دامنه یا IP را از داخل تونل تست کنید."
|
|
FontSize="10"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
TextWrapping="Wrap"
|
|
Margin="0,0,0,6"/>
|
|
<Grid>
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="6"/>
|
|
<RowDefinition Height="Auto"/>
|
|
</Grid.RowDefinitions>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="6"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBox Grid.Row="0" Grid.Column="0" Text="{Binding PingTarget, UpdateSourceTrigger=PropertyChanged}"
|
|
Style="{StaticResource ModernTextBox}"
|
|
FlowDirection="LeftToRight" FontSize="11"
|
|
Padding="8,6" VerticalAlignment="Center"
|
|
ToolTip="IP یا دامنه مقصد برای تست از داخل تونل"/>
|
|
<Button Grid.Row="0" Grid.Column="2" Content="{Binding PingButtonText}"
|
|
Command="{Binding TogglePingCommand}"
|
|
Style="{StaticResource SecondaryButton}"
|
|
FontSize="10" Padding="10,6"
|
|
ToolTip="تست همین مقصد از داخل مسیر تونل"/>
|
|
<Button Grid.Row="2" Grid.ColumnSpan="3" Content="{Binding ConnectedServerPingButtonText}"
|
|
Command="{Binding TestConnectedServerPingCommand}"
|
|
Style="{StaticResource SecondaryButton}"
|
|
FontSize="10" Padding="9,5"
|
|
HorizontalAlignment="Stretch"
|
|
ToolTip="دسترسی به سرور همین اتصال را تست میکند"/>
|
|
</Grid>
|
|
<TextBlock Text="{Binding PingResult}" FontSize="11"
|
|
FontWeight="SemiBold" FlowDirection="LeftToRight"
|
|
Foreground="{StaticResource AccentBrush}"
|
|
Margin="0,6,0,0"
|
|
TextTrimming="CharacterEllipsis"/>
|
|
</StackPanel>
|
|
</Border>
|
|
</Grid>
|
|
|
|
<Button Command="{Binding ConnectCommand}"
|
|
MinWidth="220"
|
|
Height="50"
|
|
Padding="18,8"
|
|
HorizontalAlignment="Center"
|
|
Margin="0,10,0,0"
|
|
ToolTip="قطع اتصال فعلی">
|
|
<Button.Style>
|
|
<Style TargetType="Button">
|
|
<Setter Property="Background" Value="#DC2626"/>
|
|
<Setter Property="BorderBrush" Value="Transparent"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Foreground" Value="White"/>
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
<Setter Property="Template">
|
|
<Setter.Value>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border x:Name="DisconnectButtonBorder"
|
|
Background="{TemplateBinding Background}"
|
|
BorderBrush="{TemplateBinding BorderBrush}"
|
|
BorderThickness="{TemplateBinding BorderThickness}"
|
|
CornerRadius="16"
|
|
Padding="{TemplateBinding Padding}">
|
|
<Border.Effect>
|
|
<DropShadowEffect Color="#B91C1C"
|
|
BlurRadius="18"
|
|
Opacity="0.28"
|
|
ShadowDepth="0"/>
|
|
</Border.Effect>
|
|
<Grid FlowDirection="{Binding AppFlowDirection}">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="12"/>
|
|
<ColumnDefinition Width="*"/>
|
|
</Grid.ColumnDefinitions>
|
|
<Border Grid.Column="0"
|
|
Width="34"
|
|
Height="34"
|
|
CornerRadius="17"
|
|
Background="#26FFFFFF"
|
|
VerticalAlignment="Center">
|
|
<TextBlock Text="⏻"
|
|
FontSize="18"
|
|
FontWeight="Bold"
|
|
Foreground="White"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"/>
|
|
</Border>
|
|
<StackPanel Grid.Column="2" VerticalAlignment="Center">
|
|
<TextBlock Text="قطع اتصال"
|
|
FontSize="16"
|
|
FontWeight="Bold"
|
|
Foreground="White"
|
|
HorizontalAlignment="Center"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
<ControlTemplate.Triggers>
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
<Setter TargetName="DisconnectButtonBorder" Property="Background" Value="#B91C1C"/>
|
|
</Trigger>
|
|
<Trigger Property="IsPressed" Value="True">
|
|
<Setter TargetName="DisconnectButtonBorder" Property="Background" Value="#991B1B"/>
|
|
</Trigger>
|
|
</ControlTemplate.Triggers>
|
|
</ControlTemplate>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
</Button.Style>
|
|
</Button>
|
|
|
|
<Border Background="#24E8803A"
|
|
BorderBrush="#66E8803A"
|
|
BorderThickness="1"
|
|
CornerRadius="20"
|
|
Padding="24,18"
|
|
Margin="0,16,0,0"
|
|
MinWidth="560"
|
|
MaxWidth="760"
|
|
HorizontalAlignment="Stretch">
|
|
<StackPanel HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"
|
|
FlowDirection="{Binding AppFlowDirection}">
|
|
<TextBlock Text="{Binding AdPlaceholderTitleText}"
|
|
FontSize="20"
|
|
FontWeight="Bold"
|
|
Foreground="{StaticResource TextPrimaryBrush}"
|
|
HorizontalAlignment="Center"
|
|
TextAlignment="Center"/>
|
|
<TextBlock Text="{Binding AdAudienceText}"
|
|
Visibility="{Binding HasGitHubInstallCount, Converter={StaticResource BoolToVis}}"
|
|
FontSize="12"
|
|
FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextSecondaryBrush}"
|
|
HorizontalAlignment="Center"
|
|
TextAlignment="Center"
|
|
TextWrapping="Wrap"
|
|
MaxWidth="560"
|
|
Margin="0,6,0,0"/>
|
|
<Button
|
|
Content="{Binding AdRequestButtonText}"
|
|
Command="{Binding OpenAdRequestCommand}"
|
|
Style="{StaticResource PrimaryButton}"
|
|
Padding="18,10"
|
|
FontSize="13"
|
|
MinWidth="130"
|
|
HorizontalAlignment="Center"
|
|
Margin="0,12,0,0"
|
|
VerticalAlignment="Center"
|
|
ToolTip="{Binding AdRequestButtonText}"/>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
</StackPanel>
|
|
<!-- End Connected State -->
|
|
|
|
<!-- Split Tunnel Tip (always visible) -->
|
|
<Border Background="#1AFFC107" BorderBrush="#33FFC107" BorderThickness="1"
|
|
CornerRadius="10" Padding="10,8" Margin="0,8,0,0">
|
|
<StackPanel>
|
|
<TextBlock TextWrapping="Wrap" FontSize="10" LineHeight="17"
|
|
FlowDirection="{Binding AppFlowDirection}"
|
|
Foreground="{StaticResource TextPrimaryBrush}">
|
|
<Run Text="💡 در حالت انتخابی، فقط برنامههای فعال در تب "/>
|
|
<Run Text="«برنامهها»" FontWeight="SemiBold"/>
|
|
<Run Text=" از تونل عبور میکنند؛ بقیه مستقیم میمانند."/>
|
|
</TextBlock>
|
|
<TextBlock TextWrapping="Wrap" FontSize="10" LineHeight="17"
|
|
FlowDirection="{Binding AppFlowDirection}"
|
|
Foreground="{StaticResource TextSecondaryBrush}">
|
|
<Run Text="📌 برای تلگرام، واتساپ و برنامههای Store، "/>
|
|
<Run Text="Microsoft Edge WebView2"
|
|
FlowDirection="LeftToRight"
|
|
FontWeight="SemiBold"/>
|
|
<Run Text=" را هم به لیست تونل اضافه کنید."/>
|
|
</TextBlock>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</UserControl>
|