The first letter of the guiconfig attribute must be capitalized.

This commit is contained in:
2dust 2024-10-23 17:19:57 +08:00
parent 3c550c094a
commit ffb38129e2
27 changed files with 232 additions and 250 deletions

View file

@ -61,8 +61,8 @@ namespace ServiceLib.Handler
} }
lstProxy.Add(new ClashProxyModel() lstProxy.Add(new ClashProxyModel()
{ {
name = kv.Value.name, Name = kv.Value.name,
type = kv.Value.type.ToLower(), Type = kv.Value.type.ToLower(),
}); });
} }
} }
@ -77,11 +77,11 @@ namespace ServiceLib.Handler
List<Task> tasks = new List<Task>(); List<Task> tasks = new List<Task>();
foreach (var it in lstProxy) foreach (var it in lstProxy)
{ {
if (Global.notAllowTestType.Contains(it.type.ToLower())) if (Global.notAllowTestType.Contains(it.Type.ToLower()))
{ {
continue; continue;
} }
var name = it.name; var name = it.Name;
var url = string.Format(urlBase, name); var url = string.Format(urlBase, name);
tasks.Add(Task.Run(async () => tasks.Add(Task.Run(async () =>
{ {

View file

@ -1501,7 +1501,7 @@ namespace ServiceLib.Handler
foreach (var item in lstRules) foreach (var item in lstRules)
{ {
item.id = Utils.GetGuid(false); item.Id = Utils.GetGuid(false);
} }
routingItem.RuleNum = lstRules.Count; routingItem.RuleNum = lstRules.Count;
routingItem.RuleSet = JsonUtils.Serialize(lstRules, false); routingItem.RuleSet = JsonUtils.Serialize(lstRules, false);
@ -1650,13 +1650,13 @@ namespace ServiceLib.Handler
var items = await AppHandler.Instance.RoutingItems(); var items = await AppHandler.Instance.RoutingItems();
var maxSort = items.Count; var maxSort = items.Count;
if (!blImportAdvancedRules && items.Where(t => t.Remarks.StartsWith(template.version)).ToList().Count > 0) if (!blImportAdvancedRules && items.Where(t => t.Remarks.StartsWith(template.Version)).ToList().Count > 0)
{ {
return 0; return 0;
} }
for (var i = 0; i < template.routingItems.Length; i++) for (var i = 0; i < template.RoutingItems.Length; i++)
{ {
var item = template.routingItems[i]; var item = template.RoutingItems[i];
if (string.IsNullOrEmpty(item.Url) && string.IsNullOrEmpty(item.RuleSet)) if (string.IsNullOrEmpty(item.Url) && string.IsNullOrEmpty(item.RuleSet))
continue; continue;
@ -1668,7 +1668,7 @@ namespace ServiceLib.Handler
if (string.IsNullOrEmpty(ruleSetsString)) if (string.IsNullOrEmpty(ruleSetsString))
continue; continue;
item.Remarks = $"{template.version}-{item.Remarks}"; item.Remarks = $"{template.Version}-{item.Remarks}";
item.Enabled = true; item.Enabled = true;
item.Sort = ++maxSort; item.Sort = ++maxSort;
item.Url = string.Empty; item.Url = string.Empty;

View file

@ -87,12 +87,12 @@
{ {
return; return;
} }
if (server.proxyUp != 0 || server.proxyDown != 0) if (server.ProxyUp != 0 || server.ProxyDown != 0)
{ {
_serverStatItem.TodayUp += server.proxyUp; _serverStatItem.TodayUp += server.ProxyUp;
_serverStatItem.TodayDown += server.proxyDown; _serverStatItem.TodayDown += server.ProxyDown;
_serverStatItem.TotalUp += server.proxyUp; _serverStatItem.TotalUp += server.ProxyUp;
_serverStatItem.TotalDown += server.proxyDown; _serverStatItem.TotalDown += server.ProxyDown;
} }
server.IndexId = _config.IndexId; server.IndexId = _config.IndexId;

View file

@ -2,16 +2,16 @@
{ {
public class ClashConnectionModel public class ClashConnectionModel
{ {
public string? id { get; set; } public string? Id { get; set; }
public string? network { get; set; } public string? Network { get; set; }
public string? type { get; set; } public string? Type { get; set; }
public string? host { get; set; } public string? Host { get; set; }
public ulong upload { get; set; } public ulong Upload { get; set; }
public ulong download { get; set; } public ulong Download { get; set; }
public string? uploadTraffic { get; set; } public string? UploadTraffic { get; set; }
public string? downloadTraffic { get; set; } public string? DownloadTraffic { get; set; }
public double time { get; set; } public double Time { get; set; }
public string? elapsed { get; set; } public string? Elapsed { get; set; }
public string? chain { get; set; } public string? Chain { get; set; }
} }
} }

View file

@ -3,15 +3,15 @@
[Serializable] [Serializable]
public class ClashProxyModel public class ClashProxyModel
{ {
public string? name { get; set; } public string? Name { get; set; }
public string? type { get; set; } public string? Type { get; set; }
public string? now { get; set; } public string? Now { get; set; }
public int delay { get; set; } public int Delay { get; set; }
public string? delayName { get; set; } public string? DelayName { get; set; }
public bool IsActive { get; set; } public bool IsActive { get; set; }
} }

View file

@ -3,7 +3,7 @@
[Serializable] [Serializable]
public class RoutingTemplate public class RoutingTemplate
{ {
public string version { get; set; } public string Version { get; set; }
public RoutingItem[] routingItems { get; set; } public RoutingItem[] RoutingItems { get; set; }
} }
} }

View file

@ -3,16 +3,16 @@
[Serializable] [Serializable]
public class RulesItem public class RulesItem
{ {
public string id { get; set; } public string Id { get; set; }
public string? type { get; set; } public string? Type { get; set; }
public string? port { get; set; } public string? Port { get; set; }
public string? network { get; set; } public string? Network { get; set; }
public List<string>? inboundTag { get; set; } public List<string>? InboundTag { get; set; }
public string? outboundTag { get; set; } public string? OutboundTag { get; set; }
public List<string>? ip { get; set; } public List<string>? Ip { get; set; }
public List<string>? domain { get; set; } public List<string>? Domain { get; set; }
public List<string>? protocol { get; set; } public List<string>? Protocol { get; set; }
public List<string>? process { get; set; } public List<string>? Process { get; set; }
public bool Enabled { get; set; } = true; public bool Enabled { get; set; } = true;
public string? Remarks { get; set; } public string? Remarks { get; set; }
} }

View file

@ -3,38 +3,20 @@
[Serializable] [Serializable]
public class ServerSpeedItem : ServerStatItem public class ServerSpeedItem : ServerStatItem
{ {
public long proxyUp public long ProxyUp { get; set; }
{
get; set;
}
public long proxyDown public long ProxyDown { get; set; }
{
get; set;
}
public long directUp public long DirectUp { get; set; }
{
get; set;
}
public long directDown public long DirectDown { get; set; }
{
get; set;
}
} }
[Serializable] [Serializable]
public class TrafficItem public class TrafficItem
{ {
public ulong up public ulong Up { get; set; }
{
get; set;
}
public ulong down public ulong Down { get; set; }
{
get; set;
}
} }
} }

View file

@ -1030,41 +1030,41 @@ namespace ServiceLib.Services.CoreConfig
var rule = new Rule4Sbox() var rule = new Rule4Sbox()
{ {
outbound = item.outboundTag, outbound = item.OutboundTag,
}; };
if (Utils.IsNotEmpty(item.port)) if (Utils.IsNotEmpty(item.Port))
{ {
if (item.port.Contains("-")) if (item.Port.Contains("-"))
{ {
rule.port_range = new List<string> { item.port.Replace("-", ":") }; rule.port_range = new List<string> { item.Port.Replace("-", ":") };
} }
else else
{ {
rule.port = new List<int> { Utils.ToInt(item.port) }; rule.port = new List<int> { Utils.ToInt(item.Port) };
} }
} }
if (Utils.IsNotEmpty(item.network)) if (Utils.IsNotEmpty(item.Network))
{ {
rule.network = Utils.String2List(item.network); rule.network = Utils.String2List(item.Network);
} }
if (item.protocol?.Count > 0) if (item.Protocol?.Count > 0)
{ {
rule.protocol = item.protocol; rule.protocol = item.Protocol;
} }
if (item.inboundTag?.Count >= 0) if (item.InboundTag?.Count >= 0)
{ {
rule.inbound = item.inboundTag; rule.inbound = item.InboundTag;
} }
var rule1 = JsonUtils.DeepCopy(rule); var rule1 = JsonUtils.DeepCopy(rule);
var rule2 = JsonUtils.DeepCopy(rule); var rule2 = JsonUtils.DeepCopy(rule);
var rule3 = JsonUtils.DeepCopy(rule); var rule3 = JsonUtils.DeepCopy(rule);
var hasDomainIp = false; var hasDomainIp = false;
if (item.domain?.Count > 0) if (item.Domain?.Count > 0)
{ {
var countDomain = 0; var countDomain = 0;
foreach (var it in item.domain) foreach (var it in item.Domain)
{ {
if (ParseV2Domain(it, rule1)) countDomain++; if (ParseV2Domain(it, rule1)) countDomain++;
} }
@ -1075,10 +1075,10 @@ namespace ServiceLib.Services.CoreConfig
} }
} }
if (item.ip?.Count > 0) if (item.Ip?.Count > 0)
{ {
var countIp = 0; var countIp = 0;
foreach (var it in item.ip) foreach (var it in item.Ip)
{ {
if (ParseV2Address(it, rule2)) countIp++; if (ParseV2Address(it, rule2)) countIp++;
} }
@ -1089,9 +1089,9 @@ namespace ServiceLib.Services.CoreConfig
} }
} }
if (_config.TunModeItem.EnableTun && item.process?.Count > 0) if (_config.TunModeItem.EnableTun && item.Process?.Count > 0)
{ {
rule3.process_name = item.process; rule3.process_name = item.Process;
rules.Add(rule3); rules.Add(rule3);
hasDomainIp = true; hasDomainIp = true;
} }

View file

@ -94,8 +94,8 @@ namespace ServiceLib.Services.Statistics
_updateFunc?.Invoke(new ServerSpeedItem() _updateFunc?.Invoke(new ServerSpeedItem()
{ {
proxyUp = (long)(up / 1000), ProxyUp = (long)(up / 1000),
proxyDown = (long)(down / 1000) ProxyDown = (long)(down / 1000)
}); });
} }
res = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); res = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
@ -116,8 +116,8 @@ namespace ServiceLib.Services.Statistics
var trafficItem = JsonUtils.Deserialize<TrafficItem>(source); var trafficItem = JsonUtils.Deserialize<TrafficItem>(source);
if (trafficItem != null) if (trafficItem != null)
{ {
up = trafficItem.up; up = trafficItem.Up;
down = trafficItem.down; down = trafficItem.Down;
} }
} }
catch catch

View file

@ -116,16 +116,16 @@ namespace ServiceLib.Services.Statistics
{ {
if (type == "uplink") if (type == "uplink")
{ {
server.directUp = value; server.DirectUp = value;
} }
else if (type == "downlink") else if (type == "downlink")
{ {
server.directDown = value; server.DirectDown = value;
} }
} }
} }
server.proxyUp = aggregateProxyUp; server.ProxyUp = aggregateProxyUp;
server.proxyDown = aggregateProxyDown; server.ProxyDown = aggregateProxyDown;
} }
catch catch
{ {

View file

@ -483,7 +483,7 @@ namespace ServiceLib.Services
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet); var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
foreach (var item in rules ?? []) foreach (var item in rules ?? [])
{ {
foreach (var ip in item.ip ?? []) foreach (var ip in item.Ip ?? [])
{ {
var prefix = "geoip:"; var prefix = "geoip:";
if (ip.StartsWith(prefix)) if (ip.StartsWith(prefix))
@ -492,7 +492,7 @@ namespace ServiceLib.Services
} }
} }
foreach (var domain in item.domain ?? []) foreach (var domain in item.Domain ?? [])
{ {
var prefix = "geosite:"; var prefix = "geosite:";
if (domain.StartsWith(prefix)) if (domain.StartsWith(prefix))

View file

@ -36,7 +36,7 @@ namespace ServiceLib.ViewModels
var canEditRemove = this.WhenAnyValue( var canEditRemove = this.WhenAnyValue(
x => x.SelectedSource, x => x.SelectedSource,
selectedSource => selectedSource != null && Utils.IsNotEmpty(selectedSource.id)); selectedSource => selectedSource != null && Utils.IsNotEmpty(selectedSource.Id));
this.WhenAnyValue( this.WhenAnyValue(
x => x.SortingSelected, x => x.SortingSelected,
@ -125,18 +125,18 @@ namespace ServiceLib.ViewModels
ClashConnectionModel model = new(); ClashConnectionModel model = new();
model.id = item.id; model.Id = item.id;
model.network = item.metadata.network; model.Network = item.metadata.network;
model.type = item.metadata.type; model.Type = item.metadata.type;
model.host = host; model.Host = host;
var sp = (dtNow - item.start); var sp = (dtNow - item.start);
model.time = sp.TotalSeconds < 0 ? 1 : sp.TotalSeconds; model.Time = sp.TotalSeconds < 0 ? 1 : sp.TotalSeconds;
model.upload = item.upload; model.Upload = item.upload;
model.download = item.download; model.Download = item.download;
model.uploadTraffic = $"{Utils.HumanFy((long)item.upload)}"; model.UploadTraffic = $"{Utils.HumanFy((long)item.upload)}";
model.downloadTraffic = $"{Utils.HumanFy((long)item.download)}"; model.DownloadTraffic = $"{Utils.HumanFy((long)item.download)}";
model.elapsed = sp.ToString(@"hh\:mm\:ss"); model.Elapsed = sp.ToString(@"hh\:mm\:ss");
model.chain = item.chains?.Count > 0 ? item.chains[0] : string.Empty; model.Chain = item.chains?.Count > 0 ? item.chains[0] : string.Empty;
lstModel.Add(model); lstModel.Add(model);
} }
@ -146,27 +146,27 @@ namespace ServiceLib.ViewModels
switch (SortingSelected) switch (SortingSelected)
{ {
case 0: case 0:
lstModel = lstModel.OrderBy(t => t.upload / t.time).ToList(); lstModel = lstModel.OrderBy(t => t.Upload / t.Time).ToList();
break; break;
case 1: case 1:
lstModel = lstModel.OrderBy(t => t.download / t.time).ToList(); lstModel = lstModel.OrderBy(t => t.Download / t.Time).ToList();
break; break;
case 2: case 2:
lstModel = lstModel.OrderBy(t => t.upload).ToList(); lstModel = lstModel.OrderBy(t => t.Upload).ToList();
break; break;
case 3: case 3:
lstModel = lstModel.OrderBy(t => t.download).ToList(); lstModel = lstModel.OrderBy(t => t.Download).ToList();
break; break;
case 4: case 4:
lstModel = lstModel.OrderBy(t => t.time).ToList(); lstModel = lstModel.OrderBy(t => t.Time).ToList();
break; break;
case 5: case 5:
lstModel = lstModel.OrderBy(t => t.host).ToList(); lstModel = lstModel.OrderBy(t => t.Host).ToList();
break; break;
} }
@ -183,7 +183,7 @@ namespace ServiceLib.ViewModels
{ {
return; return;
} }
id = item.id; id = item.Id;
} }
else else
{ {

View file

@ -72,7 +72,7 @@ namespace ServiceLib.ViewModels
this.WhenAnyValue( this.WhenAnyValue(
x => x.SelectedGroup, x => x.SelectedGroup,
y => y != null && Utils.IsNotEmpty(y.name)) y => y != null && Utils.IsNotEmpty(y.Name))
.Subscribe(c => RefreshProxyDetails(c)); .Subscribe(c => RefreshProxyDetails(c));
this.WhenAnyValue( this.WhenAnyValue(
@ -185,7 +185,7 @@ namespace ServiceLib.ViewModels
public void RefreshProxyGroups() public void RefreshProxyGroups()
{ {
var selectedName = SelectedGroup?.name; var selectedName = SelectedGroup?.Name;
_proxyGroups.Clear(); _proxyGroups.Clear();
var proxyGroups = ClashApiHandler.Instance.GetClashProxyGroups(); var proxyGroups = ClashApiHandler.Instance.GetClashProxyGroups();
@ -204,9 +204,9 @@ namespace ServiceLib.ViewModels
} }
_proxyGroups.Add(new ClashProxyModel() _proxyGroups.Add(new ClashProxyModel()
{ {
now = item.now, Now = item.now,
name = item.name, Name = item.name,
type = item.type Type = item.type
}); });
} }
} }
@ -218,24 +218,24 @@ namespace ServiceLib.ViewModels
{ {
continue; continue;
} }
var item = _proxyGroups.Where(t => t.name == kv.Key).FirstOrDefault(); var item = _proxyGroups.Where(t => t.Name == kv.Key).FirstOrDefault();
if (item != null && Utils.IsNotEmpty(item.name)) if (item != null && Utils.IsNotEmpty(item.Name))
{ {
continue; continue;
} }
_proxyGroups.Add(new ClashProxyModel() _proxyGroups.Add(new ClashProxyModel()
{ {
now = kv.Value.now, Now = kv.Value.now,
name = kv.Key, Name = kv.Key,
type = kv.Value.type Type = kv.Value.type
}); });
} }
if (_proxyGroups != null && _proxyGroups.Count > 0) if (_proxyGroups != null && _proxyGroups.Count > 0)
{ {
if (selectedName != null && _proxyGroups.Any(t => t.name == selectedName)) if (selectedName != null && _proxyGroups.Any(t => t.Name == selectedName))
{ {
SelectedGroup = _proxyGroups.FirstOrDefault(t => t.name == selectedName); SelectedGroup = _proxyGroups.FirstOrDefault(t => t.Name == selectedName);
} }
else else
{ {
@ -255,7 +255,7 @@ namespace ServiceLib.ViewModels
{ {
return; return;
} }
var name = SelectedGroup?.name; var name = SelectedGroup?.Name;
if (Utils.IsNullOrEmpty(name)) if (Utils.IsNullOrEmpty(name))
{ {
return; return;
@ -289,21 +289,21 @@ namespace ServiceLib.ViewModels
lstDetails.Add(new ClashProxyModel() lstDetails.Add(new ClashProxyModel()
{ {
IsActive = IsActive, IsActive = IsActive,
name = item, Name = item,
type = proxy2.type, Type = proxy2.type,
delay = delay <= 0 ? _delayTimeout : delay, Delay = delay <= 0 ? _delayTimeout : delay,
delayName = delay <= 0 ? string.Empty : $"{delay}ms", DelayName = delay <= 0 ? string.Empty : $"{delay}ms",
}); });
} }
//sort //sort
switch (SortingSelected) switch (SortingSelected)
{ {
case 0: case 0:
lstDetails = lstDetails.OrderBy(t => t.delay).ToList(); lstDetails = lstDetails.OrderBy(t => t.Delay).ToList();
break; break;
case 1: case 1:
lstDetails = lstDetails.OrderBy(t => t.name).ToList(); lstDetails = lstDetails.OrderBy(t => t.Name).ToList();
break; break;
default: default:
@ -341,20 +341,20 @@ namespace ServiceLib.ViewModels
public async Task SetActiveProxy() public async Task SetActiveProxy()
{ {
if (SelectedGroup == null || Utils.IsNullOrEmpty(SelectedGroup.name)) if (SelectedGroup == null || Utils.IsNullOrEmpty(SelectedGroup.Name))
{ {
return; return;
} }
if (SelectedDetail == null || Utils.IsNullOrEmpty(SelectedDetail.name)) if (SelectedDetail == null || Utils.IsNullOrEmpty(SelectedDetail.Name))
{ {
return; return;
} }
var name = SelectedGroup.name; var name = SelectedGroup.Name;
if (Utils.IsNullOrEmpty(name)) if (Utils.IsNullOrEmpty(name))
{ {
return; return;
} }
var nameNode = SelectedDetail.name; var nameNode = SelectedDetail.Name;
if (Utils.IsNullOrEmpty(nameNode)) if (Utils.IsNullOrEmpty(nameNode))
{ {
return; return;
@ -369,10 +369,10 @@ namespace ServiceLib.ViewModels
await ClashApiHandler.Instance.ClashSetActiveProxy(name, nameNode); await ClashApiHandler.Instance.ClashSetActiveProxy(name, nameNode);
selectedProxy.now = nameNode; selectedProxy.now = nameNode;
var group = _proxyGroups.Where(it => it.name == SelectedGroup.name).FirstOrDefault(); var group = _proxyGroups.Where(it => it.Name == SelectedGroup.Name).FirstOrDefault();
if (group != null) if (group != null)
{ {
group.now = nameNode; group.Now = nameNode;
var group2 = JsonUtils.DeepCopy(group); var group2 = JsonUtils.DeepCopy(group);
_proxyGroups.Replace(group, group2); _proxyGroups.Replace(group, group2);
@ -397,31 +397,31 @@ namespace ServiceLib.ViewModels
return; return;
} }
_updateView?.Invoke(EViewAction.DispatcherProxiesDelayTest, new SpeedTestResult() { IndexId = item.name, Delay = result }); _updateView?.Invoke(EViewAction.DispatcherProxiesDelayTest, new SpeedTestResult() { IndexId = item.Name, Delay = result });
}); });
} }
public void ProxiesDelayTestResult(SpeedTestResult result) public void ProxiesDelayTestResult(SpeedTestResult result)
{ {
//UpdateHandler(false, $"{item.name}={result}"); //UpdateHandler(false, $"{item.name}={result}");
var detail = _proxyDetails.Where(it => it.name == result.IndexId).FirstOrDefault(); var detail = _proxyDetails.Where(it => it.Name == result.IndexId).FirstOrDefault();
if (detail != null) if (detail != null)
{ {
var dicResult = JsonUtils.Deserialize<Dictionary<string, object>>(result.Delay); var dicResult = JsonUtils.Deserialize<Dictionary<string, object>>(result.Delay);
if (dicResult != null && dicResult.ContainsKey("delay")) if (dicResult != null && dicResult.ContainsKey("delay"))
{ {
detail.delay = Convert.ToInt32(dicResult["delay"].ToString()); detail.Delay = Convert.ToInt32(dicResult["delay"].ToString());
detail.delayName = $"{detail.delay}ms"; detail.DelayName = $"{detail.Delay}ms";
} }
else if (dicResult != null && dicResult.ContainsKey("message")) else if (dicResult != null && dicResult.ContainsKey("message"))
{ {
detail.delay = _delayTimeout; detail.Delay = _delayTimeout;
detail.delayName = $"{dicResult["message"]}"; detail.DelayName = $"{dicResult["message"]}";
} }
else else
{ {
detail.delay = _delayTimeout; detail.Delay = _delayTimeout;
detail.delayName = string.Empty; detail.DelayName = string.Empty;
} }
_proxyDetails.Replace(detail, JsonUtils.DeepCopy(detail)); _proxyDetails.Replace(detail, JsonUtils.DeepCopy(detail));
} }

View file

@ -265,7 +265,7 @@ namespace ServiceLib.ViewModels
try try
{ {
Locator.Current.GetService<StatusBarViewModel>()?.UpdateStatistics(update); Locator.Current.GetService<StatusBarViewModel>()?.UpdateStatistics(update);
if ((update.proxyUp + update.proxyDown) > 0 && DateTime.Now.Second % 3 == 0) if ((update.ProxyUp + update.ProxyDown) > 0 && DateTime.Now.Second % 3 == 0)
{ {
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update); Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
} }

View file

@ -36,10 +36,10 @@ namespace ServiceLib.ViewModels
await SaveRulesAsync(); await SaveRulesAsync();
}); });
if (rulesItem.id.IsNullOrEmpty()) if (rulesItem.Id.IsNullOrEmpty())
{ {
rulesItem.id = Utils.GetGuid(false); rulesItem.Id = Utils.GetGuid(false);
rulesItem.outboundTag = Global.ProxyTag; rulesItem.OutboundTag = Global.ProxyTag;
rulesItem.Enabled = true; rulesItem.Enabled = true;
SelectedSource = rulesItem; SelectedSource = rulesItem;
} }
@ -48,9 +48,9 @@ namespace ServiceLib.ViewModels
SelectedSource = rulesItem; SelectedSource = rulesItem;
} }
Domain = Utils.List2String(SelectedSource.domain, true); Domain = Utils.List2String(SelectedSource.Domain, true);
IP = Utils.List2String(SelectedSource.ip, true); IP = Utils.List2String(SelectedSource.Ip, true);
Process = Utils.List2String(SelectedSource.process, true); Process = Utils.List2String(SelectedSource.Process, true);
} }
private async Task SaveRulesAsync() private async Task SaveRulesAsync()
@ -61,24 +61,24 @@ namespace ServiceLib.ViewModels
if (AutoSort) if (AutoSort)
{ {
SelectedSource.domain = Utils.String2ListSorted(Domain); SelectedSource.Domain = Utils.String2ListSorted(Domain);
SelectedSource.ip = Utils.String2ListSorted(IP); SelectedSource.Ip = Utils.String2ListSorted(IP);
SelectedSource.process = Utils.String2ListSorted(Process); SelectedSource.Process = Utils.String2ListSorted(Process);
} }
else else
{ {
SelectedSource.domain = Utils.String2List(Domain); SelectedSource.Domain = Utils.String2List(Domain);
SelectedSource.ip = Utils.String2List(IP); SelectedSource.Ip = Utils.String2List(IP);
SelectedSource.process = Utils.String2List(Process); SelectedSource.Process = Utils.String2List(Process);
} }
SelectedSource.protocol = ProtocolItems?.ToList(); SelectedSource.Protocol = ProtocolItems?.ToList();
SelectedSource.inboundTag = InboundTagItems?.ToList(); SelectedSource.InboundTag = InboundTagItems?.ToList();
bool hasRule = SelectedSource.domain?.Count > 0 bool hasRule = SelectedSource.Domain?.Count > 0
|| SelectedSource.ip?.Count > 0 || SelectedSource.Ip?.Count > 0
|| SelectedSource.protocol?.Count > 0 || SelectedSource.Protocol?.Count > 0
|| SelectedSource.process?.Count > 0 || SelectedSource.Process?.Count > 0
|| Utils.IsNotEmpty(SelectedSource.port); || Utils.IsNotEmpty(SelectedSource.Port);
if (!hasRule) if (!hasRule)
{ {

View file

@ -40,7 +40,7 @@ namespace ServiceLib.ViewModels
var canEditRemove = this.WhenAnyValue( var canEditRemove = this.WhenAnyValue(
x => x.SelectedSource, x => x.SelectedSource,
selectedSource => selectedSource != null && !selectedSource.outboundTag.IsNullOrEmpty()); selectedSource => selectedSource != null && !selectedSource.OutboundTag.IsNullOrEmpty());
RuleAddCmd = ReactiveCommand.CreateFromTask(async () => RuleAddCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
@ -105,14 +105,14 @@ namespace ServiceLib.ViewModels
{ {
var it = new RulesItemModel() var it = new RulesItemModel()
{ {
id = item.id, Id = item.Id,
outboundTag = item.outboundTag, OutboundTag = item.OutboundTag,
port = item.port, Port = item.Port,
network = item.network, Network = item.Network,
Protocols = Utils.List2String(item.protocol), Protocols = Utils.List2String(item.Protocol),
InboundTags = Utils.List2String(item.inboundTag), InboundTags = Utils.List2String(item.InboundTag),
Domains = Utils.List2String(item.domain), Domains = Utils.List2String(item.Domain),
Ips = Utils.List2String(item.ip), Ips = Utils.List2String(item.Ip),
Enabled = item.Enabled, Enabled = item.Enabled,
Remarks = item.Remarks, Remarks = item.Remarks,
}; };
@ -129,7 +129,7 @@ namespace ServiceLib.ViewModels
} }
else else
{ {
item = _rules.FirstOrDefault(t => t.id == SelectedSource?.id); item = _rules.FirstOrDefault(t => t.Id == SelectedSource?.Id);
if (item is null) if (item is null)
{ {
return; return;
@ -147,7 +147,7 @@ namespace ServiceLib.ViewModels
public async Task RuleRemoveAsync() public async Task RuleRemoveAsync()
{ {
if (SelectedSource is null || SelectedSource.outboundTag.IsNullOrEmpty()) if (SelectedSource is null || SelectedSource.OutboundTag.IsNullOrEmpty())
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectRules); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectRules);
return; return;
@ -158,7 +158,7 @@ namespace ServiceLib.ViewModels
} }
foreach (var it in SelectedSources ?? [SelectedSource]) foreach (var it in SelectedSources ?? [SelectedSource])
{ {
var item = _rules.FirstOrDefault(t => t.id == it?.id); var item = _rules.FirstOrDefault(t => t.Id == it?.Id);
if (item != null) if (item != null)
{ {
_rules.Remove(item); _rules.Remove(item);
@ -170,7 +170,7 @@ namespace ServiceLib.ViewModels
public async Task RuleExportSelectedAsync() public async Task RuleExportSelectedAsync()
{ {
if (SelectedSource is null || SelectedSource.outboundTag.IsNullOrEmpty()) if (SelectedSource is null || SelectedSource.OutboundTag.IsNullOrEmpty())
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectRules); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectRules);
return; return;
@ -179,7 +179,7 @@ namespace ServiceLib.ViewModels
var lst = new List<RulesItem4Ray>(); var lst = new List<RulesItem4Ray>();
foreach (var it in SelectedSources ?? [SelectedSource]) foreach (var it in SelectedSources ?? [SelectedSource])
{ {
var item = _rules.FirstOrDefault(t => t.id == it?.id); var item = _rules.FirstOrDefault(t => t.Id == it?.Id);
if (item != null) if (item != null)
{ {
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item)); var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
@ -194,13 +194,13 @@ namespace ServiceLib.ViewModels
public async Task MoveRule(EMove eMove) public async Task MoveRule(EMove eMove)
{ {
if (SelectedSource is null || SelectedSource.outboundTag.IsNullOrEmpty()) if (SelectedSource is null || SelectedSource.OutboundTag.IsNullOrEmpty())
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectRules); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectRules);
return; return;
} }
var item = _rules.FirstOrDefault(t => t.id == SelectedSource?.id); var item = _rules.FirstOrDefault(t => t.Id == SelectedSource?.Id);
if (item == null) if (item == null)
{ {
return; return;
@ -223,7 +223,7 @@ namespace ServiceLib.ViewModels
var item = SelectedRouting; var item = SelectedRouting;
foreach (var it in _rules) foreach (var it in _rules)
{ {
it.id = Utils.GetGuid(false); it.Id = Utils.GetGuid(false);
} }
item.RuleNum = _rules.Count; item.RuleNum = _rules.Count;
item.RuleSet = JsonUtils.Serialize(_rules, false); item.RuleSet = JsonUtils.Serialize(_rules, false);
@ -313,7 +313,7 @@ namespace ServiceLib.ViewModels
} }
foreach (var rule in lstRules) foreach (var rule in lstRules)
{ {
rule.id = Utils.GetGuid(false); rule.Id = Utils.GetGuid(false);
} }
if (blReplace) if (blReplace)

View file

@ -140,14 +140,14 @@ namespace ServiceLib.ViewModels
if (_lockedItem != null) if (_lockedItem != null)
{ {
_lockedRules = JsonUtils.Deserialize<List<RulesItem>>(_lockedItem.RuleSet); _lockedRules = JsonUtils.Deserialize<List<RulesItem>>(_lockedItem.RuleSet);
ProxyDomain = Utils.List2String(_lockedRules[0].domain, true); ProxyDomain = Utils.List2String(_lockedRules[0].Domain, true);
ProxyIP = Utils.List2String(_lockedRules[0].ip, true); ProxyIP = Utils.List2String(_lockedRules[0].Ip, true);
DirectDomain = Utils.List2String(_lockedRules[1].domain, true); DirectDomain = Utils.List2String(_lockedRules[1].Domain, true);
DirectIP = Utils.List2String(_lockedRules[1].ip, true); DirectIP = Utils.List2String(_lockedRules[1].Ip, true);
BlockDomain = Utils.List2String(_lockedRules[2].domain, true); BlockDomain = Utils.List2String(_lockedRules[2].Domain, true);
BlockIP = Utils.List2String(_lockedRules[2].ip, true); BlockIP = Utils.List2String(_lockedRules[2].Ip, true);
} }
} }
@ -155,14 +155,14 @@ namespace ServiceLib.ViewModels
{ {
if (_lockedItem != null) if (_lockedItem != null)
{ {
_lockedRules[0].domain = Utils.String2List(Utils.Convert2Comma(ProxyDomain.TrimEx())); _lockedRules[0].Domain = Utils.String2List(Utils.Convert2Comma(ProxyDomain.TrimEx()));
_lockedRules[0].ip = Utils.String2List(Utils.Convert2Comma(ProxyIP.TrimEx())); _lockedRules[0].Ip = Utils.String2List(Utils.Convert2Comma(ProxyIP.TrimEx()));
_lockedRules[1].domain = Utils.String2List(Utils.Convert2Comma(DirectDomain.TrimEx())); _lockedRules[1].Domain = Utils.String2List(Utils.Convert2Comma(DirectDomain.TrimEx()));
_lockedRules[1].ip = Utils.String2List(Utils.Convert2Comma(DirectIP.TrimEx())); _lockedRules[1].Ip = Utils.String2List(Utils.Convert2Comma(DirectIP.TrimEx()));
_lockedRules[2].domain = Utils.String2List(Utils.Convert2Comma(BlockDomain.TrimEx())); _lockedRules[2].Domain = Utils.String2List(Utils.Convert2Comma(BlockDomain.TrimEx()));
_lockedRules[2].ip = Utils.String2List(Utils.Convert2Comma(BlockIP.TrimEx())); _lockedRules[2].Ip = Utils.String2List(Utils.Convert2Comma(BlockIP.TrimEx()));
_lockedItem.RuleSet = JsonUtils.Serialize(_lockedRules, false); _lockedItem.RuleSet = JsonUtils.Serialize(_lockedRules, false);

View file

@ -460,8 +460,8 @@ namespace ServiceLib.ViewModels
public void UpdateStatistics(ServerSpeedItem update) public void UpdateStatistics(ServerSpeedItem update)
{ {
SpeedProxyDisplay = string.Format(ResUI.SpeedDisplayText, Global.ProxyTag, Utils.HumanFy(update.proxyUp), Utils.HumanFy(update.proxyDown)); SpeedProxyDisplay = string.Format(ResUI.SpeedDisplayText, Global.ProxyTag, Utils.HumanFy(update.ProxyUp), Utils.HumanFy(update.ProxyDown));
SpeedDirectDisplay = string.Format(ResUI.SpeedDisplayText, Global.DirectTag, Utils.HumanFy(update.directUp), Utils.HumanFy(update.directDown)); SpeedDirectDisplay = string.Format(ResUI.SpeedDisplayText, Global.DirectTag, Utils.HumanFy(update.DirectUp), Utils.HumanFy(update.DirectDown));
} }
#endregion UI #endregion UI

View file

@ -86,31 +86,31 @@
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn <DataGridTextColumn
Width="240" Width="240"
Binding="{Binding host}" Binding="{Binding Host}"
Header="{x:Static resx:ResUI.TbSortingHost}" /> Header="{x:Static resx:ResUI.TbSortingHost}" />
<DataGridTextColumn <DataGridTextColumn
Width="160" Width="160"
Binding="{Binding chain}" Binding="{Binding Chain}"
Header="{x:Static resx:ResUI.TbSortingChain}" /> Header="{x:Static resx:ResUI.TbSortingChain}" />
<DataGridTextColumn <DataGridTextColumn
Width="80" Width="80"
Binding="{Binding network}" Binding="{Binding Network}"
Header="{x:Static resx:ResUI.TbSortingNetwork}" /> Header="{x:Static resx:ResUI.TbSortingNetwork}" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding type}" Binding="{Binding Type}"
Header="{x:Static resx:ResUI.TbSortingType}" /> Header="{x:Static resx:ResUI.TbSortingType}" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding uploadTraffic}" Binding="{Binding UploadTraffic}"
Header="{x:Static resx:ResUI.TbSortingUpTraffic}" /> Header="{x:Static resx:ResUI.TbSortingUpTraffic}" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding downloadTraffic}" Binding="{Binding DownloadTraffic}"
Header="{x:Static resx:ResUI.TbSortingDownTraffic}" /> Header="{x:Static resx:ResUI.TbSortingDownTraffic}" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding elapsed}" Binding="{Binding Elapsed}"
Header="{x:Static resx:ResUI.TbSortingTime}" /> Header="{x:Static resx:ResUI.TbSortingTime}" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>

View file

@ -116,10 +116,10 @@
<RowDefinition Height="1*" /> <RowDefinition Height="1*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<DockPanel Grid.Row="0"> <DockPanel Grid.Row="0">
<TextBlock DockPanel.Dock="Right" Text="{Binding type}" /> <TextBlock DockPanel.Dock="Right" Text="{Binding Type}" />
<TextBlock Text="{Binding name}" /> <TextBlock Text="{Binding Name}" />
</DockPanel> </DockPanel>
<TextBlock Grid.Row="2" Text="{Binding now}" /> <TextBlock Grid.Row="2" Text="{Binding Now}" />
</Grid> </Grid>
</DockPanel> </DockPanel>
</Border> </Border>
@ -163,14 +163,14 @@
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock <TextBlock
Grid.Row="0" Grid.Row="0"
Text="{Binding name}" Text="{Binding Name}"
TextWrapping="WrapWithOverflow" /> TextWrapping="WrapWithOverflow" />
<DockPanel Grid.Row="2"> <DockPanel Grid.Row="2">
<TextBlock <TextBlock
DockPanel.Dock="Right" DockPanel.Dock="Right"
Foreground="{Binding Path=delay, Converter={StaticResource DelayColorConverter}}" Foreground="{Binding Path=Delay, Converter={StaticResource DelayColorConverter}}"
Text="{Binding delayName}" /> Text="{Binding DelayName}" />
<TextBlock Text="{Binding type}" /> <TextBlock Text="{Binding Type}" />
</DockPanel> </DockPanel>
</Grid> </Grid>
</DockPanel> </DockPanel>

View file

@ -39,13 +39,13 @@ namespace v2rayN.Desktop.Views
cmbNetwork.Items.Add(it); cmbNetwork.Items.Add(it);
}); });
if (!rulesItem.id.IsNullOrEmpty()) if (!rulesItem.Id.IsNullOrEmpty())
{ {
rulesItem.protocol?.ForEach(it => rulesItem.Protocol?.ForEach(it =>
{ {
clbProtocol.SelectedItems.Add(it); clbProtocol.SelectedItems.Add(it);
}); });
rulesItem.inboundTag?.ForEach(it => rulesItem.InboundTag?.ForEach(it =>
{ {
clbInboundTag.SelectedItems.Add(it); clbInboundTag.SelectedItems.Add(it);
}); });
@ -54,9 +54,9 @@ namespace v2rayN.Desktop.Views
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.outboundTag, v => v.cmbOutboundTag.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.OutboundTag, v => v.cmbOutboundTag.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.port, v => v.txtPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Port, v => v.txtPort.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.Enabled, v => v.togEnabled.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Enabled, v => v.togEnabled.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Domain, v => v.txtDomain.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Domain, v => v.txtDomain.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables);

View file

@ -218,11 +218,11 @@
Header="{x:Static resx:ResUI.LvRemarks}" /> Header="{x:Static resx:ResUI.LvRemarks}" />
<DataGridTextColumn <DataGridTextColumn
Width="120" Width="120"
Binding="{Binding outboundTag}" Binding="{Binding OutboundTag}"
Header="outboundTag" /> Header="outboundTag" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding port}" Binding="{Binding Port}"
Header="port" /> Header="port" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
@ -234,7 +234,7 @@
Header="inboundTag" /> Header="inboundTag" />
<DataGridTextColumn <DataGridTextColumn
Width="90" Width="90"
Binding="{Binding network}" Binding="{Binding Network}"
Header="network" /> Header="network" />
<DataGridTextColumn <DataGridTextColumn
Width="200" Width="200"

View file

@ -1,11 +1,11 @@
<reactiveui:ReactiveUserControl <reactiveui:ReactiveUserControl
x:Class="v2rayN.Views.ClashConnectionsView" x:Class="v2rayN.Views.ClashConnectionsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib" xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
d:DesignHeight="450" d:DesignHeight="450"
@ -89,31 +89,31 @@
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn <DataGridTextColumn
Width="240" Width="240"
Binding="{Binding host}" Binding="{Binding Host}"
Header="{x:Static resx:ResUI.TbSortingHost}" /> Header="{x:Static resx:ResUI.TbSortingHost}" />
<DataGridTextColumn <DataGridTextColumn
Width="160" Width="160"
Binding="{Binding chain}" Binding="{Binding Chain}"
Header="{x:Static resx:ResUI.TbSortingChain}" /> Header="{x:Static resx:ResUI.TbSortingChain}" />
<DataGridTextColumn <DataGridTextColumn
Width="80" Width="80"
Binding="{Binding network}" Binding="{Binding Network}"
Header="{x:Static resx:ResUI.TbSortingNetwork}" /> Header="{x:Static resx:ResUI.TbSortingNetwork}" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding type}" Binding="{Binding Type}"
Header="{x:Static resx:ResUI.TbSortingType}" /> Header="{x:Static resx:ResUI.TbSortingType}" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding uploadTraffic}" Binding="{Binding UploadTraffic}"
Header="{x:Static resx:ResUI.TbSortingUpTraffic}" /> Header="{x:Static resx:ResUI.TbSortingUpTraffic}" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding downloadTraffic}" Binding="{Binding DownloadTraffic}"
Header="{x:Static resx:ResUI.TbSortingDownTraffic}" /> Header="{x:Static resx:ResUI.TbSortingDownTraffic}" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding elapsed}" Binding="{Binding Elapsed}"
Header="{x:Static resx:ResUI.TbSortingTime}" /> Header="{x:Static resx:ResUI.TbSortingTime}" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>

View file

@ -1,14 +1,14 @@
<reactiveui:ReactiveUserControl <reactiveui:ReactiveUserControl
x:Class="v2rayN.Views.ClashProxiesView" x:Class="v2rayN.Views.ClashProxiesView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib" xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
xmlns:converters="clr-namespace:v2rayN.Converters"
d:DesignHeight="450" d:DesignHeight="450"
d:DesignWidth="800" d:DesignWidth="800"
x:TypeArguments="vms:ClashProxiesViewModel" x:TypeArguments="vms:ClashProxiesViewModel"
@ -118,13 +118,13 @@
<TextBlock <TextBlock
DockPanel.Dock="Right" DockPanel.Dock="Right"
Style="{StaticResource ListItemSubTitle}" Style="{StaticResource ListItemSubTitle}"
Text="{Binding type}" /> Text="{Binding Type}" />
<TextBlock Style="{StaticResource ListItemTitle}" Text="{Binding name}" /> <TextBlock Style="{StaticResource ListItemTitle}" Text="{Binding Name}" />
</DockPanel> </DockPanel>
<TextBlock <TextBlock
Grid.Row="1" Grid.Row="1"
Style="{StaticResource ListItemSubTitle}" Style="{StaticResource ListItemSubTitle}"
Text="{Binding now}" /> Text="{Binding Now}" />
</Grid> </Grid>
</DockPanel> </DockPanel>
</Border> </Border>
@ -170,15 +170,15 @@
<TextBlock <TextBlock
Grid.Row="0" Grid.Row="0"
Style="{StaticResource ListItemSubTitle}" Style="{StaticResource ListItemSubTitle}"
Text="{Binding name}" Text="{Binding Name}"
TextWrapping="WrapWithOverflow" /> TextWrapping="WrapWithOverflow" />
<DockPanel Grid.Row="1"> <DockPanel Grid.Row="1">
<TextBlock <TextBlock
DockPanel.Dock="Right" DockPanel.Dock="Right"
Foreground="{Binding Path=delay, Converter={StaticResource DelayColorConverter}}" Foreground="{Binding Path=Delay, Converter={StaticResource DelayColorConverter}}"
Style="{StaticResource ListItemSubTitle2}" Style="{StaticResource ListItemSubTitle2}"
Text="{Binding delayName}" /> Text="{Binding DelayName}" />
<TextBlock Style="{StaticResource ListItemSubTitle2}" Text="{Binding type}" /> <TextBlock Style="{StaticResource ListItemSubTitle2}" Text="{Binding Type}" />
</DockPanel> </DockPanel>
</Grid> </Grid>
</DockPanel> </DockPanel>

View file

@ -32,13 +32,13 @@ namespace v2rayN.Views
cmbNetwork.Items.Add(it); cmbNetwork.Items.Add(it);
}); });
if (!rulesItem.id.IsNullOrEmpty()) if (!rulesItem.Id.IsNullOrEmpty())
{ {
rulesItem.protocol?.ForEach(it => rulesItem.Protocol?.ForEach(it =>
{ {
clbProtocol.SelectedItems.Add(it); clbProtocol.SelectedItems.Add(it);
}); });
rulesItem.inboundTag?.ForEach(it => rulesItem.InboundTag?.ForEach(it =>
{ {
clbInboundTag.SelectedItems.Add(it); clbInboundTag.SelectedItems.Add(it);
}); });
@ -47,9 +47,9 @@ namespace v2rayN.Views
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.outboundTag, v => v.cmbOutboundTag.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.OutboundTag, v => v.cmbOutboundTag.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.port, v => v.txtPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Port, v => v.txtPort.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.network, v => v.cmbNetwork.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.Enabled, v => v.togEnabled.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Enabled, v => v.togEnabled.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Domain, v => v.txtDomain.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Domain, v => v.txtDomain.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables);

View file

@ -308,11 +308,11 @@
Header="{x:Static resx:ResUI.LvRemarks}" /> Header="{x:Static resx:ResUI.LvRemarks}" />
<DataGridTextColumn <DataGridTextColumn
Width="120" Width="120"
Binding="{Binding outboundTag}" Binding="{Binding OutboundTag}"
Header="outboundTag" /> Header="outboundTag" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding port}" Binding="{Binding Port}"
Header="port" /> Header="port" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
@ -324,7 +324,7 @@
Header="inboundTag" /> Header="inboundTag" />
<DataGridTextColumn <DataGridTextColumn
Width="90" Width="90"
Binding="{Binding network}" Binding="{Binding Network}"
Header="network" /> Header="network" />
<DataGridTextColumn <DataGridTextColumn
Width="200" Width="200"