mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-23 16:54:40 +00:00
Compare commits
No commits in common. "2053ed5f220bfa169021bdbe43f8120e721048fe" and "4bb3c546eaa1951c164d35ae325abac33bd2fec7" have entirely different histories.
2053ed5f22
...
4bb3c546ea
16 changed files with 148 additions and 1470 deletions
50
v2rayN/ServiceLib/Common/QueryableExtension.cs
Normal file
50
v2rayN/ServiceLib/Common/QueryableExtension.cs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace ServiceLib.Common
|
||||||
|
{
|
||||||
|
public static class QueryableExtension
|
||||||
|
{
|
||||||
|
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string propertyName)
|
||||||
|
{
|
||||||
|
return _OrderBy<T>(query, propertyName, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string propertyName)
|
||||||
|
{
|
||||||
|
return _OrderBy<T>(query, propertyName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IOrderedQueryable<T> _OrderBy<T>(IQueryable<T> query, string propertyName, bool isDesc)
|
||||||
|
{
|
||||||
|
var methodname = (isDesc) ? "OrderByDescendingInternal" : "OrderByInternal";
|
||||||
|
|
||||||
|
var memberProp = typeof(T).GetProperty(propertyName);
|
||||||
|
|
||||||
|
var method = typeof(QueryableExtension).GetMethod(methodname)
|
||||||
|
.MakeGenericMethod(typeof(T), memberProp.PropertyType);
|
||||||
|
|
||||||
|
return (IOrderedQueryable<T>)method.Invoke(null, new object[] { query, memberProp });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IOrderedQueryable<T> OrderByInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)
|
||||||
|
{//public
|
||||||
|
return query.OrderBy(_GetLambda<T, TProp>(memberProperty));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IOrderedQueryable<T> OrderByDescendingInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)
|
||||||
|
{//public
|
||||||
|
return query.OrderByDescending(_GetLambda<T, TProp>(memberProperty));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Expression<Func<T, TProp>> _GetLambda<T, TProp>(PropertyInfo memberProperty)
|
||||||
|
{
|
||||||
|
if (memberProperty.PropertyType != typeof(TProp)) throw new Exception();
|
||||||
|
|
||||||
|
var thisArg = Expression.Parameter(typeof(T));
|
||||||
|
var lambda = Expression.Lambda<Func<T, TProp>>(Expression.Property(thisArg, memberProperty), thisArg);
|
||||||
|
|
||||||
|
return lambda;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,6 @@
|
||||||
SendMsgView,
|
SendMsgView,
|
||||||
SendSnackMsg,
|
SendSnackMsg,
|
||||||
RefreshProfiles,
|
RefreshProfiles,
|
||||||
StopSpeedtest,
|
StopSpeedtest
|
||||||
AppExit
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -78,7 +78,6 @@
|
||||||
public const string SpeedUnit = "";
|
public const string SpeedUnit = "";
|
||||||
public const int MinFontSize = 10;
|
public const int MinFontSize = 10;
|
||||||
public const string RebootAs = "rebootas";
|
public const string RebootAs = "rebootas";
|
||||||
public const string AvaAssets = "avares://v2rayN/Assets/";
|
|
||||||
|
|
||||||
public static readonly List<string> IEProxyProtocols = new() {
|
public static readonly List<string> IEProxyProtocols = new() {
|
||||||
"{ip}:{http_port}",
|
"{ip}:{http_port}",
|
||||||
|
@ -197,7 +196,7 @@
|
||||||
public static readonly List<string> SingboxDomainStrategy4Out = new() { "ipv4_only", "prefer_ipv4", "prefer_ipv6", "ipv6_only", "" };
|
public static readonly List<string> SingboxDomainStrategy4Out = new() { "ipv4_only", "prefer_ipv4", "prefer_ipv6", "ipv6_only", "" };
|
||||||
public static readonly List<string> DomainDNSAddress = ["223.5.5.5", "223.6.6.6", "localhost"];
|
public static readonly List<string> DomainDNSAddress = ["223.5.5.5", "223.6.6.6", "localhost"];
|
||||||
public static readonly List<string> SingboxDomainDNSAddress = ["223.5.5.5", "223.6.6.6", "dhcp://auto"];
|
public static readonly List<string> SingboxDomainDNSAddress = ["223.5.5.5", "223.6.6.6", "dhcp://auto"];
|
||||||
public static readonly List<string> Languages = new() { "zh-Hans", "zh-Hant", "en", "fa-Ir", "ru", "hu" };
|
public static readonly List<string> Languages = new() { "zh-Hans", "zh-Hant", "en", "fa-Ir", "ru" };
|
||||||
public static readonly List<string> Alpns = new() { "h3", "h2", "http/1.1", "h3,h2", "h2,http/1.1", "h3,h2,http/1.1", "" };
|
public static readonly List<string> Alpns = new() { "h3", "h2", "http/1.1", "h3,h2", "h2,http/1.1", "h3,h2,http/1.1", "" };
|
||||||
public static readonly List<string> LogLevels = new() { "debug", "info", "warning", "error", "none" };
|
public static readonly List<string> LogLevels = new() { "debug", "info", "warning", "error", "none" };
|
||||||
public static readonly List<string> InboundTags = new() { "socks", "socks2" };
|
public static readonly List<string> InboundTags = new() { "socks", "socks2" };
|
||||||
|
|
|
@ -766,65 +766,68 @@ namespace ServiceLib.Handler
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
Enum.TryParse(colName, true, out EServerColName name);
|
Enum.TryParse(colName, true, out EServerColName name);
|
||||||
|
var propertyName = string.Empty;
|
||||||
|
switch (name)
|
||||||
|
{
|
||||||
|
case EServerColName.ConfigType:
|
||||||
|
case EServerColName.Remarks:
|
||||||
|
case EServerColName.Address:
|
||||||
|
case EServerColName.Port:
|
||||||
|
case EServerColName.Network:
|
||||||
|
case EServerColName.StreamSecurity:
|
||||||
|
propertyName = name.ToString();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EServerColName.DelayVal:
|
||||||
|
propertyName = "Delay";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EServerColName.SpeedVal:
|
||||||
|
propertyName = "Speed";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EServerColName.SubRemarks:
|
||||||
|
propertyName = "Subid";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = lstProfile.AsQueryable();
|
||||||
|
|
||||||
if (asc)
|
if (asc)
|
||||||
{
|
{
|
||||||
lstProfile = name switch
|
lstProfile = items.OrderBy(propertyName).ToList();
|
||||||
{
|
|
||||||
EServerColName.ConfigType => lstProfile.OrderBy(t => t.ConfigType).ToList(),
|
|
||||||
EServerColName.Remarks => lstProfile.OrderBy(t => t.Remarks).ToList(),
|
|
||||||
EServerColName.Address => lstProfile.OrderBy(t => t.Address).ToList(),
|
|
||||||
EServerColName.Port => lstProfile.OrderBy(t => t.Port).ToList(),
|
|
||||||
EServerColName.Network => lstProfile.OrderBy(t => t.Network).ToList(),
|
|
||||||
EServerColName.StreamSecurity => lstProfile.OrderBy(t => t.StreamSecurity).ToList(),
|
|
||||||
EServerColName.DelayVal => lstProfile.OrderBy(t => t.Delay).ToList(),
|
|
||||||
EServerColName.SpeedVal => lstProfile.OrderBy(t => t.Speed).ToList(),
|
|
||||||
EServerColName.SubRemarks => lstProfile.OrderBy(t => t.Subid).ToList(),
|
|
||||||
_ => lstProfile
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lstProfile = name switch
|
lstProfile = items.OrderByDescending(propertyName).ToList();
|
||||||
{
|
|
||||||
EServerColName.ConfigType => lstProfile.OrderByDescending(t => t.ConfigType).ToList(),
|
|
||||||
EServerColName.Remarks => lstProfile.OrderByDescending(t => t.Remarks).ToList(),
|
|
||||||
EServerColName.Address => lstProfile.OrderByDescending(t => t.Address).ToList(),
|
|
||||||
EServerColName.Port => lstProfile.OrderByDescending(t => t.Port).ToList(),
|
|
||||||
EServerColName.Network => lstProfile.OrderByDescending(t => t.Network).ToList(),
|
|
||||||
EServerColName.StreamSecurity => lstProfile.OrderByDescending(t => t.StreamSecurity).ToList(),
|
|
||||||
EServerColName.DelayVal => lstProfile.OrderByDescending(t => t.Delay).ToList(),
|
|
||||||
EServerColName.SpeedVal => lstProfile.OrderByDescending(t => t.Speed).ToList(),
|
|
||||||
EServerColName.SubRemarks => lstProfile.OrderByDescending(t => t.Subid).ToList(),
|
|
||||||
_ => lstProfile
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < lstProfile.Count; i++)
|
||||||
for (var i = 0; i < lstProfile.Count; i++)
|
|
||||||
{
|
{
|
||||||
ProfileExHandler.Instance.SetSort(lstProfile[i].IndexId, (i + 1) * 10);
|
ProfileExHandler.Instance.SetSort(lstProfile[i].IndexId, (i + 1) * 10);
|
||||||
}
|
}
|
||||||
switch (name)
|
if (name == EServerColName.DelayVal)
|
||||||
{
|
|
||||||
case EServerColName.DelayVal:
|
|
||||||
{
|
{
|
||||||
var maxSort = lstProfile.Max(t => t.Sort) + 10;
|
var maxSort = lstProfile.Max(t => t.Sort) + 10;
|
||||||
foreach (var item in lstProfile.Where(item => item.Delay <= 0))
|
foreach (var item in lstProfile)
|
||||||
|
{
|
||||||
|
if (item.Delay <= 0)
|
||||||
{
|
{
|
||||||
ProfileExHandler.Instance.SetSort(item.IndexId, maxSort);
|
ProfileExHandler.Instance.SetSort(item.IndexId, maxSort);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case EServerColName.SpeedVal:
|
}
|
||||||
|
if (name == EServerColName.SpeedVal)
|
||||||
{
|
{
|
||||||
var maxSort = lstProfile.Max(t => t.Sort) + 10;
|
var maxSort = lstProfile.Max(t => t.Sort) + 10;
|
||||||
foreach (var item in lstProfile.Where(item => item.Speed <= 0))
|
foreach (var item in lstProfile)
|
||||||
|
{
|
||||||
|
if (item.Speed <= 0)
|
||||||
{
|
{
|
||||||
ProfileExHandler.Instance.SetSort(item.IndexId, maxSort);
|
ProfileExHandler.Instance.SetSort(item.IndexId, maxSort);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -60,9 +60,6 @@
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Update="Resx\ResUI.hu.resx">
|
|
||||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
|
||||||
</EmbeddedResource>
|
|
||||||
<EmbeddedResource Update="Resx\ResUI.resx">
|
<EmbeddedResource Update="Resx\ResUI.resx">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<LastGenOutput>ResUI.Designer.cs</LastGenOutput>
|
<LastGenOutput>ResUI.Designer.cs</LastGenOutput>
|
||||||
|
|
|
@ -160,9 +160,9 @@ namespace ServiceLib.ViewModels
|
||||||
var configDirZipTemp = Utils.GetTempPath($"v2rayN_{DateTime.Now:yyyyMMddHHmmss}");
|
var configDirZipTemp = Utils.GetTempPath($"v2rayN_{DateTime.Now:yyyyMMddHHmmss}");
|
||||||
var configDirTemp = Path.Combine(configDirZipTemp, _guiConfigs);
|
var configDirTemp = Path.Combine(configDirZipTemp, _guiConfigs);
|
||||||
|
|
||||||
FileManager.CopyDirectory(configDir, configDirTemp, false, "cache.db");
|
await Task.Run(() => FileManager.CopyDirectory(configDir, configDirTemp, false, "cache.db"));
|
||||||
var ret = FileManager.CreateFromDirectory(configDirZipTemp, fileName);
|
var ret = await Task.Run(() => FileManager.CreateFromDirectory(configDirZipTemp, fileName));
|
||||||
Directory.Delete(configDirZipTemp, true);
|
await Task.Run(() => Directory.Delete(configDirZipTemp, true));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,7 +283,6 @@ namespace ServiceLib.ViewModels
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logging.SaveLog("MyAppExitAsync Begin");
|
Logging.SaveLog("MyAppExitAsync Begin");
|
||||||
MessageBus.Current.SendMessage("", EMsgCommand.AppExit.ToString());
|
|
||||||
|
|
||||||
await ConfigHandler.SaveConfig(_config);
|
await ConfigHandler.SaveConfig(_config);
|
||||||
await SysProxyHandler.UpdateSysProxy(_config, true);
|
await SysProxyHandler.UpdateSysProxy(_config, true);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Common
|
namespace v2rayN.Desktop.Common
|
||||||
{
|
{
|
||||||
|
@ -7,7 +8,7 @@ namespace v2rayN.Desktop.Common
|
||||||
{
|
{
|
||||||
public static AppBuilder WithFontByDefault(this AppBuilder appBuilder)
|
public static AppBuilder WithFontByDefault(this AppBuilder appBuilder)
|
||||||
{
|
{
|
||||||
var uri = Path.Combine(Global.AvaAssets, "Fonts#Noto Sans SC");
|
var uri = $"avares://{Assembly.GetExecutingAssembly().GetName().Name}/Assets/Fonts#Noto Sans SC";
|
||||||
return appBuilder.With(new FontManagerOptions()
|
return appBuilder.With(new FontManagerOptions()
|
||||||
{
|
{
|
||||||
DefaultFamilyName = uri,
|
DefaultFamilyName = uri,
|
||||||
|
|
|
@ -3,6 +3,7 @@ using Avalonia.Controls;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using Avalonia.Platform;
|
using Avalonia.Platform;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Common
|
namespace v2rayN.Desktop.Common
|
||||||
{
|
{
|
||||||
|
@ -40,7 +41,7 @@ namespace v2rayN.Desktop.Common
|
||||||
public static WindowIcon GetAppIcon(ESysProxyType sysProxyType)
|
public static WindowIcon GetAppIcon(ESysProxyType sysProxyType)
|
||||||
{
|
{
|
||||||
var index = (int)sysProxyType + 1;
|
var index = (int)sysProxyType + 1;
|
||||||
var uri = new Uri(Path.Combine(Global.AvaAssets, $"NotifyIcon{index}.ico"));
|
var uri = new Uri($"avares://{Assembly.GetExecutingAssembly().GetName().Name}/Assets/NotifyIcon{index}.ico");
|
||||||
using var bitmap = new Bitmap(AssetLoader.Open(uri));
|
using var bitmap = new Bitmap(AssetLoader.Open(uri));
|
||||||
return new(bitmap);
|
return new(bitmap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,6 @@ namespace v2rayN.Desktop.Views
|
||||||
RestoreUI();
|
RestoreUI();
|
||||||
AddHelpMenuItem();
|
AddHelpMenuItem();
|
||||||
//WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
//WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
||||||
MessageBus.Current.Listen<string>(EMsgCommand.AppExit.ToString()).Subscribe(StorageUI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Event
|
#region Event
|
||||||
|
@ -442,7 +441,7 @@ namespace v2rayN.Desktop.Views
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StorageUI(string? n = null)
|
private void StorageUI()
|
||||||
{
|
{
|
||||||
_config.UiItem.MainWidth = Utils.ToInt(this.Width);
|
_config.UiItem.MainWidth = Utils.ToInt(this.Width);
|
||||||
_config.UiItem.MainHeight = Utils.ToInt(this.Height);
|
_config.UiItem.MainHeight = Utils.ToInt(this.Height);
|
||||||
|
@ -457,6 +456,7 @@ namespace v2rayN.Desktop.Views
|
||||||
_config.UiItem.MainGirdHeight1 = Math.Ceiling(gridMain1.RowDefinitions[0].ActualHeight + 0.1);
|
_config.UiItem.MainGirdHeight1 = Math.Ceiling(gridMain1.RowDefinitions[0].ActualHeight + 0.1);
|
||||||
_config.UiItem.MainGirdHeight2 = Math.Ceiling(gridMain1.RowDefinitions[2].ActualHeight + 0.1);
|
_config.UiItem.MainGirdHeight2 = Math.Ceiling(gridMain1.RowDefinitions[2].ActualHeight + 0.1);
|
||||||
}
|
}
|
||||||
|
ConfigHandler.SaveConfig(_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddHelpMenuItem()
|
private void AddHelpMenuItem()
|
||||||
|
|
|
@ -56,23 +56,28 @@
|
||||||
Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
||||||
</Button.Content>
|
</Button.Content>
|
||||||
</Button>
|
</Button>
|
||||||
|
<SplitButton
|
||||||
<Button
|
|
||||||
x:Name="btnAutofitColumnWidth"
|
x:Name="btnAutofitColumnWidth"
|
||||||
Width="30"
|
Width="54"
|
||||||
Height="30"
|
Height="30"
|
||||||
Margin="4,0"
|
Margin="20,0"
|
||||||
Classes="Success"
|
Padding="2"
|
||||||
Theme="{DynamicResource BorderlessButton}"
|
Classes="Tertiary"
|
||||||
|
Theme="{DynamicResource BorderlessSplitButton}"
|
||||||
ToolTip.Tip="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}">
|
ToolTip.Tip="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}">
|
||||||
<Button.Content>
|
<SplitButton.Content>
|
||||||
<PathIcon
|
<PathIcon
|
||||||
Width="24"
|
Width="24"
|
||||||
Height="24"
|
Height="24"
|
||||||
Data="{StaticResource building_fit}"
|
Data="{StaticResource building_fit}"
|
||||||
Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
||||||
</Button.Content>
|
</SplitButton.Content>
|
||||||
</Button>
|
<SplitButton.Flyout>
|
||||||
|
<MenuFlyout>
|
||||||
|
<MenuItem Name="menuStorageUI" Header="{x:Static resx:ResUI.menuStorageUI}" />
|
||||||
|
</MenuFlyout>
|
||||||
|
</SplitButton.Flyout>
|
||||||
|
</SplitButton>
|
||||||
|
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="txtServerFilter"
|
x:Name="txtServerFilter"
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace v2rayN.Desktop.Views
|
||||||
menuSelectAll.Click += menuSelectAll_Click;
|
menuSelectAll.Click += menuSelectAll_Click;
|
||||||
btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click;
|
btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click;
|
||||||
txtServerFilter.KeyDown += TxtServerFilter_KeyDown;
|
txtServerFilter.KeyDown += TxtServerFilter_KeyDown;
|
||||||
|
menuStorageUI.Click += MenuStorageUI_Click;
|
||||||
lstProfiles.KeyDown += LstProfiles_KeyDown;
|
lstProfiles.KeyDown += LstProfiles_KeyDown;
|
||||||
lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;
|
lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;
|
||||||
lstProfiles.DoubleTapped += LstProfiles_DoubleTapped;
|
lstProfiles.DoubleTapped += LstProfiles_DoubleTapped;
|
||||||
|
@ -90,7 +91,6 @@ namespace v2rayN.Desktop.Views
|
||||||
|
|
||||||
RestoreUI();
|
RestoreUI();
|
||||||
ViewModel?.RefreshServers();
|
ViewModel?.RefreshServers();
|
||||||
MessageBus.Current.Listen<string>(EMsgCommand.AppExit.ToString()).Subscribe(StorageUI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void LstProfiles_Sorting(object? sender, DataGridColumnEventArgs e)
|
private async void LstProfiles_Sorting(object? sender, DataGridColumnEventArgs e)
|
||||||
|
@ -324,6 +324,11 @@ namespace v2rayN.Desktop.Views
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void MenuStorageUI_Click(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
StorageUI();
|
||||||
|
}
|
||||||
|
|
||||||
//#endregion Event
|
//#endregion Event
|
||||||
|
|
||||||
//#region UI
|
//#region UI
|
||||||
|
@ -363,7 +368,7 @@ namespace v2rayN.Desktop.Views
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StorageUI(string? n = null)
|
private void StorageUI()
|
||||||
{
|
{
|
||||||
List<ColumnItem> lvColumnItem = new();
|
List<ColumnItem> lvColumnItem = new();
|
||||||
for (int k = 0; k < lstProfiles.Columns.Count; k++)
|
for (int k = 0; k < lstProfiles.Columns.Count; k++)
|
||||||
|
@ -381,6 +386,7 @@ namespace v2rayN.Desktop.Views
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_config.UiItem.MainColumnItem = lvColumnItem;
|
_config.UiItem.MainColumnItem = lvColumnItem;
|
||||||
|
ConfigHandler.SaveConfig(_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endregion UI
|
//#endregion UI
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace v2rayN
|
||||||
|
|
||||||
public App()
|
public App()
|
||||||
{
|
{
|
||||||
|
// Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetCallingAssembly());
|
||||||
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
|
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
|
||||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||||
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace v2rayN.Views
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
|
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
|
||||||
|
|
||||||
|
Application.Current.Exit += Current_Exit;
|
||||||
App.Current.SessionEnding += Current_SessionEnding;
|
App.Current.SessionEnding += Current_SessionEnding;
|
||||||
this.Closing += MainWindow_Closing;
|
this.Closing += MainWindow_Closing;
|
||||||
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
|
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
|
||||||
|
@ -141,7 +142,6 @@ namespace v2rayN.Views
|
||||||
RestoreUI();
|
RestoreUI();
|
||||||
AddHelpMenuItem();
|
AddHelpMenuItem();
|
||||||
WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
||||||
MessageBus.Current.Listen<string>(EMsgCommand.AppExit.ToString()).Subscribe(StorageUI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Event
|
#region Event
|
||||||
|
@ -265,6 +265,11 @@ namespace v2rayN.Views
|
||||||
ShowHideWindow(false);
|
ShowHideWindow(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Current_Exit(object sender, ExitEventArgs e)
|
||||||
|
{
|
||||||
|
StorageUI();
|
||||||
|
}
|
||||||
|
|
||||||
private async void Current_SessionEnding(object sender, SessionEndingCancelEventArgs e)
|
private async void Current_SessionEnding(object sender, SessionEndingCancelEventArgs e)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("Current_SessionEnding");
|
Logging.SaveLog("Current_SessionEnding");
|
||||||
|
@ -397,7 +402,7 @@ namespace v2rayN.Views
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StorageUI(string? n = null)
|
private void StorageUI()
|
||||||
{
|
{
|
||||||
_config.UiItem.MainWidth = Utils.ToInt(this.Width);
|
_config.UiItem.MainWidth = Utils.ToInt(this.Width);
|
||||||
_config.UiItem.MainHeight = Utils.ToInt(this.Height);
|
_config.UiItem.MainHeight = Utils.ToInt(this.Height);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using MaterialDesignThemes.Wpf;
|
using MaterialDesignThemes.Wpf;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System;
|
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
@ -25,6 +24,7 @@ namespace v2rayN.Views
|
||||||
|
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
|
|
||||||
|
Application.Current.Exit += Current_Exit;
|
||||||
btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click;
|
btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click;
|
||||||
txtServerFilter.PreviewKeyDown += TxtServerFilter_PreviewKeyDown;
|
txtServerFilter.PreviewKeyDown += TxtServerFilter_PreviewKeyDown;
|
||||||
lstProfiles.PreviewKeyDown += LstProfiles_PreviewKeyDown;
|
lstProfiles.PreviewKeyDown += LstProfiles_PreviewKeyDown;
|
||||||
|
@ -90,11 +90,15 @@ namespace v2rayN.Views
|
||||||
|
|
||||||
RestoreUI();
|
RestoreUI();
|
||||||
ViewModel?.RefreshServers();
|
ViewModel?.RefreshServers();
|
||||||
MessageBus.Current.Listen<string>(EMsgCommand.AppExit.ToString()).Subscribe(StorageUI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Event
|
#region Event
|
||||||
|
|
||||||
|
private void Current_Exit(object sender, ExitEventArgs e)
|
||||||
|
{
|
||||||
|
StorageUI();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||||
{
|
{
|
||||||
switch (action)
|
switch (action)
|
||||||
|
@ -352,7 +356,7 @@ namespace v2rayN.Views
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StorageUI(string? n = null)
|
private void StorageUI()
|
||||||
{
|
{
|
||||||
List<ColumnItem> lvColumnItem = new();
|
List<ColumnItem> lvColumnItem = new();
|
||||||
for (int k = 0; k < lstProfiles.Columns.Count; k++)
|
for (int k = 0; k < lstProfiles.Columns.Count; k++)
|
||||||
|
@ -366,6 +370,7 @@ namespace v2rayN.Views
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_config.UiItem.MainColumnItem = lvColumnItem;
|
_config.UiItem.MainColumnItem = lvColumnItem;
|
||||||
|
ConfigHandler.SaveConfig(_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion UI
|
#endregion UI
|
||||||
|
|
Loading…
Reference in a new issue