Compare commits

...

10 Commits

Author SHA1 Message Date
2dust
36e3dfdfa8 Code clean 2024-01-05 13:37:06 +08:00
2dust
e8896bfb05 Merge pull request #315 from SpaceTimee/fork
Optimized MainWindow a little
2024-01-05 12:14:57 +08:00
Space Time
147a6c4078 Optimized MainWindow a little 2024-01-04 01:59:40 +08:00
2dust
5e72ef9667 Update README.md 2024-01-02 12:01:18 +08:00
2dust
93e428edc4 up 2.19 2024-01-02 11:56:36 +08:00
2dust
9887cb6414 Merge pull request #312 from SpaceTimee/main
bug fixes
2024-01-02 11:52:37 +08:00
Space Time
3023971cf8 bug fixes 2024-01-01 21:30:06 +08:00
2dust
936602eb0c up 2.18 2024-01-01 18:21:39 +08:00
2dust
683f6e7a9d up .net 8 2024-01-01 18:10:07 +08:00
2dust
141943d11a Bug fix and remove adjust core 2024-01-01 18:09:34 +08:00
15 changed files with 240 additions and 313 deletions

View File

@@ -1,8 +1,7 @@
# ClashN
A clash client for Windows, supports [Clash core](https://github.com/Dreamacro/clash) and [Clash.Meta core](https://github.com/MetaCubeX/Clash.Meta)
A clash client for Windows, supports [Mihomo core](https://github.com/MetaCubeX/Mihomo)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/2dust/clashn)](https://github.com/2dust/clashn/commits/master)
[![CodeFactor](https://www.codefactor.io/repository/github/2dust/clashn/badge)](https://www.codefactor.io/repository/github/2dust/clashn)
[![GitHub Releases](https://img.shields.io/github/downloads/2dust/clashn/latest/total?logo=github)](https://github.com/2dust/clashn/releases)
### How to use
@@ -19,10 +18,8 @@ A clash client for Windows, supports [Clash core](https://github.com/Dreamacro/c
### Requirements
- Microsoft [.NET 6.0 Desktop Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/6.0/runtime) (or download this file directly: [windowsdesktop-runtime-6.0.22-win-x64.exe](https://download.visualstudio.microsoft.com/download/pr/66a7c4c6-8401-4799-864f-9afddf5a7733/4052f458f0266e25ab1b9c7959ca245f/windowsdesktop-runtime-6.0.22-win-x64.exe
))
- Clash core [https://github.com/Dreamacro/clash/releases](https://github.com/Dreamacro/clash/releases)
- Clash.Meta core [https://github.com/MetaCubeX/Clash.Meta/releases](https://github.com/MetaCubeX/Clash.Meta/releases)
- Microsoft [.NET 8.0 Desktop Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0/runtime)
- Mihomo core [https://github.com/MetaCubeX/Mihomo/releases](https://github.com/MetaCubeX/Mihomo/releases)

View File

@@ -105,7 +105,7 @@
""
};
public static readonly List<string> coreTypes = new List<string> { "Clash", "ClashPremium", "ClashMeta", };
public static readonly List<string> coreTypes = new List<string> { "Clash", "ClashPremium", "ClashMeta", "Mihomo" };
public static readonly List<string> allowSelectType = new List<string> { "selector", "urltest", "loadbalance", "fallback" };

View File

@@ -498,7 +498,7 @@ namespace ClashN.Handler
}
if (profileItem.coreType is null)
{
profileItem.coreType = CoreKind.ClashMeta;
profileItem.coreType = CoreKind.Mihomo;
}
if (!config.ProfileItems.Exists(it => it.indexId == profileItem.indexId))
{
@@ -558,7 +558,7 @@ namespace ClashN.Handler
{
groupId = groupId,
url = clipboardData,
coreType = CoreKind.ClashMeta,
coreType = CoreKind.Mihomo,
address = string.Empty,
enabled = true,
remarks = "clash_subscription"
@@ -582,7 +582,7 @@ namespace ClashN.Handler
{
groupId = groupId,
url = query["url"] ?? string.Empty,
coreType = CoreKind.ClashMeta,
coreType = CoreKind.Mihomo,
address = string.Empty,
enabled = true,
remarks = "clash_subscription"
@@ -600,7 +600,7 @@ namespace ClashN.Handler
{
groupId = groupId,
url = "",
coreType = CoreKind.ClashMeta,
coreType = CoreKind.Mihomo,
address = string.Empty,
enabled = false,
remarks = "clash_local_file"

View File

@@ -302,12 +302,12 @@ namespace ClashN.Handler
});
}
public List<ProxiesItem> GetClashProxyGroups()
public List<ProxiesItem>? GetClashProxyGroups()
{
try
{
var fileContent = LazyConfig.Instance.ProfileContent;
if (!fileContent.ContainsKey("proxy-groups"))
if (fileContent is null || fileContent?.ContainsKey("proxy-groups") == false)
{
return null;
}

View File

@@ -106,8 +106,9 @@ namespace ClashN.Handler
if (!string.IsNullOrEmpty(result))
{
var serverStatItem = config_.GetProfileItem(config_.IndexId);
ParseOutput(result, out ulong up, out ulong down);
if (up + down > 0)
if (serverStatItem != null && (up + down) > 0)
{
serverStatItem.uploadRemote += up;
serverStatItem.downloadRemote += down;

View File

@@ -5,7 +5,7 @@
Clash = 1,
ClashMeta = 2,
ClashPremium = 3,
Mihomo = 4,
Mihomo = 4,
ClashN = 99
}
}

View File

@@ -14,7 +14,6 @@ using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
@@ -86,16 +85,19 @@ namespace ClashN
/// <typeparam name="T"></typeparam>
/// <param name="strJson"></param>
/// <returns></returns>
public static T FromJson<T>(string strJson)
public static T? FromJson<T>(string? strJson)
{
try
{
T obj = JsonConvert.DeserializeObject<T>(strJson);
return obj;
if (string.IsNullOrEmpty(strJson))
{
return default;
}
return JsonConvert.DeserializeObject<T>(strJson);
}
catch
{
return JsonConvert.DeserializeObject<T>("");
return default;
}
}
@@ -104,14 +106,25 @@ namespace ClashN
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string ToJson(Object obj)
public static string ToJson(object? obj, bool indented = true)
{
string result = string.Empty;
try
{
result = JsonConvert.SerializeObject(obj,
if (obj == null)
{
return result;
}
if (indented)
{
result = JsonConvert.SerializeObject(obj,
Formatting.Indented,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
}
else
{
result = JsonConvert.SerializeObject(obj, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
}
}
catch (Exception ex)
{
@@ -599,7 +612,7 @@ namespace ClashN
}
return Path.Combine(startupPath, fileName);
}
/// <summary>
/// 获取启动了应用程序的数据文件的路径
/// </summary>
@@ -895,18 +908,7 @@ namespace ClashN
/// <returns></returns>
public static T DeepCopy<T>(T obj)
{
object retval;
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
//序列化成流
bf.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
//反序列化成对象
retval = bf.Deserialize(ms);
ms.Close();
}
return (T)retval;
return FromJson<T>(ToJson(obj, false))!;
}
/// <summary>

View File

@@ -14,9 +14,11 @@ namespace ClashN.ViewModels
private NoticeHandler? _noticeHandler;
public ReactiveCommand<Unit, Unit> CheckUpdateCmd { get; }
public ReactiveCommand<Unit, Unit> CheckUpdateClashCoreCmd { get; }
//public ReactiveCommand<Unit, Unit> CheckUpdateClashCoreCmd { get; }
public ReactiveCommand<Unit, Unit> CheckUpdateMihomoCoreCmd { get; }
public ReactiveCommand<Unit, Unit> CheckUpdateGeoDataCmd { get; }
//public ReactiveCommand<Unit, Unit> CheckUpdateGeoDataCmd { get; }
public HelpViewModel()
{
@@ -27,35 +29,35 @@ namespace ClashN.ViewModels
{
CheckUpdateN();
});
CheckUpdateClashCoreCmd = ReactiveCommand.Create(() =>
{
CheckUpdateCore(CoreKind.Clash);
});
//CheckUpdateClashCoreCmd = ReactiveCommand.Create(() =>
//{
// CheckUpdateCore(CoreKind.Clash);
//});
CheckUpdateMihomoCoreCmd = ReactiveCommand.Create(() =>
{
CheckUpdateCore(CoreKind.Mihomo);
});
CheckUpdateGeoDataCmd = ReactiveCommand.Create(() =>
{
CheckUpdateGeoData();
});
}
private void CheckUpdateGeoData()
{
void _updateUI(bool success, string msg)
{
_noticeHandler?.SendMessage(msg);
if (success)
{
Locator.Current.GetService<MainWindowViewModel>()?.MyAppExit(false);
}
};
UpdateHandle update = new UpdateHandle();
update.UpdateGeoFile(GeoKind.GEO_IP, _config, _updateUI);
update.UpdateGeoFile(GeoKind.GEO_SITE, _config, _updateUI);
//CheckUpdateGeoDataCmd = ReactiveCommand.Create(() =>
//{
// CheckUpdateGeoData();
//});
}
//private void CheckUpdateGeoData()
//{
// void _updateUI(bool success, string msg)
// {
// _noticeHandler?.SendMessage(msg);
// if (success)
// {
// Locator.Current.GetService<MainWindowViewModel>()?.MyAppExit(false);
// }
// };
// UpdateHandle update = new UpdateHandle();
// update.UpdateGeoFile(GeoKind.GEO_IP, _config, _updateUI);
// update.UpdateGeoFile(GeoKind.GEO_SITE, _config, _updateUI);
//}
private void CheckUpdateN()
{
void _updateUI(bool success, string msg)

View File

@@ -25,6 +25,7 @@ namespace ClashN.ViewModels
private NoticeHandler? _noticeHandler;
private StatisticsHandler? statistics;
private readonly PaletteHelper _paletteHelper = new PaletteHelper();
private bool blFirst = true;
#region Views
@@ -137,6 +138,7 @@ namespace ClashN.ViewModels
Application.Current.Dispatcher.Invoke((Action)(() =>
{
ShowHideWindow(false);
blFirst = false;
}));
});
}
@@ -220,7 +222,8 @@ namespace ClashN.ViewModels
}
}
ShowHideWindow(true);
if (!blFirst)
ShowHideWindow(true);
Locator.Current.GetService<ProfilesViewModel>()?.AddProfilesViaClipboard(true);
}));

View File

@@ -162,7 +162,7 @@ namespace ClashN.ViewModels
{
item = new()
{
coreType = CoreKind.ClashMeta
coreType = CoreKind.Mihomo
};
}
else

View File

@@ -96,43 +96,6 @@
</DockPanel>
</materialDesign:Card>
<materialDesign:Card
Width="300"
Margin="8"
Padding="16"
materialDesign:UniformCornerRadius="8">
<DockPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
Margin="16,16,16,4"
Style="{StaticResource TabItemTitle}"
Text="Update Clash Core" />
<Separator Grid.Row="1" Style="{StaticResource MaterialDesignLightSeparator}" />
<DockPanel Grid.Row="2" HorizontalAlignment="Right">
<TextBlock
Grid.Row="0"
Margin="8"
Style="{StaticResource MaterialDesignCaptionTextBlock}"
Text="" />
<Button
x:Name="btnCheckUpdateClashCore"
Width="100"
Content="{x:Static resx:ResUI.TbHelpCheck}"
DockPanel.Dock="Right"
Style="{StaticResource DefButton}" />
</DockPanel>
</Grid>
</DockPanel>
</materialDesign:Card>
<materialDesign:Card
Width="300"
Margin="8"
@@ -169,44 +132,6 @@
</Grid>
</DockPanel>
</materialDesign:Card>
<materialDesign:Card
Width="300"
Margin="8"
Padding="16"
materialDesign:UniformCornerRadius="8">
<DockPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
Margin="16,16,16,4"
Style="{StaticResource TabItemTitle}"
Text="Update Geo Data" />
<Separator Grid.Row="1" Style="{StaticResource MaterialDesignLightSeparator}" />
<DockPanel Grid.Row="2" HorizontalAlignment="Right">
<TextBlock
Grid.Row="0"
Margin="8"
Style="{StaticResource MaterialDesignCaptionTextBlock}"
Text="" />
<Button
x:Name="btnCheckUpdateGeo"
Width="100"
Content="{x:Static resx:ResUI.TbHelpCheck}"
DockPanel.Dock="Right"
Style="{StaticResource DefButton}" />
</DockPanel>
</Grid>
</DockPanel>
</materialDesign:Card>
</WrapPanel>
</ScrollViewer>
</DockPanel>

View File

@@ -17,9 +17,9 @@ namespace ClashN.Views
this.WhenActivated(disposables =>
{
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdateN).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateClashCoreCmd, v => v.btnCheckUpdateClashCore).DisposeWith(disposables);
//this.BindCommand(ViewModel, vm => vm.CheckUpdateClashCoreCmd, v => v.btnCheckUpdateClashCore).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateMihomoCoreCmd, v => v.btnCheckUpdateMihomoCore).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateGeoDataCmd, v => v.btnCheckUpdateGeo).DisposeWith(disposables);
//this.BindCommand(ViewModel, vm => vm.CheckUpdateGeoDataCmd, v => v.btnCheckUpdateGeo).DisposeWith(disposables);
});
}

View File

@@ -4,7 +4,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:ClashN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ClashN.Views"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net"
@@ -19,7 +18,7 @@
x:TypeArguments="vms:MainWindowViewModel"
Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
ShowInTaskbar="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextOptions.TextFormattingMode="Display"
@@ -31,53 +30,52 @@
SnackbarMessageQueue="{Binding ElementName=MainSnackbar, Path=MessageQueue}"
Style="{StaticResource MaterialDesignEmbeddedDialogHost}">
<Grid>
<Grid Grid.Column="0">
<TabControl Padding="2,0" Style="{StaticResource MaterialDesignNavigatilRailTabControl}">
<materialDesign:NavigationRailAssist.FloatingContent>
<StackPanel
<TabControl Padding="2,0" Style="{StaticResource MaterialDesignNavigatilRailTabControl}">
<materialDesign:NavigationRailAssist.FloatingContent>
<StackPanel
Width="auto"
Height="auto"
Margin="4">
<Grid Width="80" Margin="0,8,0,8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<materialDesign:PackIcon
<Grid Width="80" Margin="0,8,0,8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<materialDesign:PackIcon
Grid.Row="0"
Grid.Column="0"
Kind="ArrowUpThin" />
<TextBlock
<TextBlock
x:Name="txtSpeedUpload"
Grid.Row="0"
Grid.Column="1"
Margin="8,0,0,0"
Padding="0,0,4,0"
Style="{StaticResource ToolbarItem}" />
<materialDesign:PackIcon
<materialDesign:PackIcon
Grid.Row="1"
Grid.Column="0"
Kind="ArrowDownThin" />
<TextBlock
<TextBlock
x:Name="txtSpeedDownload"
Grid.Row="1"
Grid.Column="1"
Margin="8,0,0,0"
Padding="0,0,4,0"
Style="{StaticResource ToolbarItem}" />
</Grid>
<Button
</Grid>
<Button
x:Name="btnReload"
Content="{materialDesign:PackIcon Kind=Reload}"
Style="{StaticResource MaterialDesignFloatingActionMiniButton}"
Style="{StaticResource MaterialDesignFlatLightBgButton}"
ToolTip="{x:Static resx:ResUI.TbReloadCore}" />
</StackPanel>
</materialDesign:NavigationRailAssist.FloatingContent>
<!--<TabItem
</StackPanel>
</materialDesign:NavigationRailAssist.FloatingContent>
<!--<TabItem
x:Name="dashboardTabItem"
Height="auto"
Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
@@ -97,224 +95,223 @@
</StackPanel>
</TabItem.Header>
</TabItem>-->
<TabItem x:Name="proxiesTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
<TabItem x:Name="proxiesTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
Width="24"
Height="24"
HorizontalAlignment="Center"
Kind="ArrowDecisionOutline" />
<TextBlock
<TextBlock
HorizontalAlignment="Center"
Style="{StaticResource TabItemTitle}"
Text="{x:Static resx:ResUI.TbProxies}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="profilesTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="profilesTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
Width="24"
Height="24"
HorizontalAlignment="Center"
Kind="Server" />
<TextBlock
<TextBlock
HorizontalAlignment="Center"
Style="{StaticResource TabItemTitle}"
Text="{x:Static resx:ResUI.TbProfiles}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="logsTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="logsTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
Width="24"
Height="24"
HorizontalAlignment="Center"
Kind="MessageTextOutline" />
<TextBlock
<TextBlock
HorizontalAlignment="Center"
Style="{StaticResource TabItemTitle}"
Text="{x:Static resx:ResUI.TbLogs}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="connectionsTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="connectionsTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
Width="24"
Height="24"
HorizontalAlignment="Center"
Kind="LanConnect" />
<TextBlock
<TextBlock
HorizontalAlignment="Center"
Style="{StaticResource TabItemTitle}"
Text="{x:Static resx:ResUI.TbConnections}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="settingsTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="settingsTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
Width="24"
Height="24"
HorizontalAlignment="Center"
Kind="SettingsOutline" />
<TextBlock
<TextBlock
HorizontalAlignment="Center"
Style="{StaticResource TabItemTitle}"
Text="{x:Static resx:ResUI.TbSettings}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="helpTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="helpTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
Width="24"
Height="24"
HorizontalAlignment="Center"
Kind="HelpCircleOutline" />
<TextBlock
<TextBlock
HorizontalAlignment="Center"
Style="{StaticResource TabItemTitle}"
Text="{x:Static resx:ResUI.TbHelp}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="promotionTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="promotionTabItem" Style="{StaticResource MyMaterialDesignNavigationRailTabItem}">
<TabItem.Header>
<StackPanel Width="auto" Height="auto">
<materialDesign:PackIcon
Width="24"
Height="24"
HorizontalAlignment="Center"
Kind="VolumeHigh" />
<TextBlock
<TextBlock
HorizontalAlignment="Center"
Style="{StaticResource TabItemTitle}"
Text="{x:Static resx:ResUI.TbPromotion}" />
</StackPanel>
</TabItem.Header>
</TabItem>
</TabControl>
</StackPanel>
</TabItem.Header>
</TabItem>
</TabControl>
<tb:TaskbarIcon
<tb:TaskbarIcon
x:Name="tbNotify"
IconSource="/ClashN.ico"
NoLeftClickDelay="True">
<tb:TaskbarIcon.ContextMenu>
<ContextMenu Style="{StaticResource DefMenu}">
<MenuItem x:Name="menuSystemProxyClear">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
<tb:TaskbarIcon.ContextMenu>
<ContextMenu Style="{StaticResource DefMenu}">
<MenuItem x:Name="menuSystemProxyClear">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
x:Name="menuSystemProxyClear2"
Margin="0,0,8,0"
Kind="Check" />
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyClear}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuSystemProxySet">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyClear}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuSystemProxySet">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
x:Name="menuSystemProxySet2"
Margin="0,0,8,0"
Kind="Check" />
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxySet}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuSystemProxyNothing">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxySet}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuSystemProxyNothing">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
x:Name="menuSystemProxyNothing2"
Margin="0,0,8,0"
Kind="Check" />
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyNothing}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuSystemProxyPac">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyNothing}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuSystemProxyPac">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
x:Name="menuSystemProxyPac2"
Margin="0,0,8,0"
Kind="Check" />
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyPac}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<Separator />
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyPac}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<Separator />
<MenuItem x:Name="menuModeRule">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
<MenuItem x:Name="menuModeRule">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
x:Name="menuModeRule2"
Margin="0,0,8,0"
Kind="Check" />
<TextBlock Text="{x:Static resx:ResUI.menuModeRule}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuModeGlobal">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
<TextBlock Text="{x:Static resx:ResUI.menuModeRule}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuModeGlobal">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
x:Name="menuModeGlobal2"
Margin="0,0,8,0"
Kind="Check" />
<TextBlock Text="{x:Static resx:ResUI.menuModeGlobal}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuModeDirect">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
<TextBlock Text="{x:Static resx:ResUI.menuModeGlobal}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuModeDirect">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
x:Name="menuModeDirect2"
Margin="0,0,8,0"
Kind="Check" />
<TextBlock Text="{x:Static resx:ResUI.menuModeDirect}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuModeNothing">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
<TextBlock Text="{x:Static resx:ResUI.menuModeDirect}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuModeNothing">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
x:Name="menuModeNothing2"
Margin="0,0,8,0"
Kind="Check" />
<TextBlock Text="{x:Static resx:ResUI.menuModeNothing}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<TextBlock Text="{x:Static resx:ResUI.menuModeNothing}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<Separator />
<MenuItem x:Name="menuAddProfileViaScan" Header="{x:Static resx:ResUI.menuAddProfileViaScan}" />
<MenuItem x:Name="menuSubUpdate" Header="{x:Static resx:ResUI.menuSubUpdate}" />
<MenuItem x:Name="menuSubUpdateViaProxy" Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" />
<Separator />
<MenuItem
<Separator />
<MenuItem x:Name="menuAddProfileViaScan" Header="{x:Static resx:ResUI.menuAddProfileViaScan}" />
<MenuItem x:Name="menuSubUpdate" Header="{x:Static resx:ResUI.menuSubUpdate}" />
<MenuItem x:Name="menuSubUpdateViaProxy" Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" />
<Separator />
<MenuItem
x:Name="menuExit"
Click="menuExit_Click"
Header="{x:Static resx:ResUI.menuExit}" />
</ContextMenu>
</tb:TaskbarIcon.ContextMenu>
</tb:TaskbarIcon>
<materialDesign:Snackbar x:Name="MainSnackbar" MessageQueue="{materialDesign:MessageQueue}" />
</Grid>
</ContextMenu>
</tb:TaskbarIcon.ContextMenu>
</tb:TaskbarIcon>
<materialDesign:Snackbar x:Name="MainSnackbar" MessageQueue="{materialDesign:MessageQueue}" />
</Grid>
</materialDesign:DialogHost>
</reactiveui:ReactiveWindow>

View File

@@ -2,32 +2,32 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<ApplicationManifest>app.manifest</ApplicationManifest>
<ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>ClashN.ico</ApplicationIcon>
<Copyright>Copyright © 2019-2023 (GPLv3)</Copyright>
<FileVersion>2.17</FileVersion>
<Copyright>Copyright © 2019-2024 (GPLv3)</Copyright>
<FileVersion>2.19</FileVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MaterialDesignThemes" Version="4.7.1" />
<PackageReference Include="MaterialDesignThemes" Version="4.9.0" />
<PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="1.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NHotkey" Version="2.1.0" />
<PackageReference Include="NHotkey.Wpf" Version="2.1.0" />
<PackageReference Include="NHotkey" Version="2.1.1" />
<PackageReference Include="NHotkey.Wpf" Version="2.1.1" />
<PackageReference Include="QRCoder.Xaml" Version="1.4.3" />
<PackageReference Include="TaskScheduler" Version="2.10.1" />
<PackageReference Include="YamlDotNet" Version="13.0.2" />
<PackageReference Include="YamlDotNet" Version="13.7.1" />
<PackageReference Include="ZXing.Net.Bindings.Windows.Compatibility" Version="0.16.12" />
<PackageReference Include="ReactiveUI.Fody" Version="18.3.1" />
<PackageReference Include="ReactiveUI.Validation" Version="3.0.1" />
<PackageReference Include="ReactiveUI.WPF" Version="18.3.1" />
<PackageReference Include="Splat.NLog" Version="14.6.8" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="ReactiveUI.Fody" Version="19.5.39" />
<PackageReference Include="ReactiveUI.Validation" Version="3.1.7" />
<PackageReference Include="ReactiveUI.WPF" Version="19.5.39" />
<PackageReference Include="Splat.NLog" Version="14.8.12" />
<PackageReference Include="System.Reactive" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<TargetFramework>net8.0-windows</TargetFramework>
<OutputType>WinExe</OutputType>
<UseWindowsForms>true</UseWindowsForms>
<Copyright>Copyright © 2019-2020 (GPLv3)</Copyright>