Compare commits
13 Commits
22c233f0cd
...
d727ff40bb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d727ff40bb | ||
|
|
1b5069a933 | ||
|
|
18ea6fdc00 | ||
|
|
67494108ad | ||
|
|
38b2a7d2ca | ||
|
|
bf3703bca1 | ||
|
|
554632cc07 | ||
|
|
12fc3e9566 | ||
|
|
c2ef3a4a8c | ||
|
|
86eb8297dd | ||
|
|
c63d4e83f9 | ||
|
|
bf1fb0f92e | ||
|
|
3c4865982b |
93
.github/workflows/build-linux.yml
vendored
93
.github/workflows/build-linux.yml
vendored
@@ -9,6 +9,12 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- 'v*'
|
||||
- 'V*'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
OutputArch: "linux-64"
|
||||
@@ -21,7 +27,6 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Release]
|
||||
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
@@ -31,21 +36,21 @@ jobs:
|
||||
submodules: 'recursive'
|
||||
fetch-depth: '0'
|
||||
|
||||
- name: Setup
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v5.0.0
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd v2rayN
|
||||
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r linux-x64 --self-contained=true -o $OutputPath64
|
||||
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r linux-arm64 --self-contained=true -o $OutputPathArm64
|
||||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-x64 --self-contained=true -p:PublishTrimmed=true -o $OutputPath64
|
||||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-arm64 --self-contained=true -p:PublishTrimmed=true -o $OutputPathArm64
|
||||
cd v2rayN
|
||||
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r linux-x64 --self-contained=true -o "$OutputPath64"
|
||||
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r linux-arm64 --self-contained=true -o "$OutputPathArm64"
|
||||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-x64 --self-contained=true -p:PublishTrimmed=true -o "$OutputPath64"
|
||||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-arm64 --self-contained=true -p:PublishTrimmed=true -o "$OutputPathArm64"
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
uses: actions/upload-artifact@v5.0.0
|
||||
with:
|
||||
name: v2rayN-linux
|
||||
path: |
|
||||
@@ -56,8 +61,8 @@ jobs:
|
||||
if: github.event.inputs.release_tag != ''
|
||||
run: |
|
||||
chmod 755 package-debian.sh
|
||||
./package-debian.sh $OutputArch $OutputPath64 ${{ github.event.inputs.release_tag }}
|
||||
./package-debian.sh $OutputArchArm $OutputPathArm64 ${{ github.event.inputs.release_tag }}
|
||||
./package-debian.sh "$OutputArch" "$OutputPath64" "${{ github.event.inputs.release_tag }}"
|
||||
./package-debian.sh "$OutputArchArm" "$OutputPathArm64" "${{ github.event.inputs.release_tag }}"
|
||||
|
||||
- name: Upload deb to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
@@ -73,8 +78,8 @@ jobs:
|
||||
if: github.event.inputs.release_tag != ''
|
||||
run: |
|
||||
chmod 755 package-release-zip.sh
|
||||
./package-release-zip.sh $OutputArch $OutputPath64
|
||||
./package-release-zip.sh $OutputArchArm $OutputPathArm64
|
||||
./package-release-zip.sh "$OutputArch" "$OutputPath64"
|
||||
./package-release-zip.sh "$OutputArchArm" "$OutputPathArm64"
|
||||
|
||||
- name: Upload zip archive to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
@@ -85,36 +90,62 @@ jobs:
|
||||
file_glob: true
|
||||
prerelease: true
|
||||
|
||||
# release RHEL package
|
||||
- name: Package RPM (RHEL-family)
|
||||
if: github.event.inputs.release_tag != ''
|
||||
rpm:
|
||||
needs: build
|
||||
if: |
|
||||
(github.event_name == 'workflow_dispatch' && github.event.inputs.release_tag != '') ||
|
||||
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/'))
|
||||
runs-on: ubuntu-24.04
|
||||
container:
|
||||
image: quay.io/almalinuxorg/10-base:latest
|
||||
options: --platform=linux/amd64/v2
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.event.inputs.release_tag != '' && github.event.inputs.release_tag || github.ref_name }}
|
||||
|
||||
steps:
|
||||
- name: Prepare tools (Red Hat)
|
||||
run: |
|
||||
chmod 755 package-rhel.sh
|
||||
# Build for both x86_64 and aarch64 in one go (explicit version passed; no --buildfrom)
|
||||
./package-rhel.sh "${{ github.event.inputs.release_tag }}" --arch all
|
||||
dnf -y makecache
|
||||
dnf -y install epel-release
|
||||
dnf -y install sudo git rpm-build rpmdevtools dnf-plugins-core rsync findutils tar gzip unzip which
|
||||
|
||||
- name: Checkout repo (for scripts)
|
||||
uses: actions/checkout@v5.0.0
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
fetch-depth: '0'
|
||||
|
||||
- name: Restore build artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: v2rayN-linux
|
||||
path: ${{ github.workspace }}/v2rayN/Release
|
||||
|
||||
- name: Ensure script permissions
|
||||
run: chmod 755 package-rhel.sh
|
||||
|
||||
- name: Package RPM (RHEL-family)
|
||||
run: ./package-rhel.sh "${RELEASE_TAG}" --arch all
|
||||
|
||||
- name: Collect RPMs into workspace
|
||||
if: github.event.inputs.release_tag != ''
|
||||
run: |
|
||||
mkdir -p "${{ github.workspace }}/dist/rpm"
|
||||
rsync -av "$HOME/rpmbuild/RPMS/" "${{ github.workspace }}/dist/rpm/"
|
||||
# Rename to requested filenames
|
||||
find "${{ github.workspace }}/dist/rpm" -name "v2rayN-*-1.x86_64.rpm" -exec mv {} "${{ github.workspace }}/dist/rpm/v2rayN-linux-rhel-x64.rpm" \; || true
|
||||
find "${{ github.workspace }}/dist/rpm" -name "v2rayN-*-1.aarch64.rpm" -exec mv {} "${{ github.workspace }}/dist/rpm/v2rayN-linux-rhel-arm64.rpm" \; || true
|
||||
mkdir -p "$GITHUB_WORKSPACE/dist/rpm"
|
||||
rsync -av "$HOME/rpmbuild/RPMS/" "$GITHUB_WORKSPACE/dist/rpm/" || true
|
||||
find "$GITHUB_WORKSPACE/dist/rpm" -name "v2rayN-*-1*.x86_64.rpm" -exec mv {} "$GITHUB_WORKSPACE/dist/rpm/v2rayN-linux-rhel-64.rpm" \; || true
|
||||
find "$GITHUB_WORKSPACE/dist/rpm" -name "v2rayN-*-1*.aarch64.rpm" -exec mv {} "$GITHUB_WORKSPACE/dist/rpm/v2rayN-linux-rhel-arm64.rpm" \; || true
|
||||
echo "==== Dist tree ===="
|
||||
ls -R "$GITHUB_WORKSPACE/dist/rpm" || true
|
||||
|
||||
- name: Upload RPM artifacts
|
||||
if: github.event.inputs.release_tag != ''
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
uses: actions/upload-artifact@v5.0.0
|
||||
with:
|
||||
name: v2rayN-rpm
|
||||
path: |
|
||||
${{ github.workspace }}/dist/rpm/**/*.rpm
|
||||
path: dist/rpm/**/*.rpm
|
||||
|
||||
- name: Upload RPMs to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
if: github.event.inputs.release_tag != ''
|
||||
with:
|
||||
file: ${{ github.workspace }}/dist/rpm/**/*.rpm
|
||||
tag: ${{ github.event.inputs.release_tag }}
|
||||
file: dist/rpm/**/*.rpm
|
||||
tag: ${{ env.RELEASE_TAG }}
|
||||
file_glob: true
|
||||
prerelease: true
|
||||
|
||||
2
.github/workflows/build-osx.yml
vendored
2
.github/workflows/build-osx.yml
vendored
@@ -45,7 +45,7 @@ jobs:
|
||||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-arm64 --self-contained=true -p:PublishTrimmed=true -o $OutputPathArm64
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
uses: actions/upload-artifact@v5.0.0
|
||||
with:
|
||||
name: v2rayN-macos
|
||||
path: |
|
||||
|
||||
2
.github/workflows/build-windows-desktop.yml
vendored
2
.github/workflows/build-windows-desktop.yml
vendored
@@ -45,7 +45,7 @@ jobs:
|
||||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 --self-contained=true -p:EnableWindowsTargeting=true -p:PublishTrimmed=true -o $OutputPathArm64
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
uses: actions/upload-artifact@v5.0.0
|
||||
with:
|
||||
name: v2rayN-windows-desktop
|
||||
path: |
|
||||
|
||||
2
.github/workflows/build-windows.yml
vendored
2
.github/workflows/build-windows.yml
vendored
@@ -46,7 +46,7 @@ jobs:
|
||||
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
uses: actions/upload-artifact@v5.0.0
|
||||
with:
|
||||
name: v2rayN-windows
|
||||
path: |
|
||||
|
||||
@@ -19,6 +19,23 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ======================== Kernel version check (require >= 6.11) =======================
|
||||
MIN_KERNEL_MAJOR=6
|
||||
MIN_KERNEL_MINOR=11
|
||||
KERNEL_FULL=$(uname -r)
|
||||
KERNEL_MAJOR=$(echo "$KERNEL_FULL" | cut -d. -f1)
|
||||
KERNEL_MINOR=$(echo "$KERNEL_FULL" | cut -d. -f2)
|
||||
|
||||
echo "[INFO] Detected kernel version: $KERNEL_FULL"
|
||||
|
||||
if (( KERNEL_MAJOR < MIN_KERNEL_MAJOR )) || { (( KERNEL_MAJOR == MIN_KERNEL_MAJOR )) && (( KERNEL_MINOR < MIN_KERNEL_MINOR )); }; then
|
||||
echo "[ERROR] Kernel $KERNEL_FULL is too old. Requires Linux >= ${MIN_KERNEL_MAJOR}.${MIN_KERNEL_MINOR}."
|
||||
echo "Please upgrade your system or use a newer container (e.g. Fedora 42+, RHEL 10+, Debian 13+)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[OK] Kernel version >= ${MIN_KERNEL_MAJOR}.${MIN_KERNEL_MINOR}."
|
||||
|
||||
# ===== Config & Parse arguments =========================================================
|
||||
VERSION_ARG="${1:-}" # Pass version number like 7.13.8, or leave empty
|
||||
WITH_CORE="both" # Default: bundle both xray+sing-box
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>7.15.6</Version>
|
||||
<Version>7.15.7</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -35,9 +35,13 @@ public class JsonUtils
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static T DeepCopy<T>(T obj)
|
||||
public static T? DeepCopy<T>(T? obj)
|
||||
{
|
||||
return Deserialize<T>(Serialize(obj, false))!;
|
||||
if (obj is null)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
return Deserialize<T>(Serialize(obj, false));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -67,7 +71,7 @@ public class JsonUtils
|
||||
/// </summary>
|
||||
/// <param name="strJson"></param>
|
||||
/// <returns></returns>
|
||||
public static JsonNode? ParseJson(string strJson)
|
||||
public static JsonNode? ParseJson(string? strJson)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -116,7 +120,7 @@ public class JsonUtils
|
||||
/// <param name="obj"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static string Serialize(object? obj, JsonSerializerOptions options)
|
||||
public static string Serialize(object? obj, JsonSerializerOptions? options)
|
||||
{
|
||||
var result = string.Empty;
|
||||
try
|
||||
@@ -125,7 +129,7 @@ public class JsonUtils
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = JsonSerializer.Serialize(obj, options);
|
||||
result = JsonSerializer.Serialize(obj, options ?? _defaultSerializeOptions);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -424,7 +424,7 @@ public class Utils
|
||||
// Handle IPv6 addresses, e.g., "[2001:db8::1]:443"
|
||||
if (authority.StartsWith("[") && authority.Contains("]"))
|
||||
{
|
||||
int closingBracketIndex = authority.LastIndexOf(']');
|
||||
var closingBracketIndex = authority.LastIndexOf(']');
|
||||
if (closingBracketIndex < authority.Length - 1 && authority[closingBracketIndex + 1] == ':')
|
||||
{
|
||||
// Port exists
|
||||
@@ -963,13 +963,13 @@ public class Utils
|
||||
|
||||
#region Platform
|
||||
|
||||
public static bool IsWindows() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
public static bool IsWindows() => OperatingSystem.IsWindows();
|
||||
|
||||
public static bool IsLinux() => RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
public static bool IsLinux() => OperatingSystem.IsLinux();
|
||||
|
||||
public static bool IsOSX() => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
|
||||
public static bool IsOSX() => OperatingSystem.IsMacOS();
|
||||
|
||||
public static bool IsNonWindows() => !RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
public static bool IsNonWindows() => !OperatingSystem.IsWindows();
|
||||
|
||||
public static string GetExeName(string name)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ServiceLib.Common;
|
||||
/*
|
||||
* See:
|
||||
|
||||
@@ -447,13 +447,13 @@ public static class ConfigHandler
|
||||
/// <returns>0 if successful, -1 if failed</returns>
|
||||
public static async Task<int> MoveServer(Config config, List<ProfileItem> lstProfile, int index, EMove eMove, int pos = -1)
|
||||
{
|
||||
int count = lstProfile.Count;
|
||||
var count = lstProfile.Count;
|
||||
if (index < 0 || index > lstProfile.Count - 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < lstProfile.Count; i++)
|
||||
for (var i = 0; i < lstProfile.Count; i++)
|
||||
{
|
||||
ProfileExManager.Instance.SetSort(lstProfile[i].IndexId, (i + 1) * 10);
|
||||
}
|
||||
@@ -527,7 +527,7 @@ public static class ConfigHandler
|
||||
return -1;
|
||||
}
|
||||
var ext = Path.GetExtension(fileName);
|
||||
string newFileName = $"{Utils.GetGuid()}{ext}";
|
||||
var newFileName = $"{Utils.GetGuid()}{ext}";
|
||||
//newFileName = Path.Combine(Utile.GetTempPath(), newFileName);
|
||||
|
||||
try
|
||||
@@ -1356,7 +1356,7 @@ public static class ConfigHandler
|
||||
}
|
||||
continue;
|
||||
}
|
||||
var profileItem = FmtHandler.ResolveConfig(str, out string msg);
|
||||
var profileItem = FmtHandler.ResolveConfig(str, out var msg);
|
||||
if (profileItem is null)
|
||||
{
|
||||
continue;
|
||||
@@ -1440,7 +1440,7 @@ public static class ConfigHandler
|
||||
{
|
||||
await RemoveServersViaSubid(config, subid, isSub);
|
||||
}
|
||||
int count = 0;
|
||||
var count = 0;
|
||||
foreach (var it in lstProfiles)
|
||||
{
|
||||
it.Subid = subid;
|
||||
@@ -1530,7 +1530,7 @@ public static class ConfigHandler
|
||||
var lstSsServer = ShadowsocksFmt.ResolveSip008(strData);
|
||||
if (lstSsServer?.Count > 0)
|
||||
{
|
||||
int counter = 0;
|
||||
var counter = 0;
|
||||
foreach (var ssItem in lstSsServer)
|
||||
{
|
||||
ssItem.Subid = subid;
|
||||
@@ -1705,7 +1705,7 @@ public static class ConfigHandler
|
||||
var maxSort = 0;
|
||||
if (await SQLiteHelper.Instance.TableAsync<SubItem>().CountAsync() > 0)
|
||||
{
|
||||
var lstSubs = (await AppManager.Instance.SubItems());
|
||||
var lstSubs = await AppManager.Instance.SubItems();
|
||||
maxSort = lstSubs.LastOrDefault()?.Sort ?? 0;
|
||||
}
|
||||
item.Sort = maxSort + 1;
|
||||
@@ -1867,7 +1867,7 @@ public static class ConfigHandler
|
||||
/// <returns>0 if successful, -1 if failed</returns>
|
||||
public static async Task<int> MoveRoutingRule(List<RulesItem> rules, int index, EMove eMove, int pos = -1)
|
||||
{
|
||||
int count = rules.Count;
|
||||
var count = rules.Count;
|
||||
if (index < 0 || index > rules.Count - 1)
|
||||
{
|
||||
return -1;
|
||||
|
||||
@@ -58,7 +58,7 @@ public static class CoreConfigHandler
|
||||
File.Delete(fileName);
|
||||
}
|
||||
|
||||
string addressFileName = node.Address;
|
||||
var addressFileName = node.Address;
|
||||
if (!File.Exists(addressFileName))
|
||||
{
|
||||
addressFileName = Utils.GetConfigPath(addressFileName);
|
||||
|
||||
@@ -37,7 +37,7 @@ public class FmtHandler
|
||||
|
||||
try
|
||||
{
|
||||
string str = config.TrimEx();
|
||||
var str = config.TrimEx();
|
||||
if (str.IsNullOrEmpty())
|
||||
{
|
||||
msg = ResUI.FailedReadConfiguration;
|
||||
|
||||
@@ -33,9 +33,9 @@ public class Hysteria2Fmt : BaseFmt
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
string url = string.Empty;
|
||||
var url = string.Empty;
|
||||
|
||||
string remark = string.Empty;
|
||||
var remark = string.Empty;
|
||||
if (item.Remarks.IsNotEmpty())
|
||||
{
|
||||
remark = "#" + Utils.UrlEncode(item.Remarks);
|
||||
|
||||
@@ -85,7 +85,7 @@ public class ActionPrecheckManager(Config config)
|
||||
break;
|
||||
|
||||
case EConfigType.VLESS:
|
||||
if (item.Id.IsNullOrEmpty() || !Utils.IsGuidByParse(item.Id) && item.Id.Length > 30)
|
||||
if (item.Id.IsNullOrEmpty() || (!Utils.IsGuidByParse(item.Id) && item.Id.Length > 30))
|
||||
errors.Add(string.Format(ResUI.InvalidProperty, "Id"));
|
||||
if (!Global.Flows.Contains(item.Flow))
|
||||
errors.Add(string.Format(ResUI.InvalidProperty, "Flow"));
|
||||
|
||||
@@ -28,7 +28,7 @@ public class ProfileItem : ReactiveObject
|
||||
|
||||
public string GetSummary()
|
||||
{
|
||||
var summary = $"[{(ConfigType).ToString()}] ";
|
||||
var summary = $"[{ConfigType.ToString()}] ";
|
||||
if (IsComplex())
|
||||
{
|
||||
summary += $"[{CoreType.ToString()}]{Remarks}";
|
||||
|
||||
@@ -472,7 +472,7 @@
|
||||
<value>Langue (redémarrage requis)</value>
|
||||
</data>
|
||||
<data name="menuAddServerViaClipboard" xml:space="preserve">
|
||||
<value>Importer des liens depuis le presse-papiers (Ctrl+V)</value>
|
||||
<value>Importer liens depuis le presse-papiers (Ctrl+V)</value>
|
||||
</data>
|
||||
<data name="menuAddServerViaScan" xml:space="preserve">
|
||||
<value>Scanner le QR code à l’écran (Ctrl+S)</value>
|
||||
@@ -619,7 +619,7 @@
|
||||
<value>Sécurité couche transport (TLS)</value>
|
||||
</data>
|
||||
<data name="TipNetwork" xml:space="preserve">
|
||||
<value>*tcp par défaut ; un mauvais choix empêchera la connexion</value>
|
||||
<value>*tcp par défaut ; un mauvais choix bloque la connexion</value>
|
||||
</data>
|
||||
<data name="TbCoreType" xml:space="preserve">
|
||||
<value>Type de Core</value>
|
||||
@@ -652,7 +652,7 @@
|
||||
<value>Port Socks</value>
|
||||
</data>
|
||||
<data name="TipPreSocksPort" xml:space="preserve">
|
||||
<value>*Valeur du port Socks pour la configuration personnalisée (facultatif). Si défini, Xray/sing-box (Tun) démarrera un service Socks en amont supplémentaire pour fournir le routage sélectif et l’affichage de la vitesse.</value>
|
||||
<value>*Valeur du port Socks (config perso, optionnelle). Si défini, Xray/sing-box (Tun) démarre un service Socks en amont supplémentaire pour fournir le routage sélectif et l’affichage de la vitesse.</value>
|
||||
</data>
|
||||
<data name="TbBrowse" xml:space="preserve">
|
||||
<value>Parcourir</value>
|
||||
@@ -670,7 +670,7 @@
|
||||
<value>Masquer la fenêtre au démarrage</value>
|
||||
</data>
|
||||
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
|
||||
<value>Intervalle de mise à jour automatique des fichiers Geo (heures)</value>
|
||||
<value>Intervalle de mise à jour auto des fichiers Geo (heures)</value>
|
||||
</data>
|
||||
<data name="TbSettingsCore" xml:space="preserve">
|
||||
<value>Core : paramètres de base</value>
|
||||
@@ -691,7 +691,7 @@
|
||||
<value>domainStrategy de Freedom (sortant)</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableAutoAdjustMainLvColWidth" xml:space="preserve">
|
||||
<value>Auto-ajuster la largeur des colonnes après maj. des abonnements</value>
|
||||
<value>Auto-ajuster la largeur des colonnes après maj. abonnements</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
|
||||
<value>Vérifier les mises à jour pré-version (à activer avec prudence)</value>
|
||||
@@ -724,7 +724,7 @@
|
||||
<value>Mot de passe d’authentification</value>
|
||||
</data>
|
||||
<data name="TbSettingsRemoteDNS" xml:space="preserve">
|
||||
<value>DNS personnalisés (plusieurs possibles, séparés par des virgules)</value>
|
||||
<value>DNS perso (plusieurs configurables, séparés par virgules)</value>
|
||||
</data>
|
||||
<data name="TbSettingsSetUWP" xml:space="preserve">
|
||||
<value>Lever la restriction de proxy en boucle locale pour les applications Win10 UWP</value>
|
||||
@@ -865,7 +865,7 @@
|
||||
<value>Documentation détaillée des règles</value>
|
||||
</data>
|
||||
<data name="TbDnsObjectDoc" xml:space="preserve">
|
||||
<value>Saisie de DnsObject prise en charge (format JSON), cliquer pour voir la documentation</value>
|
||||
<value>Saisie DnsObject prise en charge (format JSON), cliquer pour doc</value>
|
||||
</data>
|
||||
<data name="SubUrlTips" xml:space="preserve">
|
||||
<value>Laissez vide pour les groupes ordinaires</value>
|
||||
@@ -898,7 +898,7 @@
|
||||
<value>Filtrage par alias (regex)</value>
|
||||
</data>
|
||||
<data name="TbDisplayLog" xml:space="preserve">
|
||||
<value>Afficher les journaux</value>
|
||||
<value>Afficher les logs</value>
|
||||
</data>
|
||||
<data name="TbEnableTunAs" xml:space="preserve">
|
||||
<value>Activer Tun</value>
|
||||
@@ -979,7 +979,7 @@
|
||||
<value>En attente du test (appuyer sur Échap pour arrêter)...</value>
|
||||
</data>
|
||||
<data name="TipDisplayLog" xml:space="preserve">
|
||||
<value>Désactivez ceci en cas de coupures anormales</value>
|
||||
<value>Désactiver cette option si coupure anormale</value>
|
||||
</data>
|
||||
<data name="MsgSkipSubscriptionUpdate" xml:space="preserve">
|
||||
<value>Mise à jour désactivée, abonnement ignoré</value>
|
||||
@@ -1009,10 +1009,10 @@
|
||||
<value>DNS personnalisé sing-box</value>
|
||||
</data>
|
||||
<data name="TbDnsSingboxObjectDoc" xml:space="preserve">
|
||||
<value>Veuillez renseigner la structure JSON DNS ; cliquer pour voir la documentation</value>
|
||||
<value>Saisissez la structure JSON DNS ; cliquez pour voir la doc.</value>
|
||||
</data>
|
||||
<data name="TbSettingDnsImportDefConfig" xml:space="preserve">
|
||||
<value>Cliquez pour importer la configuration DNS par défaut</value>
|
||||
<value>Cliquez pour importer la config DNS par défaut</value>
|
||||
</data>
|
||||
<data name="TbdomainStrategy4Singbox" xml:space="preserve">
|
||||
<value>Stratégie résolution domaine (sing-box)</value>
|
||||
@@ -1045,10 +1045,10 @@
|
||||
<value>Algo contrôle congestion</value>
|
||||
</data>
|
||||
<data name="LvPrevProfile" xml:space="preserve">
|
||||
<value>Alias de configuration du proxy amont</value>
|
||||
<value>Alias de config du proxy amont</value>
|
||||
</data>
|
||||
<data name="LvNextProfile" xml:space="preserve">
|
||||
<value>Alias de configuration du proxy aval</value>
|
||||
<value>Alias de config du proxy aval</value>
|
||||
</data>
|
||||
<data name="LvPrevProfileTip" xml:space="preserve">
|
||||
<value>Assurez-vous que l’alias config existe et est unique</value>
|
||||
@@ -1114,7 +1114,7 @@
|
||||
<value>Activer le fragmentation (Fragment)</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableCacheFile4Sbox" xml:space="preserve">
|
||||
<value>Activer le fichier de cache de sing-box (fichiers de reˋgles)</value>
|
||||
<value>Activer le fichier de cache de sing-box (fichiers règles)</value>
|
||||
</data>
|
||||
<data name="LvCustomRulesetPath4Singbox" xml:space="preserve">
|
||||
<value>Set de règles sing-box perso</value>
|
||||
@@ -1207,7 +1207,7 @@
|
||||
<value>Stratégie de résolution par défaut des sortants</value>
|
||||
</data>
|
||||
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
|
||||
<value>Orientation de la mise en page principale (redémarrage requis)</value>
|
||||
<value>Orientation mise en page principale (redémarrage requis)</value>
|
||||
</data>
|
||||
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
|
||||
<value>Adresse de résolution de domaine pour sortants</value>
|
||||
@@ -1330,7 +1330,7 @@
|
||||
<value>JSON brut XHTTP Extra, format : { XHTTPObject }</value>
|
||||
</data>
|
||||
<data name="TbSettingsHide2TrayWhenClose" xml:space="preserve">
|
||||
<value>Masquer dans la barre d’état lors de la fermeture de la fenêtre</value>
|
||||
<value>Masquer dans la barre d’état à la fermeture de la fenêtre</value>
|
||||
</data>
|
||||
<data name="TbSettingsMixedConcurrencyCount" xml:space="preserve">
|
||||
<value>Niveau de concurrence lors des tests multithread</value>
|
||||
@@ -1351,7 +1351,7 @@
|
||||
<value>Thème</value>
|
||||
</data>
|
||||
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
|
||||
<value>Copier la commande proxy terminal vers le presse-papiers</value>
|
||||
<value>Copier la cmd proxy terminal dans le presse-papiers</value>
|
||||
</data>
|
||||
<data name="SpeedtestingTestFailedPart" xml:space="preserve">
|
||||
<value>Recommencer le test des éléments échoués, {0} restants. Appuyez sur Échap pour arrêter...</value>
|
||||
@@ -1369,7 +1369,7 @@
|
||||
<value>Plage de ports sautés</value>
|
||||
</data>
|
||||
<data name="TbPorts7Tips" xml:space="preserve">
|
||||
<value>Écrase le port ; pour plusieurs groupes, séparez par des virgules (,)</value>
|
||||
<value>Écrase le port ; pour plusieurs groupes, séparer par virgules (,)</value>
|
||||
</data>
|
||||
<data name="menuGenGroupMultipleServer" xml:space="preserve">
|
||||
<value>Générer un groupe de stratégie depuis plusieurs profils</value>
|
||||
@@ -1447,7 +1447,7 @@
|
||||
<value>Valider les IP des domaines de la région concernée</value>
|
||||
</data>
|
||||
<data name="TbValidateDirectExpectedIPsDesc" xml:space="preserve">
|
||||
<value>Après configuration, les IP renvoyées pour les domaines régionaux (p. ex. geosite:cn) seront validées ; seules les IP attendues seront retournées</value>
|
||||
<value>Après config, les IP renvoyées des domaines régionaux (ex. geosite:cn) seront vérifiées ; seules les IP attendues seront retournées.</value>
|
||||
</data>
|
||||
<data name="TbCustomDNSEnable" xml:space="preserve">
|
||||
<value>Activer le DNS personnalisé</value>
|
||||
@@ -1471,7 +1471,7 @@
|
||||
<value>Modèle de configuration complet v2ray</value>
|
||||
</data>
|
||||
<data name="TbRayFullConfigTemplateDesc" xml:space="preserve">
|
||||
<value>Ajoute seulement la configuration sortante, routing.balancers et routing.rules.outboundTag. Voir la documentation.</value>
|
||||
<value>Ajoute seulement la config sortante, routing.balancers et routing.rules.outboundTag. Voir la doc.</value>
|
||||
</data>
|
||||
<data name="TbAddProxyProtocolOutboundOnly" xml:space="preserve">
|
||||
<value>N’ajoutez pas de sorties pour protocoles non-proxy.</value>
|
||||
@@ -1492,10 +1492,10 @@
|
||||
<value>Début de l’analyse et du traitement du contenu d’abonnement</value>
|
||||
</data>
|
||||
<data name="TbSelectProfile" xml:space="preserve">
|
||||
<value>Sélectionner une configuration</value>
|
||||
<value>Choisir une config.</value>
|
||||
</data>
|
||||
<data name="TbFakeIPTips" xml:space="preserve">
|
||||
<value>Actif globalement par défaut, avec filtrage FakeIP intégré ; ne fonctionne que dans sing-box</value>
|
||||
<value>Actif globalement par défaut, avec filtre FakeIP intégré ; ne fonctionne que dans sing-box</value>
|
||||
</data>
|
||||
<data name="PleaseAddAtLeastOneServer" xml:space="preserve">
|
||||
<value>Veuillez ajouter au moins une configuration</value>
|
||||
|
||||
@@ -94,8 +94,8 @@ public partial class CoreConfigV2rayService(Config config)
|
||||
|
||||
ret.Msg = ResUI.InitialConfiguration;
|
||||
|
||||
string result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
|
||||
string txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
|
||||
var result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
|
||||
var txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
|
||||
if (result.IsNullOrEmpty() || txtOutbound.IsNullOrEmpty())
|
||||
{
|
||||
ret.Msg = ResUI.FailedGetDefaultConfiguration;
|
||||
@@ -200,8 +200,8 @@ public partial class CoreConfigV2rayService(Config config)
|
||||
|
||||
ret.Msg = ResUI.InitialConfiguration;
|
||||
|
||||
string result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
|
||||
string txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
|
||||
var result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
|
||||
var txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
|
||||
if (result.IsNullOrEmpty() || txtOutbound.IsNullOrEmpty())
|
||||
{
|
||||
ret.Msg = ResUI.FailedGetDefaultConfiguration;
|
||||
|
||||
@@ -87,7 +87,7 @@ public partial class CoreConfigV2rayService
|
||||
}
|
||||
|
||||
var customOutboundsNode = new JsonArray();
|
||||
|
||||
|
||||
foreach (var outbound in v2rayConfig.outbounds)
|
||||
{
|
||||
if (outbound.protocol.ToLower() is "blackhole" or "dns" or "freedom")
|
||||
@@ -112,7 +112,7 @@ public partial class CoreConfigV2rayService
|
||||
}
|
||||
customOutboundsNode.Add(JsonUtils.DeepCopy(outbound));
|
||||
}
|
||||
|
||||
|
||||
if (fullConfigTemplateNode["outbounds"] is JsonArray templateOutbounds)
|
||||
{
|
||||
foreach (var outbound in templateOutbounds)
|
||||
@@ -120,7 +120,7 @@ public partial class CoreConfigV2rayService
|
||||
customOutboundsNode.Add(outbound?.DeepClone());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fullConfigTemplateNode["outbounds"] = customOutboundsNode;
|
||||
|
||||
return await Task.FromResult(JsonUtils.Serialize(fullConfigTemplateNode));
|
||||
|
||||
@@ -347,8 +347,8 @@ public partial class CoreConfigV2rayService
|
||||
if (obj is null)
|
||||
{
|
||||
List<string> servers = [];
|
||||
string[] arrDNS = normalDNS.Split(',');
|
||||
foreach (string str in arrDNS)
|
||||
var arrDNS = normalDNS.Split(',');
|
||||
foreach (var str in arrDNS)
|
||||
{
|
||||
servers.Add(str);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public partial class CoreConfigV2rayService
|
||||
|
||||
private Inbounds4Ray GetInbound(InItem inItem, EInboundProtocol protocol, bool bSocks)
|
||||
{
|
||||
string result = EmbedUtils.GetEmbedText(Global.V2raySampleInbound);
|
||||
var result = EmbedUtils.GetEmbedText(Global.V2raySampleInbound);
|
||||
if (result.IsNullOrEmpty())
|
||||
{
|
||||
return new();
|
||||
|
||||
@@ -453,16 +453,16 @@ public partial class CoreConfigV2rayService
|
||||
};
|
||||
|
||||
//request Host
|
||||
string request = EmbedUtils.GetEmbedText(Global.V2raySampleHttpRequestFileName);
|
||||
string[] arrHost = host.Split(',');
|
||||
string host2 = string.Join(",".AppendQuotes(), arrHost);
|
||||
var request = EmbedUtils.GetEmbedText(Global.V2raySampleHttpRequestFileName);
|
||||
var arrHost = host.Split(',');
|
||||
var host2 = string.Join(",".AppendQuotes(), arrHost);
|
||||
request = request.Replace("$requestHost$", $"{host2.AppendQuotes()}");
|
||||
request = request.Replace("$requestUserAgent$", $"{useragent.AppendQuotes()}");
|
||||
//Path
|
||||
string pathHttp = @"/";
|
||||
var pathHttp = @"/";
|
||||
if (path.IsNotEmpty())
|
||||
{
|
||||
string[] arrPath = path.Split(',');
|
||||
var arrPath = path.Split(',');
|
||||
pathHttp = string.Join(",".AppendQuotes(), arrPath);
|
||||
}
|
||||
request = request.Replace("$requestPath$", $"{pathHttp.AppendQuotes()}");
|
||||
@@ -623,10 +623,10 @@ public partial class CoreConfigV2rayService
|
||||
// Cache for chain proxies to avoid duplicate generation
|
||||
var nextProxyCache = new Dictionary<string, Outbounds4Ray?>();
|
||||
var prevProxyTags = new Dictionary<string, string?>(); // Map from profile name to tag
|
||||
int prevIndex = 0; // Index for prev outbounds
|
||||
var prevIndex = 0; // Index for prev outbounds
|
||||
|
||||
// Process nodes
|
||||
int index = 0;
|
||||
var index = 0;
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
index++;
|
||||
|
||||
@@ -6,7 +6,7 @@ public partial class CoreConfigV2rayService
|
||||
{
|
||||
if (_config.GuiItem.EnableStatistics || _config.GuiItem.DisplayRealTimeSpeed)
|
||||
{
|
||||
string tag = EInboundProtocol.api.ToString();
|
||||
var tag = EInboundProtocol.api.ToString();
|
||||
Metrics4Ray apiObj = new();
|
||||
Policy4Ray policyObj = new();
|
||||
SystemPolicy4Ray policySystemSetting = new();
|
||||
|
||||
@@ -167,7 +167,7 @@ public class UpdateService
|
||||
try
|
||||
{
|
||||
var coreInfo = CoreInfoManager.Instance.GetCoreInfo(type);
|
||||
string filePath = string.Empty;
|
||||
var filePath = string.Empty;
|
||||
foreach (var name in coreInfo.CoreExes)
|
||||
{
|
||||
var vName = Utils.GetBinPath(Utils.GetExeName(name), coreInfo.CoreType.ToString());
|
||||
@@ -180,14 +180,14 @@ public class UpdateService
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
string msg = string.Format(ResUI.NotFoundCore, @"", "", "");
|
||||
var msg = string.Format(ResUI.NotFoundCore, @"", "", "");
|
||||
//ShowMsg(true, msg);
|
||||
return new SemanticVersion("");
|
||||
}
|
||||
|
||||
var result = await Utils.GetCliWrapOutput(filePath, coreInfo.VersionArg);
|
||||
var echo = result ?? "";
|
||||
string version = string.Empty;
|
||||
var version = string.Empty;
|
||||
switch (type)
|
||||
{
|
||||
case ECoreType.v2fly:
|
||||
|
||||
@@ -211,7 +211,7 @@ public class ClashProxiesViewModel : MyReactiveObject
|
||||
}
|
||||
|
||||
//from api
|
||||
foreach (KeyValuePair<string, ProxiesItem> kv in _proxies)
|
||||
foreach (var kv in _proxies)
|
||||
{
|
||||
if (!Global.allowSelectType.Contains(kv.Value.type.ToLower()))
|
||||
{
|
||||
@@ -319,7 +319,7 @@ public class ClashProxiesViewModel : MyReactiveObject
|
||||
//from providers
|
||||
if (_providers != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, ProvidersItem> kv in _providers)
|
||||
foreach (var kv in _providers)
|
||||
{
|
||||
if (Global.proxyVehicleType.Contains(kv.Value.vehicleType.ToLower()))
|
||||
{
|
||||
|
||||
@@ -273,12 +273,12 @@ public class OptionSettingViewModel : MyReactiveObject
|
||||
NoticeManager.Instance.Enqueue(ResUI.FillLocalListeningPort);
|
||||
return;
|
||||
}
|
||||
var needReboot = (EnableStatistics != _config.GuiItem.EnableStatistics
|
||||
var needReboot = EnableStatistics != _config.GuiItem.EnableStatistics
|
||||
|| DisplayRealTimeSpeed != _config.GuiItem.DisplayRealTimeSpeed
|
||||
|| EnableDragDropSort != _config.UiItem.EnableDragDropSort
|
||||
|| EnableHWA != _config.GuiItem.EnableHWA
|
||||
|| CurrentFontFamily != _config.UiItem.CurrentFontFamily
|
||||
|| MainGirdOrientation != (int)_config.UiItem.MainGirdOrientation);
|
||||
|| MainGirdOrientation != (int)_config.UiItem.MainGirdOrientation;
|
||||
|
||||
//if (Utile.IsNullOrEmpty(Kcpmtu.ToString()) || !Utile.IsNumeric(Kcpmtu.ToString())
|
||||
// || Utile.IsNullOrEmpty(Kcptti.ToString()) || !Utile.IsNumeric(Kcptti.ToString())
|
||||
@@ -375,7 +375,7 @@ public class OptionSettingViewModel : MyReactiveObject
|
||||
|
||||
private async Task SaveCoreType()
|
||||
{
|
||||
for (int k = 1; k <= _config.CoreTypeItem.Count; k++)
|
||||
for (var k = 1; k <= _config.CoreTypeItem.Count; k++)
|
||||
{
|
||||
var item = _config.CoreTypeItem[k - 1];
|
||||
var type = string.Empty;
|
||||
|
||||
@@ -658,7 +658,7 @@ public class ProfilesViewModel : MyReactiveObject
|
||||
}
|
||||
|
||||
_dicHeaderSort.TryAdd(colName, true);
|
||||
_dicHeaderSort.TryGetValue(colName, out bool asc);
|
||||
_dicHeaderSort.TryGetValue(colName, out var asc);
|
||||
if (await ConfigHandler.SortServers(_config, _config.SubIndexId, colName, asc) != 0)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -215,7 +215,7 @@ public class RoutingRuleSettingViewModel : MyReactiveObject
|
||||
|
||||
private async Task SaveRoutingAsync()
|
||||
{
|
||||
string remarks = SelectedRouting.Remarks;
|
||||
var remarks = SelectedRouting.Remarks;
|
||||
if (remarks.IsNullOrEmpty())
|
||||
{
|
||||
NoticeManager.Instance.Enqueue(ResUI.PleaseFillRemarks);
|
||||
@@ -286,7 +286,7 @@ public class RoutingRuleSettingViewModel : MyReactiveObject
|
||||
return;
|
||||
}
|
||||
|
||||
DownloadService downloadHandle = new DownloadService();
|
||||
var downloadHandle = new DownloadService();
|
||||
var result = await downloadHandle.TryDownloadString(url, true, "");
|
||||
var ret = await AddBatchRoutingRulesAsync(SelectedRouting, result);
|
||||
if (ret == 0)
|
||||
@@ -298,7 +298,7 @@ public class RoutingRuleSettingViewModel : MyReactiveObject
|
||||
|
||||
private async Task<int> AddBatchRoutingRulesAsync(RoutingItem routingItem, string? clipboardData)
|
||||
{
|
||||
bool blReplace = false;
|
||||
var blReplace = false;
|
||||
if (await _updateView?.Invoke(EViewAction.AddBatchRoutingRulesYesNo, null) == false)
|
||||
{
|
||||
blReplace = true;
|
||||
|
||||
@@ -313,10 +313,10 @@ public class StatusBarViewModel : MyReactiveObject
|
||||
}
|
||||
|
||||
BlServers = true;
|
||||
for (int k = 0; k < lstModel.Count; k++)
|
||||
for (var k = 0; k < lstModel.Count; k++)
|
||||
{
|
||||
ProfileItem it = lstModel[k];
|
||||
string name = it.GetSummary();
|
||||
var name = it.GetSummary();
|
||||
|
||||
var item = new ComboItem() { ID = it.IndexId, Text = name };
|
||||
Servers.Add(item);
|
||||
@@ -394,10 +394,10 @@ public class StatusBarViewModel : MyReactiveObject
|
||||
{
|
||||
await SysProxyHandler.UpdateSysProxy(_config, false);
|
||||
|
||||
BlSystemProxyClear = (type == ESysProxyType.ForcedClear);
|
||||
BlSystemProxySet = (type == ESysProxyType.ForcedChange);
|
||||
BlSystemProxyNothing = (type == ESysProxyType.Unchanged);
|
||||
BlSystemProxyPac = (type == ESysProxyType.Pac);
|
||||
BlSystemProxyClear = type == ESysProxyType.ForcedClear;
|
||||
BlSystemProxySet = type == ESysProxyType.ForcedChange;
|
||||
BlSystemProxyNothing = type == ESysProxyType.Unchanged;
|
||||
BlSystemProxyPac = type == ESysProxyType.Pac;
|
||||
|
||||
if (blChange)
|
||||
{
|
||||
|
||||
@@ -10,15 +10,17 @@ public partial class App : Application
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
||||
|
||||
DataContext = StatusBarViewModel.Instance;
|
||||
}
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
AppManager.Instance.InitComponents();
|
||||
if (!Design.IsDesignMode)
|
||||
{
|
||||
AppManager.Instance.InitComponents();
|
||||
DataContext = StatusBarViewModel.Instance;
|
||||
}
|
||||
|
||||
desktop.Exit += OnExit;
|
||||
desktop.MainWindow = new MainWindow();
|
||||
|
||||
@@ -17,13 +17,13 @@ global using Avalonia.Markup.Xaml;
|
||||
global using Avalonia.Media;
|
||||
global using Avalonia.Media.Imaging;
|
||||
global using Avalonia.Platform;
|
||||
global using ReactiveUI.Avalonia;
|
||||
global using Avalonia.Styling;
|
||||
global using Avalonia.Threading;
|
||||
global using ReactiveUI;
|
||||
global using ReactiveUI.Fody.Helpers;
|
||||
global using DynamicData;
|
||||
global using MsBox.Avalonia.Enums;
|
||||
global using ReactiveUI;
|
||||
global using ReactiveUI.Avalonia;
|
||||
global using ReactiveUI.Fody.Helpers;
|
||||
global using ServiceLib;
|
||||
global using ServiceLib.Base;
|
||||
global using ServiceLib.Common;
|
||||
|
||||
@@ -54,12 +54,19 @@ internal class Program
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
{
|
||||
return AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
//.WithInterFont()
|
||||
.WithFontByDefault()
|
||||
.LogToTrace()
|
||||
.UseReactiveUI()
|
||||
.With(new MacOSPlatformOptions { ShowInDock = AppManager.Instance.Config.UiItem.MacOSShowInDock });
|
||||
var builder = AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
//.WithInterFont()
|
||||
.WithFontByDefault()
|
||||
.LogToTrace()
|
||||
.UseReactiveUI();
|
||||
|
||||
if (OperatingSystem.IsMacOS())
|
||||
{
|
||||
var showInDock = Design.IsDesignMode || AppManager.Instance.Config.UiItem.MacOSShowInDock;
|
||||
builder = builder.With(new MacOSPlatformOptions { ShowInDock = showInDock });
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ public partial class AddGroupServerWindow : WindowBase<AddGroupServerViewModel>
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => Close();
|
||||
lstChild.SelectionChanged += LstChild_SelectionChanged;
|
||||
|
||||
ViewModel = new AddGroupServerViewModel(profileItem, UpdateViewHandler);
|
||||
@@ -32,11 +32,11 @@ public partial class AddGroupServerWindow : WindowBase<AddGroupServerViewModel>
|
||||
switch (profileItem.ConfigType)
|
||||
{
|
||||
case EConfigType.PolicyGroup:
|
||||
this.Title = ResUI.TbConfigTypePolicyGroup;
|
||||
Title = ResUI.TbConfigTypePolicyGroup;
|
||||
break;
|
||||
|
||||
case EConfigType.ProxyChain:
|
||||
this.Title = ResUI.TbConfigTypeProxyChain;
|
||||
Title = ResUI.TbConfigTypeProxyChain;
|
||||
gridPolicyGroup.IsVisible = false;
|
||||
break;
|
||||
}
|
||||
@@ -64,7 +64,7 @@ public partial class AddGroupServerWindow : WindowBase<AddGroupServerViewModel>
|
||||
menuSelectAllChild.Click += (s, e) => lstChild.SelectAll();
|
||||
|
||||
// Keyboard shortcuts when focus is within grid
|
||||
this.AddHandler(KeyDownEvent, AddGroupServerWindow_KeyDown, RoutingStrategies.Tunnel);
|
||||
AddHandler(KeyDownEvent, AddGroupServerWindow_KeyDown, RoutingStrategies.Tunnel);
|
||||
lstChild.LoadingRow += LstChild_LoadingRow;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public partial class AddGroupServerWindow : WindowBase<AddGroupServerViewModel>
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.Close(true);
|
||||
Close(true);
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -14,8 +14,8 @@ public partial class AddServer2Window : WindowBase<AddServer2ViewModel>
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => Close();
|
||||
ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler);
|
||||
|
||||
cmbCoreType.ItemsSource = Utils.GetEnumNames<ECoreType>().Where(t => t != ECoreType.v2rayN.ToString()).ToList().AppendEmpty();
|
||||
@@ -39,7 +39,7 @@ public partial class AddServer2Window : WindowBase<AddServer2ViewModel>
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.Close(true);
|
||||
Close(true);
|
||||
break;
|
||||
|
||||
case EViewAction.BrowseServer:
|
||||
|
||||
@@ -13,8 +13,8 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => Close();
|
||||
cmbNetwork.SelectionChanged += CmbNetwork_SelectionChanged;
|
||||
cmbStreamSecurity.SelectionChanged += CmbStreamSecurity_SelectionChanged;
|
||||
btnGUID.Click += btnGUID_Click;
|
||||
@@ -196,7 +196,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||
});
|
||||
|
||||
this.Title = $"{profileItem.ConfigType}";
|
||||
Title = $"{profileItem.ConfigType}";
|
||||
}
|
||||
|
||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||
@@ -204,7 +204,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.Close(true);
|
||||
Close(true);
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -7,7 +7,7 @@ public partial class ClashProxiesView : ReactiveUserControl<ClashProxiesViewMode
|
||||
InitializeComponent();
|
||||
ViewModel = new ClashProxiesViewModel(UpdateViewHandler);
|
||||
lstProxyDetails.DoubleTapped += LstProxyDetails_DoubleTapped;
|
||||
this.KeyDown += ClashProxiesView_KeyDown;
|
||||
KeyDown += ClashProxiesView_KeyDown;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
|
||||
|
||||
_config = AppManager.Instance.Config;
|
||||
Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
btnCancel.Click += (s, e) => Close();
|
||||
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
|
||||
|
||||
cmbRayFreedomDNSStrategy.ItemsSource = Global.DomainStrategy4Freedoms;
|
||||
@@ -77,7 +77,7 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.Close(true);
|
||||
Close(true);
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -12,7 +12,7 @@ public partial class FullConfigTemplateWindow : WindowBase<FullConfigTemplateVie
|
||||
|
||||
_config = AppManager.Instance.Config;
|
||||
Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
btnCancel.Click += (s, e) => Close();
|
||||
ViewModel = new FullConfigTemplateViewModel(UpdateViewHandler);
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
@@ -36,7 +36,7 @@ public partial class FullConfigTemplateWindow : WindowBase<FullConfigTemplateVie
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.Close(true);
|
||||
Close(true);
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -17,8 +17,8 @@ public partial class GlobalHotkeySettingWindow : WindowBase<GlobalHotkeySettingV
|
||||
|
||||
HotkeyManager.Instance.IsPause = true;
|
||||
Loaded += Window_Loaded;
|
||||
this.Closing += (s, e) => HotkeyManager.Instance.IsPause = false;
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
Closing += (s, e) => HotkeyManager.Instance.IsPause = false;
|
||||
btnCancel.Click += (s, e) => Close();
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
@@ -34,7 +34,7 @@ public partial class GlobalHotkeySettingWindow : WindowBase<GlobalHotkeySettingV
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.Close(true);
|
||||
Close(true);
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -21,7 +21,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||
_config = AppManager.Instance.Config;
|
||||
_manager = new WindowNotificationManager(TopLevel.GetTopLevel(this)) { MaxItems = 3, Position = NotificationPosition.TopRight };
|
||||
|
||||
this.KeyDown += MainWindow_KeyDown;
|
||||
KeyDown += MainWindow_KeyDown;
|
||||
menuSettingsSetUWP.Click += menuSettingsSetUWP_Click;
|
||||
menuPromotion.Click += menuPromotion_Click;
|
||||
menuCheckUpdate.Click += MenuCheckUpdate_Click;
|
||||
@@ -153,14 +153,14 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||
|
||||
if (Utils.IsWindows())
|
||||
{
|
||||
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
|
||||
ThreadPool.RegisterWaitForSingleObject(Program.ProgramStarted, OnProgramStarted, null, -1, false);
|
||||
HotkeyManager.Instance.Init(_config, OnHotkeyHandler);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Title = $"{Utils.GetVersion()}";
|
||||
Title = $"{Utils.GetVersion()}";
|
||||
|
||||
menuRebootAsAdmin.IsVisible = false;
|
||||
menuSettingsSetUWP.IsVisible = false;
|
||||
@@ -168,9 +168,9 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||
}
|
||||
menuAddServerViaScan.IsVisible = false;
|
||||
|
||||
if (_config.UiItem.AutoHideStartup)
|
||||
if (_config.UiItem.AutoHideStartup && Utils.IsWindows())
|
||||
{
|
||||
this.WindowState = WindowState.Minimized;
|
||||
WindowState = WindowState.Minimized;
|
||||
}
|
||||
|
||||
AddHelpMenuItem();
|
||||
@@ -402,32 +402,32 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||
public void ShowHideWindow(bool? blShow)
|
||||
{
|
||||
var bl = blShow ??
|
||||
Utils.IsLinux()
|
||||
(Utils.IsLinux()
|
||||
? (!_config.UiItem.ShowInTaskbar ^ (WindowState == WindowState.Minimized))
|
||||
: !_config.UiItem.ShowInTaskbar;
|
||||
: !_config.UiItem.ShowInTaskbar);
|
||||
if (bl)
|
||||
{
|
||||
this.Show();
|
||||
if (this.WindowState == WindowState.Minimized)
|
||||
Show();
|
||||
if (WindowState == WindowState.Minimized)
|
||||
{
|
||||
this.WindowState = WindowState.Normal;
|
||||
WindowState = WindowState.Normal;
|
||||
}
|
||||
this.Activate();
|
||||
this.Focus();
|
||||
Activate();
|
||||
Focus();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Utils.IsLinux() && _config.UiItem.Hide2TrayWhenClose == false)
|
||||
{
|
||||
this.WindowState = WindowState.Minimized;
|
||||
WindowState = WindowState.Minimized;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var ownedWindow in this.OwnedWindows)
|
||||
foreach (var ownedWindow in OwnedWindows)
|
||||
{
|
||||
ownedWindow.Close();
|
||||
}
|
||||
this.Hide();
|
||||
Hide();
|
||||
}
|
||||
|
||||
_config.UiItem.ShowInTaskbar = bl;
|
||||
|
||||
@@ -11,7 +11,7 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
|
||||
InitializeComponent();
|
||||
|
||||
Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
btnCancel.Click += (s, e) => Close();
|
||||
_config = AppManager.Instance.Config;
|
||||
|
||||
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
|
||||
@@ -153,7 +153,7 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.Close(true);
|
||||
Close(true);
|
||||
break;
|
||||
|
||||
case EViewAction.InitSettingFont:
|
||||
|
||||
@@ -13,8 +13,8 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => Close();
|
||||
clbProtocol.SelectionChanged += ClbProtocol_SelectionChanged;
|
||||
clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged;
|
||||
|
||||
@@ -61,7 +61,7 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.Close(true);
|
||||
Close(true);
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -14,9 +14,9 @@ public partial class RoutingRuleSettingWindow : WindowBase<RoutingRuleSettingVie
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
this.KeyDown += RoutingRuleSettingWindow_KeyDown;
|
||||
Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => Close();
|
||||
KeyDown += RoutingRuleSettingWindow_KeyDown;
|
||||
lstRules.SelectionChanged += lstRules_SelectionChanged;
|
||||
lstRules.DoubleTapped += LstRules_DoubleTapped;
|
||||
menuRuleSelectAll.Click += menuRuleSelectAll_Click;
|
||||
@@ -64,7 +64,7 @@ public partial class RoutingRuleSettingWindow : WindowBase<RoutingRuleSettingVie
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.Close(true);
|
||||
Close(true);
|
||||
break;
|
||||
|
||||
case EViewAction.ShowYesNo:
|
||||
|
||||
@@ -12,9 +12,9 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||
InitializeComponent();
|
||||
|
||||
Loaded += Window_Loaded;
|
||||
this.Closing += RoutingSettingWindow_Closing;
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
this.KeyDown += RoutingSettingWindow_KeyDown;
|
||||
Closing += RoutingSettingWindow_Closing;
|
||||
btnCancel.Click += (s, e) => Close();
|
||||
KeyDown += RoutingSettingWindow_KeyDown;
|
||||
lstRoutings.SelectionChanged += lstRoutings_SelectionChanged;
|
||||
lstRoutings.DoubleTapped += LstRoutings_DoubleTapped;
|
||||
menuRoutingAdvancedSelectAll.Click += menuRoutingAdvancedSelectAll_Click;
|
||||
@@ -48,7 +48,7 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.Close(true);
|
||||
Close(true);
|
||||
break;
|
||||
|
||||
case EViewAction.ShowYesNo:
|
||||
@@ -116,7 +116,7 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||
private void btnCancel_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
_manualClose = true;
|
||||
this.Close(ViewModel?.IsModified);
|
||||
Close(ViewModel?.IsModified);
|
||||
}
|
||||
|
||||
private void RoutingSettingWindow_Closing(object? sender, WindowClosingEventArgs e)
|
||||
|
||||
@@ -14,7 +14,7 @@ public partial class SubEditWindow : WindowBase<SubEditViewModel>
|
||||
InitializeComponent();
|
||||
|
||||
Loaded += Window_Loaded;
|
||||
btnCancel.Click += (s, e) => this.Close();
|
||||
btnCancel.Click += (s, e) => Close();
|
||||
|
||||
ViewModel = new SubEditViewModel(subItem, UpdateViewHandler);
|
||||
|
||||
@@ -45,7 +45,7 @@ public partial class SubEditWindow : WindowBase<SubEditViewModel>
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.Close(true);
|
||||
Close(true);
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -14,8 +14,8 @@ public partial class SubSettingWindow : WindowBase<SubSettingViewModel>
|
||||
|
||||
menuClose.Click += menuClose_Click;
|
||||
Loaded += Window_Loaded;
|
||||
this.Closing += SubSettingWindow_Closing;
|
||||
this.KeyDown += SubSettingWindow_KeyDown;
|
||||
Closing += SubSettingWindow_Closing;
|
||||
KeyDown += SubSettingWindow_KeyDown;
|
||||
ViewModel = new SubSettingViewModel(UpdateViewHandler);
|
||||
lstSubscription.DoubleTapped += LstSubscription_DoubleTapped;
|
||||
lstSubscription.SelectionChanged += LstSubscription_SelectionChanged;
|
||||
@@ -37,7 +37,7 @@ public partial class SubSettingWindow : WindowBase<SubSettingViewModel>
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.Close();
|
||||
Close();
|
||||
break;
|
||||
|
||||
case EViewAction.ShowYesNo:
|
||||
@@ -89,7 +89,7 @@ public partial class SubSettingWindow : WindowBase<SubSettingViewModel>
|
||||
private void menuClose_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
_manualClose = true;
|
||||
this.Close(ViewModel?.IsModified);
|
||||
Close(ViewModel?.IsModified);
|
||||
}
|
||||
|
||||
private void SubSettingWindow_Closing(object? sender, WindowClosingEventArgs e)
|
||||
|
||||
@@ -9,7 +9,7 @@ public partial class SudoPasswordInputView : UserControl
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Loaded += (s, e) => txtPassword.Focus();
|
||||
Loaded += (s, e) => txtPassword.Focus();
|
||||
|
||||
btnSave.Click += async (_, _) => await SavePasswordAsync();
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ public partial class App : Application
|
||||
|
||||
public App()
|
||||
{
|
||||
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
|
||||
DispatcherUnhandledException += App_DispatcherUnhandledException;
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
||||
}
|
||||
@@ -23,7 +23,7 @@ public partial class App : Application
|
||||
var exePathKey = Utils.GetMd5(Utils.GetExePath());
|
||||
|
||||
var rebootas = (e.Args ?? Array.Empty<string>()).Any(t => t == Global.RebootAs);
|
||||
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, exePathKey, out bool bCreatedNew);
|
||||
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, exePathKey, out var bCreatedNew);
|
||||
if (!rebootas && !bCreatedNew)
|
||||
{
|
||||
ProgramStarted.Set();
|
||||
|
||||
@@ -2,9 +2,9 @@ using System.Drawing;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace v2rayN;
|
||||
namespace v2rayN.Common;
|
||||
|
||||
public class QRCodeUtils
|
||||
public class QRCodeWindowsUtils
|
||||
{
|
||||
public static ImageSource? GetQRCode(string? strContent)
|
||||
{
|
||||
@@ -14,7 +14,7 @@ public class QRCodeUtils
|
||||
}
|
||||
try
|
||||
{
|
||||
var qrCodeImage = ServiceLib.Common.QRCodeUtils.GenQRCode(strContent);
|
||||
var qrCodeImage = QRCodeUtils.GenQRCode(strContent);
|
||||
return qrCodeImage is null ? null : ByteToImage(qrCodeImage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace v2rayN;
|
||||
namespace v2rayN.Common;
|
||||
|
||||
internal class UI
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace v2rayN;
|
||||
namespace v2rayN.Common;
|
||||
|
||||
internal static class WindowsUtils
|
||||
{
|
||||
@@ -40,13 +40,13 @@ internal static class WindowsUtils
|
||||
}
|
||||
|
||||
[DllImport("dwmapi.dll")]
|
||||
public static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attribute, ref int attributeValue, uint attributeSize);
|
||||
public static extern int DwmSetWindowAttribute(nint hwnd, DWMWINDOWATTRIBUTE attribute, ref int attributeValue, uint attributeSize);
|
||||
|
||||
public static ImageSource IconToImageSource(Icon icon)
|
||||
{
|
||||
return Imaging.CreateBitmapSourceFromHIcon(
|
||||
icon.Handle,
|
||||
new System.Windows.Int32Rect(0, 0, icon.Width, icon.Height),
|
||||
new Int32Rect(0, 0, icon.Width, icon.Height),
|
||||
BitmapSizeOptions.FromEmptyOptions());
|
||||
}
|
||||
|
||||
@@ -65,9 +65,9 @@ internal static class WindowsUtils
|
||||
private static void SetDarkBorder(Window window, bool dark)
|
||||
{
|
||||
// Make sure the handle is created before the window is shown
|
||||
IntPtr hWnd = new WindowInteropHelper(window).EnsureHandle();
|
||||
int attribute = dark ? 1 : 0;
|
||||
uint attributeSize = (uint)Marshal.SizeOf(attribute);
|
||||
var hWnd = new WindowInteropHelper(window).EnsureHandle();
|
||||
var attribute = dark ? 1 : 0;
|
||||
var attributeSize = (uint)Marshal.SizeOf(attribute);
|
||||
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, ref attribute, attributeSize);
|
||||
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, ref attribute, attributeSize);
|
||||
}
|
||||
|
||||
@@ -31,3 +31,4 @@ global using ServiceLib.Manager;
|
||||
global using ServiceLib.Models;
|
||||
global using ServiceLib.Resx;
|
||||
global using ServiceLib.ViewModels;
|
||||
global using v2rayN.Common;
|
||||
|
||||
@@ -43,7 +43,7 @@ public sealed class HotkeyManager
|
||||
modifiers |= KeyModifiers.Alt;
|
||||
}
|
||||
|
||||
key = key << 16 | (int)modifiers;
|
||||
key = (key << 16) | (int)modifiers;
|
||||
if (!_hotkeyTriggerDic.ContainsKey(key))
|
||||
{
|
||||
_hotkeyTriggerDic.Add(key, new() { item.EGlobalHotkey });
|
||||
@@ -103,7 +103,7 @@ public sealed class HotkeyManager
|
||||
private (int fsModifiers, int vKey, string hotkeyStr, List<string> Names) GetHotkeyInfo(int hotkeyCode)
|
||||
{
|
||||
var fsModifiers = hotkeyCode & 0xffff;
|
||||
var vKey = hotkeyCode >> 16 & 0xffff;
|
||||
var vKey = (hotkeyCode >> 16) & 0xffff;
|
||||
var hotkeyStr = new StringBuilder();
|
||||
var names = new List<string>();
|
||||
|
||||
|
||||
@@ -60,18 +60,18 @@ public sealed class WindowsManager
|
||||
return null;
|
||||
}
|
||||
|
||||
Color color = ColorTranslator.FromHtml("#3399CC");
|
||||
int index = (int)config.SystemProxyItem.SysProxyType;
|
||||
var color = ColorTranslator.FromHtml("#3399CC");
|
||||
var index = (int)config.SystemProxyItem.SysProxyType;
|
||||
if (index > 0)
|
||||
{
|
||||
color = (new[] { Color.Red, Color.Purple, Color.DarkGreen, Color.Orange, Color.DarkSlateBlue, Color.RoyalBlue })[index - 1];
|
||||
}
|
||||
|
||||
int width = 128;
|
||||
int height = 128;
|
||||
var width = 128;
|
||||
var height = 128;
|
||||
|
||||
Bitmap bitmap = new(width, height);
|
||||
Graphics graphics = Graphics.FromImage(bitmap);
|
||||
var graphics = Graphics.FromImage(bitmap);
|
||||
SolidBrush drawBrush = new(color);
|
||||
|
||||
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
||||
@@ -79,7 +79,7 @@ public sealed class WindowsManager
|
||||
graphics.DrawImage(new Bitmap(item.CustomIcon), 0, 0, width, height);
|
||||
graphics.FillEllipse(drawBrush, width / 2, width / 2, width / 2, width / 2);
|
||||
|
||||
Icon createdIcon = Icon.FromHandle(bitmap.GetHicon());
|
||||
var createdIcon = Icon.FromHandle(bitmap.GetHicon());
|
||||
|
||||
drawBrush.Dispose();
|
||||
graphics.Dispose();
|
||||
|
||||
@@ -6,9 +6,9 @@ public partial class AddGroupServerWindow
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
this.Loaded += Window_Loaded;
|
||||
this.PreviewKeyDown += AddGroupServerWindow_PreviewKeyDown;
|
||||
Owner = Application.Current.MainWindow;
|
||||
Loaded += Window_Loaded;
|
||||
PreviewKeyDown += AddGroupServerWindow_PreviewKeyDown;
|
||||
lstChild.SelectionChanged += LstChild_SelectionChanged;
|
||||
menuSelectAllChild.Click += MenuSelectAllChild_Click;
|
||||
|
||||
@@ -27,11 +27,11 @@ public partial class AddGroupServerWindow
|
||||
switch (profileItem.ConfigType)
|
||||
{
|
||||
case EConfigType.PolicyGroup:
|
||||
this.Title = ResUI.TbConfigTypePolicyGroup;
|
||||
Title = ResUI.TbConfigTypePolicyGroup;
|
||||
break;
|
||||
|
||||
case EConfigType.ProxyChain:
|
||||
this.Title = ResUI.TbConfigTypeProxyChain;
|
||||
Title = ResUI.TbConfigTypeProxyChain;
|
||||
gridPolicyGroup.Visibility = Visibility.Collapsed;
|
||||
break;
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public partial class AddGroupServerWindow
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -6,8 +6,8 @@ public partial class AddServer2Window
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
this.Loaded += Window_Loaded;
|
||||
Owner = Application.Current.MainWindow;
|
||||
Loaded += Window_Loaded;
|
||||
ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler);
|
||||
|
||||
cmbCoreType.ItemsSource = Utils.GetEnumNames<ECoreType>().Where(t => t != ECoreType.v2rayN.ToString()).ToList().AppendEmpty();
|
||||
@@ -32,11 +32,11 @@ public partial class AddServer2Window
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
|
||||
case EViewAction.BrowseServer:
|
||||
if (UI.OpenFileDialog(out string fileName, "Config|*.json|YAML|*.yaml;*.yml|All|*.*") != true)
|
||||
if (UI.OpenFileDialog(out var fileName, "Config|*.json|YAML|*.yaml;*.yml|All|*.*") != true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ public partial class AddServerWindow
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
this.Loaded += Window_Loaded;
|
||||
Owner = Application.Current.MainWindow;
|
||||
Loaded += Window_Loaded;
|
||||
cmbNetwork.SelectionChanged += CmbNetwork_SelectionChanged;
|
||||
cmbStreamSecurity.SelectionChanged += CmbStreamSecurity_SelectionChanged;
|
||||
btnGUID.Click += btnGUID_Click;
|
||||
@@ -191,7 +191,7 @@ public partial class AddServerWindow
|
||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||
});
|
||||
|
||||
this.Title = $"{profileItem.ConfigType}";
|
||||
Title = $"{profileItem.ConfigType}";
|
||||
WindowsUtils.SetDarkBorder(this, AppManager.Instance.Config.UiItem.CurrentTheme);
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ public partial class AddServerWindow
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -28,7 +28,7 @@ public partial class BackupAndRestoreView
|
||||
|
||||
private void MenuLocalBackup_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (UI.SaveFileDialog(out string fileName, "Zip|*.zip") != true)
|
||||
if (UI.SaveFileDialog(out var fileName, "Zip|*.zip") != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -37,7 +37,7 @@ public partial class BackupAndRestoreView
|
||||
|
||||
private void MenuLocalRestore_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (UI.OpenFileDialog(out string fileName, "Zip|*.zip|All|*.*") != true)
|
||||
if (UI.OpenFileDialog(out var fileName, "Zip|*.zip|All|*.*") != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ public partial class DNSSettingWindow
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
Owner = Application.Current.MainWindow;
|
||||
_config = AppManager.Instance.Config;
|
||||
|
||||
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
|
||||
@@ -78,7 +78,7 @@ public partial class DNSSettingWindow
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -8,7 +8,7 @@ public partial class FullConfigTemplateWindow
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
Owner = Application.Current.MainWindow;
|
||||
_config = AppManager.Instance.Config;
|
||||
|
||||
ViewModel = new FullConfigTemplateViewModel(UpdateViewHandler);
|
||||
@@ -35,7 +35,7 @@ public partial class FullConfigTemplateWindow
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -11,14 +11,14 @@ public partial class GlobalHotkeySettingWindow
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
Owner = Application.Current.MainWindow;
|
||||
|
||||
ViewModel = new GlobalHotkeySettingViewModel(UpdateViewHandler);
|
||||
|
||||
btnReset.Click += btnReset_Click;
|
||||
|
||||
HotkeyManager.Instance.IsPause = true;
|
||||
this.Closing += (s, e) => HotkeyManager.Instance.IsPause = false;
|
||||
Closing += (s, e) => HotkeyManager.Instance.IsPause = false;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
@@ -35,7 +35,7 @@ public partial class GlobalHotkeySettingWindow
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -19,8 +19,8 @@ public partial class MainWindow
|
||||
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
|
||||
|
||||
App.Current.SessionEnding += Current_SessionEnding;
|
||||
this.Closing += MainWindow_Closing;
|
||||
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
|
||||
Closing += MainWindow_Closing;
|
||||
PreviewKeyDown += MainWindow_PreviewKeyDown;
|
||||
menuSettingsSetUWP.Click += menuSettingsSetUWP_Click;
|
||||
menuPromotion.Click += menuPromotion_Click;
|
||||
menuClose.Click += menuClose_Click;
|
||||
@@ -150,10 +150,10 @@ public partial class MainWindow
|
||||
.DisposeWith(disposables);
|
||||
});
|
||||
|
||||
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
if (_config.UiItem.AutoHideStartup)
|
||||
{
|
||||
this.WindowState = WindowState.Minimized;
|
||||
WindowState = WindowState.Minimized;
|
||||
}
|
||||
|
||||
if (!_config.GuiItem.EnableHWA)
|
||||
@@ -187,35 +187,35 @@ public partial class MainWindow
|
||||
case EViewAction.AddServerWindow:
|
||||
if (obj is null)
|
||||
return false;
|
||||
return (new AddServerWindow((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
return new AddServerWindow((ProfileItem)obj).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.AddServer2Window:
|
||||
if (obj is null)
|
||||
return false;
|
||||
return (new AddServer2Window((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
return new AddServer2Window((ProfileItem)obj).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.AddGroupServerWindow:
|
||||
if (obj is null)
|
||||
return false;
|
||||
return (new AddGroupServerWindow((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
return new AddGroupServerWindow((ProfileItem)obj).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.DNSSettingWindow:
|
||||
return (new DNSSettingWindow().ShowDialog() ?? false);
|
||||
return new DNSSettingWindow().ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.RoutingSettingWindow:
|
||||
return (new RoutingSettingWindow().ShowDialog() ?? false);
|
||||
return new RoutingSettingWindow().ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.OptionSettingWindow:
|
||||
return (new OptionSettingWindow().ShowDialog() ?? false);
|
||||
return new OptionSettingWindow().ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.FullConfigTemplateWindow:
|
||||
return (new FullConfigTemplateWindow().ShowDialog() ?? false);
|
||||
return new FullConfigTemplateWindow().ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.GlobalHotkeySettingWindow:
|
||||
return (new GlobalHotkeySettingWindow().ShowDialog() ?? false);
|
||||
return new GlobalHotkeySettingWindow().ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.SubSettingWindow:
|
||||
return (new SubSettingWindow().ShowDialog() ?? false);
|
||||
return new SubSettingWindow().ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.ScanScreenTask:
|
||||
await ScanScreenTaskAsync();
|
||||
@@ -328,7 +328,7 @@ public partial class MainWindow
|
||||
|
||||
if (Application.Current?.MainWindow is Window window)
|
||||
{
|
||||
var bytes = QRCodeUtils.CaptureScreen(window);
|
||||
var bytes = QRCodeWindowsUtils.CaptureScreen(window);
|
||||
await ViewModel?.ScanScreenResult(bytes);
|
||||
}
|
||||
|
||||
@@ -372,7 +372,7 @@ public partial class MainWindow
|
||||
this?.Show();
|
||||
if (this?.WindowState == WindowState.Minimized)
|
||||
{
|
||||
this.WindowState = WindowState.Normal;
|
||||
WindowState = WindowState.Normal;
|
||||
}
|
||||
this?.Activate();
|
||||
this?.Focus();
|
||||
|
||||
@@ -31,10 +31,10 @@ public partial class MsgView
|
||||
case EViewAction.DispatcherShowMsg:
|
||||
if (obj is null)
|
||||
return false;
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
Application.Current?.Dispatcher.Invoke(() =>
|
||||
{
|
||||
ShowMsg(obj);
|
||||
}), DispatcherPriority.ApplicationIdle);
|
||||
}, DispatcherPriority.ApplicationIdle);
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -10,7 +10,7 @@ public partial class OptionSettingWindow
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
Owner = Application.Current.MainWindow;
|
||||
_config = AppManager.Instance.Config;
|
||||
|
||||
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
|
||||
@@ -136,7 +136,7 @@ public partial class OptionSettingWindow
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
|
||||
case EViewAction.InitSettingFont:
|
||||
@@ -168,12 +168,12 @@ public partial class OptionSettingWindow
|
||||
foreach (var ttf in files)
|
||||
{
|
||||
var families = Fonts.GetFontFamilies(Utils.GetFontsPath(ttf));
|
||||
foreach (FontFamily family in families)
|
||||
foreach (var family in families)
|
||||
{
|
||||
var typefaces = family.GetTypefaces();
|
||||
foreach (Typeface typeface in typefaces)
|
||||
foreach (var typeface in typefaces)
|
||||
{
|
||||
typeface.TryGetGlyphTypeface(out GlyphTypeface glyph);
|
||||
typeface.TryGetGlyphTypeface(out var glyph);
|
||||
//var fontFace = glyph.Win32FaceNames[new CultureInfo("en-us")];
|
||||
//if (!fontFace.Equals("Regular") && !fontFace.Equals("Normal"))
|
||||
//{
|
||||
|
||||
@@ -71,7 +71,7 @@ public partial class ProfilesSelectWindow
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -127,7 +127,7 @@ public partial class ProfilesView
|
||||
case EViewAction.SaveFileDialog:
|
||||
if (obj is null)
|
||||
return false;
|
||||
if (UI.SaveFileDialog(out string fileName, "Config|*.json") != true)
|
||||
if (UI.SaveFileDialog(out var fileName, "Config|*.json") != true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -137,17 +137,17 @@ public partial class ProfilesView
|
||||
case EViewAction.AddServerWindow:
|
||||
if (obj is null)
|
||||
return false;
|
||||
return (new AddServerWindow((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
return new AddServerWindow((ProfileItem)obj).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.AddServer2Window:
|
||||
if (obj is null)
|
||||
return false;
|
||||
return (new AddServer2Window((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
return new AddServer2Window((ProfileItem)obj).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.AddGroupServerWindow:
|
||||
if (obj is null)
|
||||
return false;
|
||||
return (new AddGroupServerWindow((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
return new AddGroupServerWindow((ProfileItem)obj).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.ShareServer:
|
||||
if (obj is null)
|
||||
@@ -158,7 +158,7 @@ public partial class ProfilesView
|
||||
case EViewAction.SubEditWindow:
|
||||
if (obj is null)
|
||||
return false;
|
||||
return (new SubEditWindow((SubItem)obj)).ShowDialog() ?? false;
|
||||
return new SubEditWindow((SubItem)obj).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.DispatcherRefreshServersBiz:
|
||||
Application.Current?.Dispatcher.Invoke(RefreshServersBiz, DispatcherPriority.Normal);
|
||||
@@ -170,7 +170,7 @@ public partial class ProfilesView
|
||||
|
||||
public async void ShareServer(string url)
|
||||
{
|
||||
var img = QRCodeUtils.GetQRCode(url);
|
||||
var img = QRCodeWindowsUtils.GetQRCode(url);
|
||||
var dialog = new QrcodeView()
|
||||
{
|
||||
imgQrcode = { Source = img },
|
||||
@@ -415,8 +415,8 @@ public partial class ProfilesView
|
||||
private void LstProfiles_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
// Get the current mouse position
|
||||
Point mousePos = e.GetPosition(null);
|
||||
Vector diff = startPoint - mousePos;
|
||||
var mousePos = e.GetPosition(null);
|
||||
var diff = startPoint - mousePos;
|
||||
|
||||
if (e.LeftButton == MouseButtonState.Pressed &&
|
||||
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
|
||||
@@ -429,7 +429,7 @@ public partial class ProfilesView
|
||||
if (listViewItem == null)
|
||||
return; // Abort
|
||||
// Find the data behind the ListViewItem
|
||||
ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
|
||||
var item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
|
||||
if (item == null)
|
||||
return; // Abort
|
||||
// Initialize the drag & drop operation
|
||||
@@ -462,7 +462,7 @@ public partial class ProfilesView
|
||||
return;
|
||||
}
|
||||
// Find the data behind the Item
|
||||
ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
|
||||
var item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
|
||||
if (item == null)
|
||||
return;
|
||||
// Move item into observable collection
|
||||
|
||||
@@ -6,8 +6,8 @@ public partial class RoutingRuleDetailsWindow
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
this.Loaded += Window_Loaded;
|
||||
Owner = Application.Current.MainWindow;
|
||||
Loaded += Window_Loaded;
|
||||
clbProtocol.SelectionChanged += ClbProtocol_SelectionChanged;
|
||||
clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged;
|
||||
|
||||
@@ -54,7 +54,7 @@ public partial class RoutingRuleDetailsWindow
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -6,9 +6,9 @@ public partial class RoutingRuleSettingWindow
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
this.Loaded += Window_Loaded;
|
||||
this.PreviewKeyDown += RoutingRuleSettingWindow_PreviewKeyDown;
|
||||
Owner = Application.Current.MainWindow;
|
||||
Loaded += Window_Loaded;
|
||||
PreviewKeyDown += RoutingRuleSettingWindow_PreviewKeyDown;
|
||||
lstRules.SelectionChanged += lstRules_SelectionChanged;
|
||||
lstRules.MouseDoubleClick += LstRules_MouseDoubleClick;
|
||||
menuRuleSelectAll.Click += menuRuleSelectAll_Click;
|
||||
@@ -57,7 +57,7 @@ public partial class RoutingRuleSettingWindow
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
|
||||
case EViewAction.ShowYesNo:
|
||||
@@ -80,11 +80,11 @@ public partial class RoutingRuleSettingWindow
|
||||
|
||||
if (obj is null)
|
||||
return false;
|
||||
return (new RoutingRuleDetailsWindow((RulesItem)obj)).ShowDialog() ?? false;
|
||||
return new RoutingRuleDetailsWindow((RulesItem)obj).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.ImportRulesFromFile:
|
||||
|
||||
if (UI.OpenFileDialog(out string fileName, "Rules|*.json|All|*.*") != true)
|
||||
if (UI.OpenFileDialog(out var fileName, "Rules|*.json|All|*.*") != true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -174,7 +174,7 @@ public partial class RoutingRuleSettingWindow
|
||||
|
||||
private void btnBrowseCustomIcon_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
if (UI.OpenFileDialog(out string fileName,
|
||||
if (UI.OpenFileDialog(out var fileName,
|
||||
"PNG,ICO|*.png;*.ico") != true)
|
||||
{
|
||||
return;
|
||||
@@ -185,7 +185,7 @@ public partial class RoutingRuleSettingWindow
|
||||
|
||||
private void btnBrowseCustomRulesetPath4Singbox_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (UI.OpenFileDialog(out string fileName,
|
||||
if (UI.OpenFileDialog(out var fileName,
|
||||
"Config|*.json|All|*.*") != true)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -6,9 +6,9 @@ public partial class RoutingSettingWindow
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
this.Closing += RoutingSettingWindow_Closing;
|
||||
this.PreviewKeyDown += RoutingSettingWindow_PreviewKeyDown;
|
||||
Owner = Application.Current.MainWindow;
|
||||
Closing += RoutingSettingWindow_Closing;
|
||||
PreviewKeyDown += RoutingSettingWindow_PreviewKeyDown;
|
||||
lstRoutings.SelectionChanged += lstRoutings_SelectionChanged;
|
||||
lstRoutings.MouseDoubleClick += LstRoutings_MouseDoubleClick;
|
||||
menuRoutingAdvancedSelectAll.Click += menuRoutingAdvancedSelectAll_Click;
|
||||
@@ -44,7 +44,7 @@ public partial class RoutingSettingWindow
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
|
||||
case EViewAction.ShowYesNo:
|
||||
@@ -58,7 +58,7 @@ public partial class RoutingSettingWindow
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -67,7 +67,7 @@ public partial class RoutingSettingWindow
|
||||
{
|
||||
if (ViewModel?.IsModified == true)
|
||||
{
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,11 +122,11 @@ public partial class RoutingSettingWindow
|
||||
{
|
||||
if (ViewModel?.IsModified == true)
|
||||
{
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,11 +71,11 @@ public partial class StatusBarView
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.DispatcherRefreshIcon:
|
||||
Application.Current?.Dispatcher.Invoke((async () =>
|
||||
Application.Current?.Dispatcher.Invoke(async () =>
|
||||
{
|
||||
tbNotify.Icon = await WindowsManager.Instance.GetNotifyIcon(_config);
|
||||
Application.Current.MainWindow.Icon = WindowsManager.Instance.GetAppIcon(_config);
|
||||
}), DispatcherPriority.Normal);
|
||||
}, DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.SetClipboardData:
|
||||
|
||||
@@ -6,8 +6,8 @@ public partial class SubEditWindow
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
this.Loaded += Window_Loaded;
|
||||
Owner = Application.Current.MainWindow;
|
||||
Loaded += Window_Loaded;
|
||||
|
||||
ViewModel = new SubEditViewModel(subItem, UpdateViewHandler);
|
||||
|
||||
@@ -39,7 +39,7 @@ public partial class SubEditWindow
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
|
||||
@@ -8,10 +8,10 @@ public partial class SubSettingWindow
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
Owner = Application.Current.MainWindow;
|
||||
|
||||
ViewModel = new SubSettingViewModel(UpdateViewHandler);
|
||||
this.Closing += SubSettingWindow_Closing;
|
||||
Closing += SubSettingWindow_Closing;
|
||||
lstSubscription.MouseDoubleClick += LstSubscription_MouseDoubleClick;
|
||||
lstSubscription.SelectionChanged += LstSubscription_SelectionChanged;
|
||||
menuClose.Click += menuClose_Click;
|
||||
@@ -34,7 +34,7 @@ public partial class SubSettingWindow
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.CloseWindow:
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
break;
|
||||
|
||||
case EViewAction.ShowYesNo:
|
||||
@@ -47,7 +47,7 @@ public partial class SubSettingWindow
|
||||
case EViewAction.SubEditWindow:
|
||||
if (obj is null)
|
||||
return false;
|
||||
return (new SubEditWindow((SubItem)obj)).ShowDialog() ?? false;
|
||||
return new SubEditWindow((SubItem)obj).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.ShareSub:
|
||||
if (obj is null)
|
||||
@@ -64,7 +64,7 @@ public partial class SubSettingWindow
|
||||
{
|
||||
return;
|
||||
}
|
||||
var img = QRCodeUtils.GetQRCode(url);
|
||||
var img = QRCodeWindowsUtils.GetQRCode(url);
|
||||
var dialog = new QrcodeView()
|
||||
{
|
||||
imgQrcode = { Source = img },
|
||||
@@ -78,7 +78,7 @@ public partial class SubSettingWindow
|
||||
{
|
||||
if (ViewModel?.IsModified == true)
|
||||
{
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,11 +99,11 @@ public partial class SubSettingWindow
|
||||
{
|
||||
if (ViewModel?.IsModified == true)
|
||||
{
|
||||
this.DialogResult = true;
|
||||
DialogResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user