Code clean

This commit is contained in:
2dust 2025-01-30 17:10:05 +08:00
parent 253219dd16
commit 45264005a4
103 changed files with 639 additions and 498 deletions

View file

@ -1,4 +1,4 @@
using System.Diagnostics; using System.Diagnostics;
using System.IO.Compression; using System.IO.Compression;
using System.Text; using System.Text;
@ -59,7 +59,8 @@ namespace AmazTool
Console.WriteLine(entry.FullName); Console.WriteLine(entry.FullName);
var lst = entry.FullName.Split(splitKey); var lst = entry.FullName.Split(splitKey);
if (lst.Length == 1) continue; if (lst.Length == 1)
continue;
var fullName = string.Join(splitKey, lst[1..lst.Length]); var fullName = string.Join(splitKey, lst[1..lst.Length]);
if (string.Equals(Utils.GetExePath(), Utils.GetPath(fullName), StringComparison.OrdinalIgnoreCase)) if (string.Equals(Utils.GetExePath(), Utils.GetPath(fullName), StringComparison.OrdinalIgnoreCase))

View file

@ -1,5 +1,5 @@
using Downloader;
using System.Net; using System.Net;
using Downloader;
namespace ServiceLib.Common namespace ServiceLib.Common
{ {

View file

@ -38,13 +38,15 @@ namespace ServiceLib.Common
public async Task<string?> GetAsync(string url) public async Task<string?> GetAsync(string url)
{ {
if (Utils.IsNullOrEmpty(url)) return null; if (Utils.IsNullOrEmpty(url))
return null;
return await httpClient.GetStringAsync(url); return await httpClient.GetStringAsync(url);
} }
public async Task<string?> GetAsync(HttpClient client, string url, CancellationToken token = default) public async Task<string?> GetAsync(HttpClient client, string url, CancellationToken token = default)
{ {
if (Utils.IsNullOrEmpty(url)) return null; if (Utils.IsNullOrEmpty(url))
return null;
return await client.GetStringAsync(url, token); return await client.GetStringAsync(url, token);
} }
@ -75,11 +77,13 @@ namespace ServiceLib.Common
{ {
ArgumentNullException.ThrowIfNull(url); ArgumentNullException.ThrowIfNull(url);
ArgumentNullException.ThrowIfNull(fileName); ArgumentNullException.ThrowIfNull(fileName);
if (File.Exists(fileName)) File.Delete(fileName); if (File.Exists(fileName))
File.Delete(fileName);
using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token); using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
if (!response.IsSuccessStatusCode) throw new Exception(response.StatusCode.ToString()); if (!response.IsSuccessStatusCode)
throw new Exception(response.StatusCode.ToString());
var total = response.Content.Headers.ContentLength ?? -1L; var total = response.Content.Headers.ContentLength ?? -1L;
var canReportProgress = total != -1 && progress != null; var canReportProgress = total != -1 && progress != null;
@ -97,7 +101,8 @@ namespace ServiceLib.Common
var read = await stream.ReadAsync(buffer, token); var read = await stream.ReadAsync(buffer, token);
totalRead += read; totalRead += read;
if (read == 0) break; if (read == 0)
break;
await file.WriteAsync(buffer.AsMemory(0, read), token); await file.WriteAsync(buffer.AsMemory(0, read), token);
if (canReportProgress) if (canReportProgress)

View file

@ -1,4 +1,4 @@
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace ServiceLib.Common namespace ServiceLib.Common
@ -75,7 +75,8 @@ namespace ServiceLib.Common
private void Dispose(bool disposing) private void Dispose(bool disposing)
{ {
if (disposed) return; if (disposed)
return;
disposed = true; disposed = true;
if (disposing) if (disposing)

View file

@ -1,4 +1,4 @@
using NLog; using NLog;
using NLog.Config; using NLog.Config;
using NLog.Targets; using NLog.Targets;
@ -27,14 +27,16 @@ namespace ServiceLib.Common
public static void SaveLog(string strContent) public static void SaveLog(string strContent)
{ {
if (!LogManager.IsLoggingEnabled()) return; if (!LogManager.IsLoggingEnabled())
return;
LogManager.GetLogger("Log1").Info(strContent); LogManager.GetLogger("Log1").Info(strContent);
} }
public static void SaveLog(string strTitle, Exception ex) public static void SaveLog(string strTitle, Exception ex)
{ {
if (!LogManager.IsLoggingEnabled()) return; if (!LogManager.IsLoggingEnabled())
return;
var logger = LogManager.GetLogger("Log2"); var logger = LogManager.GetLogger("Log2");
logger.Debug($"{strTitle},{ex.Message}"); logger.Debug($"{strTitle},{ex.Message}");

View file

@ -19,8 +19,10 @@ public static class ProcUtils
} }
try try
{ {
if (fileName.Contains(' ')) fileName = fileName.AppendQuotes(); if (fileName.Contains(' '))
if (arguments.Contains(' ')) arguments = arguments.AppendQuotes(); fileName = fileName.AppendQuotes();
if (arguments.Contains(' '))
arguments = arguments.AppendQuotes();
Process process = new() Process process = new()
{ {
@ -83,10 +85,18 @@ public static class ProcUtils
GetProcessKeyInfo(proc, review, out var procId, out var fileName, out var processName); GetProcessKeyInfo(proc, review, out var procId, out var fileName, out var processName);
try { proc?.Kill(true); } catch (Exception ex) { Logging.SaveLog(_tag, ex); } try
try { proc?.Kill(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); } { proc?.Kill(true); }
try { proc?.Close(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try { proc?.Dispose(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); } try
{ proc?.Kill(); }
catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try
{ proc?.Close(); }
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); await ProcessKillByKeyInfo(review, procId, fileName, processName);
@ -97,7 +107,8 @@ public static class ProcUtils
procId = null; procId = null;
fileName = null; fileName = null;
processName = null; processName = null;
if (!review) return; if (!review)
return;
try try
{ {
procId = proc?.Id; procId = proc?.Id;

View file

@ -1,5 +1,5 @@
using SQLite;
using System.Collections; using System.Collections;
using SQLite;
namespace ServiceLib.Common namespace ServiceLib.Common
{ {

View file

@ -1,4 +1,4 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
namespace ServiceLib.Common namespace ServiceLib.Common
{ {
@ -21,7 +21,8 @@ namespace ServiceLib.Common
public static bool BeginWithAny(this string s, IEnumerable<char> chars) public static bool BeginWithAny(this string s, IEnumerable<char> chars)
{ {
if (s.IsNullOrEmpty()) return false; if (s.IsNullOrEmpty())
return false;
return chars.Contains(s.First()); return chars.Contains(s.First());
} }
@ -34,7 +35,8 @@ namespace ServiceLib.Common
{ {
while (reader.ReadLine() is { } line) while (reader.ReadLine() is { } line)
{ {
if (line.IsWhiteSpace()) continue; if (line.IsWhiteSpace())
continue;
yield return line; yield return line;
} }
} }

View file

@ -1,5 +1,3 @@
using CliWrap;
using CliWrap.Buffered;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Diagnostics; using System.Diagnostics;
using System.Net; using System.Net;
@ -10,6 +8,8 @@ using System.Runtime.InteropServices;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Security.Principal; using System.Security.Principal;
using System.Text; using System.Text;
using CliWrap;
using CliWrap.Buffered;
namespace ServiceLib.Common namespace ServiceLib.Common
{ {
@ -176,7 +176,8 @@ namespace ServiceLib.Common
{ {
try try
{ {
if (plainText.IsNullOrEmpty()) return ""; if (plainText.IsNullOrEmpty())
return "";
plainText = plainText.Trim() plainText = plainText.Trim()
.Replace(Environment.NewLine, "") .Replace(Environment.NewLine, "")
.Replace("\n", "") .Replace("\n", "")
@ -372,7 +373,8 @@ namespace ServiceLib.Common
public static bool IsBase64String(string? plainText) public static bool IsBase64String(string? plainText)
{ {
if (plainText.IsNullOrEmpty()) return false; if (plainText.IsNullOrEmpty())
return false;
var buffer = new Span<byte>(new byte[plainText.Length]); var buffer = new Span<byte>(new byte[plainText.Length]);
return Convert.TryFromBase64String(plainText, buffer, out var _); return Convert.TryFromBase64String(plainText, buffer, out var _);
} }
@ -462,9 +464,12 @@ namespace ServiceLib.Common
if (IPAddress.TryParse(ip, out var address)) if (IPAddress.TryParse(ip, out var address))
{ {
var ipBytes = address.GetAddressBytes(); var ipBytes = address.GetAddressBytes();
if (ipBytes[0] == 10) return true; if (ipBytes[0] == 10)
if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31) return true; return true;
if (ipBytes[0] == 192 && ipBytes[1] == 168) return true; if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31)
return true;
if (ipBytes[0] == 192 && ipBytes[1] == 168)
return true;
} }
return false; return false;
@ -604,9 +609,11 @@ namespace ServiceLib.Common
foreach (var host in hostsList) foreach (var host in hostsList)
{ {
if (host.StartsWith("#")) continue; if (host.StartsWith("#"))
continue;
var hostItem = host.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); var hostItem = host.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (hostItem.Length != 2) continue; if (hostItem.Length != 2)
continue;
systemHosts.Add(hostItem.Last(), hostItem.First()); systemHosts.Add(hostItem.Last(), hostItem.First());
} }
} }
@ -875,8 +882,10 @@ namespace ServiceLib.Common
public static async Task<string?> SetLinuxChmod(string? fileName) public static async Task<string?> SetLinuxChmod(string? fileName)
{ {
if (fileName.IsNullOrEmpty()) return null; if (fileName.IsNullOrEmpty())
if (fileName.Contains(' ')) fileName = fileName.AppendQuotes(); return null;
if (fileName.Contains(' '))
fileName = fileName.AppendQuotes();
//File.SetUnixFileMode(fileName, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute); //File.SetUnixFileMode(fileName, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);
var arg = new List<string>() { "-c", $"chmod +x {fileName}" }; var arg = new List<string>() { "-c", $"chmod +x {fileName}" };
return await GetCliWrapOutput("/bin/bash", arg); return await GetCliWrapOutput("/bin/bash", arg);

View file

@ -1,4 +1,3 @@
using System.Diagnostics;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using Microsoft.Win32; using Microsoft.Win32;
@ -56,21 +55,20 @@ namespace ServiceLib.Common
public static async Task RemoveTunDevice() public static async Task RemoveTunDevice()
{ {
try try
{ {
var sum = MD5.HashData(Encoding.UTF8.GetBytes("wintunsingbox_tun")); var sum = MD5.HashData(Encoding.UTF8.GetBytes("wintunsingbox_tun"));
var guid = new Guid(sum); var guid = new Guid(sum);
var pnpUtilPath = @"C:\Windows\System32\pnputil.exe"; var pnpUtilPath = @"C:\Windows\System32\pnputil.exe";
var arg = $$""" /remove-device "SWD\Wintun\{{{guid}}}" """; var arg = $$""" /remove-device "SWD\Wintun\{{{guid}}}" """;
// Try to remove the device // Try to remove the device
await Utils.GetCliWrapOutput(pnpUtilPath, arg); await Utils.GetCliWrapOutput(pnpUtilPath, arg);
}
} catch (Exception ex)
catch (Exception ex) {
{ Logging.SaveLog(_tag, ex);
Logging.SaveLog(_tag, ex); }
} }
} }
}
} }

View file

@ -1,4 +1,3 @@
using System.Diagnostics;
using System.Security.Principal; using System.Security.Principal;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -30,12 +29,12 @@ namespace ServiceLib.Handler
} }
else if (Utils.IsOSX()) else if (Utils.IsOSX())
{ {
await ClearTaskOSX(); await ClearTaskOSX();
if (config.GuiItem.AutoRun) if (config.GuiItem.AutoRun)
{ {
await SetTaskOSX(); await SetTaskOSX();
} }
} }
return true; return true;
@ -172,46 +171,46 @@ namespace ServiceLib.Handler
private static async Task ClearTaskOSX() private static async Task ClearTaskOSX()
{ {
try try
{ {
var launchAgentPath = GetLaunchAgentPathMacOS(); var launchAgentPath = GetLaunchAgentPathMacOS();
if (File.Exists(launchAgentPath)) if (File.Exists(launchAgentPath))
{ {
var args = new[] { "-c", $"launchctl unload -w \"{launchAgentPath}\"" }; var args = new[] { "-c", $"launchctl unload -w \"{launchAgentPath}\"" };
await Utils.GetCliWrapOutput("/bin/bash", args); await Utils.GetCliWrapOutput("/bin/bash", args);
File.Delete(launchAgentPath); File.Delete(launchAgentPath);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
} }
private static async Task SetTaskOSX() private static async Task SetTaskOSX()
{ {
try try
{ {
var plistContent = GenerateLaunchAgentPlist(); var plistContent = GenerateLaunchAgentPlist();
var launchAgentPath = GetLaunchAgentPathMacOS(); var launchAgentPath = GetLaunchAgentPathMacOS();
await File.WriteAllTextAsync(launchAgentPath, plistContent); await File.WriteAllTextAsync(launchAgentPath, plistContent);
var args = new[] { "-c", $"launchctl load -w \"{launchAgentPath}\"" }; var args = new[] { "-c", $"launchctl load -w \"{launchAgentPath}\"" };
await Utils.GetCliWrapOutput("/bin/bash", args); await Utils.GetCliWrapOutput("/bin/bash", args);
} }
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog(_tag, ex); Logging.SaveLog(_tag, ex);
} }
} }
private static string GetLaunchAgentPathMacOS() private static string GetLaunchAgentPathMacOS()
{ {
var homePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); var homePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var launchAgentPath = Path.Combine(homePath, "Library", "LaunchAgents", $"{Global.AppName}-LaunchAgent.plist"); var launchAgentPath = Path.Combine(homePath, "Library", "LaunchAgents", $"{Global.AppName}-LaunchAgent.plist");
Directory.CreateDirectory(Path.GetDirectoryName(launchAgentPath)); Directory.CreateDirectory(Path.GetDirectoryName(launchAgentPath));
return launchAgentPath; return launchAgentPath;
} }
private static string GenerateLaunchAgentPlist() private static string GenerateLaunchAgentPlist()

View file

@ -873,7 +873,8 @@ namespace ServiceLib.Handler
List<ProfileItem> lstKeep = new(); List<ProfileItem> lstKeep = new();
List<ProfileItem> lstRemove = new(); List<ProfileItem> lstRemove = new();
if (!config.GuiItem.KeepOlderDedupl) lstProfile.Reverse(); if (!config.GuiItem.KeepOlderDedupl)
lstProfile.Reverse();
foreach (ProfileItem item in lstProfile) foreach (ProfileItem item in lstProfile)
{ {
@ -1363,7 +1364,8 @@ namespace ServiceLib.Handler
}; };
var uri = Utils.TryUri(url); var uri = Utils.TryUri(url);
if (uri == null) return -1; if (uri == null)
return -1;
//Do not allow http protocol //Do not allow http protocol
if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost)) if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost))
{ {

View file

@ -84,13 +84,13 @@ namespace ServiceLib.Handler
await CoreStop(); await CoreStop();
await Task.Delay(100); await Task.Delay(100);
if (Utils.IsWindows() && _config.TunModeItem.EnableTun) if (Utils.IsWindows() && _config.TunModeItem.EnableTun)
{ {
await Task.Delay(100); await Task.Delay(100);
await WindowsUtils.RemoveTunDevice(); await WindowsUtils.RemoveTunDevice();
} }
await CoreStart(node); await CoreStart(node);
await CoreStartPreService(node); await CoreStartPreService(node);
if (_process != null) if (_process != null)
{ {
@ -246,12 +246,14 @@ namespace ServiceLib.Handler
{ {
proc.OutputDataReceived += (sender, e) => proc.OutputDataReceived += (sender, e) =>
{ {
if (Utils.IsNullOrEmpty(e.Data)) return; if (Utils.IsNullOrEmpty(e.Data))
return;
UpdateFunc(false, e.Data + Environment.NewLine); UpdateFunc(false, e.Data + Environment.NewLine);
}; };
proc.ErrorDataReceived += (sender, e) => proc.ErrorDataReceived += (sender, e) =>
{ {
if (Utils.IsNullOrEmpty(e.Data)) return; if (Utils.IsNullOrEmpty(e.Data))
return;
UpdateFunc(false, e.Data + Environment.NewLine); UpdateFunc(false, e.Data + Environment.NewLine);
}; };
} }
@ -265,7 +267,8 @@ namespace ServiceLib.Handler
await Task.Delay(10); await Task.Delay(10);
await proc.StandardInput.WriteLineAsync(pwd); await proc.StandardInput.WriteLineAsync(pwd);
} }
if (isNeedSudo) _linuxSudoPid = proc.Id; if (isNeedSudo)
_linuxSudoPid = proc.Id;
if (displayLog) if (displayLog)
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Specialized; using System.Collections.Specialized;
namespace ServiceLib.Handler.Fmt namespace ServiceLib.Handler.Fmt
{ {
@ -214,7 +214,8 @@ namespace ServiceLib.Handler.Fmt
{ {
foreach (var item in s) foreach (var item in s)
{ {
if (str.Contains(item, StringComparison.OrdinalIgnoreCase)) return true; if (str.Contains(item, StringComparison.OrdinalIgnoreCase))
return true;
} }
return false; return false;
} }

View file

@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt namespace ServiceLib.Handler.Fmt
{ {
public class Hysteria2Fmt : BaseFmt public class Hysteria2Fmt : BaseFmt
{ {
@ -11,7 +11,8 @@
}; };
var url = Utils.TryUri(str); var url = Utils.TryUri(str);
if (url == null) return null; if (url == null)
return null;
item.Address = url.IdnHost; item.Address = url.IdnHost;
item.Port = url.Port; item.Port = url.Port;
@ -28,7 +29,8 @@
public static string? ToUri(ProfileItem? item) public static string? ToUri(ProfileItem? item)
{ {
if (item == null) return null; if (item == null)
return null;
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;

View file

@ -1,4 +1,4 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace ServiceLib.Handler.Fmt namespace ServiceLib.Handler.Fmt
{ {
@ -26,7 +26,8 @@ namespace ServiceLib.Handler.Fmt
public static string? ToUri(ProfileItem? item) public static string? ToUri(ProfileItem? item)
{ {
if (item == null) return null; if (item == null)
return null;
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;
@ -82,7 +83,8 @@ namespace ServiceLib.Handler.Fmt
private static ProfileItem? ResolveSip002(string result) private static ProfileItem? ResolveSip002(string result)
{ {
var parsedUrl = Utils.TryUri(result); var parsedUrl = Utils.TryUri(result);
if (parsedUrl == null) return null; if (parsedUrl == null)
return null;
ProfileItem item = new() ProfileItem item = new()
{ {

View file

@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt namespace ServiceLib.Handler.Fmt
{ {
public class SocksFmt : BaseFmt public class SocksFmt : BaseFmt
{ {
@ -23,7 +23,8 @@
public static string? ToUri(ProfileItem? item) public static string? ToUri(ProfileItem? item)
{ {
if (item == null) return null; if (item == null)
return null;
var url = string.Empty; var url = string.Empty;
var remark = string.Empty; var remark = string.Empty;
@ -86,7 +87,8 @@
private static ProfileItem? ResolveSocksNew(string result) private static ProfileItem? ResolveSocksNew(string result)
{ {
var parsedUrl = Utils.TryUri(result); var parsedUrl = Utils.TryUri(result);
if (parsedUrl == null) return null; if (parsedUrl == null)
return null;
ProfileItem item = new() ProfileItem item = new()
{ {

View file

@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt namespace ServiceLib.Handler.Fmt
{ {
public class TrojanFmt : BaseFmt public class TrojanFmt : BaseFmt
{ {
@ -12,7 +12,8 @@
}; };
var url = Utils.TryUri(str); var url = Utils.TryUri(str);
if (url == null) return null; if (url == null)
return null;
item.Address = url.IdnHost; item.Address = url.IdnHost;
item.Port = url.Port; item.Port = url.Port;
@ -27,7 +28,8 @@
public static string? ToUri(ProfileItem? item) public static string? ToUri(ProfileItem? item)
{ {
if (item == null) return null; if (item == null)
return null;
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;

View file

@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt namespace ServiceLib.Handler.Fmt
{ {
public class TuicFmt : BaseFmt public class TuicFmt : BaseFmt
{ {
@ -12,7 +12,8 @@
}; };
var url = Utils.TryUri(str); var url = Utils.TryUri(str);
if (url == null) return null; if (url == null)
return null;
item.Address = url.IdnHost; item.Address = url.IdnHost;
item.Port = url.Port; item.Port = url.Port;
@ -34,7 +35,8 @@
public static string? ToUri(ProfileItem? item) public static string? ToUri(ProfileItem? item)
{ {
if (item == null) return null; if (item == null)
return null;
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;

View file

@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt namespace ServiceLib.Handler.Fmt
{ {
public class VLESSFmt : BaseFmt public class VLESSFmt : BaseFmt
{ {
@ -13,7 +13,8 @@
}; };
var url = Utils.TryUri(str); var url = Utils.TryUri(str);
if (url == null) return null; if (url == null)
return null;
item.Address = url.IdnHost; item.Address = url.IdnHost;
item.Port = url.Port; item.Port = url.Port;
@ -30,7 +31,8 @@
public static string? ToUri(ProfileItem? item) public static string? ToUri(ProfileItem? item)
{ {
if (item == null) return null; if (item == null)
return null;
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;

View file

@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt namespace ServiceLib.Handler.Fmt
{ {
public class VmessFmt : BaseFmt public class VmessFmt : BaseFmt
{ {
@ -19,7 +19,8 @@
public static string? ToUri(ProfileItem? item) public static string? ToUri(ProfileItem? item)
{ {
if (item == null) return null; if (item == null)
return null;
string url = string.Empty; string url = string.Empty;
VmessQRCode vmessQRCode = new() VmessQRCode vmessQRCode = new()
@ -106,7 +107,8 @@
}; };
var url = Utils.TryUri(str); var url = Utils.TryUri(str);
if (url == null) return null; if (url == null)
return null;
item.Address = url.IdnHost; item.Address = url.IdnHost;
item.Port = url.Port; item.Port = url.Port;

View file

@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt namespace ServiceLib.Handler.Fmt
{ {
public class WireguardFmt : BaseFmt public class WireguardFmt : BaseFmt
{ {
@ -12,7 +12,8 @@
}; };
var url = Utils.TryUri(str); var url = Utils.TryUri(str);
if (url == null) return null; if (url == null)
return null;
item.Address = url.IdnHost; item.Address = url.IdnHost;
item.Port = url.Port; item.Port = url.Port;
@ -31,7 +32,8 @@
public static string? ToUri(ProfileItem? item) public static string? ToUri(ProfileItem? item)
{ {
if (item == null) return null; if (item == null)
return null;
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;

View file

@ -1,4 +1,4 @@
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
namespace ServiceLib.Handler namespace ServiceLib.Handler
@ -89,7 +89,8 @@ namespace ServiceLib.Handler
public static void Stop() public static void Stop()
{ {
if (_tcpListener == null) return; if (_tcpListener == null)
return;
try try
{ {
_isRunning = false; _isRunning = false;

View file

@ -176,7 +176,8 @@ namespace ServiceLib.Handler.SysProxy
} }
// FREE the data ASAP // FREE the data ASAP
if (list.szConnection != nint.Zero) Marshal.FreeHGlobal(list.szConnection); // release mem 3 if (list.szConnection != nint.Zero)
Marshal.FreeHGlobal(list.szConnection); // release mem 3
if (optionCount > 1) if (optionCount > 1)
{ {
Marshal.FreeHGlobal(options[1].m_Value.m_StringPtr); // release mem 1 Marshal.FreeHGlobal(options[1].m_Value.m_StringPtr); // release mem 1

View file

@ -1,4 +1,4 @@
using System.Net; using System.Net;
using WebDav; using WebDav;
namespace ServiceLib.Handler namespace ServiceLib.Handler
@ -61,7 +61,8 @@ namespace ServiceLib.Handler
private async Task<bool> TryCreateDir() private async Task<bool> TryCreateDir()
{ {
if (_client is null) return false; if (_client is null)
return false;
try try
{ {
var result2 = await _client.Mkcol(_webDir); var result2 = await _client.Mkcol(_webDir);

View file

@ -1048,7 +1048,8 @@ namespace ServiceLib.Services.CoreConfig
var countDomain = 0; var countDomain = 0;
foreach (var it in item.Domain) foreach (var it in item.Domain)
{ {
if (ParseV2Domain(it, rule1)) countDomain++; if (ParseV2Domain(it, rule1))
countDomain++;
} }
if (countDomain > 0) if (countDomain > 0)
{ {
@ -1062,7 +1063,8 @@ namespace ServiceLib.Services.CoreConfig
var countIp = 0; var countIp = 0;
foreach (var it in item.Ip) foreach (var it in item.Ip)
{ {
if (ParseV2Address(it, rule2)) countIp++; if (ParseV2Address(it, rule2))
countIp++;
} }
if (countIp > 0) if (countIp > 0)
{ {
@ -1148,12 +1150,14 @@ namespace ServiceLib.Services.CoreConfig
} }
else if (address.StartsWith("geoip:")) else if (address.StartsWith("geoip:"))
{ {
if (rule.geoip is null) { rule.geoip = new(); } if (rule.geoip is null)
{ rule.geoip = new(); }
rule.geoip?.Add(address.Substring(6)); rule.geoip?.Add(address.Substring(6));
} }
else else
{ {
if (rule.ip_cidr is null) { rule.ip_cidr = new(); } if (rule.ip_cidr is null)
{ rule.ip_cidr = new(); }
rule.ip_cidr?.Add(address); rule.ip_cidr?.Add(address);
} }
return true; return true;
@ -1271,7 +1275,8 @@ namespace ServiceLib.Services.CoreConfig
{ {
static void AddRuleSets(List<string> ruleSets, List<string>? rule_set) static void AddRuleSets(List<string> ruleSets, List<string>? rule_set)
{ {
if (rule_set != null) ruleSets.AddRange(rule_set); if (rule_set != null)
ruleSets.AddRange(rule_set);
} }
var geosite = "geosite"; var geosite = "geosite";
var geoip = "geoip"; var geoip = "geoip";
@ -1339,7 +1344,8 @@ namespace ServiceLib.Services.CoreConfig
singboxConfig.route.rule_set = []; singboxConfig.route.rule_set = [];
foreach (var item in new HashSet<string>(ruleSets)) foreach (var item in new HashSet<string>(ruleSets))
{ {
if (Utils.IsNullOrEmpty(item)) { continue; } if (Utils.IsNullOrEmpty(item))
{ continue; }
var customRuleset = customRulesets.FirstOrDefault(t => t.tag != null && t.tag.Equals(item)); var customRuleset = customRulesets.FirstOrDefault(t => t.tag != null && t.tag.Equals(item));
if (customRuleset is null) if (customRuleset is null)
{ {

View file

@ -1,7 +1,7 @@
using ReactiveUI;
using System.Diagnostics; using System.Diagnostics;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using ReactiveUI;
namespace ServiceLib.Services namespace ServiceLib.Services
{ {
@ -119,7 +119,8 @@ namespace ServiceLib.Services
private void ExitLoop(string x) private void ExitLoop(string x)
{ {
if (_exitLoop) return; if (_exitLoop)
return;
_exitLoop = true; _exitLoop = true;
UpdateFunc("", ResUI.SpeedtestingStop); UpdateFunc("", ResUI.SpeedtestingStop);
} }
@ -261,7 +262,8 @@ namespace ServiceLib.Services
UpdateFunc(it.IndexId, "", ResUI.Speedtesting); UpdateFunc(it.IndexId, "", ResUI.Speedtesting);
var item = await AppHandler.Instance.GetProfileItem(it.IndexId); var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
if (item is null) continue; if (item is null)
continue;
var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}"); var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}");
@ -323,7 +325,8 @@ namespace ServiceLib.Services
UpdateFunc(it.IndexId, "", ResUI.Speedtesting); UpdateFunc(it.IndexId, "", ResUI.Speedtesting);
var item = await AppHandler.Instance.GetProfileItem(it.IndexId); var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
if (item is null) continue; if (item is null)
continue;
var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}"); var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}");
_ = downloadHandle.DownloadDataAsync(url, webProxy, timeout, (success, msg) => _ = downloadHandle.DownloadDataAsync(url, webProxy, timeout, (success, msg) =>

View file

@ -1,4 +1,4 @@
using System.Net.WebSockets; using System.Net.WebSockets;
using System.Text; using System.Text;
namespace ServiceLib.Services.Statistics namespace ServiceLib.Services.Statistics
@ -109,7 +109,8 @@ namespace ServiceLib.Services.Statistics
private void ParseOutput(string source, out ulong up, out ulong down) private void ParseOutput(string source, out ulong up, out ulong down)
{ {
up = 0; down = 0; up = 0;
down = 0;
try try
{ {
var trafficItem = JsonUtils.Deserialize<TrafficItem>(source); var trafficItem = JsonUtils.Deserialize<TrafficItem>(source);

View file

@ -1,4 +1,4 @@
namespace ServiceLib.Services.Statistics namespace ServiceLib.Services.Statistics
{ {
public class StatisticsXrayService public class StatisticsXrayService
{ {
@ -63,7 +63,8 @@
foreach (string key in source.stats.outbound.Keys) foreach (string key in source.stats.outbound.Keys)
{ {
var value = source.stats.outbound[key]; var value = source.stats.outbound[key];
if (value == null) continue; if (value == null)
continue;
var state = JsonUtils.Deserialize<V2rayMetricsVarsLink>(value.ToString()); var state = JsonUtils.Deserialize<V2rayMetricsVarsLink>(value.ToString());
if (key.StartsWith(Global.ProxyTag)) if (key.StartsWith(Global.ProxyTag))

View file

@ -1,6 +1,6 @@
using System.Reactive;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using System.Reactive;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {

View file

@ -1,6 +1,6 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive; using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {

View file

@ -1,7 +1,7 @@
using ReactiveUI; using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {

View file

@ -1,10 +1,10 @@
using DynamicData; using System.Reactive;
using System.Runtime.InteropServices;
using DynamicData;
using DynamicData.Binding; using DynamicData.Binding;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive;
using System.Runtime.InteropServices;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {
@ -83,7 +83,8 @@ namespace ServiceLib.ViewModels
for (var k = _checkUpdateModel.Count - 1; k >= 0; k--) for (var k = _checkUpdateModel.Count - 1; k >= 0; k--)
{ {
var item = _checkUpdateModel[k]; var item = _checkUpdateModel[k];
if (item.IsSelected != true) continue; if (item.IsSelected != true)
continue;
UpdateView(item.CoreType, "..."); UpdateView(item.CoreType, "...");
if (item.CoreType == _geo) if (item.CoreType == _geo)
@ -297,7 +298,8 @@ namespace ServiceLib.ViewModels
public void UpdateViewResult(CheckUpdateModel model) public void UpdateViewResult(CheckUpdateModel model)
{ {
var found = _checkUpdateModel.FirstOrDefault(t => t.CoreType == model.CoreType); var found = _checkUpdateModel.FirstOrDefault(t => t.CoreType == model.CoreType);
if (found == null) return; if (found == null)
return;
var itemCopy = JsonUtils.DeepCopy(found); var itemCopy = JsonUtils.DeepCopy(found);
itemCopy.Remarks = model.Remarks; itemCopy.Remarks = model.Remarks;
_checkUpdateModel.Replace(found, itemCopy); _checkUpdateModel.Replace(found, itemCopy);

View file

@ -1,9 +1,9 @@
using System.Reactive;
using System.Reactive.Linq;
using DynamicData; using DynamicData;
using DynamicData.Binding; using DynamicData.Binding;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using System.Reactive;
using System.Reactive.Linq;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {
@ -115,7 +115,8 @@ namespace ServiceLib.ViewModels
lstModel.Add(model); lstModel.Add(model);
} }
if (lstModel.Count <= 0) { return; } if (lstModel.Count <= 0)
{ return; }
_connectionItems.AddRange(lstModel); _connectionItems.AddRange(lstModel);
} }

View file

@ -1,9 +1,9 @@
using System.Reactive;
using System.Reactive.Linq;
using DynamicData; using DynamicData;
using DynamicData.Binding; using DynamicData.Binding;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using System.Reactive;
using System.Reactive.Linq;
using static ServiceLib.Models.ClashProviders; using static ServiceLib.Models.ClashProviders;
using static ServiceLib.Models.ClashProxies; using static ServiceLib.Models.ClashProxies;

View file

@ -1,6 +1,6 @@
using System.Reactive;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using System.Reactive;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {

View file

@ -1,7 +1,7 @@
using System.Reactive;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {
@ -570,7 +570,8 @@ namespace ServiceLib.ViewModels
{ {
Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload(); Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload();
} }
else { TabMainSelectedIndex = 0; } else
{ TabMainSelectedIndex = 0; }
} }
private async Task LoadCore() private async Task LoadCore()

View file

@ -1,7 +1,7 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {

View file

@ -1,6 +1,6 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive; using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {

View file

@ -1,11 +1,11 @@
using System.Reactive;
using System.Reactive.Linq;
using System.Text;
using DynamicData; using DynamicData;
using DynamicData.Binding; using DynamicData.Binding;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive;
using System.Reactive.Linq;
using System.Text;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {

View file

@ -1,6 +1,6 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive; using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {

View file

@ -1,9 +1,9 @@
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive; using System.Reactive;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {

View file

@ -1,7 +1,7 @@
using DynamicData.Binding; using System.Reactive;
using DynamicData.Binding;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using System.Reactive;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {

View file

@ -1,9 +1,9 @@
using DynamicData.Binding; using System.Reactive;
using System.Text;
using DynamicData.Binding;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive;
using System.Text;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {
@ -225,19 +225,22 @@ namespace ServiceLib.ViewModels
private async Task AddServerViaClipboard() private async Task AddServerViaClipboard()
{ {
var service = Locator.Current.GetService<MainWindowViewModel>(); var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) await service.AddServerViaClipboardAsync(null); if (service != null)
await service.AddServerViaClipboardAsync(null);
} }
private async Task AddServerViaScan() private async Task AddServerViaScan()
{ {
var service = Locator.Current.GetService<MainWindowViewModel>(); var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) await service.AddServerViaScanAsync(); if (service != null)
await service.AddServerViaScanAsync();
} }
private async Task UpdateSubscriptionProcess(bool blProxy) private async Task UpdateSubscriptionProcess(bool blProxy)
{ {
var service = Locator.Current.GetService<MainWindowViewModel>(); var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) await service.UpdateSubscriptionProcess("", blProxy); if (service != null)
await service.UpdateSubscriptionProcess("", blProxy);
} }
public async Task RefreshServersBiz() public async Task RefreshServersBiz()

View file

@ -1,6 +1,6 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive; using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {

View file

@ -1,8 +1,8 @@
using DynamicData; using System.Reactive;
using DynamicData;
using DynamicData.Binding; using DynamicData.Binding;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using System.Reactive;
namespace ServiceLib.ViewModels namespace ServiceLib.ViewModels
{ {

View file

@ -64,7 +64,8 @@ public partial class App : Application
{ {
var clipboardData = await AvaUtils.GetClipboardData(desktop.MainWindow); var clipboardData = await AvaUtils.GetClipboardData(desktop.MainWindow);
var service = Locator.Current.GetService<MainWindowViewModel>(); var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) _ = service.AddServerViaClipboardAsync(clipboardData); if (service != null)
_ = service.AddServerViaClipboardAsync(clipboardData);
} }
} }
} }
@ -72,7 +73,8 @@ public partial class App : Application
private async void MenuExit_Click(object? sender, EventArgs e) private async void MenuExit_Click(object? sender, EventArgs e)
{ {
var service = Locator.Current.GetService<MainWindowViewModel>(); var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) await service.MyAppExitAsync(true); if (service != null)
await service.MyAppExitAsync(true);
service?.Shutdown(true); service?.Shutdown(true);
} }
} }

View file

@ -1,4 +1,4 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Media.Imaging; using Avalonia.Media.Imaging;
@ -13,7 +13,8 @@ namespace v2rayN.Desktop.Common
try try
{ {
var clipboard = TopLevel.GetTopLevel(owner)?.Clipboard; var clipboard = TopLevel.GetTopLevel(owner)?.Clipboard;
if (clipboard == null) return null; if (clipboard == null)
return null;
return await clipboard.GetTextAsync(); return await clipboard.GetTextAsync();
} }
catch catch
@ -27,7 +28,8 @@ namespace v2rayN.Desktop.Common
try try
{ {
var clipboard = TopLevel.GetTopLevel(visual)?.Clipboard; var clipboard = TopLevel.GetTopLevel(visual)?.Clipboard;
if (clipboard == null) return; if (clipboard == null)
return;
var dataObject = new DataObject(); var dataObject = new DataObject();
dataObject.Set(DataFormats.Text, strData); dataObject.Set(DataFormats.Text, strData);
await clipboard.SetDataObjectAsync(dataObject); await clipboard.SetDataObjectAsync(dataObject);

View file

@ -1,4 +1,4 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using MsBox.Avalonia; using MsBox.Avalonia;
using MsBox.Avalonia.Enums; using MsBox.Avalonia.Enums;
@ -18,7 +18,8 @@ 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 sp = GetStorageProvider(owner); var sp = GetStorageProvider(owner);
if (sp is null) return null; if (sp is null)
return null;
// Start async operation to open the dialog. // Start async operation to open the dialog.
var files = await sp.OpenFilePickerAsync(new FilePickerOpenOptions var files = await sp.OpenFilePickerAsync(new FilePickerOpenOptions
@ -33,7 +34,8 @@ 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 sp = GetStorageProvider(owner); var sp = GetStorageProvider(owner);
if (sp is null) return null; if (sp is null)
return null;
// Start async operation to open the dialog. // Start async operation to open the dialog.
var files = await sp.SaveFilePickerAsync(new FilePickerSaveOptions var files = await sp.SaveFilePickerAsync(new FilePickerSaveOptions

View file

@ -1,6 +1,6 @@
using Avalonia.Data.Converters;
using Avalonia.Media;
using System.Globalization; using System.Globalization;
using Avalonia.Data.Converters;
using Avalonia.Media;
namespace v2rayN.Desktop.Converters namespace v2rayN.Desktop.Converters
{ {

View file

@ -53,5 +53,5 @@ internal class Program
.WithFontByDefault() .WithFontByDefault()
.LogToTrace() .LogToTrace()
.UseReactiveUI() .UseReactiveUI()
.With(new MacOSPlatformOptions { ShowInDock = false}); .With(new MacOSPlatformOptions { ShowInDock = false });
} }

View file

@ -1,3 +1,4 @@
using System.Reactive.Linq;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Notifications; using Avalonia.Controls.Notifications;
@ -7,7 +8,6 @@ using Avalonia.Styling;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Semi.Avalonia; using Semi.Avalonia;
using System.Reactive.Linq;
namespace v2rayN.Desktop.ViewModels namespace v2rayN.Desktop.ViewModels
{ {
@ -100,7 +100,8 @@ namespace v2rayN.Desktop.ViewModels
private void ModifyFontSize() private void ModifyFontSize()
{ {
double size = CurrentFontSize; double size = CurrentFontSize;
if (size < Global.MinFontSize) return; if (size < Global.MinFontSize)
return;
Style style = new(x => Selectors.Or( Style style = new(x => Selectors.Or(
x.OfType<Button>(), x.OfType<Button>(),

View file

@ -1,7 +1,7 @@
using Avalonia.Interactivity; using System.Reactive.Disposables;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common; using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views

View file

@ -1,8 +1,8 @@
using Avalonia.Controls; using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
{ {

View file

@ -1,8 +1,8 @@
using Avalonia.Controls; using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common; using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views

View file

@ -1,7 +1,7 @@
using Avalonia.ReactiveUI; using System.Reactive.Disposables;
using Avalonia.ReactiveUI;
using Avalonia.Threading; using Avalonia.Threading;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
{ {
@ -27,14 +27,16 @@ namespace v2rayN.Desktop.Views
switch (action) switch (action)
{ {
case EViewAction.DispatcherCheckUpdate: case EViewAction.DispatcherCheckUpdate:
if (obj is null) return false; if (obj is null)
return false;
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
ViewModel?.UpdateViewResult((CheckUpdateModel)obj), ViewModel?.UpdateViewResult((CheckUpdateModel)obj),
DispatcherPriority.Default); DispatcherPriority.Default);
break; break;
case EViewAction.DispatcherCheckUpdateFinished: case EViewAction.DispatcherCheckUpdateFinished:
if (obj is null) return false; if (obj is null)
return false;
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
ViewModel?.UpdateFinishedResult((bool)obj), ViewModel?.UpdateFinishedResult((bool)obj),
DispatcherPriority.Default); DispatcherPriority.Default);

View file

@ -1,9 +1,9 @@
using System.Reactive.Disposables;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using Avalonia.Threading; using Avalonia.Threading;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
{ {
@ -34,7 +34,8 @@ namespace v2rayN.Desktop.Views
switch (action) switch (action)
{ {
case EViewAction.DispatcherRefreshConnections: case EViewAction.DispatcherRefreshConnections:
if (obj is null) return false; if (obj is null)
return false;
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
ViewModel?.RefreshConnections((List<ConnectionItem>?)obj), ViewModel?.RefreshConnections((List<ConnectionItem>?)obj),
DispatcherPriority.Default); DispatcherPriority.Default);

View file

@ -1,10 +1,10 @@
using System.Reactive.Disposables;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using Avalonia.Threading; using Avalonia.Threading;
using DynamicData; using DynamicData;
using ReactiveUI; using ReactiveUI;
using Splat; using Splat;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
{ {
@ -49,7 +49,8 @@ namespace v2rayN.Desktop.Views
break; break;
case EViewAction.DispatcherProxiesDelayTest: case EViewAction.DispatcherProxiesDelayTest:
if (obj is null) return false; if (obj is null)
return false;
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
ViewModel?.ProxiesDelayTestResult((SpeedTestResult)obj), ViewModel?.ProxiesDelayTestResult((SpeedTestResult)obj),
DispatcherPriority.Default); DispatcherPriority.Default);

View file

@ -1,7 +1,7 @@
using Avalonia.Interactivity; using System.Reactive.Disposables;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
{ {

View file

@ -1,4 +1,5 @@
using Avalonia; using System.Reactive.Disposables;
using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Notifications; using Avalonia.Controls.Notifications;
@ -10,7 +11,6 @@ using DialogHostAvalonia;
using MsBox.Avalonia.Enums; using MsBox.Avalonia.Enums;
using ReactiveUI; using ReactiveUI;
using Splat; using Splat;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common; using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
@ -181,11 +181,13 @@ namespace v2rayN.Desktop.Views
switch (action) switch (action)
{ {
case EViewAction.AddServerWindow: case EViewAction.AddServerWindow:
if (obj is null) return false; if (obj is null)
return false;
return await new AddServerWindow((ProfileItem)obj).ShowDialog<bool>(this); return await new AddServerWindow((ProfileItem)obj).ShowDialog<bool>(this);
case EViewAction.AddServer2Window: case EViewAction.AddServer2Window:
if (obj is null) return false; if (obj is null)
return false;
return await new AddServer2Window((ProfileItem)obj).ShowDialog<bool>(this); return await new AddServer2Window((ProfileItem)obj).ShowDialog<bool>(this);
case EViewAction.DNSSettingWindow: case EViewAction.DNSSettingWindow:
@ -210,7 +212,8 @@ namespace v2rayN.Desktop.Views
break; break;
case EViewAction.DispatcherStatistics: case EViewAction.DispatcherStatistics:
if (obj is null) return false; if (obj is null)
return false;
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
ViewModel?.SetStatisticsResult((ServerSpeedItem)obj), ViewModel?.SetStatisticsResult((ServerSpeedItem)obj),
DispatcherPriority.Default); DispatcherPriority.Default);
@ -389,7 +392,7 @@ namespace v2rayN.Desktop.Views
_blCloseByUser = true; _blCloseByUser = true;
StorageUI(); StorageUI();
await ViewModel?.MyAppExitAsync(false); await ViewModel?.MyAppExitAsync(false);
} }
#endregion Event #endregion Event
@ -398,32 +401,32 @@ namespace v2rayN.Desktop.Views
public void ShowHideWindow(bool? blShow) public void ShowHideWindow(bool? blShow)
{ {
var bl = blShow ?? (!_config.UiItem.ShowInTaskbar ^ (WindowState==WindowState.Minimized)); var bl = blShow ?? (!_config.UiItem.ShowInTaskbar ^ (WindowState == WindowState.Minimized));
if (bl) if (bl)
{ {
this.Show(); this.Show();
if (this.WindowState == WindowState.Minimized) if (this.WindowState == WindowState.Minimized)
{ {
this.WindowState = WindowState.Normal; this.WindowState = WindowState.Normal;
} }
this.Activate(); this.Activate();
this.Focus(); this.Focus();
} }
else else
{ {
if (Utils.IsOSX() || _config.UiItem.Hide2TrayWhenClose) if (Utils.IsOSX() || _config.UiItem.Hide2TrayWhenClose)
{ {
foreach (var ownedWindow in this.OwnedWindows) foreach (var ownedWindow in this.OwnedWindows)
{ {
ownedWindow.Close(); ownedWindow.Close();
} }
this.Hide(); this.Hide();
} }
else else
{ {
this.WindowState = WindowState.Minimized; this.WindowState = WindowState.Minimized;
} }
} }
_config.UiItem.ShowInTaskbar = bl; _config.UiItem.ShowInTaskbar = bl;
} }

View file

@ -1,8 +1,8 @@
using System.Reactive.Disposables;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using Avalonia.Threading; using Avalonia.Threading;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common; using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
@ -27,7 +27,8 @@ namespace v2rayN.Desktop.Views
switch (action) switch (action)
{ {
case EViewAction.DispatcherShowMsg: case EViewAction.DispatcherShowMsg:
if (obj is null) return false; if (obj is null)
return false;
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
ShowMsg(obj), ShowMsg(obj),

View file

@ -1,7 +1,7 @@
using Avalonia.Controls; using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
{ {

View file

@ -1,3 +1,4 @@
using System.Reactive.Disposables;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
@ -7,7 +8,6 @@ using DialogHostAvalonia;
using MsBox.Avalonia.Enums; using MsBox.Avalonia.Enums;
using ReactiveUI; using ReactiveUI;
using Splat; using Splat;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common; using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
@ -112,7 +112,8 @@ namespace v2rayN.Desktop.Views
switch (action) switch (action)
{ {
case EViewAction.SetClipboardData: case EViewAction.SetClipboardData:
if (obj is null) return false; if (obj is null)
return false;
await AvaUtils.SetClipboardData(this, (string)obj); await AvaUtils.SetClipboardData(this, (string)obj);
break; break;
@ -135,7 +136,8 @@ namespace v2rayN.Desktop.Views
break; break;
case EViewAction.SaveFileDialog: case EViewAction.SaveFileDialog:
if (obj is null) return false; if (obj is null)
return false;
var fileName = await UI.SaveFileDialog(_window, ""); var fileName = await UI.SaveFileDialog(_window, "");
if (fileName.IsNullOrEmpty()) if (fileName.IsNullOrEmpty())
{ {
@ -145,24 +147,29 @@ namespace v2rayN.Desktop.Views
break; break;
case EViewAction.AddServerWindow: case EViewAction.AddServerWindow:
if (obj is null) return false; if (obj is null)
return false;
return await new AddServerWindow((ProfileItem)obj).ShowDialog<bool>(_window); return await new AddServerWindow((ProfileItem)obj).ShowDialog<bool>(_window);
case EViewAction.AddServer2Window: case EViewAction.AddServer2Window:
if (obj is null) return false; if (obj is null)
return false;
return await new AddServer2Window((ProfileItem)obj).ShowDialog<bool>(_window); return await new AddServer2Window((ProfileItem)obj).ShowDialog<bool>(_window);
case EViewAction.ShareServer: case EViewAction.ShareServer:
if (obj is null) return false; if (obj is null)
return false;
await ShareServer((string)obj); await ShareServer((string)obj);
break; break;
case EViewAction.SubEditWindow: case EViewAction.SubEditWindow:
if (obj is null) return false; if (obj is null)
return false;
return await new SubEditWindow((SubItem)obj).ShowDialog<bool>(_window); return await new SubEditWindow((SubItem)obj).ShowDialog<bool>(_window);
case EViewAction.DispatcherSpeedTest: case EViewAction.DispatcherSpeedTest:
if (obj is null) return false; if (obj is null)
return false;
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
ViewModel?.SetSpeedTestResult((SpeedTestResult)obj), ViewModel?.SetSpeedTestResult((SpeedTestResult)obj),
DispatcherPriority.Default); DispatcherPriority.Default);
@ -198,7 +205,8 @@ namespace v2rayN.Desktop.Views
private void LstProfiles_DoubleTapped(object? sender, Avalonia.Input.TappedEventArgs e) private void LstProfiles_DoubleTapped(object? sender, Avalonia.Input.TappedEventArgs e)
{ {
var source = e.Source as Border; var source = e.Source as Border;
if (source?.Name == "HeaderBackground") return; if (source?.Name == "HeaderBackground")
return;
if (_config.UiItem.DoubleClick2Activate) if (_config.UiItem.DoubleClick2Activate)
{ {
ViewModel?.SetDefaultServer(); ViewModel?.SetDefaultServer();

View file

@ -1,4 +1,4 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Media.Imaging; using Avalonia.Media.Imaging;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
@ -28,7 +28,8 @@ namespace v2rayN.Desktop.Views
private Bitmap? ByteToBitmap(byte[]? bytes) private Bitmap? ByteToBitmap(byte[]? bytes)
{ {
if (bytes is null) return null; if (bytes is null)
return null;
using var ms = new MemoryStream(bytes); using var ms = new MemoryStream(bytes);
return new Bitmap(ms); return new Bitmap(ms);

View file

@ -1,8 +1,8 @@
using Avalonia.Controls; using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
{ {

View file

@ -1,11 +1,10 @@
using Avalonia.Controls; using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using MsBox.Avalonia.Enums; using MsBox.Avalonia.Enums;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common; using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
@ -95,7 +94,8 @@ namespace v2rayN.Desktop.Views
break; break;
case EViewAction.RoutingRuleDetailsWindow: case EViewAction.RoutingRuleDetailsWindow:
if (obj is null) return false; if (obj is null)
return false;
return await new RoutingRuleDetailsWindow((RulesItem)obj).ShowDialog<bool>(this); return await new RoutingRuleDetailsWindow((RulesItem)obj).ShowDialog<bool>(this);
case EViewAction.ImportRulesFromFile: case EViewAction.ImportRulesFromFile:
@ -108,7 +108,8 @@ namespace v2rayN.Desktop.Views
break; break;
case EViewAction.SetClipboardData: case EViewAction.SetClipboardData:
if (obj is null) return false; if (obj is null)
return false;
await AvaUtils.SetClipboardData(this, (string)obj); await AvaUtils.SetClipboardData(this, (string)obj);
break; break;

View file

@ -1,10 +1,10 @@
using Avalonia.Controls; using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using MsBox.Avalonia.Enums; using MsBox.Avalonia.Enums;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common; using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
@ -75,7 +75,8 @@ namespace v2rayN.Desktop.Views
break; break;
case EViewAction.RoutingRuleSettingWindow: case EViewAction.RoutingRuleSettingWindow:
if (obj is null) return false; if (obj is null)
return false;
return await new RoutingRuleSettingWindow((RoutingItem)obj).ShowDialog<bool>(this); return await new RoutingRuleSettingWindow((RoutingItem)obj).ShowDialog<bool>(this);
} }
return await Task.FromResult(true); return await Task.FromResult(true);

View file

@ -1,3 +1,4 @@
using System.Reactive.Disposables;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
@ -5,7 +6,6 @@ using Avalonia.ReactiveUI;
using Avalonia.Threading; using Avalonia.Threading;
using ReactiveUI; using ReactiveUI;
using Splat; using Splat;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common; using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
@ -50,7 +50,8 @@ namespace v2rayN.Desktop.Views
switch (action) switch (action)
{ {
case EViewAction.DispatcherServerAvailability: case EViewAction.DispatcherServerAvailability:
if (obj is null) return false; if (obj is null)
return false;
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
ViewModel?.TestServerAvailabilityResult((string)obj), ViewModel?.TestServerAvailabilityResult((string)obj),
DispatcherPriority.Default); DispatcherPriority.Default);
@ -71,7 +72,8 @@ namespace v2rayN.Desktop.Views
break; break;
case EViewAction.SetClipboardData: case EViewAction.SetClipboardData:
if (obj is null) return false; if (obj is null)
return false;
await AvaUtils.SetClipboardData(this, (string)obj); await AvaUtils.SetClipboardData(this, (string)obj);
break; break;
} }

View file

@ -1,8 +1,8 @@
using System.Reactive.Disposables;
using Avalonia; using Avalonia;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
{ {

View file

@ -1,11 +1,11 @@
using Avalonia.Controls; using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using DialogHostAvalonia; using DialogHostAvalonia;
using DynamicData; using DynamicData;
using MsBox.Avalonia.Enums; using MsBox.Avalonia.Enums;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common; using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views
@ -52,13 +52,15 @@ namespace v2rayN.Desktop.Views
break; break;
case EViewAction.SubEditWindow: case EViewAction.SubEditWindow:
if (obj is null) return false; if (obj is null)
return false;
var window = new SubEditWindow((SubItem)obj); var window = new SubEditWindow((SubItem)obj);
await window.ShowDialog(this); await window.ShowDialog(this);
break; break;
case EViewAction.ShareSub: case EViewAction.ShareSub:
if (obj is null) return false; if (obj is null)
return false;
await ShareSub((string)obj); await ShareSub((string)obj);
break; break;
} }

View file

@ -1,7 +1,7 @@
using Avalonia; using System.Reactive.Disposables;
using Avalonia;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.ViewModels; using v2rayN.Desktop.ViewModels;
namespace v2rayN.Desktop.Views namespace v2rayN.Desktop.Views

View file

@ -1,9 +1,9 @@
<Application <Application
x:Class="v2rayN.App" x:Class="v2rayN.App"
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:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters" xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
ShutdownMode="OnExplicitShutdown" ShutdownMode="OnExplicitShutdown"
StartupUri="Views/MainWindow.xaml"> StartupUri="Views/MainWindow.xaml">
<Application.Resources> <Application.Resources>

View file

@ -1,5 +1,5 @@
using Microsoft.Win32;
using System.Windows; using System.Windows;
using Microsoft.Win32;
namespace v2rayN namespace v2rayN
{ {

View file

@ -1,13 +1,10 @@
using Microsoft.Win32;
using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Interop; using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using Microsoft.Win32;
namespace v2rayN namespace v2rayN
{ {
@ -64,8 +61,6 @@ namespace v2rayN
BitmapSizeOptions.FromEmptyOptions()); BitmapSizeOptions.FromEmptyOptions());
} }
public static void SetDarkBorder(Window window, string? theme) public static void SetDarkBorder(Window window, string? theme)
{ {
var isDark = theme switch var isDark = theme switch

View file

@ -1,4 +1,4 @@
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Windows; using System.Windows;
@ -37,16 +37,20 @@ namespace v2rayN.Handler
private void Init() private void Init()
{ {
_hotkeyTriggerDic.Clear(); _hotkeyTriggerDic.Clear();
if (_config.GlobalHotkeys == null) return; if (_config.GlobalHotkeys == null)
return;
foreach (var item in _config.GlobalHotkeys) foreach (var item in _config.GlobalHotkeys)
{ {
if (item.KeyCode != null && (Key)item.KeyCode != Key.None) if (item.KeyCode != null && (Key)item.KeyCode != Key.None)
{ {
int key = KeyInterop.VirtualKeyFromKey((Key)item.KeyCode); int key = KeyInterop.VirtualKeyFromKey((Key)item.KeyCode);
KeyModifiers modifiers = KeyModifiers.None; KeyModifiers modifiers = KeyModifiers.None;
if (item.Control) modifiers |= KeyModifiers.Ctrl; if (item.Control)
if (item.Shift) modifiers |= KeyModifiers.Shift; modifiers |= KeyModifiers.Ctrl;
if (item.Alt) modifiers |= KeyModifiers.Alt; if (item.Shift)
modifiers |= KeyModifiers.Shift;
if (item.Alt)
modifiers |= KeyModifiers.Alt;
key = (key << 16) | (int)modifiers; key = (key << 16) | (int)modifiers;
if (!_hotkeyTriggerDic.ContainsKey(key)) if (!_hotkeyTriggerDic.ContainsKey(key))
{ {
@ -111,9 +115,12 @@ namespace v2rayN.Handler
var mdif = (KeyModifiers)_fsModifiers; var mdif = (KeyModifiers)_fsModifiers;
var key = KeyInterop.KeyFromVirtualKey(_vkey); var key = KeyInterop.KeyFromVirtualKey(_vkey);
if ((mdif & KeyModifiers.Ctrl) == KeyModifiers.Ctrl) _hotkeyStr.Append($"{KeyModifiers.Ctrl}+"); if ((mdif & KeyModifiers.Ctrl) == KeyModifiers.Ctrl)
if ((mdif & KeyModifiers.Alt) == KeyModifiers.Alt) _hotkeyStr.Append($"{KeyModifiers.Alt}+"); _hotkeyStr.Append($"{KeyModifiers.Ctrl}+");
if ((mdif & KeyModifiers.Shift) == KeyModifiers.Shift) _hotkeyStr.Append($"{KeyModifiers.Shift}+"); if ((mdif & KeyModifiers.Alt) == KeyModifiers.Alt)
_hotkeyStr.Append($"{KeyModifiers.Alt}+");
if ((mdif & KeyModifiers.Shift) == KeyModifiers.Shift)
_hotkeyStr.Append($"{KeyModifiers.Shift}+");
_hotkeyStr.Append(key.ToString()); _hotkeyStr.Append(key.ToString());
foreach (var name in _hotkeyTriggerDic[hotkeycode]) foreach (var name in _hotkeyTriggerDic[hotkeycode])

View file

@ -1,3 +1,7 @@
using System.Reactive.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using DynamicData; using DynamicData;
using DynamicData.Binding; using DynamicData.Binding;
using MaterialDesignColors; using MaterialDesignColors;
@ -5,10 +9,6 @@ using MaterialDesignColors.ColorManipulation;
using MaterialDesignThemes.Wpf; using MaterialDesignThemes.Wpf;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using System.Reactive.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {
@ -145,7 +145,8 @@ namespace v2rayN.ViewModels
private void ModifyFontSize() private void ModifyFontSize()
{ {
double size = (long)CurrentFontSize; double size = (long)CurrentFontSize;
if (size < Global.MinFontSize) return; if (size < Global.MinFontSize)
return;
Application.Current.Resources["StdFontSize"] = size; Application.Current.Resources["StdFontSize"] = size;
Application.Current.Resources["StdFontSize1"] = size + 1; Application.Current.Resources["StdFontSize1"] = size + 1;

View file

@ -1,6 +1,6 @@
using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using ReactiveUI;
namespace v2rayN.Views namespace v2rayN.Views
{ {

View file

@ -1,7 +1,7 @@
using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using ReactiveUI;
namespace v2rayN.Views namespace v2rayN.Views
{ {

View file

@ -1,6 +1,6 @@
using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using ReactiveUI;
namespace v2rayN.Views namespace v2rayN.Views
{ {

View file

@ -1,7 +1,7 @@
using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Threading; using System.Windows.Threading;
using ReactiveUI;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -27,7 +27,8 @@ namespace v2rayN.Views
switch (action) switch (action)
{ {
case EViewAction.DispatcherCheckUpdate: case EViewAction.DispatcherCheckUpdate:
if (obj is null) return false; if (obj is null)
return false;
Application.Current?.Dispatcher.Invoke((() => Application.Current?.Dispatcher.Invoke((() =>
{ {
ViewModel?.UpdateViewResult((CheckUpdateModel)obj); ViewModel?.UpdateViewResult((CheckUpdateModel)obj);
@ -35,7 +36,8 @@ namespace v2rayN.Views
break; break;
case EViewAction.DispatcherCheckUpdateFinished: case EViewAction.DispatcherCheckUpdateFinished:
if (obj is null) return false; if (obj is null)
return false;
Application.Current?.Dispatcher.Invoke((() => Application.Current?.Dispatcher.Invoke((() =>
{ {
ViewModel?.UpdateFinishedResult((bool)obj); ViewModel?.UpdateFinishedResult((bool)obj);

View file

@ -1,11 +1,11 @@
<reactiveui:ReactiveUserControl <reactiveui:ReactiveUserControl
x:Class="v2rayN.Views.ClashConnectionsView" x:Class="v2rayN.Views.ClashConnectionsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
d:DesignHeight="450" d:DesignHeight="450"

View file

@ -1,8 +1,8 @@
using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Threading; using System.Windows.Threading;
using ReactiveUI;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -36,7 +36,8 @@ namespace v2rayN.Views
switch (action) switch (action)
{ {
case EViewAction.DispatcherRefreshConnections: case EViewAction.DispatcherRefreshConnections:
if (obj is null) return false; if (obj is null)
return false;
Application.Current?.Dispatcher.Invoke((() => Application.Current?.Dispatcher.Invoke((() =>
{ {
ViewModel?.RefreshConnections((List<ConnectionItem>?)obj); ViewModel?.RefreshConnections((List<ConnectionItem>?)obj);

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: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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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" 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"

View file

@ -1,9 +1,9 @@
using ReactiveUI;
using Splat;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Threading; using System.Windows.Threading;
using ReactiveUI;
using Splat;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -52,7 +52,8 @@ namespace v2rayN.Views
case EViewAction.DispatcherProxiesDelayTest: case EViewAction.DispatcherProxiesDelayTest:
if (obj is null) return false; if (obj is null)
return false;
Application.Current?.Dispatcher.Invoke((() => Application.Current?.Dispatcher.Invoke((() =>
{ {
ViewModel?.ProxiesDelayTestResult((SpeedTestResult)obj); ViewModel?.ProxiesDelayTestResult((SpeedTestResult)obj);

View file

@ -1,6 +1,6 @@
using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using ReactiveUI;
namespace v2rayN.Views namespace v2rayN.Views
{ {

View file

@ -1,11 +1,11 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.GlobalHotkeySettingWindow" x:Class="v2rayN.Views.GlobalHotkeySettingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuSetting}" Title="{x:Static resx:ResUI.menuSetting}"

View file

@ -1,4 +1,4 @@
using System.Text; using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
@ -75,9 +75,12 @@ namespace v2rayN.Views
{ {
var res = new StringBuilder(); var res = new StringBuilder();
if (item.Control) res.Append($"{ModifierKeys.Control}+"); if (item.Control)
if (item.Shift) res.Append($"{ModifierKeys.Shift}+"); res.Append($"{ModifierKeys.Control}+");
if (item.Alt) res.Append($"{ModifierKeys.Alt}+"); if (item.Shift)
res.Append($"{ModifierKeys.Shift}+");
if (item.Alt)
res.Append($"{ModifierKeys.Alt}+");
if (item.KeyCode != null && (Key)item.KeyCode != Key.None) if (item.KeyCode != null && (Key)item.KeyCode != Key.None)
res.Append($"{(Key)item.KeyCode}"); res.Append($"{(Key)item.KeyCode}");

View file

@ -1,14 +1,14 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.MainWindow" x:Class="v2rayN.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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:view="clr-namespace:v2rayN.Views"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
xmlns:view="clr-namespace:v2rayN.Views"
Title="v2rayN" Title="v2rayN"
Width="900" Width="900"
Height="700" Height="700"

View file

@ -1,6 +1,3 @@
using MaterialDesignThemes.Wpf;
using ReactiveUI;
using Splat;
using System.ComponentModel; using System.ComponentModel;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
@ -9,6 +6,9 @@ using System.Windows.Input;
using System.Windows.Interop; using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading; using System.Windows.Threading;
using MaterialDesignThemes.Wpf;
using ReactiveUI;
using Splat;
using v2rayN.Handler; using v2rayN.Handler;
namespace v2rayN.Views namespace v2rayN.Views
@ -168,11 +168,13 @@ namespace v2rayN.Views
switch (action) switch (action)
{ {
case EViewAction.AddServerWindow: case EViewAction.AddServerWindow:
if (obj is null) return false; if (obj is null)
return false;
return (new AddServerWindow((ProfileItem)obj)).ShowDialog() ?? false; return (new AddServerWindow((ProfileItem)obj)).ShowDialog() ?? false;
case EViewAction.AddServer2Window: case EViewAction.AddServer2Window:
if (obj is null) return false; if (obj is null)
return false;
return (new AddServer2Window((ProfileItem)obj)).ShowDialog() ?? false; return (new AddServer2Window((ProfileItem)obj)).ShowDialog() ?? false;
case EViewAction.DNSSettingWindow: case EViewAction.DNSSettingWindow:
@ -198,7 +200,8 @@ namespace v2rayN.Views
break; break;
case EViewAction.DispatcherStatistics: case EViewAction.DispatcherStatistics:
if (obj is null) return false; if (obj is null)
return false;
Application.Current?.Dispatcher.Invoke((() => Application.Current?.Dispatcher.Invoke((() =>
{ {
ViewModel?.SetStatisticsResult((ServerSpeedItem)obj); ViewModel?.SetStatisticsResult((ServerSpeedItem)obj);
@ -280,10 +283,12 @@ namespace v2rayN.Views
switch (e.Key) switch (e.Key)
{ {
case Key.V: case Key.V:
if (Keyboard.FocusedElement is TextBox) return; if (Keyboard.FocusedElement is TextBox)
return;
var clipboardData = WindowsUtils.GetClipboardData(); var clipboardData = WindowsUtils.GetClipboardData();
var service = Locator.Current.GetService<MainWindowViewModel>(); var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) _ = service.AddServerViaClipboardAsync(clipboardData); if (service != null)
_ = service.AddServerViaClipboardAsync(clipboardData);
break; break;
case Key.S: case Key.S:
@ -388,8 +393,10 @@ namespace v2rayN.Views
var maxWidth = SystemParameters.WorkArea.Width; var maxWidth = SystemParameters.WorkArea.Width;
var maxHeight = SystemParameters.WorkArea.Height; var maxHeight = SystemParameters.WorkArea.Height;
if (Width > maxWidth) Width = maxWidth; if (Width > maxWidth)
if (Height > maxHeight) Height = maxHeight; Width = maxWidth;
if (Height > maxHeight)
Height = maxHeight;
if (_config.UiItem.MainGirdHeight1 > 0 && _config.UiItem.MainGirdHeight2 > 0) if (_config.UiItem.MainGirdHeight1 > 0 && _config.UiItem.MainGirdHeight2 > 0)
{ {
if (_config.UiItem.MainGirdOrientation == EGirdOrientation.Horizontal) if (_config.UiItem.MainGirdOrientation == EGirdOrientation.Horizontal)

View file

@ -1,7 +1,7 @@
using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Threading; using System.Windows.Threading;
using ReactiveUI;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -37,7 +37,8 @@ namespace v2rayN.Views
switch (action) switch (action)
{ {
case EViewAction.DispatcherShowMsg: case EViewAction.DispatcherShowMsg:
if (obj is null) return false; if (obj is null)
return false;
Application.Current?.Dispatcher.Invoke((() => Application.Current?.Dispatcher.Invoke((() =>
{ {
ShowMsg(obj); ShowMsg(obj);

View file

@ -1,9 +1,9 @@
using ReactiveUI;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using ReactiveUI;
namespace v2rayN.Views namespace v2rayN.Views
{ {

View file

@ -1,6 +1,3 @@
using MaterialDesignThemes.Wpf;
using ReactiveUI;
using Splat;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
@ -8,6 +5,9 @@ using System.Windows.Controls.Primitives;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading; using System.Windows.Threading;
using MaterialDesignThemes.Wpf;
using ReactiveUI;
using Splat;
using v2rayN.Base; using v2rayN.Base;
using Point = System.Windows.Point; using Point = System.Windows.Point;
@ -99,7 +99,8 @@ namespace v2rayN.Views
switch (action) switch (action)
{ {
case EViewAction.SetClipboardData: case EViewAction.SetClipboardData:
if (obj is null) return false; if (obj is null)
return false;
WindowsUtils.SetClipboardData((string)obj); WindowsUtils.SetClipboardData((string)obj);
break; break;
@ -122,7 +123,8 @@ namespace v2rayN.Views
break; break;
case EViewAction.SaveFileDialog: case EViewAction.SaveFileDialog:
if (obj is null) return false; if (obj is null)
return false;
if (UI.SaveFileDialog(out string fileName, "Config|*.json") != true) if (UI.SaveFileDialog(out string fileName, "Config|*.json") != true)
{ {
return false; return false;
@ -131,24 +133,29 @@ namespace v2rayN.Views
break; break;
case EViewAction.AddServerWindow: case EViewAction.AddServerWindow:
if (obj is null) return false; if (obj is null)
return false;
return (new AddServerWindow((ProfileItem)obj)).ShowDialog() ?? false; return (new AddServerWindow((ProfileItem)obj)).ShowDialog() ?? false;
case EViewAction.AddServer2Window: case EViewAction.AddServer2Window:
if (obj is null) return false; if (obj is null)
return false;
return (new AddServer2Window((ProfileItem)obj)).ShowDialog() ?? false; return (new AddServer2Window((ProfileItem)obj)).ShowDialog() ?? false;
case EViewAction.ShareServer: case EViewAction.ShareServer:
if (obj is null) return false; if (obj is null)
return false;
ShareServer((string)obj); ShareServer((string)obj);
break; break;
case EViewAction.SubEditWindow: case EViewAction.SubEditWindow:
if (obj is null) return false; if (obj is null)
return false;
return (new SubEditWindow((SubItem)obj)).ShowDialog() ?? false; return (new SubEditWindow((SubItem)obj)).ShowDialog() ?? false;
case EViewAction.DispatcherSpeedTest: case EViewAction.DispatcherSpeedTest:
if (obj is null) return false; if (obj is null)
return false;
Application.Current?.Dispatcher.Invoke((() => Application.Current?.Dispatcher.Invoke((() =>
{ {
ViewModel?.SetSpeedTestResult((SpeedTestResult)obj); ViewModel?.SetSpeedTestResult((SpeedTestResult)obj);
@ -403,13 +410,16 @@ namespace v2rayN.Views
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)) Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
{ {
// Get the dragged Item // Get the dragged Item
if (sender is not DataGrid listView) return; if (sender is not DataGrid listView)
return;
var listViewItem = FindAncestor<DataGridRow>((DependencyObject)e.OriginalSource); var listViewItem = FindAncestor<DataGridRow>((DependencyObject)e.OriginalSource);
if (listViewItem == null) return; // Abort if (listViewItem == null)
// Find the data behind the ListViewItem return; // Abort
// Find the data behind the ListViewItem
ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem); ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
if (item == null) return; // Abort if (item == null)
// Initialize the drag & drop operation return; // Abort
// Initialize the drag & drop operation
startIndex = lstProfiles.SelectedIndex; startIndex = lstProfiles.SelectedIndex;
DataObject dragData = new(formatData, item); DataObject dragData = new(formatData, item);
DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Copy | DragDropEffects.Move); DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Copy | DragDropEffects.Move);
@ -429,7 +439,8 @@ namespace v2rayN.Views
if (e.Data.GetDataPresent(formatData) && sender == e.Source) if (e.Data.GetDataPresent(formatData) && sender == e.Source)
{ {
// Get the drop Item destination // Get the drop Item destination
if (sender is not DataGrid listView) return; if (sender is not DataGrid listView)
return;
var listViewItem = FindAncestor<DataGridRow>((DependencyObject)e.OriginalSource); var listViewItem = FindAncestor<DataGridRow>((DependencyObject)e.OriginalSource);
if (listViewItem == null) if (listViewItem == null)
{ {
@ -439,7 +450,8 @@ namespace v2rayN.Views
} }
// Find the data behind the Item // Find the data behind the Item
ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem); ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
if (item == null) return; if (item == null)
return;
// Move item into observable collection // Move item into observable collection
// (this will be automatically reflected to lstView.ItemsSource) // (this will be automatically reflected to lstView.ItemsSource)
e.Effects = DragDropEffects.Move; e.Effects = DragDropEffects.Move;

View file

@ -1,11 +1,11 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.RoutingRuleDetailsWindow" x:Class="v2rayN.Views.RoutingRuleDetailsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}" Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}"

View file

@ -1,6 +1,6 @@
using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using ReactiveUI;
namespace v2rayN.Views namespace v2rayN.Views
{ {

View file

@ -1,11 +1,11 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.RoutingRuleSettingWindow" x:Class="v2rayN.Views.RoutingRuleSettingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuRoutingRuleSetting}" Title="{x:Static resx:ResUI.menuRoutingRuleSetting}"

View file

@ -1,7 +1,7 @@
using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using ReactiveUI;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -89,7 +89,8 @@ namespace v2rayN.Views
case EViewAction.RoutingRuleDetailsWindow: case EViewAction.RoutingRuleDetailsWindow:
if (obj is null) return false; if (obj is null)
return false;
return (new RoutingRuleDetailsWindow((RulesItem)obj)).ShowDialog() ?? false; return (new RoutingRuleDetailsWindow((RulesItem)obj)).ShowDialog() ?? false;
case EViewAction.ImportRulesFromFile: case EViewAction.ImportRulesFromFile:
@ -102,7 +103,8 @@ namespace v2rayN.Views
break; break;
case EViewAction.SetClipboardData: case EViewAction.SetClipboardData:
if (obj is null) return false; if (obj is null)
return false;
WindowsUtils.SetClipboardData((string)obj); WindowsUtils.SetClipboardData((string)obj);
break; break;

View file

@ -1,7 +1,7 @@
using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using ReactiveUI;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -72,7 +72,8 @@ namespace v2rayN.Views
case EViewAction.RoutingRuleSettingWindow: case EViewAction.RoutingRuleSettingWindow:
if (obj is null) return false; if (obj is null)
return false;
return (new RoutingRuleSettingWindow((RoutingItem)obj)).ShowDialog() ?? false; return (new RoutingRuleSettingWindow((RoutingItem)obj)).ShowDialog() ?? false;
} }
return await Task.FromResult(true); return await Task.FromResult(true);

View file

@ -1,9 +1,9 @@
using ReactiveUI;
using Splat;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Threading; using System.Windows.Threading;
using ReactiveUI;
using Splat;
using v2rayN.Handler; using v2rayN.Handler;
namespace v2rayN.Views namespace v2rayN.Views
@ -77,7 +77,8 @@ namespace v2rayN.Views
switch (action) switch (action)
{ {
case EViewAction.DispatcherServerAvailability: case EViewAction.DispatcherServerAvailability:
if (obj is null) return false; if (obj is null)
return false;
Application.Current?.Dispatcher.Invoke((() => Application.Current?.Dispatcher.Invoke((() =>
{ {
ViewModel?.TestServerAvailabilityResult((string)obj); ViewModel?.TestServerAvailabilityResult((string)obj);
@ -98,8 +99,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: case EViewAction.SetClipboardData:
if (obj is null) return false; if (obj is null)
return false;
WindowsUtils.SetClipboardData((string)obj); WindowsUtils.SetClipboardData((string)obj);
break; break;
} }
@ -110,7 +113,8 @@ namespace v2rayN.Views
{ {
tbNotify.Dispose(); tbNotify.Dispose();
var service = Locator.Current.GetService<MainWindowViewModel>(); var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) await service.MyAppExitAsync(false); if (service != null)
await service.MyAppExitAsync(false);
} }
private void txtRunningInfoDisplay_MouseDoubleClick(object sender, MouseButtonEventArgs e) private void txtRunningInfoDisplay_MouseDoubleClick(object sender, MouseButtonEventArgs e)

View file

@ -1,11 +1,11 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.SubEditWindow" x:Class="v2rayN.Views.SubEditWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuSubSetting}" Title="{x:Static resx:ResUI.menuSubSetting}"

View file

@ -1,6 +1,6 @@
using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using ReactiveUI;
namespace v2rayN.Views namespace v2rayN.Views
{ {

Some files were not shown because too many files have changed in this diff Show more