更改一点点离谱代码, 顺便按照 issue 中的意见, 添加了双击切换 proxy 的简单逻辑
This commit is contained in:
@@ -4,45 +4,26 @@ namespace ClashN.Base
|
||||
{
|
||||
static class StringEx
|
||||
{
|
||||
public static bool IsNullOrEmpty(this string value)
|
||||
public static bool BeginWithAny(this string? s, IEnumerable<char> chars)
|
||||
{
|
||||
return string.IsNullOrEmpty(value);
|
||||
}
|
||||
if (string.IsNullOrEmpty(s))
|
||||
return false;
|
||||
|
||||
public static bool IsNullOrWhiteSpace(this string value)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(value);
|
||||
}
|
||||
|
||||
public static bool BeginWithAny(this string s, IEnumerable<char> chars)
|
||||
{
|
||||
if (s.IsNullOrEmpty()) return false;
|
||||
return chars.Contains(s[0]);
|
||||
}
|
||||
|
||||
public static bool IsWhiteSpace(this string value)
|
||||
{
|
||||
foreach (char c in value)
|
||||
{
|
||||
if (char.IsWhiteSpace(c)) continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static IEnumerable<string> NonWhiteSpaceLines(this TextReader reader)
|
||||
{
|
||||
string line;
|
||||
string? line;
|
||||
while ((line = reader.ReadLine()) != null)
|
||||
{
|
||||
if (line.IsWhiteSpace()) continue;
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
yield return line;
|
||||
}
|
||||
}
|
||||
|
||||
public static string TrimEx(this string value)
|
||||
public static string TrimEx(this string? value)
|
||||
{
|
||||
return value == null ? string.Empty : value.Trim();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using ClashN.Mode;
|
||||
using ClashN.Tool;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
|
||||
@@ -93,9 +94,7 @@ namespace ClashN.Handler
|
||||
config.ConstItem.defIEProxyExceptions = Global.IEProxyExceptions;
|
||||
}
|
||||
|
||||
if (config == null
|
||||
|| config.ProfileItems.Count <= 0
|
||||
)
|
||||
if (config.ProfileItems.Count <= 0)
|
||||
{
|
||||
Global.reloadCore = false;
|
||||
}
|
||||
@@ -114,7 +113,7 @@ namespace ClashN.Handler
|
||||
}
|
||||
}
|
||||
|
||||
LazyConfig.Instance.SetConfig(ref config);
|
||||
LazyConfig.Instance.SetConfig(config);
|
||||
return 0;
|
||||
}
|
||||
/// <summary>
|
||||
@@ -262,7 +261,7 @@ namespace ClashN.Handler
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public static ProfileItem GetDefaultProfile(ref Config config)
|
||||
public static ProfileItem? GetDefaultProfile(ref Config config)
|
||||
{
|
||||
if (config.ProfileItems.Count <= 0)
|
||||
{
|
||||
@@ -571,13 +570,15 @@ namespace ClashN.Handler
|
||||
Uri url = new Uri(clipboardData);
|
||||
if (url.Host == "install-config")
|
||||
{
|
||||
var query = HttpUtility.ParseQueryString(url.Query);
|
||||
NameValueCollection query =
|
||||
HttpUtility.ParseQueryString(url.Query);
|
||||
|
||||
if (!string.IsNullOrEmpty(query["url"] ?? ""))
|
||||
{
|
||||
ProfileItem item = new ProfileItem()
|
||||
{
|
||||
groupId = groupId,
|
||||
url = query["url"],
|
||||
url = query["url"] ?? string.Empty,
|
||||
coreType = CoreKind.ClashMeta,
|
||||
address = string.Empty,
|
||||
enabled = true,
|
||||
@@ -613,15 +614,12 @@ namespace ClashN.Handler
|
||||
else
|
||||
{ return -1; }
|
||||
|
||||
ProfileItem profileItem;
|
||||
ProfileItem? profileItem = null;
|
||||
if (!string.IsNullOrEmpty(indexId))
|
||||
{
|
||||
profileItem = config.GetProfileItem(indexId);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (profileItem == null)
|
||||
profileItem = new ProfileItem();
|
||||
}
|
||||
profileItem.groupId = groupId;
|
||||
|
||||
if (AddProfileViaContent(ref config, profileItem, clipboardData) == 0)
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace ClashN.Handler
|
||||
/// DownloadString
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
public async Task<(string, HttpResponseHeaders)> DownloadStringAsync(string url, bool blProxy, string userAgent)
|
||||
public async Task<(string, HttpResponseHeaders)?> DownloadStringAsync(string url, bool blProxy, string userAgent)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -108,10 +108,11 @@ namespace ClashN.Handler
|
||||
Error?.Invoke(this, new ErrorEventArgs(ex.InnerException));
|
||||
}
|
||||
}
|
||||
return (null, null);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<string> UrlRedirectAsync(string url, bool blProxy)
|
||||
public async Task<string?> UrlRedirectAsync(string url, bool blProxy)
|
||||
{
|
||||
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.EnableSecurityProtocolTls13);
|
||||
SocketsHttpHandler webRequestHandler = new SocketsHttpHandler
|
||||
@@ -124,7 +125,7 @@ namespace ClashN.Handler
|
||||
HttpResponseMessage response = await client.GetAsync(url);
|
||||
if (response.StatusCode.ToString() == "Redirect")
|
||||
{
|
||||
return response.Headers.Location.ToString();
|
||||
return response.Headers.Location?.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace ClashN.Handler
|
||||
{
|
||||
get { return _instance.Value; }
|
||||
}
|
||||
public void SetConfig(ref Config config)
|
||||
public void SetConfig(Config config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
@@ -218,10 +218,10 @@ namespace ClashN.Handler
|
||||
{
|
||||
_updateFunc(false, $"{hashCode}{args.GetException().Message}");
|
||||
};
|
||||
var result = await downloadHandle.DownloadStringAsync(url, blProxy, userAgent);
|
||||
var result = (await downloadHandle.DownloadStringAsync(url, blProxy, userAgent)) ?? throw new Exception();
|
||||
if (blProxy && string.IsNullOrEmpty(result.Item1))
|
||||
{
|
||||
result = await downloadHandle.DownloadStringAsync(url, false, userAgent);
|
||||
result = (await downloadHandle.DownloadStringAsync(url, false, userAgent)) ?? throw new Exception();
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(result.Item1))
|
||||
|
||||
@@ -74,12 +74,11 @@ namespace ClashN.Mode
|
||||
return ProfileItems.FindIndex(it => it.indexId == id);
|
||||
}
|
||||
|
||||
public ProfileItem GetProfileItem(string id)
|
||||
public ProfileItem? GetProfileItem(string id)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ProfileItems.FirstOrDefault(it => it.indexId == id);
|
||||
}
|
||||
|
||||
@@ -160,7 +159,7 @@ namespace ClashN.Mode
|
||||
|
||||
public bool colorModeDark { get; set; }
|
||||
public string? colorPrimaryName { get; set; }
|
||||
public string currentFontFamily { get; set; }
|
||||
public string currentFontFamily { get; set; } = string.Empty;
|
||||
public int currentFontSize { get; set; }
|
||||
|
||||
public int proxiesSorting { get; set; }
|
||||
@@ -174,21 +173,9 @@ namespace ClashN.Mode
|
||||
[Serializable]
|
||||
public class ConstItem
|
||||
{
|
||||
public string subConvertUrl
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string speedTestUrl
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string speedPingTestUrl
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string defIEProxyExceptions
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string subConvertUrl { get; set; } = string.Empty;
|
||||
public string speedTestUrl { get; set; } = string.Empty;
|
||||
public string speedPingTestUrl { get; set; } = string.Empty;
|
||||
public string defIEProxyExceptions { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace ClashN.ViewModels
|
||||
|
||||
var canEditRemove = this.WhenAnyValue(
|
||||
x => x.SelectedSource,
|
||||
selectedSource => selectedSource != null && !selectedSource.id.IsNullOrEmpty());
|
||||
selectedSource => selectedSource != null && !string.IsNullOrEmpty(selectedSource.id));
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.SortingSelected,
|
||||
@@ -144,7 +144,7 @@ namespace ClashN.ViewModels
|
||||
model.id = item.Id;
|
||||
model.network = item.metadata.Network;
|
||||
model.type = item.metadata.Type;
|
||||
model.host = $"{(item.metadata.Host.IsNullOrEmpty() ? item.metadata.DestinationIP : item.metadata.Host)}:{item.metadata.DestinationPort}";
|
||||
model.host = $"{(string.IsNullOrEmpty(item.metadata.Host) ? item.metadata.DestinationIP : item.metadata.Host)}:{item.metadata.DestinationPort}";
|
||||
var sp = (dtNow - item.start);
|
||||
model.time = sp.TotalSeconds < 0 ? 1 : sp.TotalSeconds;
|
||||
model.upload = item.upload;
|
||||
|
||||
@@ -460,7 +460,7 @@ namespace ClashN.ViewModels
|
||||
{
|
||||
ModifyTheme(_config.UiItem.colorModeDark);
|
||||
|
||||
if (!_config.UiItem.colorPrimaryName.IsNullOrEmpty())
|
||||
if (!string.IsNullOrEmpty(_config.UiItem.colorPrimaryName))
|
||||
{
|
||||
var swatch = new SwatchesProvider().Swatches.FirstOrDefault(t => t.Name == _config.UiItem.colorPrimaryName);
|
||||
if (swatch != null
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace ClashN.ViewModels
|
||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||
_config = LazyConfig.Instance.Config;
|
||||
|
||||
if (profileItem.indexId.IsNullOrEmpty())
|
||||
if (string.IsNullOrEmpty(profileItem.indexId))
|
||||
{
|
||||
SelectedSource = profileItem;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace ClashN.ViewModels
|
||||
|
||||
var canEditRemove = this.WhenAnyValue(
|
||||
x => x.SelectedSource,
|
||||
selectedSource => selectedSource != null && !selectedSource.indexId.IsNullOrEmpty());
|
||||
selectedSource => selectedSource != null && !string.IsNullOrEmpty(selectedSource.indexId));
|
||||
|
||||
//Profile
|
||||
EditLocalFileCmd = ReactiveCommand.Create(() =>
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace ClashN.ViewModels
|
||||
//GetClashProxies(true);
|
||||
this.WhenAnyValue(
|
||||
x => x.SelectedGroup,
|
||||
y => y != null && !y.name.IsNullOrEmpty())
|
||||
y => y != null && !string.IsNullOrEmpty(y.name))
|
||||
.Subscribe(c => RefreshProxyDetails(c));
|
||||
|
||||
this.WhenAnyValue(
|
||||
@@ -268,7 +268,7 @@ namespace ClashN.ViewModels
|
||||
continue;
|
||||
}
|
||||
var item = _proxyGroups.Where(t => t.name == kv.Key).FirstOrDefault();
|
||||
if (item != null && !item.name.IsNullOrEmpty())
|
||||
if (item != null && !string.IsNullOrEmpty(item.name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -379,11 +379,11 @@ namespace ClashN.ViewModels
|
||||
|
||||
public void SetActiveProxy()
|
||||
{
|
||||
if (SelectedGroup == null || SelectedGroup.name.IsNullOrEmpty())
|
||||
if (SelectedGroup == null || string.IsNullOrEmpty(SelectedGroup.name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (SelectedDetail == null || SelectedDetail.name.IsNullOrEmpty())
|
||||
if (SelectedDetail == null || string.IsNullOrEmpty(SelectedDetail.name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ namespace ClashN.ViewModels
|
||||
//UI
|
||||
ColorModeDark = _config.UiItem.colorModeDark;
|
||||
_swatches.AddRange(new SwatchesProvider().Swatches);
|
||||
if (!_config.UiItem.colorPrimaryName.IsNullOrEmpty())
|
||||
if (!string.IsNullOrEmpty(_config.UiItem.colorPrimaryName))
|
||||
{
|
||||
SelectedSwatch = _swatches.FirstOrDefault(t => t.Name == _config.UiItem.colorPrimaryName);
|
||||
}
|
||||
@@ -163,11 +163,11 @@ namespace ClashN.ViewModels
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.SelectedSwatch,
|
||||
y => y != null && !y.Name.IsNullOrEmpty())
|
||||
y => y != null && !string.IsNullOrEmpty(y.Name))
|
||||
.Subscribe(c =>
|
||||
{
|
||||
if (SelectedSwatch == null
|
||||
|| SelectedSwatch.Name.IsNullOrEmpty()
|
||||
|| string.IsNullOrEmpty(SelectedSwatch.Name)
|
||||
|| SelectedSwatch.ExemplarHue == null
|
||||
|| SelectedSwatch.ExemplarHue?.Color == null)
|
||||
{
|
||||
@@ -183,7 +183,7 @@ namespace ClashN.ViewModels
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.CurrentLanguage,
|
||||
y => y != null && !y.IsNullOrEmpty())
|
||||
y => y != null && !string.IsNullOrEmpty(y))
|
||||
.Subscribe(c =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(CurrentLanguage))
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
</ListView.ItemsPanel>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Width="160" Padding="0">
|
||||
<Border Width="160" Padding="0" KeyDown="ProxyItem_KeyDown">
|
||||
<DockPanel>
|
||||
<Border
|
||||
Width="5"
|
||||
|
||||
@@ -43,15 +43,29 @@ namespace ClashN.Views
|
||||
|
||||
private void ProxiesView_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (Keyboard.IsKeyDown(Key.F5))
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.F5:
|
||||
ViewModel?.ProxiesReload();
|
||||
break;
|
||||
case Key.Enter:
|
||||
ViewModel?.SetActiveProxy();
|
||||
break;
|
||||
}
|
||||
else if (Keyboard.IsKeyDown(Key.Enter))
|
||||
}
|
||||
|
||||
|
||||
private object? lastProxyItemKeyDownSender;
|
||||
private int lastProxyItemKeyDownTimestamp;
|
||||
private void ProxyItem_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (sender == lastProxyItemKeyDownSender && e.Timestamp - lastProxyItemKeyDownTimestamp < 500)
|
||||
{
|
||||
ViewModel?.SetActiveProxy();
|
||||
}
|
||||
|
||||
lastProxyItemKeyDownSender = sender;
|
||||
lastProxyItemKeyDownTimestamp = e.Timestamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user