Compare commits

...

35 Commits
7.5.6 ... 7.6.2

Author SHA1 Message Date
2dust
43c95422b7 up 7.6.2 2025-01-15 19:49:14 +08:00
esmaiel777
2662243641 Update dns_singbox_normal (#6511) 2025-01-15 19:47:45 +08:00
esmaiel777
060a35e091 Update tun_singbox_dns (#6510) 2025-01-15 19:47:34 +08:00
2dust
de1132c2df Added option to display real-time speed 2025-01-15 19:45:53 +08:00
2dust
f19edc9370 Improvements and Adjustments
InitCoreInfo()
2025-01-15 17:31:13 +08:00
2dust
f1601c463b Improvements and Adjustments
await Task.CompletedTask;
return await Task.FromResult(0);
2025-01-15 17:26:15 +08:00
2dust
77b15cd530 Add a prompt for not setting a password when open Tun on macos 2025-01-15 11:02:49 +08:00
2dust
a6479fe0d0 Update build-windows.yml 2025-01-14 18:15:45 +08:00
2dust
4ad4e27dc1 Improve reload function 2025-01-14 17:05:13 +08:00
2dust
7370684985 Improve delete expired files 2025-01-14 17:04:43 +08:00
2dust
5ae58e6a98 Improve reload function 2025-01-14 14:49:17 +08:00
2dust
780ccb1932 Improved ProfileItemsEx 2025-01-14 11:48:02 +08:00
2dust
6b4076be10 up 7.6.1 2025-01-12 19:36:19 +08:00
alphax-hue3682
d7a04a15ae Update Persian translate (#6487) 2025-01-12 19:33:57 +08:00
2dust
2ae43f8bdb Revert "Remove rules custom Icon"
This reverts commit d3ebc17a10.
2025-01-12 19:33:23 +08:00
2dust
d3ebc17a10 Remove rules custom Icon 2025-01-12 14:35:59 +08:00
2dust
7a8680711e Improvements and Adjustments 2025-01-12 14:30:49 +08:00
2dust
649e89e7af Added Copy Terminal proxy command to clipboard in tray menu
https://github.com/2dust/v2rayN/issues/6482
2025-01-12 11:07:34 +08:00
2dust
cb94d64395 Bug fix 2025-01-11 19:35:32 +08:00
2dust
2440dc2440 Remove deprecated DefIEProxyExceptions 2025-01-11 19:34:04 +08:00
Little丶Dreams
364a24c580 CloneServerStatItem 时检查indexId和toIndexId是否相同 (#6478) 2025-01-11 14:44:09 +08:00
2dust
8f3e0dbd82 up 7.6.0 2025-01-11 11:48:57 +08:00
alphax-hue3682
596234df26 Update Persian translate (#6465)
* Update ResUI.fa-Ir.resx

e0ae101ff4

* Update ResUI.fa-Ir.resx
2025-01-11 11:30:06 +08:00
2dust
c38aec50dc Delete unused resources 2025-01-11 11:28:35 +08:00
2dust
40915b5f98 Adjust theme options for windows 2025-01-11 11:23:40 +08:00
2dust
a176613119 Bug fix for ProcUtils 2025-01-11 10:44:34 +08:00
2dust
6c6de1ae7f Improvements and Adjustments 2025-01-10 20:12:42 +08:00
2dust
edbd168dcf Add theme options for desktop 2025-01-10 15:53:06 +08:00
2dust
127858d582 Adjust UI for desktop 2025-01-10 14:23:03 +08:00
2dust
baf90cfbdd Sing-box cache file specified path
https://github.com/2dust/v2rayN/issues/6460
2025-01-10 10:00:00 +08:00
2dust
1a5eeb9401 Adjust UI for desktop 2025-01-09 21:03:17 +08:00
2dust
e0ae101ff4 Adjust UI for desktop 2025-01-09 15:14:03 +08:00
Long Yixing
8b4a07dfe8 Modify the macos build script (#6461)
No longer generate AppIcon.icns
2025-01-09 10:21:07 +08:00
2dust
db934e70cb The icon of the system proxy can be customized
https://github.com/2dust/v2rayN/issues/6459
2025-01-08 20:35:33 +08:00
2dust
b770048f05 The exported routing rules are compatible with the import function of v2rayNG 2025-01-08 17:57:23 +08:00
95 changed files with 1066 additions and 1085 deletions

View File

@@ -29,6 +29,11 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Setup
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Build - name: Build
run: | run: |
cd v2rayN cd v2rayN

View File

@@ -7,22 +7,10 @@ Version="$3"
PackagePath="v2rayN-Package-${Arch}" PackagePath="v2rayN-Package-${Arch}"
mkdir -p "$PackagePath/v2rayN.app/Contents/Resources" mkdir -p "$PackagePath/v2rayN.app/Contents/Resources"
cp -rf "$OutputPath" "$PackagePath/v2rayN.app/Contents/MacOS" cp -rf "$OutputPath" "$PackagePath/v2rayN.app/Contents/MacOS"
cp -f "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN.icns" "$PackagePath/v2rayN.app/Contents/Resources/AppIcon.icns"
echo "When this file exists, app will not store configs under this folder" > "$PackagePath/v2rayN.app/Contents/MacOS/NotStoreConfigHere.txt" echo "When this file exists, app will not store configs under this folder" > "$PackagePath/v2rayN.app/Contents/MacOS/NotStoreConfigHere.txt"
chmod +x "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN" chmod +x "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN"
mkdir -p "$PackagePath/icons.iconset"
sips -z 16 16 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_16x16.png"
sips -z 32 32 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_16x16@2x.png"
sips -z 32 32 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_32x32.png"
sips -z 64 64 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_32x32@2x.png"
sips -z 128 128 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_128x128.png"
sips -z 256 256 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_128x128@2x.png"
sips -z 256 256 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_256x256.png"
sips -z 512 512 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_256x256@2x.png"
sips -z 512 512 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_512x512.png"
sips -z 1024 1024 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_512x512@2x.png"
iconutil -c icns "$PackagePath/icons.iconset" -o "$PackagePath/v2rayN.app/Contents/Resources/AppIcon.icns"
cat >"$PackagePath/v2rayN.app/Contents/Info.plist" <<-EOF cat >"$PackagePath/v2rayN.app/Contents/Info.plist" <<-EOF
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

View File

@@ -5,7 +5,7 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright> <Copyright>Copyright © 2017-2025 (GPLv3)</Copyright>
<FileVersion>1.3.1</FileVersion> <FileVersion>1.3.1</FileVersion>
</PropertyGroup> </PropertyGroup>

View File

@@ -10,7 +10,7 @@ namespace AmazTool
{ {
Console.WriteLine($"{Resx.Resource.StartUnzipping}\n{fileName}"); Console.WriteLine($"{Resx.Resource.StartUnzipping}\n{fileName}");
Waiting(3); Waiting(5);
if (!File.Exists(fileName)) if (!File.Exists(fileName))
{ {

View File

@@ -196,5 +196,26 @@ namespace ServiceLib.Common
} }
} }
} }
public static void DeleteExpiredFiles(string sourceDir, DateTime dtLine)
{
try
{
var files = Directory.GetFiles(sourceDir, "*.*");
foreach (var filePath in files)
{
var file = new FileInfo(filePath);
if (file.CreationTime >= dtLine)
{
continue;
}
file.Delete();
}
}
catch
{
// ignored
}
}
} }
} }

View File

@@ -97,6 +97,30 @@ namespace ServiceLib.Common
return result; return result;
} }
/// <summary>
/// Serialize Object to Json string
/// </summary>
/// <param name="obj"></param>
/// <param name="options"></param>
/// <returns></returns>
public static string Serialize(object? obj, JsonSerializerOptions options)
{
var result = string.Empty;
try
{
if (obj == null)
{
return result;
}
result = JsonSerializer.Serialize(obj, options);
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return result;
}
/// <summary> /// <summary>
/// SerializeToNode /// SerializeToNode
/// </summary> /// </summary>

View File

@@ -25,36 +25,6 @@ namespace ServiceLib.Common
} }
} }
public static void ClearLogs()
{
Task.Run(() =>
{
try
{
var now = DateTime.Now.AddMonths(-1);
var dir = Utils.GetLogPath();
var files = Directory.GetFiles(dir, "*.txt");
foreach (var filePath in files)
{
var file = new FileInfo(filePath);
if (file.CreationTime >= now) continue;
try
{
file.Delete();
}
catch
{
// ignored
}
}
}
catch
{
// ignored
}
});
}
public static void SaveLog(string strContent) public static void SaveLog(string strContent)
{ {
if (!LogManager.IsLoggingEnabled()) return; if (!LogManager.IsLoggingEnabled()) return;

View File

@@ -81,9 +81,7 @@ public static class ProcUtils
return; return;
} }
var procId = review ? proc?.Id : null; GetProcessKeyInfo(proc, review, out var procId, out var fileName, out var processName);
var fileName = review ? proc?.MainModule?.FileName : null;
var processName = review ? proc?.ProcessName : null;
try { proc?.Kill(true); } catch (Exception ex) { Logging.SaveLog(_tag, ex); } try { proc?.Kill(true); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try { proc?.Kill(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); } try { proc?.Kill(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
@@ -91,6 +89,29 @@ public static class ProcUtils
try { proc?.Dispose(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); } try { proc?.Dispose(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
await Task.Delay(300); await Task.Delay(300);
await ProcessKillByKeyInfo(review, procId, fileName, processName);
}
private static void GetProcessKeyInfo(Process? proc, bool review, out int? procId, out string? fileName, out string? processName)
{
procId = null;
fileName = null;
processName = null;
if (!review) return;
try
{
procId = proc?.Id;
fileName = proc?.MainModule?.FileName;
processName = proc?.ProcessName;
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
}
private static async Task ProcessKillByKeyInfo(bool review, int? procId, string? fileName, string? processName)
{
if (review && procId != null && fileName != null) if (review && procId != null && fileName != null)
{ {
try try

View File

@@ -558,7 +558,7 @@ namespace ServiceLib.Common
public static string GetRuntimeInfo() public static string GetRuntimeInfo()
{ {
return $"{Utils.GetVersion()} | {Utils.StartupPath()} | {Utils.GetExePath()} | {Environment.OSVersion} | {(Environment.Is64BitOperatingSystem ? 64 : 32)}"; return $"{Utils.GetVersion()} | {Utils.StartupPath()} | {Utils.GetExePath()} | {Environment.OSVersion}";
} }
/// <summary> /// <summary>

View File

@@ -0,0 +1,13 @@
namespace ServiceLib.Enums
{
public enum ETheme
{
FollowSystem,
Dark,
Light,
Aquatic,
Desert,
Dusk,
NightSky
}
}

View File

@@ -63,6 +63,7 @@
public const string HttpProtocol = "http://"; public const string HttpProtocol = "http://";
public const string HttpsProtocol = "https://"; public const string HttpsProtocol = "https://";
public const string SocksProtocol = "socks://"; public const string SocksProtocol = "socks://";
public const string Socks5Protocol = "socks5://";
public const string UserEMail = "t@t.tt"; public const string UserEMail = "t@t.tt";
public const string AutoRunRegPath = @"Software\Microsoft\Windows\CurrentVersion\Run"; public const string AutoRunRegPath = @"Software\Microsoft\Windows\CurrentVersion\Run";

View File

@@ -79,7 +79,8 @@
{ {
Logging.SaveLog($"v2rayN start up | {Utils.GetRuntimeInfo()}"); Logging.SaveLog($"v2rayN start up | {Utils.GetRuntimeInfo()}");
Logging.LoggingEnabled(_config.GuiItem.EnableLog); Logging.LoggingEnabled(_config.GuiItem.EnableLog);
Logging.ClearLogs();
ClearExpiredFiles();
return true; return true;
} }
@@ -91,6 +92,15 @@
return true; return true;
} }
private void ClearExpiredFiles()
{
Task.Run(() =>
{
FileManager.DeleteExpiredFiles(Utils.GetLogPath(), DateTime.Now.AddMonths(-1));
FileManager.DeleteExpiredFiles(Utils.GetTempPath(), DateTime.Now.AddMonths(-1));
});
}
#endregion Init #endregion Init
#region Config #region Config
@@ -106,8 +116,14 @@
if (Utils.IsWindows()) if (Utils.IsWindows())
{ {
_processJob ??= new(); _processJob ??= new();
try
{
_processJob?.AddProcess(processHandle); _processJob?.AddProcess(processHandle);
} }
catch
{
}
}
} }
#endregion Config #endregion Config
@@ -119,7 +135,7 @@
return await SQLiteHelper.Instance.TableAsync<SubItem>().OrderBy(t => t.Sort).ToListAsync(); return await SQLiteHelper.Instance.TableAsync<SubItem>().OrderBy(t => t.Sort).ToListAsync();
} }
public async Task<SubItem?> GetSubItem(string subid) public async Task<SubItem?> GetSubItem(string? subid)
{ {
return await SQLiteHelper.Instance.TableAsync<SubItem>().FirstOrDefaultAsync(t => t.Id == subid); return await SQLiteHelper.Instance.TableAsync<SubItem>().FirstOrDefaultAsync(t => t.Id == subid);
} }
@@ -164,45 +180,6 @@
return await SQLiteHelper.Instance.QueryAsync<ProfileItemModel>(sql); return await SQLiteHelper.Instance.QueryAsync<ProfileItemModel>(sql);
} }
public async Task<List<ProfileItemModel>?> ProfileItemsEx(string subid, string filter)
{
var lstModel = await ProfileItems(_config.SubIndexId, filter);
await ConfigHandler.SetDefaultServer(_config, lstModel);
var lstServerStat = (_config.GuiItem.EnableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
var lstProfileExs = await ProfileExHandler.Instance.GetProfileExs();
lstModel = (from t in lstModel
join t2 in lstServerStat on t.IndexId equals t2.IndexId into t2b
from t22 in t2b.DefaultIfEmpty()
join t3 in lstProfileExs on t.IndexId equals t3.IndexId into t3b
from t33 in t3b.DefaultIfEmpty()
select new ProfileItemModel
{
IndexId = t.IndexId,
ConfigType = t.ConfigType,
Remarks = t.Remarks,
Address = t.Address,
Port = t.Port,
Security = t.Security,
Network = t.Network,
StreamSecurity = t.StreamSecurity,
Subid = t.Subid,
SubRemarks = t.SubRemarks,
IsActive = t.IndexId == _config.IndexId,
Sort = t33 == null ? 0 : t33.Sort,
Delay = t33 == null ? 0 : t33.Delay,
DelayVal = t33?.Delay != 0 ? $"{t33?.Delay} {Global.DelayUnit}" : string.Empty,
SpeedVal = t33?.Speed != 0 ? $"{t33?.Speed} {Global.SpeedUnit}" : string.Empty,
TodayDown = t22 == null ? "" : Utils.HumanFy(t22.TodayDown),
TodayUp = t22 == null ? "" : Utils.HumanFy(t22.TodayUp),
TotalDown = t22 == null ? "" : Utils.HumanFy(t22.TotalDown),
TotalUp = t22 == null ? "" : Utils.HumanFy(t22.TotalUp)
}).OrderBy(t => t.Sort).ToList();
return lstModel;
}
public async Task<ProfileItem?> GetProfileItem(string indexId) public async Task<ProfileItem?> GetProfileItem(string indexId)
{ {
if (Utils.IsNullOrEmpty(indexId)) if (Utils.IsNullOrEmpty(indexId))

View File

@@ -45,6 +45,8 @@ namespace ServiceLib.Handler
{ {
AutoStartTaskService(autoRunName, "", ""); AutoStartTaskService(autoRunName, "", "");
} }
await Task.CompletedTask;
} }
private static async Task SetTaskWindows() private static async Task SetTaskWindows()
@@ -66,6 +68,7 @@ namespace ServiceLib.Handler
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
await Task.CompletedTask;
} }
/// <summary> /// <summary>
@@ -127,6 +130,7 @@ namespace ServiceLib.Handler
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
await Task.CompletedTask;
} }
private static async Task SetTaskLinux() private static async Task SetTaskLinux()

View File

@@ -94,10 +94,7 @@ namespace ServiceLib.Handler
EnableTun = false, EnableTun = false,
Mtu = 9000, Mtu = 9000,
}; };
config.GuiItem ??= new() config.GuiItem ??= new();
{
EnableStatistics = false,
};
config.MsgUIItem ??= new(); config.MsgUIItem ??= new();
config.UiItem ??= new UIItem() config.UiItem ??= new UIItem()
@@ -163,11 +160,6 @@ namespace ServiceLib.Handler
Interval = "10-20" Interval = "10-20"
}; };
if (Utils.IsNotEmpty(config.ConstItem.DefIEProxyExceptions))
{
config.SystemProxyItem.SystemProxyExceptions = $"{config.ConstItem.DefIEProxyExceptions};{config.SystemProxyItem.SystemProxyExceptions}";
config.ConstItem.DefIEProxyExceptions = string.Empty;
}
if (config.SystemProxyItem.SystemProxyExceptions.IsNullOrEmpty()) if (config.SystemProxyItem.SystemProxyExceptions.IsNullOrEmpty())
{ {
config.SystemProxyItem.SystemProxyExceptions = Utils.IsWindows() ? Global.SystemProxyExceptionsWindows : Global.SystemProxyExceptionsLinux; config.SystemProxyItem.SystemProxyExceptions = Utils.IsWindows() ? Global.SystemProxyExceptionsWindows : Global.SystemProxyExceptionsLinux;
@@ -477,7 +469,7 @@ namespace ServiceLib.Handler
} }
ProfileExHandler.Instance.SetSort(lstProfile[index].IndexId, sort); ProfileExHandler.Instance.SetSort(lstProfile[index].IndexId, sort);
return 0; return await Task.FromResult(0);
} }
/// <summary> /// <summary>
@@ -1055,7 +1047,7 @@ namespace ServiceLib.Handler
Port = node.PreSocksPort.Value, Port = node.PreSocksPort.Value,
}; };
} }
await Task.CompletedTask;
return itemSocks; return itemSocks;
} }
@@ -1625,7 +1617,7 @@ namespace ServiceLib.Handler
break; break;
} }
} }
return 0; return await Task.FromResult(0);
} }
public static async Task<int> SetDefaultRouting(Config config, RoutingItem routingItem) public static async Task<int> SetDefaultRouting(Config config, RoutingItem routingItem)

View File

@@ -80,7 +80,7 @@
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, ""); ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
ret.Success = true; ret.Success = true;
return ret; return await Task.FromResult(ret);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -67,13 +67,17 @@ namespace ServiceLib.Handler
return; return;
} }
UpdateFunc(true, $"{node.GetSummary()}"); UpdateFunc(false, $"{node.GetSummary()}");
UpdateFunc(false, $"{Utils.GetRuntimeInfo()}"); UpdateFunc(false, $"{Utils.GetRuntimeInfo()}");
UpdateFunc(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"))); UpdateFunc(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
await CoreStop(); await CoreStop();
await Task.Delay(100); await Task.Delay(100);
await CoreStart(node); await CoreStart(node);
await CoreStartPreService(node); await CoreStartPreService(node);
if (_process != null)
{
UpdateFunc(true, $"{node.GetSummary()}");
}
} }
public async Task<int> LoadCoreConfigSpeedtest(List<ServerTestItem> selecteds) public async Task<int> LoadCoreConfigSpeedtest(List<ServerTestItem> selecteds)
@@ -220,8 +224,6 @@ namespace ServiceLib.Handler
await RunProcessAsLinuxSudo(proc, fileName, coreInfo, configPath); await RunProcessAsLinuxSudo(proc, fileName, coreInfo, configPath);
} }
var startUpErrorMessage = new StringBuilder();
var startUpSuccessful = false;
if (displayLog) if (displayLog)
{ {
proc.OutputDataReceived += (sender, e) => proc.OutputDataReceived += (sender, e) =>
@@ -233,11 +235,6 @@ namespace ServiceLib.Handler
{ {
if (Utils.IsNullOrEmpty(e.Data)) return; if (Utils.IsNullOrEmpty(e.Data)) return;
UpdateFunc(false, e.Data + Environment.NewLine); UpdateFunc(false, e.Data + Environment.NewLine);
if (!startUpSuccessful)
{
startUpErrorMessage.Append(e.Data + Environment.NewLine);
}
}; };
} }
proc.Start(); proc.Start();
@@ -258,17 +255,12 @@ namespace ServiceLib.Handler
proc.BeginErrorReadLine(); proc.BeginErrorReadLine();
} }
if (proc.WaitForExit(1000)) await Task.Delay(500);
{
proc.CancelErrorRead();
throw new Exception(displayLog ? startUpErrorMessage.ToString() : "启动进程失败并退出 (Failed to start the process and exited)");
}
else
{
startUpSuccessful = true;
}
AppHandler.Instance.AddProcess(proc.Handle); AppHandler.Instance.AddProcess(proc.Handle);
if (proc is null or { HasExited: true })
{
throw new Exception(ResUI.FailedToRunCore);
}
return proc; return proc;
} }
catch (Exception ex) catch (Exception ex)

View File

@@ -52,9 +52,9 @@
private void InitCoreInfo() private void InitCoreInfo()
{ {
_coreInfo = []; _coreInfo =
[
_coreInfo.Add(new CoreInfo new CoreInfo
{ {
CoreType = ECoreType.v2rayN, CoreType = ECoreType.v2rayN,
Url = Global.NUrl, Url = Global.NUrl,
@@ -65,36 +65,36 @@
DownloadUrlLinuxArm64 = Global.NUrl + "/download/{0}/v2rayN-linux-arm64.zip", DownloadUrlLinuxArm64 = Global.NUrl + "/download/{0}/v2rayN-linux-arm64.zip",
DownloadUrlOSX64 = Global.NUrl + "/download/{0}/v2rayN-macos-64.zip", DownloadUrlOSX64 = Global.NUrl + "/download/{0}/v2rayN-macos-64.zip",
DownloadUrlOSXArm64 = Global.NUrl + "/download/{0}/v2rayN-macos-arm64.zip", DownloadUrlOSXArm64 = Global.NUrl + "/download/{0}/v2rayN-macos-arm64.zip",
}); },
_coreInfo.Add(new CoreInfo new CoreInfo
{ {
CoreType = ECoreType.v2fly, CoreType = ECoreType.v2fly,
CoreExes = new List<string> { "wv2ray", "v2ray" }, CoreExes = ["wv2ray", "v2ray"],
Arguments = "", Arguments = "",
Url = Global.V2flyCoreUrl, Url = Global.V2flyCoreUrl,
ReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl), ReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
Match = "V2Ray", Match = "V2Ray",
VersionArg = "-version", VersionArg = "-version",
RedirectInfo = true, RedirectInfo = true,
}); },
_coreInfo.Add(new CoreInfo new CoreInfo
{ {
CoreType = ECoreType.v2fly_v5, CoreType = ECoreType.v2fly_v5,
CoreExes = new List<string> { "v2ray" }, CoreExes = ["v2ray"],
Arguments = "run -c config.json -format jsonv5", Arguments = "run -c config.json -format jsonv5",
Url = Global.V2flyCoreUrl, Url = Global.V2flyCoreUrl,
ReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl), ReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
Match = "V2Ray", Match = "V2Ray",
VersionArg = "version", VersionArg = "version",
RedirectInfo = true, RedirectInfo = true,
}); },
_coreInfo.Add(new CoreInfo new CoreInfo
{ {
CoreType = ECoreType.Xray, CoreType = ECoreType.Xray,
CoreExes = new List<string> { "xray", "wxray" }, CoreExes = ["xray", "wxray"],
Arguments = "run -c {0}", Arguments = "run -c {0}",
Url = Global.XrayCoreUrl, Url = Global.XrayCoreUrl,
ReleaseApiUrl = Global.XrayCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl), ReleaseApiUrl = Global.XrayCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
@@ -107,12 +107,12 @@
Match = "Xray", Match = "Xray",
VersionArg = "-version", VersionArg = "-version",
RedirectInfo = true, RedirectInfo = true,
}); },
_coreInfo.Add(new CoreInfo new CoreInfo
{ {
CoreType = ECoreType.mihomo, CoreType = ECoreType.mihomo,
CoreExes = new List<string> { "mihomo-windows-amd64-compatible", "mihomo-windows-amd64", "mihomo-linux-amd64", "mihomo", "clash" }, CoreExes = ["mihomo-windows-amd64-compatible", "mihomo-windows-amd64", "mihomo-linux-amd64", "mihomo", "clash"],
Arguments = "-f config.json" + PortableMode(), Arguments = "-f config.json" + PortableMode(),
Url = Global.MihomoCoreUrl, Url = Global.MihomoCoreUrl,
ReleaseApiUrl = Global.MihomoCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl), ReleaseApiUrl = Global.MihomoCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
@@ -125,40 +125,40 @@
Match = "Mihomo", Match = "Mihomo",
VersionArg = "-v", VersionArg = "-v",
RedirectInfo = true, RedirectInfo = true,
}); },
_coreInfo.Add(new CoreInfo new CoreInfo
{ {
CoreType = ECoreType.hysteria, CoreType = ECoreType.hysteria,
CoreExes = new List<string> { "hysteria-windows-amd64", "hysteria" }, CoreExes = ["hysteria-windows-amd64", "hysteria"],
Arguments = "", Arguments = "",
Url = Global.HysteriaCoreUrl, Url = Global.HysteriaCoreUrl,
ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl), ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
RedirectInfo = true, RedirectInfo = true,
}); },
_coreInfo.Add(new CoreInfo new CoreInfo
{ {
CoreType = ECoreType.naiveproxy, CoreType = ECoreType.naiveproxy,
CoreExes = new List<string> { "naiveproxy", "naive" }, CoreExes = ["naiveproxy", "naive"],
Arguments = "config.json", Arguments = "config.json",
Url = Global.NaiveproxyCoreUrl, Url = Global.NaiveproxyCoreUrl,
RedirectInfo = false, RedirectInfo = false,
}); },
_coreInfo.Add(new CoreInfo new CoreInfo
{ {
CoreType = ECoreType.tuic, CoreType = ECoreType.tuic,
CoreExes = new List<string> { "tuic-client", "tuic" }, CoreExes = ["tuic-client", "tuic"],
Arguments = "-c config.json", Arguments = "-c config.json",
Url = Global.TuicCoreUrl, Url = Global.TuicCoreUrl,
RedirectInfo = true, RedirectInfo = true,
}); },
_coreInfo.Add(new CoreInfo new CoreInfo
{ {
CoreType = ECoreType.sing_box, CoreType = ECoreType.sing_box,
CoreExes = new List<string> { "sing-box-client", "sing-box" }, CoreExes = ["sing-box-client", "sing-box"],
Arguments = "run -c {0} --disable-color", Arguments = "run -c {0} --disable-color",
Url = Global.SingboxCoreUrl, Url = Global.SingboxCoreUrl,
RedirectInfo = true, RedirectInfo = true,
@@ -171,25 +171,27 @@
DownloadUrlOSXArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-darwin-arm64.tar.gz", DownloadUrlOSXArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-darwin-arm64.tar.gz",
Match = "sing-box", Match = "sing-box",
VersionArg = "version", VersionArg = "version",
}); },
_coreInfo.Add(new CoreInfo new CoreInfo
{ {
CoreType = ECoreType.juicity, CoreType = ECoreType.juicity,
CoreExes = new List<string> { "juicity-client", "juicity" }, CoreExes = ["juicity-client", "juicity"],
Arguments = "run -c config.json", Arguments = "run -c config.json",
Url = Global.JuicityCoreUrl Url = Global.JuicityCoreUrl
}); },
_coreInfo.Add(new CoreInfo new CoreInfo
{ {
CoreType = ECoreType.hysteria2, CoreType = ECoreType.hysteria2,
CoreExes = new List<string> { "hysteria-windows-amd64", "hysteria-linux-amd64", "hysteria" }, CoreExes = ["hysteria-windows-amd64", "hysteria-linux-amd64", "hysteria"],
Arguments = "", Arguments = "",
Url = Global.HysteriaCoreUrl, Url = Global.HysteriaCoreUrl,
ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl), ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
RedirectInfo = true, RedirectInfo = true,
}); }
];
} }
private string PortableMode() private string PortableMode()

View File

@@ -20,7 +20,7 @@ namespace ServiceLib.Handler
public async Task Init() public async Task Init()
{ {
await InitData(); await InitData();
Task.Run(async () => _ = Task.Run(async () =>
{ {
while (true) while (true)
{ {
@@ -32,7 +32,7 @@ namespace ServiceLib.Handler
public async Task<ConcurrentBag<ProfileExItem>> GetProfileExs() public async Task<ConcurrentBag<ProfileExItem>> GetProfileExs()
{ {
return _lstProfileEx; return await Task.FromResult(_lstProfileEx);
} }
private async Task InitData() private async Task InitData()

View File

@@ -19,16 +19,14 @@
{ {
_config = config; _config = config;
_updateFunc = updateFunc; _updateFunc = updateFunc;
if (!config.GuiItem.EnableStatistics) if (config.GuiItem.EnableStatistics || _config.GuiItem.DisplayRealTimeSpeed)
{ {
return;
}
await InitData(); await InitData();
_statisticsXray = new StatisticsXrayService(config, UpdateServerStatHandler); _statisticsXray = new StatisticsXrayService(config, UpdateServerStatHandler);
_statisticsSingbox = new StatisticsSingboxService(config, UpdateServerStatHandler); _statisticsSingbox = new StatisticsSingboxService(config, UpdateServerStatHandler);
} }
}
public void Close() public void Close()
{ {
@@ -72,6 +70,11 @@
return; return;
} }
if (indexId == toIndexId)
{
return;
}
var stat = _lstServerStat.FirstOrDefault(t => t.IndexId == indexId); var stat = _lstServerStat.FirstOrDefault(t => t.IndexId == indexId);
if (stat == null) if (stat == null)
{ {
@@ -96,7 +99,7 @@
private void UpdateServerStatHandler(ServerSpeedItem server) private void UpdateServerStatHandler(ServerSpeedItem server)
{ {
UpdateServerStat(server); _ = UpdateServerStat(server);
} }
private async Task UpdateServerStat(ServerSpeedItem server) private async Task UpdateServerStat(ServerSpeedItem server)

View File

@@ -16,7 +16,7 @@
try try
{ {
var port = AppHandler.Instance.GetLocalPort(EInboundProtocol.socks); var port = AppHandler.Instance.GetLocalPort(EInboundProtocol.socks);
var exceptions = config.SystemProxyItem.SystemProxyExceptions; var exceptions = config.SystemProxyItem.SystemProxyExceptions.Replace(" ", "");
if (port <= 0) if (port <= 0)
{ {
return false; return false;
@@ -68,7 +68,7 @@
private static void GetWindowsProxyString(Config config, int port, out string strProxy, out string strExceptions) private static void GetWindowsProxyString(Config config, int port, out string strProxy, out string strExceptions)
{ {
strExceptions = config.SystemProxyItem.SystemProxyExceptions; strExceptions = config.SystemProxyItem.SystemProxyExceptions.Replace(" ", "");
if (config.SystemProxyItem.NotProxyLocalAddress) if (config.SystemProxyItem.NotProxyLocalAddress)
{ {
strExceptions = $"<local>;{strExceptions}"; strExceptions = $"<local>;{strExceptions}";

View File

@@ -29,7 +29,7 @@
public string? destinationPort { get; set; } public string? destinationPort { get; set; }
public string? host { get; set; } public string? host { get; set; }
public string? nsMode { get; set; } public string? nsMode { get; set; }
public object uid { get; set; } public object? uid { get; set; }
public string? process { get; set; } public string? process { get; set; }
public string? processPath { get; set; } public string? processPath { get; set; }
public string? remoteDestination { get; set; } public string? remoteDestination { get; set; }

View File

@@ -67,21 +67,13 @@
public class GUIItem public class GUIItem
{ {
public bool AutoRun { get; set; } public bool AutoRun { get; set; }
public bool EnableStatistics { get; set; } public bool EnableStatistics { get; set; }
public bool DisplayRealTimeSpeed { get; set; }
public bool KeepOlderDedupl { get; set; } public bool KeepOlderDedupl { get; set; }
public bool IgnoreGeoUpdateCore { get; set; } = true;
public int AutoUpdateInterval { get; set; } public int AutoUpdateInterval { get; set; }
public bool EnableSecurityProtocolTls13 { get; set; } public bool EnableSecurityProtocolTls13 { get; set; }
public int TrayMenuServersLimit { get; set; } = 20; public int TrayMenuServersLimit { get; set; } = 20;
public bool EnableHWA { get; set; } = false; public bool EnableHWA { get; set; } = false;
public bool EnableLog { get; set; } = true; public bool EnableLog { get; set; } = true;
} }
@@ -102,9 +94,8 @@
public double MainGirdHeight1 { get; set; } public double MainGirdHeight1 { get; set; }
public double MainGirdHeight2 { get; set; } public double MainGirdHeight2 { get; set; }
public EGirdOrientation MainGirdOrientation { get; set; } = EGirdOrientation.Vertical; public EGirdOrientation MainGirdOrientation { get; set; } = EGirdOrientation.Vertical;
public bool ColorModeDark { get; set; }
public bool FollowSystemTheme { get; set; }
public string? ColorPrimaryName { get; set; } public string? ColorPrimaryName { get; set; }
public string? CurrentTheme { get; set; }
public string CurrentLanguage { get; set; } public string CurrentLanguage { get; set; }
public string CurrentFontFamily { get; set; } public string CurrentFontFamily { get; set; }
public int CurrentFontSize { get; set; } public int CurrentFontSize { get; set; }
@@ -119,8 +110,7 @@
[Serializable] [Serializable]
public class ConstItem public class ConstItem
{ {
public string DefIEProxyExceptions { get; set; } public string? SubConvertUrl { get; set; }
public string SubConvertUrl { get; set; } = string.Empty;
public string? GeoSourceUrl { get; set; } public string? GeoSourceUrl { get; set; }
public string? SrsSourceUrl { get; set; } public string? SrsSourceUrl { get; set; }
public string? RouteRulesTemplateSourceUrl { get; set; } public string? RouteRulesTemplateSourceUrl { get; set; }

View File

@@ -843,6 +843,15 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Copy proxy command to clipboard 的本地化字符串。
/// </summary>
public static string menuCopyProxyCmdToClipboard {
get {
return ResourceManager.GetString("menuCopyProxyCmdToClipboard", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Clone selected server 的本地化字符串。 /// 查找类似 Clone selected server 的本地化字符串。
/// </summary> /// </summary>
@@ -942,15 +951,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Import old config (guiNConfig) 的本地化字符串。
/// </summary>
public static string menuImportOldGuiConfig {
get {
return ResourceManager.GetString("menuImportOldGuiConfig", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Import Rules From Clipboard 的本地化字符串。 /// 查找类似 Import Rules From Clipboard 的本地化字符串。
/// </summary> /// </summary>
@@ -1348,7 +1348,7 @@ namespace ServiceLib.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 Import Advanced Rules 的本地化字符串。 /// 查找类似 Import Rules 的本地化字符串。
/// </summary> /// </summary>
public static string menuRoutingAdvancedImportRules { public static string menuRoutingAdvancedImportRules {
get { get {
@@ -1536,15 +1536,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Save Interface Layout 的本地化字符串。
/// </summary>
public static string menuStorageUI {
get {
return ResourceManager.GetString("menuStorageUI", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Add 的本地化字符串。 /// 查找类似 Add 的本地化字符串。
/// </summary> /// </summary>
@@ -2356,15 +2347,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Enable advanced function 的本地化字符串。
/// </summary>
public static string TbenableRoutingAdvanced {
get {
return ResourceManager.GetString("TbenableRoutingAdvanced", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Enable Tun 的本地化字符串。 /// 查找类似 Enable Tun 的本地化字符串。
/// </summary> /// </summary>
@@ -2815,15 +2797,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Dark Mode 的本地化字符串。
/// </summary>
public static string TbSettingsColorMode {
get {
return ResourceManager.GetString("TbSettingsColorMode", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Core: basic settings 的本地化字符串。 /// 查找类似 Core: basic settings 的本地化字符串。
/// </summary> /// </summary>
@@ -2941,6 +2914,15 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Display real-time speed 的本地化字符串。
/// </summary>
public static string TbSettingsDisplayRealTimeSpeed {
get {
return ResourceManager.GetString("TbSettingsDisplayRealTimeSpeed", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Outbound DNS address 的本地化字符串。 /// 查找类似 Outbound DNS address 的本地化字符串。
/// </summary> /// </summary>
@@ -3094,15 +3076,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Follow System Theme 的本地化字符串。
/// </summary>
public static string TbSettingsFollowSystemTheme {
get {
return ResourceManager.GetString("TbSettingsFollowSystemTheme", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Font Size 的本地化字符串。 /// 查找类似 Font Size 的本地化字符串。
/// </summary> /// </summary>
@@ -3148,15 +3121,6 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Ignore Geo files when updating core 的本地化字符串。
/// </summary>
public static string TbSettingsIgnoreGeoUpdateCore {
get {
return ResourceManager.GetString("TbSettingsIgnoreGeoUpdateCore", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Keep older when deduplication 的本地化字符串。 /// 查找类似 Keep older when deduplication 的本地化字符串。
/// </summary> /// </summary>
@@ -3437,7 +3401,7 @@ namespace ServiceLib.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 Enable Statistics (Require restart) 的本地化字符串。 /// 查找类似 Enable traffic statistics (Require restart) 的本地化字符串。
/// </summary> /// </summary>
public static string TbSettingsStatistics { public static string TbSettingsStatistics {
get { get {
@@ -3463,6 +3427,15 @@ namespace ServiceLib.Resx {
} }
} }
/// <summary>
/// 查找类似 Theme 的本地化字符串。
/// </summary>
public static string TbSettingsTheme {
get {
return ResourceManager.GetString("TbSettingsTheme", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Enable Security Protocol TLS v1.3 (subscription/update) 的本地化字符串。 /// 查找类似 Enable Security Protocol TLS v1.3 (subscription/update) 的本地化字符串。
/// </summary> /// </summary>

View File

@@ -481,9 +481,6 @@
<data name="TbSettingsColor" xml:space="preserve"> <data name="TbSettingsColor" xml:space="preserve">
<value>رنگ</value> <value>رنگ</value>
</data> </data>
<data name="TbSettingsColorMode" xml:space="preserve">
<value>حالت تاریک</value>
</data>
<data name="TbSettingsLanguage" xml:space="preserve"> <data name="TbSettingsLanguage" xml:space="preserve">
<value>زبان</value> <value>زبان</value>
</data> </data>
@@ -721,8 +718,8 @@
<data name="TbSettingsHttpPort" xml:space="preserve"> <data name="TbSettingsHttpPort" xml:space="preserve">
<value>پورت Http</value> <value>پورت Http</value>
</data> </data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve"> <data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>هنگام به‌روزرسانی هسته، فایل‌های Geo را نادیده بگیرید</value> <value>Display real-time speed</value>
</data> </data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve"> <data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>هنگام کپی برداری، نگه داری قدیمی تر ها</value> <value>هنگام کپی برداری، نگه داری قدیمی تر ها</value>
@@ -839,7 +836,7 @@
<value>اضافه کردن</value> <value>اضافه کردن</value>
</data> </data>
<data name="menuRoutingAdvancedImportRules" xml:space="preserve"> <data name="menuRoutingAdvancedImportRules" xml:space="preserve">
<value>وارد کردن قوانین پیشرفته</value> <value>وارد کردن مجموعه قوانین</value>
</data> </data>
<data name="menuRoutingAdvancedRemove" xml:space="preserve"> <data name="menuRoutingAdvancedRemove" xml:space="preserve">
<value>حذف انتخاب شده</value> <value>حذف انتخاب شده</value>
@@ -853,9 +850,6 @@
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>استراتژی دامنه</value> <value>استراتژی دامنه</value>
</data> </data>
<data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>فعال کردن عملکرد پیشرفته</value>
</data>
<data name="TbRoutingTabBlock" xml:space="preserve"> <data name="TbRoutingTabBlock" xml:space="preserve">
<value>3. مسدود کردن دامنه یا آیپی</value> <value>3. مسدود کردن دامنه یا آیپی</value>
</data> </data>
@@ -940,9 +934,6 @@
<data name="TbDisplayLog" xml:space="preserve"> <data name="TbDisplayLog" xml:space="preserve">
<value>نمایش گزارش</value> <value>نمایش گزارش</value>
</data> </data>
<data name="menuImportOldGuiConfig" xml:space="preserve">
<value>پیکربندی قدیمی guiNConfig را وارد شود</value>
</data>
<data name="TbEnableTunAs" xml:space="preserve"> <data name="TbEnableTunAs" xml:space="preserve">
<value>فعال سازی Tun</value> <value>فعال سازی Tun</value>
</data> </data>
@@ -1105,9 +1096,6 @@
<data name="TipActiveServer" xml:space="preserve"> <data name="TipActiveServer" xml:space="preserve">
<value>فعال سازی</value> <value>فعال سازی</value>
</data> </data>
<data name="menuStorageUI" xml:space="preserve">
<value>ذخیره طرح رابط</value>
</data>
<data name="TbSettingsGeoFilesSource" xml:space="preserve"> <data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>منبع فایل های جغرافیایی (اختیاری)</value> <value>منبع فایل های جغرافیایی (اختیاری)</value>
</data> </data>
@@ -1273,9 +1261,6 @@
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve"> <data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
<value>حداکتر پهنای باند هیستریا (آپلود/دانلود)</value> <value>حداکتر پهنای باند هیستریا (آپلود/دانلود)</value>
</data> </data>
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
<value>دنبال کردن تم سیستم</value>
</data>
<data name="menuAddTuicServer" xml:space="preserve"> <data name="menuAddTuicServer" xml:space="preserve">
<value>افزودن سرور [TUIC]</value> <value>افزودن سرور [TUIC]</value>
</data> </data>
@@ -1402,4 +1387,10 @@
<data name="TbRoutingInboundTagTips" xml:space="preserve"> <data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks:پورت محلی، socks2: پورت دوم محلی، socks3: پورت LAN</value> <value>socks:پورت محلی، socks2: پورت دوم محلی، socks3: پورت LAN</value>
</data> </data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>تم</value>
</data>
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
<value>کپی کردن دستور پروکسی در کلیپ بورد</value>
</data>
</root> </root>

View File

@@ -481,12 +481,6 @@
<data name="TbSettingsColor" xml:space="preserve"> <data name="TbSettingsColor" xml:space="preserve">
<value>Szín</value> <value>Szín</value>
</data> </data>
<data name="TbSettingsColorMode" xml:space="preserve">
<value>Sötét mód</value>
</data>
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
<value>Kövesse a rendszer témáját</value>
</data>
<data name="TbSettingsLanguage" xml:space="preserve"> <data name="TbSettingsLanguage" xml:space="preserve">
<value>Nyelv (Újraindítás)</value> <value>Nyelv (Újraindítás)</value>
</data> </data>
@@ -724,8 +718,8 @@
<data name="TbSettingsHttpPort" xml:space="preserve"> <data name="TbSettingsHttpPort" xml:space="preserve">
<value>HTTP Port</value> <value>HTTP Port</value>
</data> </data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve"> <data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>Geo fájlok figyelmen kívül hagyása a yalap frissítésekor</value> <value>Display real-time speed</value>
</data> </data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve"> <data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>Régi megőrzése a deduplikáció során</value> <value>Régi megőrzése a deduplikáció során</value>
@@ -856,9 +850,6 @@
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>Domain stratégia</value> <value>Domain stratégia</value>
</data> </data>
<data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>Fejlett funkció engedélyezése</value>
</data>
<data name="TbRoutingTabBlock" xml:space="preserve"> <data name="TbRoutingTabBlock" xml:space="preserve">
<value>3. Domain vagy IP blokkolása</value> <value>3. Domain vagy IP blokkolása</value>
</data> </data>
@@ -943,9 +934,6 @@
<data name="TbDisplayLog" xml:space="preserve"> <data name="TbDisplayLog" xml:space="preserve">
<value>Napló megjelenítése</value> <value>Napló megjelenítése</value>
</data> </data>
<data name="menuImportOldGuiConfig" xml:space="preserve">
<value>Régi konfiguráció importálása (guiNConfig)</value>
</data>
<data name="TbEnableTunAs" xml:space="preserve"> <data name="TbEnableTunAs" xml:space="preserve">
<value>Tun engedélyezése</value> <value>Tun engedélyezése</value>
</data> </data>
@@ -1318,9 +1306,6 @@
<data name="TipActiveServer" xml:space="preserve"> <data name="TipActiveServer" xml:space="preserve">
<value>Aktív</value> <value>Aktív</value>
</data> </data>
<data name="menuStorageUI" xml:space="preserve">
<value>Szoftverfelület elmentése</value>
</data>
<data name="TbSettingsGeoFilesSource" xml:space="preserve"> <data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>Geo fájlok forrása (opcionális)</value> <value>Geo fájlok forrása (opcionális)</value>
</data> </data>
@@ -1402,4 +1387,10 @@
<data name="TbRoutingInboundTagTips" xml:space="preserve"> <data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks: local port, socks2: second local port, socks3: LAN port</value> <value>socks: local port, socks2: second local port, socks3: LAN port</value>
</data> </data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>Theme</value>
</data>
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
<value>Copy proxy command to clipboard</value>
</data>
</root> </root>

View File

@@ -481,12 +481,6 @@
<data name="TbSettingsColor" xml:space="preserve"> <data name="TbSettingsColor" xml:space="preserve">
<value>Color</value> <value>Color</value>
</data> </data>
<data name="TbSettingsColorMode" xml:space="preserve">
<value>Dark Mode</value>
</data>
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
<value>Follow System Theme</value>
</data>
<data name="TbSettingsLanguage" xml:space="preserve"> <data name="TbSettingsLanguage" xml:space="preserve">
<value>Language (Restart)</value> <value>Language (Restart)</value>
</data> </data>
@@ -724,8 +718,8 @@
<data name="TbSettingsHttpPort" xml:space="preserve"> <data name="TbSettingsHttpPort" xml:space="preserve">
<value>HTTP Port</value> <value>HTTP Port</value>
</data> </data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve"> <data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>Ignore Geo files when updating core</value> <value>Display real-time speed (Require restart)</value>
</data> </data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve"> <data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>Keep older when deduplication</value> <value>Keep older when deduplication</value>
@@ -761,7 +755,7 @@
<value>Start on boot</value> <value>Start on boot</value>
</data> </data>
<data name="TbSettingsStatistics" xml:space="preserve"> <data name="TbSettingsStatistics" xml:space="preserve">
<value>Enable Statistics (Require restart)</value> <value>Enable traffic statistics (Require restart)</value>
</data> </data>
<data name="TbSettingsSubConvert" xml:space="preserve"> <data name="TbSettingsSubConvert" xml:space="preserve">
<value>Subscription conversion URL</value> <value>Subscription conversion URL</value>
@@ -842,7 +836,7 @@
<value>Add</value> <value>Add</value>
</data> </data>
<data name="menuRoutingAdvancedImportRules" xml:space="preserve"> <data name="menuRoutingAdvancedImportRules" xml:space="preserve">
<value>Import Advanced Rules</value> <value>Import Rules</value>
</data> </data>
<data name="menuRoutingAdvancedRemove" xml:space="preserve"> <data name="menuRoutingAdvancedRemove" xml:space="preserve">
<value>Remove selected (Delete)</value> <value>Remove selected (Delete)</value>
@@ -856,9 +850,6 @@
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>Domain strategy</value> <value>Domain strategy</value>
</data> </data>
<data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>Enable advanced function</value>
</data>
<data name="TbRoutingTabBlock" xml:space="preserve"> <data name="TbRoutingTabBlock" xml:space="preserve">
<value>3.Block Domain or IP</value> <value>3.Block Domain or IP</value>
</data> </data>
@@ -943,9 +934,6 @@
<data name="TbDisplayLog" xml:space="preserve"> <data name="TbDisplayLog" xml:space="preserve">
<value>Display Log</value> <value>Display Log</value>
</data> </data>
<data name="menuImportOldGuiConfig" xml:space="preserve">
<value>Import old config (guiNConfig)</value>
</data>
<data name="TbEnableTunAs" xml:space="preserve"> <data name="TbEnableTunAs" xml:space="preserve">
<value>Enable Tun</value> <value>Enable Tun</value>
</data> </data>
@@ -1318,9 +1306,6 @@
<data name="TipActiveServer" xml:space="preserve"> <data name="TipActiveServer" xml:space="preserve">
<value>Active</value> <value>Active</value>
</data> </data>
<data name="menuStorageUI" xml:space="preserve">
<value>Save Interface Layout</value>
</data>
<data name="TbSettingsGeoFilesSource" xml:space="preserve"> <data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>Geo files source (optional)</value> <value>Geo files source (optional)</value>
</data> </data>
@@ -1402,4 +1387,10 @@
<data name="TbRoutingInboundTagTips" xml:space="preserve"> <data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks: local port, socks2: second local port, socks3: LAN port</value> <value>socks: local port, socks2: second local port, socks3: LAN port</value>
</data> </data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>Theme</value>
</data>
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
<value>Copy proxy command to clipboard</value>
</data>
</root> </root>

View File

@@ -481,12 +481,6 @@
<data name="TbSettingsColor" xml:space="preserve"> <data name="TbSettingsColor" xml:space="preserve">
<value>Цвет</value> <value>Цвет</value>
</data> </data>
<data name="TbSettingsColorMode" xml:space="preserve">
<value>Тёмный режим</value>
</data>
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
<value>Следить за системной темой</value>
</data>
<data name="TbSettingsLanguage" xml:space="preserve"> <data name="TbSettingsLanguage" xml:space="preserve">
<value>Язык (требуется перезапуск)</value> <value>Язык (требуется перезапуск)</value>
</data> </data>
@@ -730,8 +724,8 @@
<data name="TbSettingsHttpPort" xml:space="preserve"> <data name="TbSettingsHttpPort" xml:space="preserve">
<value>HTTP порт</value> <value>HTTP порт</value>
</data> </data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve"> <data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>Игнорировать файлы Geo при обновлении ядра</value> <value>Display real-time speed</value>
</data> </data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve"> <data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>Сохранить старые при удалении дублей</value> <value>Сохранить старые при удалении дублей</value>
@@ -862,9 +856,6 @@
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>Доменная стратегия</value> <value>Доменная стратегия</value>
</data> </data>
<data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>Включить расширенные функции</value>
</data>
<data name="TbRoutingTabBlock" xml:space="preserve"> <data name="TbRoutingTabBlock" xml:space="preserve">
<value>3.Заблокировать домен или IP</value> <value>3.Заблокировать домен или IP</value>
</data> </data>
@@ -949,9 +940,6 @@
<data name="TbDisplayLog" xml:space="preserve"> <data name="TbDisplayLog" xml:space="preserve">
<value>Показать логи</value> <value>Показать логи</value>
</data> </data>
<data name="menuImportOldGuiConfig" xml:space="preserve">
<value>Импортировать старый конфиг guiNConfig</value>
</data>
<data name="TbEnableTunAs" xml:space="preserve"> <data name="TbEnableTunAs" xml:space="preserve">
<value>Режим VPN</value> <value>Режим VPN</value>
</data> </data>
@@ -1270,9 +1258,6 @@
<data name="LvConvertTarget" xml:space="preserve"> <data name="LvConvertTarget" xml:space="preserve">
<value>Convert target type</value> <value>Convert target type</value>
</data> </data>
<data name="menuStorageUI" xml:space="preserve">
<value>Save Interface Layout</value>
</data>
<data name="SpeedDisplayText" xml:space="preserve"> <data name="SpeedDisplayText" xml:space="preserve">
<value>{0} : {1}/s↑ | {2}/s↓</value> <value>{0} : {1}/s↑ | {2}/s↓</value>
</data> </data>
@@ -1402,4 +1387,10 @@
<data name="TbRoutingInboundTagTips" xml:space="preserve"> <data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks: local port, socks2: second local port, socks3: LAN port</value> <value>socks: local port, socks2: second local port, socks3: LAN port</value>
</data> </data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>Theme</value>
</data>
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
<value>Copy proxy command to clipboard</value>
</data>
</root> </root>

View File

@@ -481,12 +481,6 @@
<data name="TbSettingsColor" xml:space="preserve"> <data name="TbSettingsColor" xml:space="preserve">
<value>颜色</value> <value>颜色</value>
</data> </data>
<data name="TbSettingsColorMode" xml:space="preserve">
<value>暗黑模式</value>
</data>
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
<value>跟随系统主题</value>
</data>
<data name="TbSettingsLanguage" xml:space="preserve"> <data name="TbSettingsLanguage" xml:space="preserve">
<value>语言(需重启)</value> <value>语言(需重启)</value>
</data> </data>
@@ -724,8 +718,8 @@
<data name="TbSettingsHttpPort" xml:space="preserve"> <data name="TbSettingsHttpPort" xml:space="preserve">
<value>本地http监听端口</value> <value>本地http监听端口</value>
</data> </data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve"> <data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>更新Core时忽略Geo文件</value> <value>显示实时速度(需重启)</value>
</data> </data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve"> <data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>去重时保留序号较小的项</value> <value>去重时保留序号较小的项</value>
@@ -761,7 +755,7 @@
<value>开机启动(可能会不成功)</value> <value>开机启动(可能会不成功)</value>
</data> </data>
<data name="TbSettingsStatistics" xml:space="preserve"> <data name="TbSettingsStatistics" xml:space="preserve">
<value>启用统计(实时网速显示,需重启)</value> <value>启用流量统计(需重启</value>
</data> </data>
<data name="TbSettingsSubConvert" xml:space="preserve"> <data name="TbSettingsSubConvert" xml:space="preserve">
<value>订阅转换网址(可选)</value> <value>订阅转换网址(可选)</value>
@@ -842,7 +836,7 @@
<value>添加规则集</value> <value>添加规则集</value>
</data> </data>
<data name="menuRoutingAdvancedImportRules" xml:space="preserve"> <data name="menuRoutingAdvancedImportRules" xml:space="preserve">
<value>一键导入高级规则</value> <value>一键导入规则</value>
</data> </data>
<data name="menuRoutingAdvancedRemove" xml:space="preserve"> <data name="menuRoutingAdvancedRemove" xml:space="preserve">
<value>移除所选规则 (Delete)</value> <value>移除所选规则 (Delete)</value>
@@ -856,9 +850,6 @@
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>域名解析策略</value> <value>域名解析策略</value>
</data> </data>
<data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>启用高级功能</value>
</data>
<data name="TbRoutingTabBlock" xml:space="preserve"> <data name="TbRoutingTabBlock" xml:space="preserve">
<value>3.阻止的Domain或IP</value> <value>3.阻止的Domain或IP</value>
</data> </data>
@@ -943,9 +934,6 @@
<data name="TbDisplayLog" xml:space="preserve"> <data name="TbDisplayLog" xml:space="preserve">
<value>显示日志</value> <value>显示日志</value>
</data> </data>
<data name="menuImportOldGuiConfig" xml:space="preserve">
<value>导入旧的配置文件guiNConfig</value>
</data>
<data name="TbEnableTunAs" xml:space="preserve"> <data name="TbEnableTunAs" xml:space="preserve">
<value>启用Tun</value> <value>启用Tun</value>
</data> </data>
@@ -1315,9 +1303,6 @@
<data name="TipActiveServer" xml:space="preserve"> <data name="TipActiveServer" xml:space="preserve">
<value>活动</value> <value>活动</value>
</data> </data>
<data name="menuStorageUI" xml:space="preserve">
<value>保存界面布局</value>
</data>
<data name="TbSettingsGeoFilesSource" xml:space="preserve"> <data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>Geo文件来源(可选)</value> <value>Geo文件来源(可选)</value>
</data> </data>
@@ -1399,4 +1384,10 @@
<data name="TbRoutingInboundTagTips" xml:space="preserve"> <data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks本地端口socks2第二个本地端口socks3局域网端口</value> <value>socks本地端口socks2第二个本地端口socks3局域网端口</value>
</data> </data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>主题</value>
</data>
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
<value>复制终端代理命令至剪贴板</value>
</data>
</root> </root>

View File

@@ -481,12 +481,6 @@
<data name="TbSettingsColor" xml:space="preserve"> <data name="TbSettingsColor" xml:space="preserve">
<value>顏色</value> <value>顏色</value>
</data> </data>
<data name="TbSettingsColorMode" xml:space="preserve">
<value>暗黑模式</value>
</data>
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
<value>跟隨系統主題</value>
</data>
<data name="TbSettingsLanguage" xml:space="preserve"> <data name="TbSettingsLanguage" xml:space="preserve">
<value>語言(需重啟)</value> <value>語言(需重啟)</value>
</data> </data>
@@ -725,8 +719,8 @@
<data name="TbSettingsHttpPort" xml:space="preserve"> <data name="TbSettingsHttpPort" xml:space="preserve">
<value>本機HTTP偵聽埠</value> <value>本機HTTP偵聽埠</value>
</data> </data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve"> <data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>更新Core時忽略Geo檔案</value> <value>顯示即時速度(需重啟)</value>
</data> </data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve"> <data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>去重時保留序號較小的項</value> <value>去重時保留序號較小的項</value>
@@ -762,7 +756,7 @@
<value>開機啟動(可能會不成功)</value> <value>開機啟動(可能會不成功)</value>
</data> </data>
<data name="TbSettingsStatistics" xml:space="preserve"> <data name="TbSettingsStatistics" xml:space="preserve">
<value>啟用統計(即時網速顯示,需重啟)</value> <value>啟用流量統計(需重啟</value>
</data> </data>
<data name="TbSettingsSubConvert" xml:space="preserve"> <data name="TbSettingsSubConvert" xml:space="preserve">
<value>訂閱轉換網址(可選)</value> <value>訂閱轉換網址(可選)</value>
@@ -843,7 +837,7 @@
<value>新增規則集</value> <value>新增規則集</value>
</data> </data>
<data name="menuRoutingAdvancedImportRules" xml:space="preserve"> <data name="menuRoutingAdvancedImportRules" xml:space="preserve">
<value>一鍵匯入進階規則</value> <value>一鍵匯入規則</value>
</data> </data>
<data name="menuRoutingAdvancedRemove" xml:space="preserve"> <data name="menuRoutingAdvancedRemove" xml:space="preserve">
<value>移除所選規則 (Delete)</value> <value>移除所選規則 (Delete)</value>
@@ -857,9 +851,6 @@
<data name="TbdomainStrategy" xml:space="preserve"> <data name="TbdomainStrategy" xml:space="preserve">
<value>域名解析策略</value> <value>域名解析策略</value>
</data> </data>
<data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>啟動進階功能</value>
</data>
<data name="TbRoutingTabBlock" xml:space="preserve"> <data name="TbRoutingTabBlock" xml:space="preserve">
<value>3.阻止的Domain或IP</value> <value>3.阻止的Domain或IP</value>
</data> </data>
@@ -944,9 +935,6 @@
<data name="TbDisplayLog" xml:space="preserve"> <data name="TbDisplayLog" xml:space="preserve">
<value>顯示日誌</value> <value>顯示日誌</value>
</data> </data>
<data name="menuImportOldGuiConfig" xml:space="preserve">
<value>匯入舊的設定檔guiNConfig</value>
</data>
<data name="TbEnableTunAs" xml:space="preserve"> <data name="TbEnableTunAs" xml:space="preserve">
<value>啟用Tun</value> <value>啟用Tun</value>
</data> </data>
@@ -1196,9 +1184,6 @@
<data name="TipActiveServer" xml:space="preserve"> <data name="TipActiveServer" xml:space="preserve">
<value>活動</value> <value>活動</value>
</data> </data>
<data name="menuStorageUI" xml:space="preserve">
<value>儲存介面佈局</value>
</data>
<data name="TbSettingsGeoFilesSource" xml:space="preserve"> <data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>Geo檔案來源(可選)</value> <value>Geo檔案來源(可選)</value>
</data> </data>
@@ -1400,4 +1385,10 @@
<data name="TbRoutingInboundTagTips" xml:space="preserve"> <data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks本地端口socks2第二個本地端口socks3區域網路端口</value> <value>socks本地端口socks2第二個本地端口socks3區域網路端口</value>
</data> </data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>主題</value>
</data>
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
<value>複製終端代理指令至剪貼簿</value>
</data>
</root> </root>

View File

@@ -2,7 +2,7 @@
"servers": [ "servers": [
{ {
"tag": "remote", "tag": "remote",
"address": "8.8.8.8", "address": "tcp://8.8.8.8",
"strategy": "prefer_ipv4", "strategy": "prefer_ipv4",
"detour": "proxy" "detour": "proxy"
}, },

View File

@@ -2,7 +2,7 @@
"servers": [ "servers": [
{ {
"tag": "remote", "tag": "remote",
"address": "8.8.8.8", "address": "tcp://8.8.8.8",
"strategy": "prefer_ipv4", "strategy": "prefer_ipv4",
"detour": "proxy" "detour": "proxy"
}, },

View File

@@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Version>7.5.6</Version> <Version>7.6.2</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@@ -476,7 +476,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
return 0; return await Task.FromResult(0);
} }
private async Task<int> GenInbounds(SingboxConfig singboxConfig) private async Task<int> GenInbounds(SingboxConfig singboxConfig)
@@ -721,7 +721,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
return 0; return await Task.FromResult(0);
} }
private async Task<int> GenOutboundTls(ProfileItem node, Outbound4Sbox outbound) private async Task<int> GenOutboundTls(ProfileItem node, Outbound4Sbox outbound)
@@ -771,7 +771,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
return 0; return await Task.FromResult(0);
} }
private async Task<int> GenOutboundTransport(ProfileItem node, Outbound4Sbox outbound) private async Task<int> GenOutboundTransport(ProfileItem node, Outbound4Sbox outbound)
@@ -848,7 +848,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
return 0; return await Task.FromResult(0);
} }
private async Task<int> GenMoreOutbounds(ProfileItem node, SingboxConfig singboxConfig) private async Task<int> GenMoreOutbounds(ProfileItem node, SingboxConfig singboxConfig)
@@ -1088,7 +1088,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
return 0; return await Task.FromResult(0);
} }
private bool ParseV2Domain(string domain, Rule4Sbox rule) private bool ParseV2Domain(string domain, Rule4Sbox rule)
@@ -1240,7 +1240,7 @@ namespace ServiceLib.Services.CoreConfig
} }
singboxConfig.dns = dns4Sbox; singboxConfig.dns = dns4Sbox;
return 0; return await Task.FromResult(0);
} }
private async Task<int> GenExperimental(SingboxConfig singboxConfig) private async Task<int> GenExperimental(SingboxConfig singboxConfig)
@@ -1259,11 +1259,12 @@ namespace ServiceLib.Services.CoreConfig
singboxConfig.experimental ??= new Experimental4Sbox(); singboxConfig.experimental ??= new Experimental4Sbox();
singboxConfig.experimental.cache_file = new CacheFile4Sbox() singboxConfig.experimental.cache_file = new CacheFile4Sbox()
{ {
enabled = true enabled = true,
path = Utils.GetConfigPath("cache.db")
}; };
} }
return 0; return await Task.FromResult(0);
} }
private async Task<int> ConvertGeo2Ruleset(SingboxConfig singboxConfig) private async Task<int> ConvertGeo2Ruleset(SingboxConfig singboxConfig)

View File

@@ -379,7 +379,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
return 0; return await Task.FromResult(0);
} }
private async Task<int> GenInbounds(V2rayConfig v2rayConfig) private async Task<int> GenInbounds(V2rayConfig v2rayConfig)
@@ -423,7 +423,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
return 0; return await Task.FromResult(0);
} }
private Inbounds4Ray GetInbound(InItem inItem, EInboundProtocol protocol, bool bSocks) private Inbounds4Ray GetInbound(InItem inItem, EInboundProtocol protocol, bool bSocks)
@@ -560,7 +560,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
return 0; return await Task.FromResult(0);
} }
private async Task<int> GenOutbound(ProfileItem node, Outbounds4Ray outbound) private async Task<int> GenOutbound(ProfileItem node, Outbounds4Ray outbound)
@@ -774,7 +774,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
return 0; return await Task.FromResult(0);
} }
private async Task<int> GenBoundStreamSettings(ProfileItem node, Outbounds4Ray outbound) private async Task<int> GenBoundStreamSettings(ProfileItem node, Outbounds4Ray outbound)
@@ -1103,12 +1103,12 @@ namespace ServiceLib.Services.CoreConfig
servers.AsArray().Add(JsonUtils.SerializeToNode(dnsServer)); servers.AsArray().Add(JsonUtils.SerializeToNode(dnsServer));
} }
} }
return 0; return await Task.FromResult(0);
} }
private async Task<int> GenStatistic(V2rayConfig v2rayConfig) private async Task<int> GenStatistic(V2rayConfig v2rayConfig)
{ {
if (_config.GuiItem.EnableStatistics) if (_config.GuiItem.EnableStatistics || _config.GuiItem.DisplayRealTimeSpeed)
{ {
string tag = EInboundProtocol.api.ToString(); string tag = EInboundProtocol.api.ToString();
Metrics4Ray apiObj = new(); Metrics4Ray apiObj = new();
@@ -1150,7 +1150,7 @@ namespace ServiceLib.Services.CoreConfig
v2rayConfig.routing.rules.Add(apiRoutingRule); v2rayConfig.routing.rules.Add(apiRoutingRule);
} }
} }
return 0; return await Task.FromResult(0);
} }
private async Task<int> GenMoreOutbounds(ProfileItem node, V2rayConfig v2rayConfig) private async Task<int> GenMoreOutbounds(ProfileItem node, V2rayConfig v2rayConfig)

View File

@@ -25,6 +25,7 @@ namespace ServiceLib.ViewModels
BrowseServerCmd = ReactiveCommand.CreateFromTask(async () => BrowseServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
_updateView?.Invoke(EViewAction.BrowseServer, null); _updateView?.Invoke(EViewAction.BrowseServer, null);
await Task.CompletedTask;
}); });
EditServerCmd = ReactiveCommand.CreateFromTask(async () => EditServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
@@ -109,6 +110,7 @@ namespace ServiceLib.ViewModels
{ {
NoticeHandler.Instance.Enqueue(ResUI.FailedReadConfiguration); NoticeHandler.Instance.Enqueue(ResUI.FailedReadConfiguration);
} }
await Task.CompletedTask;
} }
} }
} }

View File

@@ -176,7 +176,7 @@ namespace ServiceLib.ViewModels
FileManager.CopyDirectory(configDir, configDirTemp, false, "cache.db"); FileManager.CopyDirectory(configDir, configDirTemp, false, "cache.db");
var ret = FileManager.CreateFromDirectory(configDirZipTemp, fileName); var ret = FileManager.CreateFromDirectory(configDirZipTemp, fileName);
Directory.Delete(configDirZipTemp, true); Directory.Delete(configDirZipTemp, true);
return ret; return await Task.FromResult(ret);
} }
} }
} }

View File

@@ -259,7 +259,7 @@ namespace ServiceLib.ViewModels
} }
else else
{ {
FileManager.ZipExtractToFile(fileName, toPath, _config.GuiItem.IgnoreGeoUpdateCore ? "geo" : ""); FileManager.ZipExtractToFile(fileName, toPath, "geo");
} }
if (Utils.IsNonWindows()) if (Utils.IsNonWindows())

View File

@@ -48,7 +48,7 @@ namespace ServiceLib.ViewModels
await ClashConnectionClose(true); await ClashConnectionClose(true);
}); });
Init(); _ = Init();
} }
private async Task Init() private async Task Init()
@@ -73,6 +73,7 @@ namespace ServiceLib.ViewModels
Task.Delay(1000).Wait(); Task.Delay(1000).Wait();
} }
}); });
await Task.CompletedTask;
} }
private async Task GetClashConnections() private async Task GetClashConnections()

View File

@@ -90,13 +90,13 @@ namespace ServiceLib.ViewModels
y => y == true) y => y == true)
.Subscribe(c => { _config.ClashUIItem.ProxiesAutoRefresh = AutoRefresh; }); .Subscribe(c => { _config.ClashUIItem.ProxiesAutoRefresh = AutoRefresh; });
Init(); _ = Init();
} }
private async Task Init() private async Task Init()
{ {
await ProxiesReload(); await ProxiesReload();
DelayTestTask(); _ = DelayTestTask();
} }
private async Task DoRulemodeSelected(bool c) private async Task DoRulemodeSelected(bool c)
@@ -265,7 +265,7 @@ namespace ServiceLib.ViewModels
return; return;
} }
_proxies.TryGetValue(name, out ProxiesItem proxy); _proxies.TryGetValue(name, out var proxy);
if (proxy == null || proxy.all == null) if (proxy == null || proxy.all == null)
{ {
return; return;
@@ -316,7 +316,7 @@ namespace ServiceLib.ViewModels
{ {
if (_proxies is null) if (_proxies is null)
return null; return null;
_proxies.TryGetValue(name, out ProxiesItem proxy2); _proxies.TryGetValue(name, out var proxy2);
if (proxy2 != null) if (proxy2 != null)
{ {
return proxy2; return proxy2;
@@ -399,6 +399,7 @@ namespace ServiceLib.ViewModels
_updateView?.Invoke(EViewAction.DispatcherProxiesDelayTest, new SpeedTestResult() { IndexId = item.Name, Delay = result }); _updateView?.Invoke(EViewAction.DispatcherProxiesDelayTest, new SpeedTestResult() { IndexId = item.Name, Delay = result });
}); });
await Task.CompletedTask;
} }
public void ProxiesDelayTestResult(SpeedTestResult result) public void ProxiesDelayTestResult(SpeedTestResult result)
@@ -434,7 +435,7 @@ namespace ServiceLib.ViewModels
public async Task DelayTestTask() public async Task DelayTestTask()
{ {
var lastTime = DateTime.Now; var lastTime = DateTime.Now;
Task.Run(async () => _ = Task.Run(async () =>
{ {
while (true) while (true)
{ {
@@ -457,6 +458,7 @@ namespace ServiceLib.ViewModels
lastTime = dtNow; lastTime = dtNow;
} }
}); });
await Task.CompletedTask;
} }
#endregion task #endregion task

View File

@@ -32,15 +32,17 @@ namespace ServiceLib.ViewModels
ImportDefConfig4V2rayCmd = ReactiveCommand.CreateFromTask(async () => ImportDefConfig4V2rayCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName); normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName);
await Task.CompletedTask;
}); });
ImportDefConfig4SingboxCmd = ReactiveCommand.CreateFromTask(async () => ImportDefConfig4SingboxCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName); normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName);
tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName); tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName);
await Task.CompletedTask;
}); });
Init(); _ = Init();
} }
private async Task Init() private async Task Init()

View File

@@ -63,6 +63,8 @@ namespace ServiceLib.ViewModels
#endregion Menu #endregion Menu
private bool _hasNextReloadJob = false;
#region Init #region Init
public MainWindowViewModel(Func<EViewAction, object?, Task<bool>>? updateView) public MainWindowViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
@@ -204,7 +206,7 @@ namespace ServiceLib.ViewModels
#endregion WhenAnyValue && ReactiveCommand #endregion WhenAnyValue && ReactiveCommand
Init(); _ = Init();
} }
private async Task Init() private async Task Init()
@@ -217,11 +219,12 @@ namespace ServiceLib.ViewModels
await CoreHandler.Instance.Init(_config, UpdateHandler); await CoreHandler.Instance.Init(_config, UpdateHandler);
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler); TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
if (_config.GuiItem.EnableStatistics) if (_config.GuiItem.EnableStatistics || _config.GuiItem.DisplayRealTimeSpeed)
{ {
await StatisticsHandler.Instance.Init(_config, UpdateStatisticsHandler); await StatisticsHandler.Instance.Init(_config, UpdateStatisticsHandler);
} }
BlReloadEnabled = true;
await Reload(); await Reload();
await AutoHideStartup(); await AutoHideStartup();
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu(); Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
@@ -249,7 +252,7 @@ namespace ServiceLib.ViewModels
RefreshServers(); RefreshServers();
if (indexIdOld != _config.IndexId) if (indexIdOld != _config.IndexId)
{ {
Reload(); _ = Reload();
} }
if (_config.UiItem.EnableAutoAdjustMainLvColWidth) if (_config.UiItem.EnableAutoAdjustMainLvColWidth)
{ {
@@ -269,18 +272,15 @@ namespace ServiceLib.ViewModels
public void SetStatisticsResult(ServerSpeedItem update) public void SetStatisticsResult(ServerSpeedItem update)
{ {
try if (_config.GuiItem.DisplayRealTimeSpeed)
{ {
Locator.Current.GetService<StatusBarViewModel>()?.UpdateStatistics(update); Locator.Current.GetService<StatusBarViewModel>()?.UpdateStatistics(update);
if ((update.ProxyUp + update.ProxyDown) > 0 && DateTime.Now.Second % 9 == 0) }
if (_config.GuiItem.EnableStatistics && (update.ProxyUp + update.ProxyDown) > 0 && DateTime.Now.Second % 9 == 0)
{ {
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update); Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
} }
} }
catch
{
}
}
public async Task MyAppExitAsync(bool blWindowsShutDown) public async Task MyAppExitAsync(bool blWindowsShutDown)
{ {
@@ -403,6 +403,7 @@ namespace ServiceLib.ViewModels
public async Task AddServerViaScanAsync() public async Task AddServerViaScanAsync()
{ {
_updateView?.Invoke(EViewAction.ScanScreenTask, null); _updateView?.Invoke(EViewAction.ScanScreenTask, null);
await Task.CompletedTask;
} }
public async Task ScanScreenResult(byte[]? bytes) public async Task ScanScreenResult(byte[]? bytes)
@@ -414,6 +415,7 @@ namespace ServiceLib.ViewModels
public async Task AddServerViaImageAsync() public async Task AddServerViaImageAsync()
{ {
_updateView?.Invoke(EViewAction.ScanImageTask, null); _updateView?.Invoke(EViewAction.ScanImageTask, null);
await Task.CompletedTask;
} }
public async Task ScanImageResult(string fileName) public async Task ScanImageResult(string fileName)
@@ -527,6 +529,7 @@ namespace ServiceLib.ViewModels
{ {
ProcUtils.ProcessStart("open", path); ProcUtils.ProcessStart("open", path);
} }
await Task.CompletedTask;
} }
#endregion Setting #endregion Setting
@@ -535,19 +538,33 @@ namespace ServiceLib.ViewModels
public async Task Reload() public async Task Reload()
{ {
//If there are unfinished reload job, marked with next job.
if (!BlReloadEnabled)
{
_hasNextReloadJob = true;
return;
}
BlReloadEnabled = false; BlReloadEnabled = false;
await LoadCore(); await LoadCore();
Locator.Current.GetService<StatusBarViewModel>()?.TestServerAvailability();
await SysProxyHandler.UpdateSysProxy(_config, false); await SysProxyHandler.UpdateSysProxy(_config, false);
Locator.Current.GetService<StatusBarViewModel>()?.TestServerAvailability();
_updateView?.Invoke(EViewAction.DispatcherReload, null); _updateView?.Invoke(EViewAction.DispatcherReload, null);
BlReloadEnabled = true;
if (_hasNextReloadJob)
{
_hasNextReloadJob = false;
await Reload();
}
} }
public void ReloadResult() public void ReloadResult()
{ {
// BlReloadEnabled = true;
//Locator.Current.GetService<StatusBarViewModel>()?.ChangeSystemProxyAsync(_config.systemProxyItem.sysProxyType, false); //Locator.Current.GetService<StatusBarViewModel>()?.ChangeSystemProxyAsync(_config.systemProxyItem.sysProxyType, false);
BlReloadEnabled = true;
ShowClashUI = _config.IsRunningCore(ECoreType.sing_box); ShowClashUI = _config.IsRunningCore(ECoreType.sing_box);
if (ShowClashUI) if (ShowClashUI)
{ {
@@ -557,17 +574,9 @@ namespace ServiceLib.ViewModels
} }
private async Task LoadCore() private async Task LoadCore()
{
//if (_config.tunModeItem.enableTun)
//{
// Task.Delay(1000).Wait();
// WindowsUtils.RemoveTunDevice();
//}
await Task.Run(async () =>
{ {
var node = await ConfigHandler.GetDefaultServer(_config); var node = await ConfigHandler.GetDefaultServer(_config);
await CoreHandler.Instance.LoadCore(node); await CoreHandler.Instance.LoadCore(node);
});
} }
public async Task CloseCore() public async Task CloseCore()
@@ -582,6 +591,7 @@ namespace ServiceLib.ViewModels
{ {
ShowHideWindow(false); ShowHideWindow(false);
} }
await Task.CompletedTask;
} }
#endregion core job #endregion core job

View File

@@ -59,14 +59,14 @@ namespace ServiceLib.ViewModels
{ {
return; return;
} }
_blLockShow = true;
if (!_config.UiItem.ShowInTaskbar) if (!_config.UiItem.ShowInTaskbar)
{ {
await Task.Delay(1000); return;
} }
await Task.Delay(100); _blLockShow = true;
await Task.Delay(500);
var txt = string.Join("", _queueMsg.ToArray()); var txt = string.Join("", _queueMsg.ToArray());
await _updateView?.Invoke(EViewAction.DispatcherShowMsg, txt); await _updateView?.Invoke(EViewAction.DispatcherShowMsg, txt);
@@ -105,6 +105,7 @@ namespace ServiceLib.ViewModels
{ {
_queueMsg.Enqueue(Environment.NewLine); _queueMsg.Enqueue(Environment.NewLine);
} }
await Task.CompletedTask;
} }
public void ClearMsg() public void ClearMsg()

View File

@@ -49,7 +49,7 @@ namespace ServiceLib.ViewModels
[Reactive] public bool AutoRun { get; set; } [Reactive] public bool AutoRun { get; set; }
[Reactive] public bool EnableStatistics { get; set; } [Reactive] public bool EnableStatistics { get; set; }
[Reactive] public bool KeepOlderDedupl { get; set; } [Reactive] public bool KeepOlderDedupl { get; set; }
[Reactive] public bool IgnoreGeoUpdateCore { get; set; } [Reactive] public bool DisplayRealTimeSpeed { get; set; }
[Reactive] public bool EnableAutoAdjustMainLvColWidth { get; set; } [Reactive] public bool EnableAutoAdjustMainLvColWidth { get; set; }
[Reactive] public bool EnableUpdateSubOnlyRemarksExist { get; set; } [Reactive] public bool EnableUpdateSubOnlyRemarksExist { get; set; }
[Reactive] public bool EnableSecurityProtocolTls13 { get; set; } [Reactive] public bool EnableSecurityProtocolTls13 { get; set; }
@@ -115,7 +115,7 @@ namespace ServiceLib.ViewModels
await SaveSettingAsync(); await SaveSettingAsync();
}); });
Init(); _ = Init();
} }
private async Task Init() private async Task Init()
@@ -164,8 +164,8 @@ namespace ServiceLib.ViewModels
AutoRun = _config.GuiItem.AutoRun; AutoRun = _config.GuiItem.AutoRun;
EnableStatistics = _config.GuiItem.EnableStatistics; EnableStatistics = _config.GuiItem.EnableStatistics;
DisplayRealTimeSpeed = _config.GuiItem.DisplayRealTimeSpeed;
KeepOlderDedupl = _config.GuiItem.KeepOlderDedupl; KeepOlderDedupl = _config.GuiItem.KeepOlderDedupl;
IgnoreGeoUpdateCore = _config.GuiItem.IgnoreGeoUpdateCore;
EnableAutoAdjustMainLvColWidth = _config.UiItem.EnableAutoAdjustMainLvColWidth; EnableAutoAdjustMainLvColWidth = _config.UiItem.EnableAutoAdjustMainLvColWidth;
EnableUpdateSubOnlyRemarksExist = _config.UiItem.EnableUpdateSubOnlyRemarksExist; EnableUpdateSubOnlyRemarksExist = _config.UiItem.EnableUpdateSubOnlyRemarksExist;
EnableSecurityProtocolTls13 = _config.GuiItem.EnableSecurityProtocolTls13; EnableSecurityProtocolTls13 = _config.GuiItem.EnableSecurityProtocolTls13;
@@ -261,6 +261,7 @@ namespace ServiceLib.ViewModels
break; break;
} }
}); });
await Task.CompletedTask;
} }
private async Task SaveSettingAsync() private async Task SaveSettingAsync()
@@ -272,6 +273,7 @@ namespace ServiceLib.ViewModels
return; return;
} }
var needReboot = (EnableStatistics != _config.GuiItem.EnableStatistics var needReboot = (EnableStatistics != _config.GuiItem.EnableStatistics
|| DisplayRealTimeSpeed != _config.GuiItem.DisplayRealTimeSpeed
|| EnableDragDropSort != _config.UiItem.EnableDragDropSort || EnableDragDropSort != _config.UiItem.EnableDragDropSort
|| EnableHWA != _config.GuiItem.EnableHWA || EnableHWA != _config.GuiItem.EnableHWA
|| CurrentFontFamily != _config.UiItem.CurrentFontFamily || CurrentFontFamily != _config.UiItem.CurrentFontFamily
@@ -317,8 +319,8 @@ namespace ServiceLib.ViewModels
_config.GuiItem.AutoRun = AutoRun; _config.GuiItem.AutoRun = AutoRun;
_config.GuiItem.EnableStatistics = EnableStatistics; _config.GuiItem.EnableStatistics = EnableStatistics;
_config.GuiItem.DisplayRealTimeSpeed = DisplayRealTimeSpeed;
_config.GuiItem.KeepOlderDedupl = KeepOlderDedupl; _config.GuiItem.KeepOlderDedupl = KeepOlderDedupl;
_config.GuiItem.IgnoreGeoUpdateCore = IgnoreGeoUpdateCore;
_config.UiItem.EnableAutoAdjustMainLvColWidth = EnableAutoAdjustMainLvColWidth; _config.UiItem.EnableAutoAdjustMainLvColWidth = EnableAutoAdjustMainLvColWidth;
_config.UiItem.EnableUpdateSubOnlyRemarksExist = EnableUpdateSubOnlyRemarksExist; _config.UiItem.EnableUpdateSubOnlyRemarksExist = EnableUpdateSubOnlyRemarksExist;
_config.GuiItem.EnableSecurityProtocolTls13 = EnableSecurityProtocolTls13; _config.GuiItem.EnableSecurityProtocolTls13 = EnableSecurityProtocolTls13;
@@ -410,6 +412,7 @@ namespace ServiceLib.ViewModels
} }
item.CoreType = (ECoreType)Enum.Parse(typeof(ECoreType), type); item.CoreType = (ECoreType)Enum.Parse(typeof(ECoreType), type);
} }
await Task.CompletedTask;
} }
} }
} }

View File

@@ -231,7 +231,7 @@ namespace ServiceLib.ViewModels
MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString()).Subscribe(OnNext); MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString()).Subscribe(OnNext);
} }
Init(); _ = Init();
} }
private async Task Init() private async Task Init()
@@ -360,7 +360,7 @@ namespace ServiceLib.ViewModels
public async Task RefreshServersBiz() public async Task RefreshServersBiz()
{ {
var lstModel = await AppHandler.Instance.ProfileItemsEx(_config.SubIndexId, _serverFilter); var lstModel = await GetProfileItemsEx(_config.SubIndexId, _serverFilter);
_lstProfile = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(lstModel)) ?? []; _lstProfile = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(lstModel)) ?? [];
_profileItems.Clear(); _profileItems.Clear();
@@ -399,6 +399,45 @@ namespace ServiceLib.ViewModels
} }
} }
private async Task<List<ProfileItemModel>?> GetProfileItemsEx(string subid, string filter)
{
var lstModel = await AppHandler.Instance.ProfileItems(_config.SubIndexId, filter);
await ConfigHandler.SetDefaultServer(_config, lstModel);
var lstServerStat = (_config.GuiItem.EnableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
var lstProfileExs = await ProfileExHandler.Instance.GetProfileExs();
lstModel = (from t in lstModel
join t2 in lstServerStat on t.IndexId equals t2.IndexId into t2b
from t22 in t2b.DefaultIfEmpty()
join t3 in lstProfileExs on t.IndexId equals t3.IndexId into t3b
from t33 in t3b.DefaultIfEmpty()
select new ProfileItemModel
{
IndexId = t.IndexId,
ConfigType = t.ConfigType,
Remarks = t.Remarks,
Address = t.Address,
Port = t.Port,
Security = t.Security,
Network = t.Network,
StreamSecurity = t.StreamSecurity,
Subid = t.Subid,
SubRemarks = t.SubRemarks,
IsActive = t.IndexId == _config.IndexId,
Sort = t33 == null ? 0 : t33.Sort,
Delay = t33 == null ? 0 : t33.Delay,
DelayVal = t33?.Delay != 0 ? $"{t33?.Delay} {Global.DelayUnit}" : string.Empty,
SpeedVal = t33?.Speed != 0 ? $"{t33?.Speed} {Global.SpeedUnit}" : string.Empty,
TodayDown = t22 == null ? "" : Utils.HumanFy(t22.TodayDown),
TodayUp = t22 == null ? "" : Utils.HumanFy(t22.TodayUp),
TotalDown = t22 == null ? "" : Utils.HumanFy(t22.TotalDown),
TotalUp = t22 == null ? "" : Utils.HumanFy(t22.TotalUp)
}).OrderBy(t => t.Sort).ToList();
return lstModel;
}
#endregion Servers && Groups #endregion Servers && Groups
#region Add Servers #region Add Servers

View File

@@ -2,6 +2,8 @@
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using System.Reactive; using System.Reactive;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {
@@ -189,7 +191,13 @@ namespace ServiceLib.ViewModels
} }
if (lst.Count > 0) if (lst.Count > 0)
{ {
await _updateView?.Invoke(EViewAction.SetClipboardData, JsonUtils.Serialize(lst)); var options = new JsonSerializerOptions
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
await _updateView?.Invoke(EViewAction.SetClipboardData, JsonUtils.Serialize(lst, options));
} }
} }
@@ -249,7 +257,7 @@ namespace ServiceLib.ViewModels
return; return;
} }
string result = Utils.LoadResource(fileName); var result = Utils.LoadResource(fileName);
if (Utils.IsNullOrEmpty(result)) if (Utils.IsNullOrEmpty(result))
{ {
return; return;

View File

@@ -67,7 +67,7 @@ namespace ServiceLib.ViewModels
await SaveRoutingAsync(); await SaveRoutingAsync();
}); });
Init(); _ = Init();
} }
private async Task Init() private async Task Init()

View File

@@ -32,6 +32,7 @@ namespace ServiceLib.ViewModels
public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; } public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; }
public ReactiveCommand<Unit, Unit> SubUpdateCmd { get; } public ReactiveCommand<Unit, Unit> SubUpdateCmd { get; }
public ReactiveCommand<Unit, Unit> SubUpdateViaProxyCmd { get; } public ReactiveCommand<Unit, Unit> SubUpdateViaProxyCmd { get; }
public ReactiveCommand<Unit, Unit> CopyProxyCmdToClipboardCmd { get; }
public ReactiveCommand<Unit, Unit> NotifyLeftClickCmd { get; } public ReactiveCommand<Unit, Unit> NotifyLeftClickCmd { get; }
#region System Proxy #region System Proxy
@@ -48,18 +49,6 @@ namespace ServiceLib.ViewModels
[Reactive] [Reactive]
public bool BlSystemProxyPac { get; set; } public bool BlSystemProxyPac { get; set; }
[Reactive]
public bool BlNotSystemProxyClear { get; set; }
[Reactive]
public bool BlNotSystemProxySet { get; set; }
[Reactive]
public bool BlNotSystemProxyNothing { get; set; }
[Reactive]
public bool BlNotSystemProxyPac { get; set; }
public ReactiveCommand<Unit, Unit> SystemProxyClearCmd { get; } public ReactiveCommand<Unit, Unit> SystemProxyClearCmd { get; }
public ReactiveCommand<Unit, Unit> SystemProxySetCmd { get; } public ReactiveCommand<Unit, Unit> SystemProxySetCmd { get; }
public ReactiveCommand<Unit, Unit> SystemProxyNothingCmd { get; } public ReactiveCommand<Unit, Unit> SystemProxyNothingCmd { get; }
@@ -140,9 +129,15 @@ namespace ServiceLib.ViewModels
y => y == true) y => y == true)
.Subscribe(async c => await DoEnableTun(c)); .Subscribe(async c => await DoEnableTun(c));
CopyProxyCmdToClipboardCmd = ReactiveCommand.CreateFromTask(async () =>
{
await CopyProxyCmdToClipboard();
});
NotifyLeftClickCmd = ReactiveCommand.CreateFromTask(async () => NotifyLeftClickCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(null); Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(null);
await Task.CompletedTask;
}); });
AddServerViaClipboardCmd = ReactiveCommand.CreateFromTask(async () => AddServerViaClipboardCmd = ReactiveCommand.CreateFromTask(async () =>
@@ -186,7 +181,7 @@ namespace ServiceLib.ViewModels
{ {
InitUpdateView(updateView); InitUpdateView(updateView);
} }
Init(); _ = Init();
} }
private async Task Init() private async Task Init()
@@ -210,6 +205,23 @@ namespace ServiceLib.ViewModels
await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null); await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null);
} }
private async Task CopyProxyCmdToClipboard()
{
var cmd = Utils.IsWindows() ? "set" : "export";
var address = $"{Global.Loopback}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.socks)}";
var sb = new StringBuilder();
sb.AppendLine($"{cmd} http_proxy={Global.HttpProtocol}{address}");
sb.AppendLine($"{cmd} https_proxy={Global.HttpProtocol}{address}");
sb.AppendLine($"{cmd} all_proxy={Global.Socks5Protocol}{address}");
sb.AppendLine("");
sb.AppendLine($"{cmd} HTTP_PROXY={Global.HttpProtocol}{address}");
sb.AppendLine($"{cmd} HTTPS_PROXY={Global.HttpProtocol}{address}");
sb.AppendLine($"{cmd} ALL_PROXY={Global.Socks5Protocol}{address}");
await _updateView?.Invoke(EViewAction.SetClipboardData, sb.ToString());
}
private async Task AddServerViaClipboard() private async Task AddServerViaClipboard()
{ {
var service = Locator.Current.GetService<MainWindowViewModel>(); var service = Locator.Current.GetService<MainWindowViewModel>();
@@ -333,11 +345,6 @@ namespace ServiceLib.ViewModels
BlSystemProxyNothing = (type == ESysProxyType.Unchanged); BlSystemProxyNothing = (type == ESysProxyType.Unchanged);
BlSystemProxyPac = (type == ESysProxyType.Pac); BlSystemProxyPac = (type == ESysProxyType.Pac);
BlNotSystemProxyClear = !BlSystemProxyClear;
BlNotSystemProxySet = !BlSystemProxySet;
BlNotSystemProxyNothing = !BlSystemProxyNothing;
BlNotSystemProxyPac = !BlSystemProxyPac;
if (blChange) if (blChange)
{ {
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null); _updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
@@ -417,10 +424,12 @@ namespace ServiceLib.ViewModels
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin(); Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
return; return;
} }
//else if (Utils.IsLinux()) else if (Utils.IsOSX())
//{ {
// NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordIsEmpty); _config.TunModeItem.EnableTun = false;
//} NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordIsEmpty);
return;
}
} }
await ConfigHandler.SaveConfig(_config); await ConfigHandler.SaveConfig(_config);
Locator.Current.GetService<MainWindowViewModel>()?.Reload(); Locator.Current.GetService<MainWindowViewModel>()?.Reload();
@@ -470,13 +479,20 @@ namespace ServiceLib.ViewModels
{ {
InboundLanDisplay = $"{ResUI.LabLAN}:{Global.None}"; InboundLanDisplay = $"{ResUI.LabLAN}:{Global.None}";
} }
await Task.CompletedTask;
} }
public void UpdateStatistics(ServerSpeedItem update) public void UpdateStatistics(ServerSpeedItem update)
{
try
{ {
SpeedProxyDisplay = string.Format(ResUI.SpeedDisplayText, Global.ProxyTag, Utils.HumanFy(update.ProxyUp), Utils.HumanFy(update.ProxyDown)); SpeedProxyDisplay = string.Format(ResUI.SpeedDisplayText, Global.ProxyTag, Utils.HumanFy(update.ProxyUp), Utils.HumanFy(update.ProxyDown));
SpeedDirectDisplay = string.Format(ResUI.SpeedDisplayText, Global.DirectTag, Utils.HumanFy(update.DirectUp), Utils.HumanFy(update.DirectDown)); SpeedDirectDisplay = string.Format(ResUI.SpeedDisplayText, Global.DirectTag, Utils.HumanFy(update.DirectUp), Utils.HumanFy(update.DirectDown));
} }
catch
{
}
}
#endregion UI #endregion UI
} }

View File

@@ -48,7 +48,7 @@ namespace ServiceLib.ViewModels
await _updateView?.Invoke(EViewAction.ShareSub, SelectedSource?.Url); await _updateView?.Invoke(EViewAction.ShareSub, SelectedSource?.Url);
}, canEditRemove); }, canEditRemove);
Init(); _ = Init();
} }
private async Task Init() private async Task Init()

View File

@@ -32,38 +32,26 @@
<NativeMenuItem <NativeMenuItem
Command="{Binding SystemProxyClearCmd}" Command="{Binding SystemProxyClearCmd}"
Header="{x:Static resx:ResUI.menuSystemProxyClear}" Header="{x:Static resx:ResUI.menuSystemProxyClear}"
IsVisible="{Binding BlNotSystemProxyClear}" /> IsChecked="{Binding BlSystemProxyClear}"
<NativeMenuItem ToggleType="Radio" />
Command="{Binding SystemProxyClearCmd}"
Header="{x:Static resx:ResUI.menuSystemProxyClear}"
Icon="/Assets/NotifyIcon1.ico"
IsVisible="{Binding BlSystemProxyClear}" />
<NativeMenuItem <NativeMenuItem
Command="{Binding SystemProxySetCmd}" Command="{Binding SystemProxySetCmd}"
Header="{x:Static resx:ResUI.menuSystemProxySet}" Header="{x:Static resx:ResUI.menuSystemProxySet}"
IsVisible="{Binding BlNotSystemProxySet}" /> IsChecked="{Binding BlSystemProxySet}"
<NativeMenuItem ToggleType="Radio" />
Command="{Binding SystemProxySetCmd}"
Header="{x:Static resx:ResUI.menuSystemProxySet}"
Icon="/Assets/NotifyIcon2.ico"
IsVisible="{Binding BlSystemProxySet}" />
<NativeMenuItem <NativeMenuItem
Command="{Binding SystemProxyNothingCmd}" Command="{Binding SystemProxyNothingCmd}"
Header="{x:Static resx:ResUI.menuSystemProxyNothing}" Header="{x:Static resx:ResUI.menuSystemProxyNothing}"
IsVisible="{Binding BlNotSystemProxyNothing}" /> IsChecked="{Binding BlSystemProxyNothing}"
<NativeMenuItem ToggleType="Radio" />
Command="{Binding SystemProxyNothingCmd}"
Header="{x:Static resx:ResUI.menuSystemProxyNothing}"
Icon="/Assets/NotifyIcon3.ico"
IsVisible="{Binding BlSystemProxyNothing}" />
<NativeMenuItemSeparator /> <NativeMenuItemSeparator />
<NativeMenuItem Click="MenuAddServerViaClipboardClick" Header="{x:Static resx:ResUI.menuAddServerViaClipboard}" /> <NativeMenuItem Click="MenuAddServerViaClipboardClick" Header="{x:Static resx:ResUI.menuAddServerViaClipboard}" />
<NativeMenuItem Header="{x:Static resx:ResUI.menuAddServerViaScan}" IsVisible="False" /> <NativeMenuItem Header="{x:Static resx:ResUI.menuAddServerViaScan}" IsVisible="False" />
<NativeMenuItem Command="{Binding SubUpdateCmd}" Header="{x:Static resx:ResUI.menuSubUpdate}" /> <NativeMenuItem Command="{Binding SubUpdateCmd}" Header="{x:Static resx:ResUI.menuSubUpdate}" />
<NativeMenuItem Command="{Binding SubUpdateViaProxyCmd}" Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" /> <NativeMenuItem Command="{Binding SubUpdateViaProxyCmd}" Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" />
<NativeMenuItemSeparator /> <NativeMenuItemSeparator />
<NativeMenuItem Command="{Binding CopyProxyCmdToClipboardCmd}" Header="{x:Static resx:ResUI.menuCopyProxyCmdToClipboard}" />
<NativeMenuItemSeparator />
<NativeMenuItem Command="{Binding NotifyLeftClickCmd}" Header="{x:Static resx:ResUI.menuShowOrHideMainWindow}" /> <NativeMenuItem Command="{Binding NotifyLeftClickCmd}" Header="{x:Static resx:ResUI.menuShowOrHideMainWindow}" />
<NativeMenuItem Click="MenuExit_Click" Header="{x:Static resx:ResUI.menuExit}" /> <NativeMenuItem Click="MenuExit_Click" Header="{x:Static resx:ResUI.menuExit}" />
</NativeMenu> </NativeMenu>

View File

@@ -40,6 +40,12 @@ 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 fileName = Utils.GetPath($"NotifyIcon{index}.ico");
if (File.Exists(fileName))
{
return new(fileName);
}
var uri = new Uri(Path.Combine(Global.AvaAssets, $"NotifyIcon{index}.ico")); var uri = new Uri(Path.Combine(Global.AvaAssets, $"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);

View File

@@ -17,13 +17,11 @@ namespace v2rayN.Desktop.Common
public static async Task<string?> OpenFileDialog(Window owner, FilePickerFileType? filter) public static async Task<string?> OpenFileDialog(Window owner, FilePickerFileType? filter)
{ {
var topLevel = TopLevel.GetTopLevel(owner); var sp = GetStorageProvider(owner);
if (topLevel == null) if (sp is null) return null;
{
return null;
}
// Start async operation to open the dialog. // Start async operation to open the dialog.
var files = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions var files = await sp.OpenFilePickerAsync(new FilePickerOpenOptions
{ {
AllowMultiple = false, AllowMultiple = false,
FileTypeFilter = filter is null ? [FilePickerFileTypes.All, FilePickerFileTypes.ImagePng] : [filter] FileTypeFilter = filter is null ? [FilePickerFileTypes.All, FilePickerFileTypes.ImagePng] : [filter]
@@ -34,17 +32,21 @@ namespace v2rayN.Desktop.Common
public static async Task<string?> SaveFileDialog(Window owner, string filter) public static async Task<string?> SaveFileDialog(Window owner, string filter)
{ {
var topLevel = TopLevel.GetTopLevel(owner); var sp = GetStorageProvider(owner);
if (topLevel == null) if (sp is null) return null;
{
return null;
}
// Start async operation to open the dialog. // Start async operation to open the dialog.
var files = await topLevel.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions var files = await sp.SaveFilePickerAsync(new FilePickerSaveOptions
{ {
}); });
return files?.TryGetLocalPath(); return files?.TryGetLocalPath();
} }
private static IStorageProvider? GetStorageProvider(Window owner)
{
var topLevel = TopLevel.GetTopLevel(owner);
return topLevel?.StorageProvider;
}
} }
} }

View File

@@ -6,14 +6,14 @@ using Avalonia.Media;
using Avalonia.Styling; using Avalonia.Styling;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Semi.Avalonia;
using System.Reactive.Linq; using System.Reactive.Linq;
namespace v2rayN.Desktop.ViewModels namespace v2rayN.Desktop.ViewModels
{ {
public class ThemeSettingViewModel : MyReactiveObject public class ThemeSettingViewModel : MyReactiveObject
{ {
[Reactive] public bool ColorModeDark { get; set; } [Reactive] public string CurrentTheme { get; set; }
[Reactive] public bool FollowSystemTheme { get; set; }
[Reactive] public int CurrentFontSize { get; set; } [Reactive] public int CurrentFontSize { get; set; }
@@ -36,28 +36,16 @@ namespace v2rayN.Desktop.ViewModels
private void BindingUI() private void BindingUI()
{ {
ColorModeDark = _config.UiItem.ColorModeDark; CurrentTheme = _config.UiItem.CurrentTheme;
FollowSystemTheme = _config.UiItem.FollowSystemTheme;
CurrentFontSize = _config.UiItem.CurrentFontSize; CurrentFontSize = _config.UiItem.CurrentFontSize;
CurrentLanguage = _config.UiItem.CurrentLanguage; CurrentLanguage = _config.UiItem.CurrentLanguage;
this.WhenAnyValue(x => x.ColorModeDark) this.WhenAnyValue(x => x.CurrentTheme)
.Subscribe(c => .Subscribe(c =>
{ {
if (_config.UiItem.ColorModeDark != ColorModeDark) if (_config.UiItem.CurrentTheme != CurrentTheme)
{ {
_config.UiItem.ColorModeDark = ColorModeDark; _config.UiItem.CurrentTheme = CurrentTheme;
ModifyTheme();
ConfigHandler.SaveConfig(_config);
}
});
this.WhenAnyValue(x => x.FollowSystemTheme,
y => y == true)
.Subscribe(c =>
{
if (_config.UiItem.FollowSystemTheme != FollowSystemTheme)
{
_config.UiItem.FollowSystemTheme = FollowSystemTheme;
ModifyTheme(); ModifyTheme();
ConfigHandler.SaveConfig(_config); ConfigHandler.SaveConfig(_config);
} }
@@ -96,7 +84,16 @@ namespace v2rayN.Desktop.ViewModels
var app = Application.Current; var app = Application.Current;
if (app is not null) if (app is not null)
{ {
app.RequestedThemeVariant = FollowSystemTheme ? ThemeVariant.Default : (ColorModeDark ? ThemeVariant.Dark : ThemeVariant.Light); app.RequestedThemeVariant = CurrentTheme switch
{
nameof(ETheme.Dark) => ThemeVariant.Dark,
nameof(ETheme.Light) => ThemeVariant.Light,
nameof(ETheme.Aquatic) => SemiTheme.Aquatic,
nameof(ETheme.Desert) => SemiTheme.Desert,
nameof(ETheme.Dusk) => SemiTheme.Dusk,
nameof(ETheme.NightSky) => SemiTheme.NightSky,
_ => ThemeVariant.Default,
};
} }
} }

View File

@@ -5,25 +5,28 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib" xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
d:DesignHeight="450" d:DesignHeight="450"
d:DesignWidth="800" d:DesignWidth="800"
x:DataType="vms:BackupAndRestoreViewModel"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.Styles>
<Style Selector="Button">
<Setter Property="MinWidth" Value="180" />
</Style>
</UserControl.Styles>
<DockPanel Classes="Margin8"> <DockPanel Classes="Margin8">
<DockPanel Classes="Margin8" DockPanel.Dock="Bottom"> <StackPanel Classes="Margin8" DockPanel.Dock="Bottom">
<TextBlock <TextBlock
Name="txtMsg" Name="txtMsg"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Classes="Margin8" /> Classes="Margin8" />
</DockPanel> </StackPanel>
<StackPanel> <StackPanel>
<Border <Border
Margin="4" Margin="4"
VerticalAlignment="Center" VerticalAlignment="Center"
Theme="{StaticResource CardBorder}"> Theme="{DynamicResource CardBorder}">
<Grid <Grid
Classes="Margin8" Classes="Margin8"
@@ -49,7 +52,10 @@
Classes="Margin8" Classes="Margin8"
Content="{x:Static resx:ResUI.menuLocalBackup}" /> Content="{x:Static resx:ResUI.menuLocalBackup}" />
<Separator Grid.Row="2" Grid.ColumnSpan="2" /> <Separator
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2" />
<TextBlock <TextBlock
Grid.Row="3" Grid.Row="3"
@@ -69,21 +75,21 @@
<Border <Border
Margin="4" Margin="4"
VerticalAlignment="Center" VerticalAlignment="Center"
Theme="{StaticResource CardBorder}"> Theme="{DynamicResource CardBorder}">
<Grid <Grid
Classes="Margin8" Classes="Margin8"
ColumnDefinitions="300,200" ColumnDefinitions="300,200"
RowDefinitions="Auto,Auto,Auto,Auto,Auto"> RowDefinitions="Auto,Auto,Auto,Auto,Auto">
<StackPanel Orientation="Horizontal"> <StackPanel
<TextBlock
Grid.Row="0" Grid.Row="0"
Grid.Column="0" Grid.Column="0"
Classes="Margin8" Orientation="Horizontal">
Text="{x:Static resx:ResUI.menuRemoteBackupAndRestore}" /> <TextBlock Classes="Margin8" Text="{x:Static resx:ResUI.menuRemoteBackupAndRestore}" />
<Button <Button
Width="30" Width="30"
Height="30" Height="30"
MinWidth="30"
Margin="10,0" Margin="10,0"
Theme="{DynamicResource BorderlessButton}"> Theme="{DynamicResource BorderlessButton}">
<Button.Content> <Button.Content>
@@ -184,7 +190,10 @@
Classes="Margin8" Classes="Margin8"
Content="{x:Static resx:ResUI.menuRemoteBackup}" /> Content="{x:Static resx:ResUI.menuRemoteBackup}" />
<Separator Grid.Row="2" Grid.ColumnSpan="3" /> <Separator
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2" />
<TextBlock <TextBlock
Grid.Row="3" Grid.Row="3"
Grid.Column="0" Grid.Column="0"

View File

@@ -9,7 +9,12 @@ namespace v2rayN.Desktop.Views
{ {
public partial class BackupAndRestoreView : ReactiveUserControl<BackupAndRestoreViewModel> public partial class BackupAndRestoreView : ReactiveUserControl<BackupAndRestoreViewModel>
{ {
private Window _window; private Window? _window;
public BackupAndRestoreView()
{
InitializeComponent();
}
public BackupAndRestoreView(Window window) public BackupAndRestoreView(Window window)
{ {

View File

@@ -35,11 +35,16 @@
Content="{x:Static resx:ResUI.menuCheckUpdate}" /> Content="{x:Static resx:ResUI.menuCheckUpdate}" />
</StackPanel> </StackPanel>
<StackPanel> <Border
Margin="4"
VerticalAlignment="Center"
Theme="{DynamicResource CardBorder}">
<ListBox <ListBox
x:Name="lstCheckUpdates" x:Name="lstCheckUpdates"
BorderThickness="1" BorderThickness="1"
ItemsSource="{Binding CheckUpdateModels}"> ItemsSource="{Binding CheckUpdateModels}"
Theme="{StaticResource ButtonRadioGroupListBox}">
<ItemsControl.ItemsPanel> <ItemsControl.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<StackPanel Orientation="Vertical" /> <StackPanel Orientation="Vertical" />
@@ -47,12 +52,7 @@
</ItemsControl.ItemsPanel> </ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate> <DataTemplate>
<Border <Panel Width="500" VerticalAlignment="Center">
Width="500"
Height="80"
Margin="-8"
VerticalAlignment="Center"
Theme="{StaticResource CardBorder}">
<Grid ColumnDefinitions="1*,1*,3*" RowDefinitions="Auto"> <Grid ColumnDefinitions="1*,1*,3*" RowDefinitions="Auto">
<ToggleSwitch <ToggleSwitch
x:Name="togAutoRefresh" x:Name="togAutoRefresh"
@@ -73,11 +73,10 @@
Text="{Binding Remarks}" Text="{Binding Remarks}"
TextWrapping="WrapWithOverflow" /> TextWrapping="WrapWithOverflow" />
</Grid> </Grid>
</Border> </Panel>
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
</ListBox> </ListBox>
</StackPanel> </Border>
</DockPanel> </DockPanel>
</UserControl> </UserControl>

View File

@@ -28,7 +28,7 @@
Text="{x:Static resx:ResUI.menuRulemode}" /> Text="{x:Static resx:ResUI.menuRulemode}" />
<ComboBox <ComboBox
x:Name="cmbRulemode" x:Name="cmbRulemode"
Width="80" Width="100"
Margin="8,0"> Margin="8,0">
<ComboBoxItem Content="{x:Static resx:ResUI.menuModeRule}" /> <ComboBoxItem Content="{x:Static resx:ResUI.menuModeRule}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuModeGlobal}" /> <ComboBoxItem Content="{x:Static resx:ResUI.menuModeGlobal}" />
@@ -41,7 +41,7 @@
Text="{x:Static resx:ResUI.TbSorting}" /> Text="{x:Static resx:ResUI.TbSorting}" />
<ComboBox <ComboBox
x:Name="cmbSorting" x:Name="cmbSorting"
Width="60" Width="100"
Margin="8,0"> Margin="8,0">
<ComboBoxItem Content="{x:Static resx:ResUI.TbSortingDelay}" /> <ComboBoxItem Content="{x:Static resx:ResUI.TbSortingDelay}" />
<ComboBoxItem Content="{x:Static resx:ResUI.TbSortingName}" /> <ComboBoxItem Content="{x:Static resx:ResUI.TbSortingName}" />
@@ -95,7 +95,8 @@
<ListBox <ListBox
x:Name="lstProxyGroups" x:Name="lstProxyGroups"
DockPanel.Dock="Left" DockPanel.Dock="Left"
ItemsSource="{Binding ProxyGroups}"> ItemsSource="{Binding ProxyGroups}"
Theme="{StaticResource ButtonRadioGroupListBox}">
<ItemsControl.ItemsPanel> <ItemsControl.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<StackPanel Orientation="Vertical" /> <StackPanel Orientation="Vertical" />
@@ -105,10 +106,9 @@
<DataTemplate> <DataTemplate>
<Border <Border
Width="160" Width="160"
Margin="-6" Margin="-8,-4"
Padding="0" Padding="0"
Theme="{StaticResource CardBorder}"> Theme="{StaticResource CardBorder}">
<DockPanel>
<Grid Classes="Margin8" RowDefinitions="1*,8,1*"> <Grid Classes="Margin8" RowDefinitions="1*,8,1*">
<DockPanel Grid.Row="0"> <DockPanel Grid.Row="0">
<TextBlock DockPanel.Dock="Right" Text="{Binding Type}" /> <TextBlock DockPanel.Dock="Right" Text="{Binding Type}" />
@@ -116,13 +116,15 @@
</DockPanel> </DockPanel>
<TextBlock Grid.Row="2" Text="{Binding Now}" /> <TextBlock Grid.Row="2" Text="{Binding Now}" />
</Grid> </Grid>
</DockPanel>
</Border> </Border>
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
</ListBox> </ListBox>
<ListBox x:Name="lstProxyDetails" ItemsSource="{Binding ProxyDetails}"> <ListBox
x:Name="lstProxyDetails"
ItemsSource="{Binding ProxyDetails}"
Theme="{StaticResource ButtonRadioGroupListBox}">
<ItemsControl.ContextMenu> <ItemsControl.ContextMenu>
<ContextMenu> <ContextMenu>
<MenuItem x:Name="menuProxiesDelaytestPart" Header="{x:Static resx:ResUI.menuProxiesDelaytestPart}" /> <MenuItem x:Name="menuProxiesDelaytestPart" Header="{x:Static resx:ResUI.menuProxiesDelaytestPart}" />
@@ -138,7 +140,7 @@
<DataTemplate> <DataTemplate>
<Border <Border
Width="160" Width="160"
Margin="-6" Margin="-12,-4"
Padding="0" Padding="0"
Theme="{StaticResource CardBorder}"> Theme="{StaticResource CardBorder}">
<DockPanel> <DockPanel>

View File

@@ -150,71 +150,20 @@
x:Name="tabMain1" x:Name="tabMain1"
Grid.Row="2" Grid.Row="2"
TabStripPlacement="Left"> TabStripPlacement="Left">
<TabItem x:Name="tabMsgView1"> <TabItem x:Name="tabMsgView1" Header="{x:Static resx:ResUI.MsgInformationTitle}" />
<TabItem.Header> <TabItem x:Name="tabClashProxies1" Header="{x:Static resx:ResUI.TbProxies}" />
<StackPanel> <TabItem x:Name="tabClashConnections1" Header="{x:Static resx:ResUI.TbConnections}" />
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.MsgInformationTitle}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="tabClashProxies1">
<TabItem.Header>
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.TbProxies}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="tabClashConnections1">
<TabItem.Header>
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.TbConnections}" />
</StackPanel>
</TabItem.Header>
</TabItem>
</TabControl> </TabControl>
</Grid> </Grid>
<Grid x:Name="gridMain2" IsVisible="False"> <Grid x:Name="gridMain2" IsVisible="False">
<TabControl x:Name="tabMain2" TabStripPlacement="Left"> <TabControl x:Name="tabMain2" TabStripPlacement="Left">
<TabItem x:Name="tabProfiles2"> <TabItem x:Name="tabProfiles2" Header="{x:Static resx:ResUI.menuServers}" />
<TabItem.Header> <TabItem x:Name="tabMsgView2" Header="{x:Static resx:ResUI.MsgInformationTitle}" />
<StackPanel> <TabItem x:Name="tabClashProxies2" Header="{x:Static resx:ResUI.TbProxies}" />
<TabItem x:Name="tabClashConnections2" Header="{x:Static resx:ResUI.TbConnections}" />
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.menuServers}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="tabMsgView2">
<TabItem.Header>
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.MsgInformationTitle}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="tabClashProxies2">
<TabItem.Header>
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.TbProxies}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="tabClashConnections2">
<TabItem.Header>
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.TbConnections}" />
</StackPanel>
</TabItem.Header>
</TabItem>
</TabControl> </TabControl>
</Grid> </Grid>
</Grid> </Grid>
</DockPanel> </DockPanel>
</dialogHost:DialogHost> </dialogHost:DialogHost>
</Window> </Window>

View File

@@ -65,7 +65,7 @@
Margin="8,0" Margin="8,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
IsChecked="True" IsChecked="True"
Theme="{StaticResource SimpleToggleSwitch}" /> Theme="{DynamicResource SimpleToggleSwitch}" />
<TextBlock <TextBlock
Margin="8,0" Margin="8,0"
VerticalAlignment="Center" VerticalAlignment="Center"
@@ -75,7 +75,7 @@
Margin="8,0" Margin="8,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
IsChecked="True" IsChecked="True"
Theme="{StaticResource SimpleToggleSwitch}" /> Theme="{DynamicResource SimpleToggleSwitch}" />
</WrapPanel> </WrapPanel>
<TextBox <TextBox
Name="txtMsg" Name="txtMsg"

View File

@@ -114,8 +114,8 @@
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Classes="Margin8" Classes="Margin8"
SelectionMode="Multiple" SelectionMode="Multiple,Toggle"
Theme="{DynamicResource PureCardRadioGroupListBox}" /> Theme="{DynamicResource CardCheckGroupListBox}" />
<TextBlock <TextBlock
Grid.Row="6" Grid.Row="6"
@@ -385,9 +385,9 @@
Grid.Column="0" Grid.Column="0"
VerticalAlignment="Center" VerticalAlignment="Center"
Classes="Margin8" Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsKeepOlderDedupl}" /> Text="{x:Static resx:ResUI.TbSettingsDisplayRealTimeSpeed}" />
<ToggleSwitch <ToggleSwitch
x:Name="togKeepOlderDedupl" x:Name="togDisplayRealTimeSpeed"
Grid.Row="3" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
HorizontalAlignment="Left" HorizontalAlignment="Left"
@@ -398,9 +398,9 @@
Grid.Column="0" Grid.Column="0"
VerticalAlignment="Center" VerticalAlignment="Center"
Classes="Margin8" Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsIgnoreGeoUpdateCore}" /> Text="{x:Static resx:ResUI.TbSettingsKeepOlderDedupl}" />
<ToggleSwitch <ToggleSwitch
x:Name="togIgnoreGeoUpdateCore" x:Name="togKeepOlderDedupl"
Grid.Row="4" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
HorizontalAlignment="Left" HorizontalAlignment="Left"
@@ -714,7 +714,6 @@
</TabItem> </TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsTunMode}"> <TabItem Header="{x:Static resx:ResUI.TbSettingsTunMode}">
<DockPanel Classes="Margin8">
<Grid <Grid
Classes="Margin8" Classes="Margin8"
ColumnDefinitions="Auto,Auto,Auto" ColumnDefinitions="Auto,Auto,Auto"
@@ -809,7 +808,6 @@
Text="{x:Static resx:ResUI.TbSettingsLinuxSudoPasswordTip}" Text="{x:Static resx:ResUI.TbSettingsLinuxSudoPasswordTip}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
</Grid> </Grid>
</DockPanel>
</TabItem> </TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreType}"> <TabItem Header="{x:Static resx:ResUI.TbSettingsCoreType}">

View File

@@ -126,8 +126,8 @@ namespace v2rayN.Desktop.Views
this.Bind(ViewModel, vm => vm.AutoRun, v => v.togAutoRun.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.AutoRun, v => v.togAutoRun.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableStatistics, v => v.togEnableStatistics.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableStatistics, v => v.togEnableStatistics.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DisplayRealTimeSpeed, v => v.togDisplayRealTimeSpeed.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.KeepOlderDedupl, v => v.togKeepOlderDedupl.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.KeepOlderDedupl, v => v.togKeepOlderDedupl.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.IgnoreGeoUpdateCore, v => v.togIgnoreGeoUpdateCore.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableAutoAdjustMainLvColWidth, v => v.togEnableAutoAdjustMainLvColWidth.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableAutoAdjustMainLvColWidth, v => v.togEnableAutoAdjustMainLvColWidth.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableUpdateSubOnlyRemarksExist, v => v.togEnableUpdateSubOnlyRemarksExist.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableUpdateSubOnlyRemarksExist, v => v.togEnableUpdateSubOnlyRemarksExist.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableSecurityProtocolTls13, v => v.togEnableSecurityProtocolTls13.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableSecurityProtocolTls13, v => v.togEnableSecurityProtocolTls13.IsChecked).DisposeWith(disposables);

View File

@@ -165,7 +165,7 @@
Classes="Solid Red" Classes="Solid Red"
Content="{x:Static resx:ResUI.TipActiveServer}" Content="{x:Static resx:ResUI.TipActiveServer}"
IsVisible="{Binding IsActive}" IsVisible="{Binding IsActive}"
Theme="{StaticResource TagLabel}" /> Theme="{DynamicResource TagLabel}" />
<TextBlock <TextBlock
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"

View File

@@ -15,7 +15,12 @@ namespace v2rayN.Desktop.Views
public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel> public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
{ {
private static Config _config; private static Config _config;
private Window _window; private Window? _window;
public ProfilesView()
{
InitializeComponent();
}
public ProfilesView(Window window) public ProfilesView(Window window)
{ {

View File

@@ -4,12 +4,10 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
d:DesignHeight="480" d:DesignHeight="480"
d:DesignWidth="400" d:DesignWidth="400"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid Margin="30" RowDefinitions="Auto,Auto"> <Grid Margin="30" RowDefinitions="Auto,Auto">
<Image <Image
Name="imgQrcode" Name="imgQrcode"
Width="300" Width="300"
@@ -24,6 +22,5 @@
IsReadOnly="True" IsReadOnly="True"
MaxLines="1" /> MaxLines="1" />
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -5,6 +5,11 @@ namespace v2rayN.Desktop.Views
{ {
public partial class QrcodeView : UserControl public partial class QrcodeView : UserControl
{ {
public QrcodeView()
{
InitializeComponent();
}
public QrcodeView(string? url) public QrcodeView(string? url)
{ {
InitializeComponent(); InitializeComponent();

View File

@@ -94,8 +94,8 @@
Grid.Column="1" Grid.Column="1"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Classes="Margin8" Classes="Margin8"
SelectionMode="Multiple" SelectionMode="Multiple,Toggle"
Theme="{DynamicResource PureCardRadioGroupListBox}" /> Theme="{DynamicResource CardCheckGroupListBox}" />
<TextBlock <TextBlock
Grid.Row="4" Grid.Row="4"
@@ -108,8 +108,8 @@
Grid.Row="4" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
Classes="Margin8" Classes="Margin8"
SelectionMode="Multiple" SelectionMode="Multiple,Toggle"
Theme="{DynamicResource PureCardRadioGroupListBox}" /> Theme="{DynamicResource CardCheckGroupListBox}" />
<TextBlock <TextBlock
Grid.Row="4" Grid.Row="4"
Grid.Column="2" Grid.Column="2"

View File

@@ -123,6 +123,7 @@
Classes="Margin8" Classes="Margin8"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<!--
<TextBlock <TextBlock
Grid.Row="3" Grid.Row="3"
Grid.Column="0" Grid.Column="0"
@@ -144,6 +145,7 @@
Grid.Column="2" Grid.Column="2"
Classes="Margin8" Classes="Margin8"
Content="{x:Static resx:ResUI.TbBrowse}" /> Content="{x:Static resx:ResUI.TbBrowse}" />
-->
<TextBlock <TextBlock
Grid.Row="4" Grid.Row="4"

View File

@@ -27,7 +27,7 @@ namespace v2rayN.Desktop.Views
lstRules.SelectionChanged += lstRules_SelectionChanged; lstRules.SelectionChanged += lstRules_SelectionChanged;
lstRules.DoubleTapped += LstRules_DoubleTapped; lstRules.DoubleTapped += LstRules_DoubleTapped;
menuRuleSelectAll.Click += menuRuleSelectAll_Click; menuRuleSelectAll.Click += menuRuleSelectAll_Click;
btnBrowseCustomIcon.Click += btnBrowseCustomIcon_Click; //btnBrowseCustomIcon.Click += btnBrowseCustomIcon_Click;
btnBrowseCustomRulesetPath4Singbox.Click += btnBrowseCustomRulesetPath4Singbox_ClickAsync; btnBrowseCustomRulesetPath4Singbox.Click += btnBrowseCustomRulesetPath4Singbox_ClickAsync;
ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler); ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler);
@@ -51,7 +51,7 @@ namespace v2rayN.Desktop.Views
this.Bind(ViewModel, vm => vm.SelectedRouting.DomainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.DomainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.Url, v => v.txtUrl.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.Url, v => v.txtUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.CustomIcon, v => v.txtCustomIcon.Text).DisposeWith(disposables); //this.Bind(ViewModel, vm => vm.SelectedRouting.CustomIcon, v => v.txtCustomIcon.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.CustomRulesetPath4Singbox, v => v.txtCustomRulesetPath4Singbox.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.CustomRulesetPath4Singbox, v => v.txtCustomRulesetPath4Singbox.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.Sort, v => v.txtSort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.Sort, v => v.txtSort.Text).DisposeWith(disposables);
@@ -179,16 +179,16 @@ namespace v2rayN.Desktop.Views
lstRules.SelectAll(); lstRules.SelectAll();
} }
private async void btnBrowseCustomIcon_Click(object? sender, RoutedEventArgs e) //private async void btnBrowseCustomIcon_Click(object? sender, RoutedEventArgs e)
{ //{
var fileName = await UI.OpenFileDialog(this, FilePickerFileTypes.ImagePng); // var fileName = await UI.OpenFileDialog(this, FilePickerFileTypes.ImagePng);
if (fileName.IsNullOrEmpty()) // if (fileName.IsNullOrEmpty())
{ // {
return; // return;
} // }
txtCustomIcon.Text = fileName; // txtCustomIcon.Text = fileName;
} //}
private async void btnBrowseCustomRulesetPath4Singbox_ClickAsync(object? sender, RoutedEventArgs e) private async void btnBrowseCustomRulesetPath4Singbox_ClickAsync(object? sender, RoutedEventArgs e)
{ {

View File

@@ -18,40 +18,29 @@
<StackPanel <StackPanel
Classes="Margin8" Classes="Margin8"
DockPanel.Dock="Top" DockPanel.Dock="Top"
Orientation="Horizontal"> Orientation="Horizontal"
Spacing="4">
<Menu> <Menu>
<MenuItem x:Name="menuRoutingAdvancedAdd2" Header="{x:Static resx:ResUI.menuRoutingAdvancedAdd}" /> <MenuItem x:Name="menuRoutingAdvancedAdd2" Header="{x:Static resx:ResUI.menuRoutingAdvancedAdd}" />
<MenuItem x:Name="menuRoutingAdvancedImportRules2" Header="{x:Static resx:ResUI.menuRoutingAdvancedImportRules}" /> <MenuItem x:Name="menuRoutingAdvancedImportRules2" Header="{x:Static resx:ResUI.menuRoutingAdvancedImportRules}" />
</Menu> </Menu>
<TextBlock Margin="8,0,0,0" VerticalAlignment="Center"> <TextBlock VerticalAlignment="Center">
<HyperlinkButton Classes="WithIcon" Click="linkdomainStrategy_Click"> <HyperlinkButton Classes="WithIcon" Click="linkdomainStrategy_Click">
<TextBlock Text="{x:Static resx:ResUI.TbdomainStrategy}" /> <TextBlock Text="{x:Static resx:ResUI.TbdomainStrategy}" />
</HyperlinkButton> </HyperlinkButton>
</TextBlock> </TextBlock>
<ComboBox <ComboBox x:Name="cmbdomainStrategy" Width="110" />
x:Name="cmbdomainStrategy"
Width="110"
Margin="8,0,0,0" />
<Separator /> <Separator />
<TextBlock <TextBlock VerticalAlignment="Center" Text="{x:Static resx:ResUI.TbdomainMatcher}" />
Margin="8,0,0,0" <ComboBox x:Name="cmbdomainMatcher" Width="60" />
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbdomainMatcher}" />
<ComboBox
x:Name="cmbdomainMatcher"
Width="60"
Margin="8,0,0,0" />
<Separator /> <Separator />
<TextBlock Margin="8,0,0,0" VerticalAlignment="Center"> <TextBlock VerticalAlignment="Center">
<HyperlinkButton Classes="WithIcon" Click="linkdomainStrategy4Singbox_Click"> <HyperlinkButton Classes="WithIcon" Click="linkdomainStrategy4Singbox_Click">
<TextBlock Text="{x:Static resx:ResUI.TbdomainStrategy4Singbox}" /> <TextBlock Text="{x:Static resx:ResUI.TbdomainStrategy4Singbox}" />
</HyperlinkButton> </HyperlinkButton>
</TextBlock> </TextBlock>
<ComboBox <ComboBox x:Name="cmbdomainStrategy4Singbox" Width="100" />
x:Name="cmbdomainStrategy4Singbox"
Width="100"
Margin="8,0,0,0" />
</StackPanel> </StackPanel>
<StackPanel <StackPanel

View File

@@ -11,15 +11,14 @@
x:DataType="vms:StatusBarViewModel" x:DataType="vms:StatusBarViewModel"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid> <Grid>
<StackPanel Height="50"> <DockPanel Margin="4">
<DockPanel>
<StackPanel <StackPanel
Margin="8,0" Margin="8,0"
VerticalAlignment="Center" VerticalAlignment="Center"
DockPanel.Dock="Right"> DockPanel.Dock="Right">
<TextBlock x:Name="txtSpeedProxyDisplay" /> <TextBlock x:Name="txtSpeedProxyDisplay" HorizontalAlignment="Right" />
<Border Margin="2" /> <Border Margin="1" />
<TextBlock x:Name="txtSpeedDirectDisplay" /> <TextBlock x:Name="txtSpeedDirectDisplay" HorizontalAlignment="Right" />
</StackPanel> </StackPanel>
<StackPanel <StackPanel
@@ -27,7 +26,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
DockPanel.Dock="Left"> DockPanel.Dock="Left">
<TextBlock x:Name="txtInboundDisplay" /> <TextBlock x:Name="txtInboundDisplay" />
<Border Margin="2" /> <Border Margin="1" />
<TextBlock x:Name="txtInboundLanDisplay" /> <TextBlock x:Name="txtInboundLanDisplay" />
</StackPanel> </StackPanel>
@@ -45,7 +44,7 @@
x:Name="togEnableTun" x:Name="togEnableTun"
HorizontalAlignment="Center" HorizontalAlignment="Center"
Classes="Margin8" Classes="Margin8"
Theme="{StaticResource SimpleToggleSwitch}" /> Theme="{DynamicResource SimpleToggleSwitch}" />
</StackPanel> </StackPanel>
<StackPanel <StackPanel
@@ -74,10 +73,9 @@
<StackPanel Margin="8,0" VerticalAlignment="Center"> <StackPanel Margin="8,0" VerticalAlignment="Center">
<TextBlock x:Name="txtRunningServerDisplay" /> <TextBlock x:Name="txtRunningServerDisplay" />
<Border Margin="2" /> <Border Margin="1" />
<TextBlock x:Name="txtRunningInfoDisplay" /> <TextBlock x:Name="txtRunningInfoDisplay" />
</StackPanel> </StackPanel>
</DockPanel> </DockPanel>
</StackPanel>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -69,6 +69,11 @@ namespace v2rayN.Desktop.Views
}, },
DispatcherPriority.Default); DispatcherPriority.Default);
break; break;
case EViewAction.SetClipboardData:
if (obj is null) return false;
await AvaUtils.SetClipboardData(this, (string)obj);
break;
} }
return await Task.FromResult(true); return await Task.FromResult(true);
} }

View File

@@ -10,6 +10,15 @@
d:DesignWidth="800" d:DesignWidth="800"
x:DataType="vms:ThemeSettingViewModel" x:DataType="vms:ThemeSettingViewModel"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.Styles>
<Style Selector="TextBlock">
<Setter Property="Width" Value="100" />
</Style>
<Style Selector="ComboBox">
<Setter Property="Width" Value="130" />
</Style>
</UserControl.Styles>
<Button <Button
Width="30" Width="30"
Height="30" Height="30"
@@ -24,43 +33,35 @@
</Button.Content> </Button.Content>
<Button.Flyout> <Button.Flyout>
<Flyout> <Flyout>
<StackPanel> <StackPanel Margin="0,12">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock <TextBlock
Width="100"
VerticalAlignment="Center" VerticalAlignment="Center"
Classes="Margin8" Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsColorMode}" /> Text="{x:Static resx:ResUI.TbSettingsTheme}" />
<ToggleSwitch x:Name="togDarkMode" Classes="Margin8" /> <ComboBox
x:Name="cmbCurrentTheme"
HorizontalAlignment="Center"
Classes="Margin8" />
</StackPanel> </StackPanel>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock <TextBlock
Width="100"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsFollowSystemTheme}" />
<ToggleSwitch x:Name="togFollowSystemTheme" Classes="Margin8" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock
Width="100"
VerticalAlignment="Center" VerticalAlignment="Center"
Classes="Margin8" Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsFontSize}" /> Text="{x:Static resx:ResUI.TbSettingsFontSize}" />
<ComboBox <ComboBox
x:Name="cmbCurrentFontSize" x:Name="cmbCurrentFontSize"
Width="100" HorizontalAlignment="Center"
Classes="Margin8" /> Classes="Margin8" />
</StackPanel> </StackPanel>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock <TextBlock
Width="100"
VerticalAlignment="Center" VerticalAlignment="Center"
Classes="Margin8" Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsLanguage}" /> Text="{x:Static resx:ResUI.TbSettingsLanguage}" />
<ComboBox <ComboBox
x:Name="cmbCurrentLanguage" x:Name="cmbCurrentLanguage"
Width="100" HorizontalAlignment="Center"
Classes="Margin8" /> Classes="Margin8" />
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>

View File

@@ -16,6 +16,11 @@ namespace v2rayN.Desktop.Views
InitializeComponent(); InitializeComponent();
ViewModel = new ThemeSettingViewModel(); ViewModel = new ThemeSettingViewModel();
foreach (ETheme it in Enum.GetValues(typeof(ETheme)))
{
cmbCurrentTheme.Items.Add(it.ToString());
}
for (int i = Global.MinFontSize; i <= Global.MinFontSize + 10; i++) for (int i = Global.MinFontSize; i <= Global.MinFontSize + 10; i++)
{ {
cmbCurrentFontSize.Items.Add(i); cmbCurrentFontSize.Items.Add(i);
@@ -28,8 +33,7 @@ namespace v2rayN.Desktop.Views
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.ColorModeDark, v => v.togDarkMode.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CurrentTheme, v => v.cmbCurrentTheme.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.FollowSystemTheme, v => v.togFollowSystemTheme.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CurrentFontSize, v => v.cmbCurrentFontSize.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CurrentFontSize, v => v.cmbCurrentFontSize.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CurrentLanguage, v => v.cmbCurrentLanguage.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CurrentLanguage, v => v.cmbCurrentLanguage.SelectedValue).DisposeWith(disposables);
}); });

View File

@@ -6,7 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>Assets\v2rayN.ico</ApplicationIcon> <ApplicationIcon>Assets\v2rayN.ico</ApplicationIcon>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport> <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright> <Copyright>Copyright © 2017-2025 (GPLv3)</Copyright>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault> <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<AssemblyName>v2rayN</AssemblyName> <AssemblyName>v2rayN</AssemblyName>
</PropertyGroup> </PropertyGroup>
@@ -48,7 +48,7 @@
<None Update="v2rayN.png"> <None Update="v2rayN.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Update="v2rayN2.png"> <None Update="v2rayN.icns">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -64,14 +64,6 @@ namespace v2rayN
BitmapSizeOptions.FromEmptyOptions()); BitmapSizeOptions.FromEmptyOptions());
} }
public static bool IsDarkTheme()
{
using var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
var obj = key?.GetValue("AppsUseLightTheme");
int.TryParse(obj?.ToString(), out var value);
return value == 0;
}
public static void RemoveTunDevice() public static void RemoveTunDevice()
{ {
try try
@@ -103,7 +95,19 @@ namespace v2rayN
} }
} }
public static void SetDarkBorder(Window window, bool dark) public static void SetDarkBorder(Window window, string? theme)
{
var isDark = theme switch
{
nameof(ETheme.Dark) => true,
nameof(ETheme.Light) => false,
_ => IsDarkTheme(),
};
SetDarkBorder(window, isDark);
}
private static void SetDarkBorder(Window window, bool dark)
{ {
// Make sure the handle is created before the window is shown // Make sure the handle is created before the window is shown
IntPtr hWnd = new WindowInteropHelper(window).EnsureHandle(); IntPtr hWnd = new WindowInteropHelper(window).EnsureHandle();
@@ -113,6 +117,14 @@ namespace v2rayN
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, ref attribute, attributeSize); DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, ref attribute, attributeSize);
} }
private static bool IsDarkTheme()
{
using var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
var obj = key?.GetValue("AppsUseLightTheme");
int.TryParse(obj?.ToString(), out var value);
return value == 0;
}
#region Windows API #region Windows API
[Flags] [Flags]

View File

@@ -16,23 +16,17 @@ namespace v2rayN.ViewModels
{ {
private readonly PaletteHelper _paletteHelper = new(); private readonly PaletteHelper _paletteHelper = new();
[Reactive]
public bool ColorModeDark { get; set; }
private IObservableCollection<Swatch> _swatches = new ObservableCollectionExtended<Swatch>(); private IObservableCollection<Swatch> _swatches = new ObservableCollectionExtended<Swatch>();
public IObservableCollection<Swatch> Swatches => _swatches; public IObservableCollection<Swatch> Swatches => _swatches;
[Reactive] [Reactive]
public Swatch SelectedSwatch { get; set; } public Swatch SelectedSwatch { get; set; }
[Reactive] [Reactive] public string CurrentTheme { get; set; }
public int CurrentFontSize { get; set; }
[Reactive] [Reactive] public int CurrentFontSize { get; set; }
public bool FollowSystemTheme { get; set; }
[Reactive] [Reactive] public string CurrentLanguage { get; set; }
public string CurrentLanguage { get; set; }
public ThemeSettingViewModel() public ThemeSettingViewModel()
{ {
@@ -62,36 +56,23 @@ namespace v2rayN.ViewModels
private void BindingUI() private void BindingUI()
{ {
ColorModeDark = _config.UiItem.ColorModeDark;
FollowSystemTheme = _config.UiItem.FollowSystemTheme;
_swatches.AddRange(new SwatchesProvider().Swatches); _swatches.AddRange(new SwatchesProvider().Swatches);
if (!_config.UiItem.ColorPrimaryName.IsNullOrEmpty()) if (!_config.UiItem.ColorPrimaryName.IsNullOrEmpty())
{ {
SelectedSwatch = _swatches.FirstOrDefault(t => t.Name == _config.UiItem.ColorPrimaryName); SelectedSwatch = _swatches.FirstOrDefault(t => t.Name == _config.UiItem.ColorPrimaryName);
} }
CurrentTheme = _config.UiItem.CurrentTheme;
CurrentFontSize = _config.UiItem.CurrentFontSize; CurrentFontSize = _config.UiItem.CurrentFontSize;
CurrentLanguage = _config.UiItem.CurrentLanguage; CurrentLanguage = _config.UiItem.CurrentLanguage;
this.WhenAnyValue( this.WhenAnyValue(
x => x.ColorModeDark, x => x.CurrentTheme,
y => y == true) y => y != null && !y.IsNullOrEmpty())
.Subscribe(c => .Subscribe(c =>
{ {
if (_config.UiItem.ColorModeDark != ColorModeDark) if (_config.UiItem.CurrentTheme != CurrentTheme)
{ {
_config.UiItem.ColorModeDark = ColorModeDark; _config.UiItem.CurrentTheme = CurrentTheme;
ModifyTheme();
ConfigHandler.SaveConfig(_config);
}
});
this.WhenAnyValue(x => x.FollowSystemTheme,
y => y == true)
.Subscribe(c =>
{
if (_config.UiItem.FollowSystemTheme != FollowSystemTheme)
{
_config.UiItem.FollowSystemTheme = FollowSystemTheme;
ModifyTheme(); ModifyTheme();
ConfigHandler.SaveConfig(_config); ConfigHandler.SaveConfig(_config);
} }
@@ -147,12 +128,18 @@ namespace v2rayN.ViewModels
public void ModifyTheme() public void ModifyTheme()
{ {
var theme = _paletteHelper.GetTheme(); var baseTheme = CurrentTheme switch
{
nameof(ETheme.Dark) => BaseTheme.Dark,
nameof(ETheme.Light) => BaseTheme.Light,
_ => BaseTheme.Inherit,
};
var isDarkTheme = FollowSystemTheme ? WindowsUtils.IsDarkTheme() : ColorModeDark; var theme = _paletteHelper.GetTheme();
theme.SetBaseTheme(isDarkTheme ? BaseTheme.Dark : BaseTheme.Light); theme.SetBaseTheme(baseTheme);
_paletteHelper.SetTheme(theme); _paletteHelper.SetTheme(theme);
WindowsUtils.SetDarkBorder(Application.Current.MainWindow, isDarkTheme);
WindowsUtils.SetDarkBorder(Application.Current.MainWindow, CurrentTheme);
} }
private void ModifyFontSize() private void ModifyFontSize()
@@ -182,7 +169,7 @@ namespace v2rayN.ViewModels
var hwndSource = HwndSource.FromHwnd(helper.EnsureHandle()); var hwndSource = HwndSource.FromHwnd(helper.EnsureHandle());
hwndSource.AddHook((IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) => hwndSource.AddHook((IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) =>
{ {
if (config.UiItem.FollowSystemTheme) if (config.UiItem.CurrentTheme == nameof(ETheme.FollowSystem))
{ {
const int WM_SETTINGCHANGE = 0x001A; const int WM_SETTINGCHANGE = 0x001A;
if (msg == WM_SETTINGCHANGE) if (msg == WM_SETTINGCHANGE)

View File

@@ -34,7 +34,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SaveServerCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveServerCmd, v => v.btnSave).DisposeWith(disposables);
}); });
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark); WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -210,7 +210,7 @@ namespace v2rayN.Views
}); });
this.Title = $"{profileItem.ConfigType}"; this.Title = $"{profileItem.ConfigType}";
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark); WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -64,7 +64,6 @@
<DataTemplate> <DataTemplate>
<Border <Border
Width="500" Width="500"
Height="50"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
Padding="0" Padding="0"
VerticalAlignment="Center"> VerticalAlignment="Center">

View File

@@ -1,14 +1,14 @@
<reactiveui:ReactiveUserControl <reactiveui:ReactiveUserControl
x:Class="v2rayN.Views.ClashProxiesView" x:Class="v2rayN.Views.ClashProxiesView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib" xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
xmlns:converters="clr-namespace:v2rayN.Converters"
d:DesignHeight="450" d:DesignHeight="450"
d:DesignWidth="800" d:DesignWidth="800"
x:TypeArguments="vms:ClashProxiesViewModel" x:TypeArguments="vms:ClashProxiesViewModel"
@@ -34,7 +34,7 @@
Text="{x:Static resx:ResUI.menuRulemode}" /> Text="{x:Static resx:ResUI.menuRulemode}" />
<ComboBox <ComboBox
x:Name="cmbRulemode" x:Name="cmbRulemode"
Width="80" Width="100"
Margin="{StaticResource MarginLeftRight8}" Margin="{StaticResource MarginLeftRight8}"
Style="{StaticResource DefComboBox}"> Style="{StaticResource DefComboBox}">
<ComboBoxItem Content="{x:Static resx:ResUI.menuModeRule}" /> <ComboBoxItem Content="{x:Static resx:ResUI.menuModeRule}" />
@@ -49,7 +49,7 @@
Text="{x:Static resx:ResUI.TbSorting}" /> Text="{x:Static resx:ResUI.TbSorting}" />
<ComboBox <ComboBox
x:Name="cmbSorting" x:Name="cmbSorting"
Width="60" Width="100"
Margin="{StaticResource MarginLeftRight8}" Margin="{StaticResource MarginLeftRight8}"
Style="{StaticResource DefComboBox}"> Style="{StaticResource DefComboBox}">
<ComboBoxItem Content="{x:Static resx:ResUI.TbSortingDelay}" /> <ComboBoxItem Content="{x:Static resx:ResUI.TbSortingDelay}" />

View File

@@ -50,7 +50,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCmd, v => v.btnImportDefConfig4Singbox).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCmd, v => v.btnImportDefConfig4Singbox).DisposeWith(disposables);
}); });
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark); WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -30,7 +30,7 @@ namespace v2rayN.Views
HotkeyHandler.Instance.IsPause = true; HotkeyHandler.Instance.IsPause = true;
this.Closing += (s, e) => HotkeyHandler.Instance.IsPause = false; this.Closing += (s, e) => HotkeyHandler.Instance.IsPause = false;
WindowsUtils.SetDarkBorder(this, _config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : _config.UiItem.ColorModeDark); WindowsUtils.SetDarkBorder(this, _config.UiItem.CurrentTheme);
InitData(); InitData();
} }

View File

@@ -601,9 +601,9 @@
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsKeepOlderDedupl}" /> Text="{x:Static resx:ResUI.TbSettingsDisplayRealTimeSpeed}" />
<ToggleButton <ToggleButton
x:Name="togKeepOlderDedupl" x:Name="togDisplayRealTimeSpeed"
Grid.Row="3" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
@@ -615,9 +615,9 @@
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsIgnoreGeoUpdateCore}" /> Text="{x:Static resx:ResUI.TbSettingsKeepOlderDedupl}" />
<ToggleButton <ToggleButton
x:Name="togIgnoreGeoUpdateCore" x:Name="togKeepOlderDedupl"
Grid.Row="4" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
@@ -997,7 +997,6 @@
</TabItem> </TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsTunMode}"> <TabItem Header="{x:Static resx:ResUI.TbSettingsTunMode}">
<DockPanel Margin="{StaticResource Margin8}">
<Grid Margin="{StaticResource Margin8}" DockPanel.Dock="Top"> <Grid Margin="{StaticResource Margin8}" DockPanel.Dock="Top">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
@@ -1088,7 +1087,6 @@
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" /> HorizontalAlignment="Left" />
</Grid> </Grid>
</DockPanel>
</TabItem> </TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreType}"> <TabItem Header="{x:Static resx:ResUI.TbSettingsCoreType}">

View File

@@ -136,8 +136,8 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.AutoRun, v => v.togAutoRun.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.AutoRun, v => v.togAutoRun.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableStatistics, v => v.togEnableStatistics.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableStatistics, v => v.togEnableStatistics.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DisplayRealTimeSpeed, v => v.togDisplayRealTimeSpeed.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.KeepOlderDedupl, v => v.togKeepOlderDedupl.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.KeepOlderDedupl, v => v.togKeepOlderDedupl.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.IgnoreGeoUpdateCore, v => v.togIgnoreGeoUpdateCore.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableAutoAdjustMainLvColWidth, v => v.togEnableAutoAdjustMainLvColWidth.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableAutoAdjustMainLvColWidth, v => v.togEnableAutoAdjustMainLvColWidth.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableUpdateSubOnlyRemarksExist, v => v.togEnableUpdateSubOnlyRemarksExist.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableUpdateSubOnlyRemarksExist, v => v.togEnableUpdateSubOnlyRemarksExist.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableSecurityProtocolTls13, v => v.togEnableSecurityProtocolTls13.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableSecurityProtocolTls13, v => v.togEnableSecurityProtocolTls13.IsChecked).DisposeWith(disposables);
@@ -177,7 +177,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
}); });
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark); WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
@@ -248,7 +248,9 @@ namespace v2rayN.Views
{ {
Logging.SaveLog("GetFonts", ex); Logging.SaveLog("GetFonts", ex);
} }
return lstFonts.OrderBy(t => t).ToList();
var lst = lstFonts.OrderBy(t => t).ToList();
return await Task.FromResult(lst);
} }
private void ClbdestOverride_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) private void ClbdestOverride_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)

View File

@@ -58,7 +58,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
}); });
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark); WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -60,7 +60,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
}); });
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark); WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -52,7 +52,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
}); });
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark); WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -15,15 +15,24 @@
Style="{StaticResource ViewGlobal}" Style="{StaticResource ViewGlobal}"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid> <Grid>
<materialDesign:ColorZone Height="50" Mode="Standard"> <materialDesign:ColorZone
Height="auto"
Margin="{StaticResource Margin4}"
Mode="Standard">
<DockPanel> <DockPanel>
<StackPanel <StackPanel
Margin="{StaticResource MarginLeftRight8}" Margin="{StaticResource MarginLeftRight8}"
VerticalAlignment="Center" VerticalAlignment="Center"
DockPanel.Dock="Right"> DockPanel.Dock="Right">
<TextBlock x:Name="txtSpeedProxyDisplay" Style="{StaticResource StatusbarItem}" /> <TextBlock
<Border Margin="{StaticResource Margin4}" /> x:Name="txtSpeedProxyDisplay"
<TextBlock x:Name="txtSpeedDirectDisplay" Style="{StaticResource StatusbarItem}" /> HorizontalAlignment="Right"
Style="{StaticResource StatusbarItem}" />
<Border Margin="1" />
<TextBlock
x:Name="txtSpeedDirectDisplay"
HorizontalAlignment="Right"
Style="{StaticResource StatusbarItem}" />
</StackPanel> </StackPanel>
<StackPanel <StackPanel
@@ -32,7 +41,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
DockPanel.Dock="Left"> DockPanel.Dock="Left">
<TextBlock x:Name="txtInboundDisplay" Style="{StaticResource StatusbarItem}" /> <TextBlock x:Name="txtInboundDisplay" Style="{StaticResource StatusbarItem}" />
<Border Margin="{StaticResource Margin4}" /> <Border Margin="1" />
<TextBlock x:Name="txtInboundLanDisplay" Style="{StaticResource StatusbarItem}" /> <TextBlock x:Name="txtInboundLanDisplay" Style="{StaticResource StatusbarItem}" />
</StackPanel> </StackPanel>
@@ -85,7 +94,7 @@
<StackPanel Margin="{StaticResource MarginLeftRight8}" VerticalAlignment="Center"> <StackPanel Margin="{StaticResource MarginLeftRight8}" VerticalAlignment="Center">
<TextBlock x:Name="txtRunningServerDisplay" Style="{StaticResource StatusbarItem}" /> <TextBlock x:Name="txtRunningServerDisplay" Style="{StaticResource StatusbarItem}" />
<Border Margin="{StaticResource Margin4}" /> <Border Margin="1" />
<TextBlock x:Name="txtRunningInfoDisplay" Style="{StaticResource StatusbarItem}" /> <TextBlock x:Name="txtRunningInfoDisplay" Style="{StaticResource StatusbarItem}" />
</StackPanel> </StackPanel>
</DockPanel> </DockPanel>
@@ -193,6 +202,11 @@
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" /> Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" />
<Separator /> <Separator />
<MenuItem
x:Name="menuCopyProxyCmdToClipboard"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuCopyProxyCmdToClipboard}" />
<Separator />
<MenuItem <MenuItem
x:Name="menuExit" x:Name="menuExit"
Height="{StaticResource MenuItemHeight}" Height="{StaticResource MenuItemHeight}"

View File

@@ -51,6 +51,8 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SubUpdateCmd, v => v.menuSubUpdate2).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SubUpdateCmd, v => v.menuSubUpdate2).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SubUpdateViaProxyCmd, v => v.menuSubUpdateViaProxy2).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SubUpdateViaProxyCmd, v => v.menuSubUpdateViaProxy2).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CopyProxyCmdToClipboardCmd, v => v.menuCopyProxyCmdToClipboard).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.RunningServerToolTipText, v => v.tbNotify.ToolTipText).DisposeWith(disposables); this.OneWayBind(ViewModel, vm => vm.RunningServerToolTipText, v => v.tbNotify.ToolTipText).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.NotifyLeftClickCmd, v => v.tbNotify.LeftClickCommand).DisposeWith(disposables); this.OneWayBind(ViewModel, vm => vm.NotifyLeftClickCmd, v => v.tbNotify.LeftClickCommand).DisposeWith(disposables);
@@ -96,6 +98,10 @@ namespace v2rayN.Views
Application.Current.MainWindow.Icon = WindowsHandler.Instance.GetAppIcon(_config); Application.Current.MainWindow.Icon = WindowsHandler.Instance.GetAppIcon(_config);
}), DispatcherPriority.Normal); }), DispatcherPriority.Normal);
break; break;
case EViewAction.SetClipboardData:
if (obj is null) return false;
WindowsUtils.SetClipboardData((string)obj);
break;
} }
return await Task.FromResult(true); return await Task.FromResult(true);
} }

View File

@@ -38,7 +38,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
}); });
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark); WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -31,7 +31,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SubEditCmd, v => v.menuSubEdit).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SubEditCmd, v => v.menuSubEdit).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SubShareCmd, v => v.menuSubShare).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SubShareCmd, v => v.menuSubShare).DisposeWith(disposables);
}); });
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark); WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -25,29 +25,20 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock
Grid.Row="0"
Grid.Column="0"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsColorMode}" />
<ToggleButton
x:Name="togDarkMode"
Grid.Row="0"
Grid.Column="1"
Margin="{StaticResource Margin8}" />
<TextBlock <TextBlock
Grid.Row="1" Grid.Row="1"
Grid.Column="0" Grid.Column="0"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsFollowSystemTheme}" /> Text="{x:Static resx:ResUI.TbSettingsTheme}" />
<ToggleButton <ComboBox
x:Name="togFollowSystemTheme" x:Name="cmbCurrentTheme"
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource Margin8}" /> Width="120"
Margin="{StaticResource Margin8}"
Style="{StaticResource DefComboBox}" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
@@ -59,7 +50,7 @@
x:Name="cmbSwatches" x:Name="cmbSwatches"
Grid.Row="2" Grid.Row="2"
Grid.Column="1" Grid.Column="1"
Width="100" Width="120"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
DisplayMemberPath="Name" DisplayMemberPath="Name"
Style="{StaticResource DefComboBox}" /> Style="{StaticResource DefComboBox}" />
@@ -74,7 +65,7 @@
x:Name="cmbCurrentFontSize" x:Name="cmbCurrentFontSize"
Grid.Row="3" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
Width="100" Width="120"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
Style="{StaticResource DefComboBox}" /> Style="{StaticResource DefComboBox}" />
@@ -88,7 +79,7 @@
x:Name="cmbCurrentLanguage" x:Name="cmbCurrentLanguage"
Grid.Row="4" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
Width="100" Width="120"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
Style="{StaticResource DefComboBox}" /> Style="{StaticResource DefComboBox}" />
</Grid> </Grid>

View File

@@ -13,6 +13,11 @@ namespace v2rayN.Views
{ {
InitializeComponent(); InitializeComponent();
ViewModel = new ThemeSettingViewModel(); ViewModel = new ThemeSettingViewModel();
foreach (ETheme it in Enum.GetValues(typeof(ETheme)))
{
if ((int)it > 2) continue;
cmbCurrentTheme.Items.Add(it.ToString());
}
for (int i = Global.MinFontSize; i <= Global.MinFontSize + 10; i++) for (int i = Global.MinFontSize; i <= Global.MinFontSize + 10; i++)
{ {
@@ -26,8 +31,7 @@ namespace v2rayN.Views
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.ColorModeDark, v => v.togDarkMode.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CurrentTheme, v => v.cmbCurrentTheme.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.FollowSystemTheme, v => v.togFollowSystemTheme.IsChecked).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.Swatches, v => v.cmbSwatches.ItemsSource).DisposeWith(disposables); this.OneWayBind(ViewModel, vm => vm.Swatches, v => v.cmbSwatches.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSwatch, v => v.cmbSwatches.SelectedItem).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSwatch, v => v.cmbSwatches.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CurrentFontSize, v => v.cmbCurrentFontSize.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CurrentFontSize, v => v.cmbCurrentFontSize.Text).DisposeWith(disposables);

View File

@@ -9,12 +9,12 @@
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>Resources\v2rayN.ico</ApplicationIcon> <ApplicationIcon>Resources\v2rayN.ico</ApplicationIcon>
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright> <Copyright>Copyright © 2017-2025 (GPLv3)</Copyright>
<SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion> <SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MaterialDesignThemes" Version="5.2.0" /> <PackageReference Include="MaterialDesignThemes" Version="5.2.1" />
<PackageReference Include="H.NotifyIcon.Wpf" Version="2.2.0" /> <PackageReference Include="H.NotifyIcon.Wpf" Version="2.2.0" />
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" /> <PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
<PackageReference Include="ReactiveUI.WPF" Version="20.1.63" /> <PackageReference Include="ReactiveUI.WPF" Version="20.1.63" />