diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
index 46de8983..6f223693 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
+++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
@@ -1680,6 +1680,15 @@ namespace ServiceLib.Resx {
}
}
+ ///
+ /// 查找类似 Configuration item preview 的本地化字符串。
+ ///
+ public static string menuServerListPreview {
+ get {
+ return ResourceManager.GetString("menuServerListPreview", resourceCulture);
+ }
+ }
+
///
/// 查找类似 Configuration 的本地化字符串。
///
diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
index fdcffe9b..dbce6ac4 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
@@ -1668,4 +1668,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
Port hopping interval
+
+ Configuration item preview
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.fr.resx b/v2rayN/ServiceLib/Resx/ResUI.fr.resx
index 5db657ca..005a51d5 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.fr.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.fr.resx
@@ -1665,4 +1665,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
Port hopping interval
+
+ Configuration item preview
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx
index 9e5c9c4d..3d169590 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx
@@ -1668,4 +1668,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
Port hopping interval
+
+ Configuration item preview
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx
index dfd744a3..041a103b 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.resx
@@ -1668,4 +1668,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
Port hopping interval
+
+ Configuration item preview
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
index 67cffea7..66ebef79 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
@@ -1668,4 +1668,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
Port hopping interval
+
+ Configuration item preview
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
index f17495fd..c8936668 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
@@ -1665,4 +1665,7 @@
端口跳跃间隔
+
+ 子配置项预览
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
index 160340d1..2ee4dc4f 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
@@ -1665,4 +1665,7 @@
Port hopping interval
+
+ Configuration item preview
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs b/v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs
index c19d218b..6e4d021c 100644
--- a/v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs
@@ -27,6 +27,8 @@ public class AddGroupServerViewModel : MyReactiveObject
public IObservableCollection ChildItemsObs { get; } = new ObservableCollectionExtended();
+ public IObservableCollection AllProfilePreviewItemsObs { get; } = new ObservableCollectionExtended();
+
//public ReactiveCommand AddCmd { get; }
public ReactiveCommand RemoveCmd { get; }
@@ -182,6 +184,32 @@ public class AddGroupServerViewModel : MyReactiveObject
await Task.CompletedTask;
}
+ private ProtocolExtraItem GetUpdatedProtocolExtra()
+ {
+ return SelectedSource.GetProtocolExtra() with
+ {
+ ChildItems =
+ Utils.List2String(ChildItemsObs.Where(s => !s.IndexId.IsNullOrEmpty()).Select(s => s.IndexId).ToList()),
+ MultipleLoad = PolicyGroupType switch
+ {
+ var s when s == ResUI.TbLeastPing => EMultipleLoad.LeastPing,
+ var s when s == ResUI.TbFallback => EMultipleLoad.Fallback,
+ var s when s == ResUI.TbRandom => EMultipleLoad.Random,
+ var s when s == ResUI.TbRoundRobin => EMultipleLoad.RoundRobin,
+ var s when s == ResUI.TbLeastLoad => EMultipleLoad.LeastLoad,
+ _ => EMultipleLoad.LeastPing,
+ },
+ SubChildItems = SelectedSubItem?.Id,
+ Filter = Filter,
+ };
+ }
+
+ public async Task UpdatePreviewList()
+ {
+ AllProfilePreviewItemsObs.Clear();
+ AllProfilePreviewItemsObs.AddRange(await GroupProfileManager.GetChildProfileItemsByProtocolExtra(GetUpdatedProtocolExtra()));
+ }
+
private async Task SaveServerAsync()
{
var remarks = SelectedSource.Remarks;
@@ -202,24 +230,11 @@ public class AddGroupServerViewModel : MyReactiveObject
return;
}
- SelectedSource.SetProtocolExtra(SelectedSource.GetProtocolExtra() with
- {
- ChildItems =
- Utils.List2String(ChildItemsObs.Where(s => !s.IndexId.IsNullOrEmpty()).Select(s => s.IndexId).ToList()),
- MultipleLoad = PolicyGroupType switch
- {
- var s when s == ResUI.TbLeastPing => EMultipleLoad.LeastPing,
- var s when s == ResUI.TbFallback => EMultipleLoad.Fallback,
- var s when s == ResUI.TbRandom => EMultipleLoad.Random,
- var s when s == ResUI.TbRoundRobin => EMultipleLoad.RoundRobin,
- var s when s == ResUI.TbLeastLoad => EMultipleLoad.LeastLoad,
- _ => EMultipleLoad.LeastPing,
- },
- SubChildItems = SelectedSubItem?.Id,
- Filter = Filter,
- });
+ var protocolExtra = GetUpdatedProtocolExtra();
- var hasCycle = await GroupProfileManager.HasCycle(SelectedSource.IndexId, SelectedSource.GetProtocolExtra());
+ SelectedSource.SetProtocolExtra(protocolExtra);
+
+ var hasCycle = await GroupProfileManager.HasCycle(SelectedSource.IndexId, protocolExtra);
if (hasCycle)
{
NoticeManager.Instance.Enqueue(string.Format(ResUI.GroupSelfReference, remarks));
diff --git a/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml b/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml
index bb95588d..c036bb03 100644
--- a/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml
+++ b/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml
@@ -88,7 +88,10 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs
index 26827350..83f4a788 100644
--- a/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs
@@ -1,3 +1,4 @@
+using Avalonia.Controls;
using v2rayN.Desktop.Base;
namespace v2rayN.Desktop.Views;
@@ -16,6 +17,7 @@ public partial class AddGroupServerWindow : WindowBase
Loaded += Window_Loaded;
btnCancel.Click += (s, e) => Close();
lstChild.SelectionChanged += LstChild_SelectionChanged;
+ tabControl.SelectionChanged += TabControl_SelectionChanged;
ViewModel = new AddGroupServerViewModel(profileItem, UpdateViewHandler);
@@ -38,6 +40,10 @@ public partial class AddGroupServerWindow : WindowBase
case EConfigType.ProxyChain:
Title = ResUI.TbConfigTypeProxyChain;
gridPolicyGroup.IsVisible = false;
+ if (tabControl.Items.Count > 0)
+ {
+ tabControl.Items.RemoveAt(0);
+ }
break;
}
@@ -50,7 +56,6 @@ public partial class AddGroupServerWindow : WindowBase
this.Bind(ViewModel, vm => vm.SelectedSubItem, v => v.cmbSubChildItems.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Filter, v => v.txtFilter.Text).DisposeWith(disposables);
- this.OneWayBind(ViewModel, vm => vm.ChildItemsObs, v => v.lstChild.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedChild, v => v.lstChild.SelectedItem).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.RemoveCmd, v => v.menuRemoveChildServer).DisposeWith(disposables);
@@ -167,4 +172,29 @@ public partial class AddGroupServerWindow : WindowBase
ViewModel.SelectedChildren = lstChild.SelectedItems.Cast().ToList();
}
}
+
+ private async void TabControl_SelectionChanged(object? sender, SelectionChangedEventArgs e)
+ {
+ try
+ {
+ if (e.Source is not TabControl tc)
+ {
+ return;
+ }
+ if (!(tc.SelectedIndex == tc.Items.Count - 1 && tc.Items.Count > 0))
+ {
+ return;
+ }
+ if (ViewModel == null)
+ {
+ return;
+ }
+
+ await ViewModel.UpdatePreviewList();
+ }
+ catch
+ {
+ // ignored
+ }
+ }
}
diff --git a/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml b/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml
index 841b3d84..baaa0114 100644
--- a/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml
+++ b/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml
@@ -135,6 +135,7 @@
@@ -272,6 +273,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs b/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs
index 14f5a7bf..916196b8 100644
--- a/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs
+++ b/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs
@@ -1,3 +1,5 @@
+using System.Windows.Controls;
+
namespace v2rayN.Views;
public partial class AddGroupServerWindow
@@ -11,6 +13,7 @@ public partial class AddGroupServerWindow
PreviewKeyDown += AddGroupServerWindow_PreviewKeyDown;
lstChild.SelectionChanged += LstChild_SelectionChanged;
menuSelectAllChild.Click += MenuSelectAllChild_Click;
+ tabControl.SelectionChanged += TabControl_SelectionChanged;
ViewModel = new AddGroupServerViewModel(profileItem, UpdateViewHandler);
@@ -33,6 +36,10 @@ public partial class AddGroupServerWindow
case EConfigType.ProxyChain:
Title = ResUI.TbConfigTypeProxyChain;
gridPolicyGroup.Visibility = Visibility.Collapsed;
+ if (tabControl.Items.Count > 0)
+ {
+ tabControl.Items.RemoveAt(0);
+ }
break;
}
@@ -48,6 +55,8 @@ public partial class AddGroupServerWindow
this.OneWayBind(ViewModel, vm => vm.ChildItemsObs, v => v.lstChild.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedChild, v => v.lstChild.SelectedItem).DisposeWith(disposables);
+ this.OneWayBind(ViewModel, vm => vm.AllProfilePreviewItemsObs, v => v.lstPreviewChild.ItemsSource).DisposeWith(disposables);
+
this.BindCommand(ViewModel, vm => vm.RemoveCmd, v => v.menuRemoveChildServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.MoveTopCmd, v => v.menuMoveTop).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.MoveUpCmd, v => v.menuMoveUp).DisposeWith(disposables);
@@ -148,4 +157,29 @@ public partial class AddGroupServerWindow
{
lstChild.SelectAll();
}
+
+ private async void TabControl_SelectionChanged(object? sender, SelectionChangedEventArgs e)
+ {
+ try
+ {
+ if (e.Source is not TabControl tc)
+ {
+ return;
+ }
+ if (!(tc.SelectedIndex == tc.Items.Count - 1 && tc.Items.Count > 0))
+ {
+ return;
+ }
+ if (ViewModel == null)
+ {
+ return;
+ }
+
+ await ViewModel.UpdatePreviewList();
+ }
+ catch
+ {
+ // ignored
+ }
+ }
}