diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
index b0bde1df..700b1a46 100644
--- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs
+++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
@@ -342,9 +342,9 @@ public static class ConfigHandler
/// 0 if successful
public static async Task CopyServer(Config config, List indexes)
{
- foreach (var it in indexes)
+ var items = await AppManager.Instance.GetProfileItemsOrderedByIndexIds(indexes.Select(i => i.IndexId).ToList());
+ foreach (var item in items)
{
- var item = await AppManager.Instance.GetProfileItem(it.IndexId);
if (item is null)
{
continue;
diff --git a/v2rayN/ServiceLib/Manager/AppManager.cs b/v2rayN/ServiceLib/Manager/AppManager.cs
index e773c2ef..43c5611d 100644
--- a/v2rayN/ServiceLib/Manager/AppManager.cs
+++ b/v2rayN/ServiceLib/Manager/AppManager.cs
@@ -242,6 +242,30 @@ public sealed class AppManager
.ToListAsync();
}
+ public async Task> GetProfileItemsByIndexIdsAsMap(IEnumerable indexIds)
+ {
+ var items = await GetProfileItemsByIndexIds(indexIds);
+ return items.ToDictionary(it => it.IndexId);
+ }
+
+ public async Task> GetProfileItemsOrderedByIndexIds(IEnumerable indexIds)
+ {
+ var idList = indexIds.Where(id => !id.IsNullOrEmpty()).Distinct().ToList();
+ if (idList.Count == 0)
+ {
+ return [];
+ }
+
+ var items = await SQLiteHelper.Instance.TableAsync()
+ .Where(it => idList.Contains(it.IndexId))
+ .ToListAsync();
+ var itemMap = items.ToDictionary(it => it.IndexId);
+
+ return idList.Select(id => itemMap.GetValueOrDefault(id))
+ .Where(item => item != null)
+ .ToList();
+ }
+
public async Task GetProfileItemViaRemarks(string? remarks)
{
if (remarks.IsNullOrEmpty())
diff --git a/v2rayN/ServiceLib/Manager/GroupProfileManager.cs b/v2rayN/ServiceLib/Manager/GroupProfileManager.cs
index 510667dd..8a7389a0 100644
--- a/v2rayN/ServiceLib/Manager/GroupProfileManager.cs
+++ b/v2rayN/ServiceLib/Manager/GroupProfileManager.cs
@@ -52,10 +52,10 @@ public class GroupProfileManager
return false;
}
- foreach (var child in childIds)
+ var childItems = await AppManager.Instance.GetProfileItemsByIndexIds(childIds);
+ foreach (var childItem in childItems)
{
- var childItem = await AppManager.Instance.GetProfileItem(child);
- if (await HasCycle(child, childItem?.GetProtocolExtra(), visited, stack))
+ if (await HasCycle(childItem.IndexId, childItem?.GetProtocolExtra(), visited, stack))
{
return true;
}
@@ -103,26 +103,7 @@ public class GroupProfileManager
return [];
}
- var childProfiles = await AppManager.Instance.GetProfileItemsByIndexIds(childProfileIds);
- if (childProfiles == null || childProfiles.Count == 0)
- {
- return [];
- }
-
- var profileMap = childProfiles
- .Where(p => p != null && !p.IndexId.IsNullOrEmpty())
- .GroupBy(p => p!.IndexId!)
- .ToDictionary(g => g.Key, g => g.First());
-
- var ordered = new List(childProfileIds.Count);
- foreach (var id in childProfileIds)
- {
- if (id != null && profileMap.TryGetValue(id, out var item) && item != null)
- {
- ordered.Add(item);
- }
- }
-
+ var ordered = await AppManager.Instance.GetProfileItemsOrderedByIndexIds(childProfileIds);
return ordered;
}
diff --git a/v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs b/v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs
index d30917ec..7d4d0948 100644
--- a/v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs
@@ -99,15 +99,8 @@ public class AddGroupServerViewModel : MyReactiveObject
Filter = protocolExtra?.Filter;
var childIndexIds = Utils.String2List(protocolExtra?.ChildItems) ?? [];
- foreach (var item in childIndexIds)
- {
- var child = await AppManager.Instance.GetProfileItem(item);
- if (child == null)
- {
- continue;
- }
- ChildItemsObs.Add(child);
- }
+ var childItemList = await AppManager.Instance.GetProfileItemsOrderedByIndexIds(childIndexIds);
+ ChildItemsObs.AddRange(childItemList);
}
public async Task ChildRemoveAsync()
diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesSelectViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesSelectViewModel.cs
index ce349cb4..eb010c58 100644
--- a/v2rayN/ServiceLib/ViewModels/ProfilesSelectViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/ProfilesSelectViewModel.cs
@@ -255,19 +255,7 @@ public class ProfilesSelectViewModel : MyReactiveObject
{
return null;
}
- var lst = new List();
- foreach (var sp in SelectedProfiles)
- {
- if (string.IsNullOrEmpty(sp?.IndexId))
- {
- continue;
- }
- var item = await AppManager.Instance.GetProfileItem(sp.IndexId);
- if (item != null)
- {
- lst.Add(item);
- }
- }
+ var lst = await AppManager.Instance.GetProfileItemsOrderedByIndexIds(SelectedProfiles.Select(sp => sp?.IndexId));
if (lst.Count == 0)
{
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectServer);
diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs
index 1cc6f46e..dbcf457c 100644
--- a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs
@@ -481,14 +481,7 @@ public class ProfilesViewModel : MyReactiveObject
var orderProfiles = SelectedProfiles?.OrderBy(t => t.Sort);
if (latest)
{
- foreach (var profile in orderProfiles)
- {
- var item = await AppManager.Instance.GetProfileItem(profile.IndexId);
- if (item is not null)
- {
- lstSelected.Add(item);
- }
- }
+ lstSelected.AddRange(await AppManager.Instance.GetProfileItemsOrderedByIndexIds(orderProfiles.Select(sp => sp?.IndexId)));
}
else
{
diff --git a/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs
index 142f9d6b..2f24b197 100644
--- a/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs
@@ -147,14 +147,7 @@ public partial class AddGroupServerWindow : WindowBase
private async void MenuAddChild_Click(object? sender, RoutedEventArgs e)
{
var selectWindow = new ProfilesSelectWindow();
- if (ViewModel?.SelectedSource?.ConfigType == EConfigType.PolicyGroup)
- {
- selectWindow.SetConfigTypeFilter(new[] { EConfigType.Custom }, exclude: true);
- }
- else
- {
- selectWindow.SetConfigTypeFilter(new[] { EConfigType.Custom, EConfigType.PolicyGroup, EConfigType.ProxyChain }, exclude: true);
- }
+ selectWindow.SetConfigTypeFilter([EConfigType.Custom], exclude: true);
selectWindow.AllowMultiSelect(true);
var result = await selectWindow.ShowDialog(this);
if (result == true)
diff --git a/v2rayN/v2rayN.Desktop/Views/SubEditWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/SubEditWindow.axaml.cs
index 9d749ba8..2d7358d0 100644
--- a/v2rayN/v2rayN.Desktop/Views/SubEditWindow.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/SubEditWindow.axaml.cs
@@ -59,7 +59,7 @@ public partial class SubEditWindow : WindowBase
private async void BtnSelectPrevProfile_Click(object? sender, RoutedEventArgs e)
{
var selectWindow = new ProfilesSelectWindow();
- selectWindow.SetConfigTypeFilter(new[] { EConfigType.Custom, EConfigType.PolicyGroup, EConfigType.ProxyChain }, exclude: true);
+ selectWindow.SetConfigTypeFilter([EConfigType.Custom], exclude: true);
var result = await selectWindow.ShowDialog(this);
if (result == true)
{
@@ -74,7 +74,7 @@ public partial class SubEditWindow : WindowBase
private async void BtnSelectNextProfile_Click(object? sender, RoutedEventArgs e)
{
var selectWindow = new ProfilesSelectWindow();
- selectWindow.SetConfigTypeFilter(new[] { EConfigType.Custom, EConfigType.PolicyGroup, EConfigType.ProxyChain }, exclude: true);
+ selectWindow.SetConfigTypeFilter([EConfigType.Custom], exclude: true);
var result = await selectWindow.ShowDialog(this);
if (result == true)
{
diff --git a/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs b/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs
index 4b1642d2..9c98fb06 100644
--- a/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs
+++ b/v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs
@@ -127,14 +127,7 @@ public partial class AddGroupServerWindow
private async void MenuAddChild_Click(object sender, RoutedEventArgs e)
{
var selectWindow = new ProfilesSelectWindow();
- if (ViewModel?.SelectedSource?.ConfigType == EConfigType.PolicyGroup)
- {
- selectWindow.SetConfigTypeFilter(new[] { EConfigType.Custom }, exclude: true);
- }
- else
- {
- selectWindow.SetConfigTypeFilter(new[] { EConfigType.Custom, EConfigType.PolicyGroup, EConfigType.ProxyChain }, exclude: true);
- }
+ selectWindow.SetConfigTypeFilter([EConfigType.Custom], exclude: true);
selectWindow.AllowMultiSelect(true);
if (selectWindow.ShowDialog() == true)
{
diff --git a/v2rayN/v2rayN/Views/SubEditWindow.xaml.cs b/v2rayN/v2rayN/Views/SubEditWindow.xaml.cs
index d1451a9c..6323034a 100644
--- a/v2rayN/v2rayN/Views/SubEditWindow.xaml.cs
+++ b/v2rayN/v2rayN/Views/SubEditWindow.xaml.cs
@@ -53,7 +53,7 @@ public partial class SubEditWindow
private async void BtnSelectPrevProfile_Click(object sender, RoutedEventArgs e)
{
var selectWindow = new ProfilesSelectWindow();
- selectWindow.SetConfigTypeFilter(new[] { EConfigType.Custom, EConfigType.PolicyGroup, EConfigType.ProxyChain }, exclude: true);
+ selectWindow.SetConfigTypeFilter([EConfigType.Custom], exclude: true);
if (selectWindow.ShowDialog() == true)
{
var profile = await selectWindow.ProfileItem;
@@ -67,7 +67,7 @@ public partial class SubEditWindow
private async void BtnSelectNextProfile_Click(object sender, RoutedEventArgs e)
{
var selectWindow = new ProfilesSelectWindow();
- selectWindow.SetConfigTypeFilter(new[] { EConfigType.Custom, EConfigType.PolicyGroup, EConfigType.ProxyChain }, exclude: true);
+ selectWindow.SetConfigTypeFilter([EConfigType.Custom], exclude: true);
if (selectWindow.ShowDialog() == true)
{
var profile = await selectWindow.ProfileItem;