mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-13 11:59:13 +00:00

* Multi Profile * VM and wpf * avalonia * Fix right click not working * Exclude specific profile types from selection * Rename * Add Policy Group support * Add generate policy group * Adjust UI * Add Proxy Chain support * Fix * Add fallback support * Add PolicyGroup include other Group support * Add group in traffic splitting support * Avoid duplicate tags * Refactor * Adjust chained proxy, actual outbound is at the top Based on actual network flow instead of data packets * Add helper function * Refactor * Add chain selection control to group outbounds * Avoid self-reference * Fix * Improves Tun2Socks address handling * Avoids circular dependency in profile groups Adds cycle detection to prevent infinite loops when evaluating profile groups. This ensures that profile group configurations don't result in stack overflow errors when groups reference each other, directly or indirectly. * Fix * Fix * Update ProfileGroupItem.cs * Refactor * Remove unnecessary checks --------- Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
252 lines
14 KiB
XML
252 lines
14 KiB
XML
<UserControl
|
|
x:Class="v2rayN.Desktop.Views.ProfilesView"
|
|
xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:conv="using:v2rayN.Desktop.Converters"
|
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
|
d:DesignHeight="450"
|
|
d:DesignWidth="800"
|
|
x:DataType="vms:ProfilesViewModel"
|
|
mc:Ignorable="d">
|
|
<UserControl.Resources>
|
|
<conv:DelayColorConverter x:Key="DelayColorConverter" />
|
|
</UserControl.Resources>
|
|
<Grid>
|
|
<DockPanel>
|
|
<WrapPanel Margin="2" DockPanel.Dock="Top">
|
|
<ListBox
|
|
x:Name="lstGroup"
|
|
Margin="{StaticResource MarginLr4}"
|
|
DisplayMemberBinding="{Binding Remarks}"
|
|
ItemsSource="{Binding SubItems}"
|
|
Theme="{DynamicResource PureCardRadioGroupListBox}">
|
|
<ListBox.ItemsPanel>
|
|
<ItemsPanelTemplate>
|
|
<WrapPanel />
|
|
</ItemsPanelTemplate>
|
|
</ListBox.ItemsPanel>
|
|
</ListBox>
|
|
|
|
<Button
|
|
x:Name="btnEditSub"
|
|
Width="{StaticResource IconButtonWidth}"
|
|
Height="{StaticResource IconButtonHeight}"
|
|
Margin="{StaticResource MarginLr4}"
|
|
Classes="Success"
|
|
Theme="{DynamicResource BorderlessButton}"
|
|
ToolTip.Tip="{x:Static resx:ResUI.menuSubEdit}">
|
|
<Button.Content>
|
|
<PathIcon Data="{StaticResource building_edit}" Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
|
</Button.Content>
|
|
</Button>
|
|
<Button
|
|
x:Name="btnAddSub"
|
|
Width="{StaticResource IconButtonWidth}"
|
|
Height="{StaticResource IconButtonHeight}"
|
|
Margin="{StaticResource MarginLr4}"
|
|
Classes="Success"
|
|
Theme="{DynamicResource BorderlessButton}"
|
|
ToolTip.Tip="{x:Static resx:ResUI.menuSubAdd}">
|
|
<Button.Content>
|
|
<PathIcon Data="{StaticResource building_add}" Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
|
</Button.Content>
|
|
</Button>
|
|
|
|
<Button
|
|
x:Name="btnAutofitColumnWidth"
|
|
Width="{StaticResource IconButtonWidth}"
|
|
Height="{StaticResource IconButtonHeight}"
|
|
Margin="{StaticResource MarginLr4}"
|
|
Classes="Success"
|
|
Theme="{DynamicResource BorderlessButton}"
|
|
ToolTip.Tip="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}">
|
|
<Button.Content>
|
|
<PathIcon Data="{StaticResource building_fit}" Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
|
</Button.Content>
|
|
</Button>
|
|
|
|
<TextBox
|
|
x:Name="txtServerFilter"
|
|
Width="200"
|
|
Margin="{StaticResource MarginLr4}"
|
|
VerticalContentAlignment="Center"
|
|
Watermark="{x:Static resx:ResUI.MsgServerTitle}" />
|
|
</WrapPanel>
|
|
<DataGrid
|
|
x:Name="lstProfiles"
|
|
AutoGenerateColumns="False"
|
|
BorderThickness="1"
|
|
CanUserReorderColumns="True"
|
|
CanUserResizeColumns="True"
|
|
Classes.InsetContent="True"
|
|
GridLinesVisibility="All"
|
|
HeadersVisibility="All"
|
|
IsReadOnly="True"
|
|
ItemsSource="{Binding ProfileItems}">
|
|
<DataGrid.KeyBindings>
|
|
<KeyBinding Command="{Binding Export2ShareUrlCmd}" Gesture="Ctrl+C" />
|
|
<KeyBinding Command="{Binding SetDefaultServerCmd}" Gesture="Enter" />
|
|
</DataGrid.KeyBindings>
|
|
<DataGrid.ContextMenu>
|
|
<ContextMenu>
|
|
<MenuItem x:Name="menuEditServer" Header="{x:Static resx:ResUI.menuEditServer}" />
|
|
<MenuItem x:Name="menuSetDefaultServer" Header="{x:Static resx:ResUI.menuSetDefaultServer}" />
|
|
<MenuItem x:Name="menuRemoveServer" Header="{x:Static resx:ResUI.menuRemoveServer}" />
|
|
<MenuItem x:Name="menuRemoveDuplicateServer" Header="{x:Static resx:ResUI.menuRemoveDuplicateServer}" />
|
|
<MenuItem x:Name="menuCopyServer" Header="{x:Static resx:ResUI.menuCopyServer}" />
|
|
<MenuItem x:Name="menuShareServer" Header="{x:Static resx:ResUI.menuShareServer}" />
|
|
<Separator />
|
|
<MenuItem Header="{x:Static resx:ResUI.menuGenGroupMultipleServer}">
|
|
<MenuItem x:Name="menuGenGroupMultipleServerXrayRandom" Header="{x:Static resx:ResUI.menuGenGroupMultipleServerXrayRandom}" />
|
|
<MenuItem x:Name="menuGenGroupMultipleServerXrayRoundRobin" Header="{x:Static resx:ResUI.menuGenGroupMultipleServerXrayRoundRobin}" />
|
|
<MenuItem x:Name="menuGenGroupMultipleServerXrayLeastPing" Header="{x:Static resx:ResUI.menuGenGroupMultipleServerXrayLeastPing}" />
|
|
<MenuItem x:Name="menuGenGroupMultipleServerXrayLeastLoad" Header="{x:Static resx:ResUI.menuGenGroupMultipleServerXrayLeastLoad}" />
|
|
<Separator />
|
|
<MenuItem x:Name="menuGenGroupMultipleServerSingBoxLeastPing" Header="{x:Static resx:ResUI.menuGenGroupMultipleServerSingBoxLeastPing}" />
|
|
<MenuItem x:Name="menuGenGroupMultipleServerSingBoxFallback" Header="{x:Static resx:ResUI.menuGenGroupMultipleServerSingBoxFallback}" />
|
|
</MenuItem>
|
|
<Separator />
|
|
<MenuItem x:Name="menuMixedTestServer" Header="{x:Static resx:ResUI.menuMixedTestServer}" />
|
|
<MenuItem x:Name="menuTcpingServer" Header="{x:Static resx:ResUI.menuTcpingServer}" />
|
|
<MenuItem x:Name="menuRealPingServer" Header="{x:Static resx:ResUI.menuRealPingServer}" />
|
|
<MenuItem x:Name="menuSpeedServer" Header="{x:Static resx:ResUI.menuSpeedServer}" />
|
|
<MenuItem Header="{x:Static resx:ResUI.menuTestServerResult}">
|
|
<MenuItem x:Name="menuSortServerResult" Header="{x:Static resx:ResUI.menuSortServerResult}" />
|
|
<MenuItem x:Name="menuRemoveInvalidServerResult" Header="{x:Static resx:ResUI.menuRemoveInvalidServerResult}" />
|
|
</MenuItem>
|
|
<Separator />
|
|
<MenuItem x:Name="menuMoveToGroup" Header="{x:Static resx:ResUI.menuMoveToGroup}">
|
|
<MenuItem>
|
|
<MenuItem.Header>
|
|
<DockPanel>
|
|
<ComboBox
|
|
x:Name="cmbMoveToGroup"
|
|
Width="200"
|
|
DisplayMemberBinding="{Binding Remarks}"
|
|
ItemsSource="{Binding SubItems}"
|
|
ToolTip.Tip="{x:Static resx:ResUI.menuSubscription}" />
|
|
</DockPanel>
|
|
</MenuItem.Header>
|
|
</MenuItem>
|
|
</MenuItem>
|
|
<MenuItem Header="{x:Static resx:ResUI.menuMoveTo}">
|
|
<MenuItem x:Name="menuMoveTop" Header="{x:Static resx:ResUI.menuMoveTop}" />
|
|
<MenuItem x:Name="menuMoveUp" Header="{x:Static resx:ResUI.menuMoveUp}" />
|
|
<MenuItem x:Name="menuMoveDown" Header="{x:Static resx:ResUI.menuMoveDown}" />
|
|
<MenuItem x:Name="menuMoveBottom" Header="{x:Static resx:ResUI.menuMoveBottom}" />
|
|
</MenuItem>
|
|
<MenuItem x:Name="menuSelectAll" Header="{x:Static resx:ResUI.menuSelectAll}" />
|
|
<Separator />
|
|
<MenuItem Header="{x:Static resx:ResUI.menuExportConfig}">
|
|
<MenuItem x:Name="menuExport2ClientConfig" Header="{x:Static resx:ResUI.menuExport2ClientConfig}" />
|
|
<MenuItem x:Name="menuExport2ClientConfigClipboard" Header="{x:Static resx:ResUI.menuExport2ClientConfigClipboard}" />
|
|
<Separator />
|
|
<MenuItem x:Name="menuExport2ShareUrl" Header="{x:Static resx:ResUI.menuExport2ShareUrl}" />
|
|
<MenuItem x:Name="menuExport2ShareUrlBase64" Header="{x:Static resx:ResUI.menuExport2ShareUrlBase64}" />
|
|
</MenuItem>
|
|
</ContextMenu>
|
|
</DataGrid.ContextMenu>
|
|
|
|
<DataGrid.Columns>
|
|
<DataGridTextColumn
|
|
Width="80"
|
|
Binding="{Binding ConfigType}"
|
|
Header="{x:Static resx:ResUI.LvServiceType}"
|
|
Tag="ConfigType" />
|
|
|
|
<DataGridTemplateColumn SortMemberPath="Remarks" Tag="Remarks">
|
|
<DataGridTemplateColumn.Header>
|
|
<TextBlock Text="{x:Static resx:ResUI.LvRemarks}" />
|
|
</DataGridTemplateColumn.Header>
|
|
<DataGridTemplateColumn.CellTemplate>
|
|
<DataTemplate>
|
|
<StackPanel Margin="{StaticResource MarginLr8}" Orientation="Horizontal">
|
|
<Label
|
|
Margin="{StaticResource MarginLr4}"
|
|
Classes="Solid Red"
|
|
Content="{x:Static resx:ResUI.TipActiveServer}"
|
|
IsVisible="{Binding IsActive}"
|
|
Theme="{DynamicResource TagLabel}" />
|
|
<TextBlock
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"
|
|
Text="{Binding Remarks}" />
|
|
</StackPanel>
|
|
</DataTemplate>
|
|
</DataGridTemplateColumn.CellTemplate>
|
|
</DataGridTemplateColumn>
|
|
|
|
<DataGridTextColumn
|
|
Width="120"
|
|
Binding="{Binding Address}"
|
|
Header="{x:Static resx:ResUI.LvAddress}"
|
|
Tag="Address" />
|
|
<DataGridTextColumn
|
|
Width="60"
|
|
Binding="{Binding Port}"
|
|
Header="{x:Static resx:ResUI.LvPort}"
|
|
Tag="Port" />
|
|
<DataGridTextColumn
|
|
Width="100"
|
|
Binding="{Binding Network}"
|
|
Header="{x:Static resx:ResUI.LvTransportProtocol}"
|
|
Tag="Network" />
|
|
<DataGridTextColumn
|
|
Width="100"
|
|
Binding="{Binding StreamSecurity}"
|
|
Header="{x:Static resx:ResUI.LvTLS}"
|
|
Tag="StreamSecurity" />
|
|
<DataGridTextColumn
|
|
Width="100"
|
|
Binding="{Binding SubRemarks}"
|
|
Header="{x:Static resx:ResUI.LvSubscription}"
|
|
Tag="SubRemarks" />
|
|
<DataGridTemplateColumn SortMemberPath="Delay" Tag="DelayVal">
|
|
<DataGridTemplateColumn.Header>
|
|
<TextBlock Text="{x:Static resx:ResUI.LvTestDelay}" />
|
|
</DataGridTemplateColumn.Header>
|
|
<DataGridTemplateColumn.CellTemplate>
|
|
<DataTemplate>
|
|
<TextBlock
|
|
Margin="{StaticResource MarginLr8}"
|
|
HorizontalAlignment="Right"
|
|
VerticalAlignment="Center"
|
|
Foreground="{Binding Delay, Converter={StaticResource DelayColorConverter}}"
|
|
Text="{Binding Path=DelayVal, Mode=OneWay}" />
|
|
</DataTemplate>
|
|
</DataGridTemplateColumn.CellTemplate>
|
|
</DataGridTemplateColumn>
|
|
<DataGridTextColumn
|
|
Width="100"
|
|
Binding="{Binding SpeedVal}"
|
|
Header="{x:Static resx:ResUI.LvTestSpeed}"
|
|
Tag="SpeedVal" />
|
|
|
|
<DataGridTextColumn
|
|
Width="100"
|
|
Binding="{Binding TodayUp}"
|
|
Header="{x:Static resx:ResUI.LvTodayUploadDataAmount}"
|
|
Tag="TodayUp" />
|
|
<DataGridTextColumn
|
|
Width="100"
|
|
Binding="{Binding TodayDown}"
|
|
Header="{x:Static resx:ResUI.LvTodayDownloadDataAmount}"
|
|
Tag="TodayDown" />
|
|
<DataGridTextColumn
|
|
Width="100"
|
|
Binding="{Binding TotalUp}"
|
|
Header="{x:Static resx:ResUI.LvTotalUploadDataAmount}"
|
|
Tag="TotalUp" />
|
|
<DataGridTextColumn
|
|
Width="100"
|
|
Binding="{Binding TotalDown}"
|
|
Header="{x:Static resx:ResUI.LvTotalDownloadDataAmount}"
|
|
Tag="TotalDown" />
|
|
</DataGrid.Columns>
|
|
</DataGrid>
|
|
</DockPanel>
|
|
</Grid>
|
|
</UserControl>
|