Code optimization, function asynchrony

This commit is contained in:
2dust 2024-10-21 13:46:13 +08:00
parent a866017b4c
commit 3dd54312e7
22 changed files with 258 additions and 266 deletions

View file

@ -22,30 +22,21 @@ namespace ServiceLib.ViewModels
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
if (profileItem.indexId.IsNullOrEmpty())
{
SelectedSource = profileItem;
}
else
{
SelectedSource = JsonUtils.DeepCopy(profileItem);
}
CoreType = SelectedSource?.coreType?.ToString();
BrowseServerCmd = ReactiveCommand.CreateFromTask(async () => BrowseServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
_updateView?.Invoke(EViewAction.BrowseServer, null); _updateView?.Invoke(EViewAction.BrowseServer, null);
}); });
EditServerCmd = ReactiveCommand.CreateFromTask(async () => EditServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await EditServer(); await EditServer();
}); });
SaveServerCmd = ReactiveCommand.CreateFromTask(async () => SaveServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await SaveServerAsync(); await SaveServerAsync();
}); });
SelectedSource = profileItem.indexId.IsNullOrEmpty() ? profileItem : JsonUtils.DeepCopy(profileItem);
CoreType = SelectedSource?.coreType?.ToString();
} }
private async Task SaveServerAsync() private async Task SaveServerAsync()

View file

@ -17,9 +17,13 @@ namespace ServiceLib.ViewModels
public AddServerViewModel(ProfileItem profileItem, Func<EViewAction, object?, Task<bool>>? updateView) public AddServerViewModel(ProfileItem profileItem, Func<EViewAction, object?, Task<bool>>? updateView)
{ {
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SaveServerAsync();
});
if (profileItem.indexId.IsNullOrEmpty()) if (profileItem.indexId.IsNullOrEmpty())
{ {
profileItem.network = Global.DefaultNetwork; profileItem.network = Global.DefaultNetwork;
@ -33,11 +37,6 @@ namespace ServiceLib.ViewModels
SelectedSource = JsonUtils.DeepCopy(profileItem); SelectedSource = JsonUtils.DeepCopy(profileItem);
} }
CoreType = SelectedSource?.coreType?.ToString(); CoreType = SelectedSource?.coreType?.ToString();
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SaveServerAsync();
});
} }
private async Task SaveServerAsync() private async Task SaveServerAsync()

View file

@ -29,7 +29,6 @@ namespace ServiceLib.ViewModels
{ {
await WebDavCheck(); await WebDavCheck();
}); });
RemoteBackupCmd = ReactiveCommand.CreateFromTask(async () => RemoteBackupCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await RemoteBackup(); await RemoteBackup();

View file

@ -17,31 +17,25 @@ namespace ServiceLib.ViewModels
public IObservableCollection<CheckUpdateItem> CheckUpdateItems => _checkUpdateItem; public IObservableCollection<CheckUpdateItem> CheckUpdateItems => _checkUpdateItem;
public ReactiveCommand<Unit, Unit> CheckUpdateCmd { get; } public ReactiveCommand<Unit, Unit> CheckUpdateCmd { get; }
[Reactive] public bool EnableCheckPreReleaseUpdate { get; set; } [Reactive] public bool EnableCheckPreReleaseUpdate { get; set; }
[Reactive] public bool IsCheckUpdate { get; set; }
[Reactive] public bool AutoRun { get; set; }
public CheckUpdateViewModel(Func<EViewAction, object?, Task<bool>>? updateView) public CheckUpdateViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
{ {
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
RefreshSubItems();
CheckUpdateCmd = ReactiveCommand.CreateFromTask(async () => CheckUpdateCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await CheckUpdate() await CheckUpdate();
.ContinueWith(t =>
{
_ = UpdateFinished();
});
}); });
EnableCheckPreReleaseUpdate = _config.guiItem.checkPreReleaseUpdate; EnableCheckPreReleaseUpdate = _config.guiItem.checkPreReleaseUpdate;
IsCheckUpdate = true;
this.WhenAnyValue( this.WhenAnyValue(
x => x.EnableCheckPreReleaseUpdate, x => x.EnableCheckPreReleaseUpdate,
y => y == true) y => y == true)
.Subscribe(c => { _config.guiItem.checkPreReleaseUpdate = EnableCheckPreReleaseUpdate; }); .Subscribe(c => { _config.guiItem.checkPreReleaseUpdate = EnableCheckPreReleaseUpdate; });
RefreshSubItems();
} }
private void RefreshSubItems() private void RefreshSubItems()
@ -86,31 +80,31 @@ namespace ServiceLib.ViewModels
_lstUpdated = _checkUpdateItem.Where(x => x.IsSelected == true) _lstUpdated = _checkUpdateItem.Where(x => x.IsSelected == true)
.Select(x => new CheckUpdateItem() { CoreType = x.CoreType }).ToList(); .Select(x => new CheckUpdateItem() { CoreType = x.CoreType }).ToList();
for (int k = _checkUpdateItem.Count - 1; k >= 0; k--) for (var k = _checkUpdateItem.Count - 1; k >= 0; k--)
{ {
var item = _checkUpdateItem[k]; var item = _checkUpdateItem[k];
if (item.IsSelected == true) if (item.IsSelected != true) continue;
UpdateView(item.CoreType, "...");
if (item.CoreType == _geo)
{ {
IsCheckUpdate = false; await CheckUpdateGeo();
UpdateView(item.CoreType, "..."); }
if (item.CoreType == _geo) else if (item.CoreType == _v2rayN)
{ {
await CheckUpdateGeo(); await CheckUpdateN(EnableCheckPreReleaseUpdate);
} }
else if (item.CoreType == _v2rayN) else if (item.CoreType == ECoreType.mihomo.ToString())
{ {
await CheckUpdateN(EnableCheckPreReleaseUpdate); await CheckUpdateCore(item, false);
} }
else if (item.CoreType == ECoreType.mihomo.ToString()) else
{ {
await CheckUpdateCore(item, false); await CheckUpdateCore(item, EnableCheckPreReleaseUpdate);
}
else
{
await CheckUpdateCore(item, EnableCheckPreReleaseUpdate);
}
} }
} }
await UpdateFinished();
} }
private void UpdatedPlusPlus(string coreType, string fileName) private void UpdatedPlusPlus(string coreType, string fileName)
@ -204,7 +198,6 @@ namespace ServiceLib.ViewModels
{ {
if (blReload) if (blReload)
{ {
IsCheckUpdate = true;
Locator.Current.GetService<MainWindowViewModel>()?.Reload(); Locator.Current.GetService<MainWindowViewModel>()?.Reload();
} }
else else

View file

@ -10,7 +10,6 @@ namespace ServiceLib.ViewModels
public class ClashConnectionsViewModel : MyReactiveObject public class ClashConnectionsViewModel : MyReactiveObject
{ {
private IObservableCollection<ClashConnectionModel> _connectionItems = new ObservableCollectionExtended<ClashConnectionModel>(); private IObservableCollection<ClashConnectionModel> _connectionItems = new ObservableCollectionExtended<ClashConnectionModel>();
public IObservableCollection<ClashConnectionModel> ConnectionItems => _connectionItems; public IObservableCollection<ClashConnectionModel> ConnectionItems => _connectionItems;
[Reactive] [Reactive]
@ -42,13 +41,12 @@ namespace ServiceLib.ViewModels
this.WhenAnyValue( this.WhenAnyValue(
x => x.SortingSelected, x => x.SortingSelected,
y => y >= 0) y => y >= 0)
.Subscribe(c => DoSortingSelected(c)); .Subscribe(async c => await DoSortingSelected(c));
this.WhenAnyValue( this.WhenAnyValue(
x => x.AutoRefresh, x => x.AutoRefresh,
y => y == true) y => y == true)
.Subscribe(c => { _config.clashUIItem.connectionsAutoRefresh = AutoRefresh; }); .Subscribe(c => { _config.clashUIItem.connectionsAutoRefresh = AutoRefresh; });
ConnectionCloseCmd = ReactiveCommand.CreateFromTask(async () => ConnectionCloseCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await ClashConnectionClose(false); await ClashConnectionClose(false);
@ -62,26 +60,12 @@ namespace ServiceLib.ViewModels
Init(); Init();
} }
private void DoSortingSelected(bool c) private async Task Init()
{
if (!c)
{
return;
}
if (SortingSelected != _config.clashUIItem.connectionsSorting)
{
_config.clashUIItem.connectionsSorting = SortingSelected;
}
GetClashConnections();
}
private void Init()
{ {
var lastTime = DateTime.Now; var lastTime = DateTime.Now;
Observable.Interval(TimeSpan.FromSeconds(5)) Observable.Interval(TimeSpan.FromSeconds(5))
.Subscribe(x => .Subscribe(async x =>
{ {
if (!(AutoRefresh && _config.uiItem.showInTaskbar && _config.IsRunningCore(ECoreType.sing_box))) if (!(AutoRefresh && _config.uiItem.showInTaskbar && _config.IsRunningCore(ECoreType.sing_box)))
{ {
@ -92,7 +76,7 @@ namespace ServiceLib.ViewModels
{ {
if ((dtNow - lastTime).Minutes % _config.clashUIItem.connectionsRefreshInterval == 0) if ((dtNow - lastTime).Minutes % _config.clashUIItem.connectionsRefreshInterval == 0)
{ {
GetClashConnections(); await GetClashConnections();
lastTime = dtNow; lastTime = dtNow;
} }
Task.Delay(1000).Wait(); Task.Delay(1000).Wait();
@ -100,6 +84,20 @@ namespace ServiceLib.ViewModels
}); });
} }
private async Task DoSortingSelected(bool c)
{
if (!c)
{
return;
}
if (SortingSelected != _config.clashUIItem.connectionsSorting)
{
_config.clashUIItem.connectionsSorting = SortingSelected;
}
await GetClashConnections();
}
private async Task GetClashConnections() private async Task GetClashConnections()
{ {
var ret = await ClashApiHandler.Instance.GetClashConnectionsAsync(_config); var ret = await ClashApiHandler.Instance.GetClashConnectionsAsync(_config);

View file

@ -46,33 +46,6 @@ namespace ServiceLib.ViewModels
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
SelectedGroup = new();
SelectedDetail = new();
AutoRefresh = _config.clashUIItem.proxiesAutoRefresh;
SortingSelected = _config.clashUIItem.proxiesSorting;
RuleModeSelected = (int)_config.clashUIItem.ruleMode;
this.WhenAnyValue(
x => x.SelectedGroup,
y => y != null && Utils.IsNotEmpty(y.name))
.Subscribe(c => RefreshProxyDetails(c));
this.WhenAnyValue(
x => x.RuleModeSelected,
y => y >= 0)
.Subscribe(c => DoRulemodeSelected(c));
this.WhenAnyValue(
x => x.SortingSelected,
y => y >= 0)
.Subscribe(c => DoSortingSelected(c));
this.WhenAnyValue(
x => x.AutoRefresh,
y => y == true)
.Subscribe(c => { _config.clashUIItem.proxiesAutoRefresh = AutoRefresh; });
ProxiesReloadCmd = ReactiveCommand.CreateFromTask(async () => ProxiesReloadCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await ProxiesReload(); await ProxiesReload();
@ -91,11 +64,42 @@ namespace ServiceLib.ViewModels
await SetActiveProxy(); await SetActiveProxy();
}); });
ProxiesReload(); SelectedGroup = new();
DelayTestTask(); SelectedDetail = new();
AutoRefresh = _config.clashUIItem.proxiesAutoRefresh;
SortingSelected = _config.clashUIItem.proxiesSorting;
RuleModeSelected = (int)_config.clashUIItem.ruleMode;
this.WhenAnyValue(
x => x.SelectedGroup,
y => y != null && Utils.IsNotEmpty(y.name))
.Subscribe(c => RefreshProxyDetails(c));
this.WhenAnyValue(
x => x.RuleModeSelected,
y => y >= 0)
.Subscribe(async c => await DoRulemodeSelected(c));
this.WhenAnyValue(
x => x.SortingSelected,
y => y >= 0)
.Subscribe(c => DoSortingSelected(c));
this.WhenAnyValue(
x => x.AutoRefresh,
y => y == true)
.Subscribe(c => { _config.clashUIItem.proxiesAutoRefresh = AutoRefresh; });
Init();
} }
private void DoRulemodeSelected(bool c) private async Task Init()
{
await ProxiesReload();
await DelayTestTask();
}
private async Task DoRulemodeSelected(bool c)
{ {
if (!c) if (!c)
{ {
@ -105,16 +109,16 @@ namespace ServiceLib.ViewModels
{ {
return; return;
} }
SetRuleModeCheck((ERuleMode)RuleModeSelected); await SetRuleModeCheck((ERuleMode)RuleModeSelected);
} }
public void SetRuleModeCheck(ERuleMode mode) public async Task SetRuleModeCheck(ERuleMode mode)
{ {
if (_config.clashUIItem.ruleMode == mode) if (_config.clashUIItem.ruleMode == mode)
{ {
return; return;
} }
SetRuleMode(mode); await SetRuleMode(mode);
} }
private void DoSortingSelected(bool c) private void DoSortingSelected(bool c)
@ -385,7 +389,7 @@ namespace ServiceLib.ViewModels
{ {
if (item == null) if (item == null)
{ {
GetClashProxies(true); await GetClashProxies(true);
return; return;
} }
if (Utils.IsNullOrEmpty(result)) if (Utils.IsNullOrEmpty(result))
@ -427,7 +431,7 @@ namespace ServiceLib.ViewModels
#region task #region task
public void DelayTestTask() public async Task DelayTestTask()
{ {
var lastTime = DateTime.Now; var lastTime = DateTime.Now;

View file

@ -23,21 +23,7 @@ namespace ServiceLib.ViewModels
public DNSSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView) public DNSSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
{ {
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
var item = AppHandler.Instance.GetDNSItem(ECoreType.Xray).Result;
useSystemHosts = item.useSystemHosts;
domainStrategy4Freedom = item?.domainStrategy4Freedom ?? string.Empty;
domainDNSAddress = item?.domainDNSAddress ?? string.Empty;
normalDNS = item?.normalDNS ?? string.Empty;
var item2 = AppHandler.Instance.GetDNSItem(ECoreType.sing_box).Result;
domainStrategy4Freedom2 = item2?.domainStrategy4Freedom ?? string.Empty;
domainDNSAddress2 = item2?.domainDNSAddress ?? string.Empty;
normalDNS2 = item2?.normalDNS ?? string.Empty;
tunDNS2 = item2?.tunDNS ?? string.Empty;
SaveCmd = ReactiveCommand.CreateFromTask(async () => SaveCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await SaveSettingAsync(); await SaveSettingAsync();
@ -53,6 +39,23 @@ namespace ServiceLib.ViewModels
normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName); normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName);
tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName); tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName);
}); });
Init();
}
private async Task Init()
{
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
useSystemHosts = item.useSystemHosts;
domainStrategy4Freedom = item?.domainStrategy4Freedom ?? string.Empty;
domainDNSAddress = item?.domainDNSAddress ?? string.Empty;
normalDNS = item?.normalDNS ?? string.Empty;
var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
domainStrategy4Freedom2 = item2?.domainStrategy4Freedom ?? string.Empty;
domainDNSAddress2 = item2?.domainDNSAddress ?? string.Empty;
normalDNS2 = item2?.normalDNS ?? string.Empty;
tunDNS2 = item2?.tunDNS ?? string.Empty;
} }
private async Task SaveSettingAsync() private async Task SaveSettingAsync()

View file

@ -70,10 +70,6 @@ namespace ServiceLib.ViewModels
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
Init();
_config.uiItem.showInTaskbar = true;
#region WhenAnyValue && ReactiveCommand #region WhenAnyValue && ReactiveCommand
//servers //servers
@ -203,11 +199,13 @@ namespace ServiceLib.ViewModels
#endregion WhenAnyValue && ReactiveCommand #endregion WhenAnyValue && ReactiveCommand
AutoHideStartup(); Init();
} }
private async Task Init() private async Task Init()
{ {
_config.uiItem.showInTaskbar = true;
await ConfigHandler.InitBuiltinRouting(_config); await ConfigHandler.InitBuiltinRouting(_config);
await ConfigHandler.InitBuiltinDNS(_config); await ConfigHandler.InitBuiltinDNS(_config);
CoreHandler.Instance.Init(_config, UpdateHandler); CoreHandler.Instance.Init(_config, UpdateHandler);
@ -219,6 +217,7 @@ namespace ServiceLib.ViewModels
} }
await Reload(); await Reload();
await AutoHideStartup();
} }
#endregion Init #endregion Init
@ -571,16 +570,11 @@ namespace ServiceLib.ViewModels
CoreHandler.Instance.CoreStop(); CoreHandler.Instance.CoreStop();
} }
private void AutoHideStartup() private async Task AutoHideStartup()
{ {
if (_config.uiItem.autoHideStartup) if (_config.uiItem.autoHideStartup)
{ {
Observable.Range(1, 1) ShowHideWindow(false);
.Delay(TimeSpan.FromSeconds(1))
.Subscribe(async x =>
{
ShowHideWindow(false);
});
} }
} }

View file

@ -23,9 +23,6 @@ namespace ServiceLib.ViewModels
{ {
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
MessageBus.Current.Listen<string>(EMsgCommand.SendMsgView.ToString()).Subscribe(async x => await AppendQueueMsg(x));
MsgFilter = _config.msgUIItem.mainMsgFilter ?? string.Empty; MsgFilter = _config.msgUIItem.mainMsgFilter ?? string.Empty;
AutoRefresh = _config.msgUIItem.autoRefresh ?? true; AutoRefresh = _config.msgUIItem.autoRefresh ?? true;
@ -37,6 +34,13 @@ namespace ServiceLib.ViewModels
x => x.AutoRefresh, x => x.AutoRefresh,
y => y == true) y => y == true)
.Subscribe(c => { _config.msgUIItem.autoRefresh = AutoRefresh; }); .Subscribe(c => { _config.msgUIItem.autoRefresh = AutoRefresh; });
MessageBus.Current.Listen<string>(EMsgCommand.SendMsgView.ToString()).Subscribe(OnNext);
}
private async void OnNext(string x)
{
await AppendQueueMsg(x);
} }
private async Task AppendQueueMsg(string msg) private async Task AppendQueueMsg(string msg)

View file

@ -105,9 +105,18 @@ namespace ServiceLib.ViewModels
public OptionSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView) public OptionSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
{ {
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SaveSettingAsync();
});
Init();
}
private async Task Init()
{
#region Core #region Core
var inbound = _config.inbound[0]; var inbound = _config.inbound[0];
@ -191,15 +200,10 @@ namespace ServiceLib.ViewModels
#endregion Tun mode #endregion Tun mode
InitCoreType(); await InitCoreType();
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SaveSettingAsync();
});
} }
private void InitCoreType() private async Task InitCoreType()
{ {
if (_config.coreTypeItem == null) if (_config.coreTypeItem == null)
{ {
@ -339,7 +343,7 @@ namespace ServiceLib.ViewModels
_config.tunModeItem.enableIPv6Address = TunEnableIPv6Address; _config.tunModeItem.enableIPv6Address = TunEnableIPv6Address;
//coreType //coreType
SaveCoreType(); await SaveCoreType();
if (await ConfigHandler.SaveConfig(_config) == 0) if (await ConfigHandler.SaveConfig(_config) == 0)
{ {
@ -359,7 +363,7 @@ namespace ServiceLib.ViewModels
} }
} }
private int SaveCoreType() private async Task SaveCoreType()
{ {
for (int k = 1; k <= _config.coreTypeItem.Count; k++) for (int k = 1; k <= _config.coreTypeItem.Count; k++)
{ {
@ -396,7 +400,6 @@ namespace ServiceLib.ViewModels
} }
item.coreType = (ECoreType)Enum.Parse(typeof(ECoreType), type); item.coreType = (ECoreType)Enum.Parse(typeof(ECoreType), type);
} }
return 0;
} }
} }
} }

View file

@ -99,20 +99,6 @@ namespace ServiceLib.ViewModels
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
if (_updateView != null)
{
MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString())
.Subscribe(async x => await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null));
}
SelectedProfile = new();
SelectedSub = new();
SelectedMoveToGroup = new();
SelectedServer = new();
RefreshSubscriptions();
RefreshServers();
#region WhenAnyValue && ReactiveCommand #region WhenAnyValue && ReactiveCommand
var canEditRemove = this.WhenAnyValue( var canEditRemove = this.WhenAnyValue(
@ -122,16 +108,16 @@ namespace ServiceLib.ViewModels
this.WhenAnyValue( this.WhenAnyValue(
x => x.SelectedSub, x => x.SelectedSub,
y => y != null && !y.remarks.IsNullOrEmpty() && _config.subIndexId != y.id) y => y != null && !y.remarks.IsNullOrEmpty() && _config.subIndexId != y.id)
.Subscribe(c => SubSelectedChangedAsync(c)); .Subscribe(async c => await SubSelectedChangedAsync(c));
this.WhenAnyValue( this.WhenAnyValue(
x => x.SelectedMoveToGroup, x => x.SelectedMoveToGroup,
y => y != null && !y.remarks.IsNullOrEmpty()) y => y != null && !y.remarks.IsNullOrEmpty())
.Subscribe(c => MoveToGroup(c)); .Subscribe(async c => await MoveToGroup(c));
this.WhenAnyValue( this.WhenAnyValue(
x => x.SelectedServer, x => x.SelectedServer,
y => y != null && !y.Text.IsNullOrEmpty()) y => y != null && !y.Text.IsNullOrEmpty())
.Subscribe(c => ServerSelectedChanged(c)); .Subscribe(async c => await ServerSelectedChanged(c));
this.WhenAnyValue( this.WhenAnyValue(
x => x.ServerFilter, x => x.ServerFilter,
@ -240,12 +226,35 @@ namespace ServiceLib.ViewModels
}); });
#endregion WhenAnyValue && ReactiveCommand #endregion WhenAnyValue && ReactiveCommand
if (_updateView != null)
{
MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString()).Subscribe(OnNext);
}
Init();
}
private async Task Init()
{
SelectedProfile = new();
SelectedSub = new();
SelectedMoveToGroup = new();
SelectedServer = new();
await RefreshSubscriptions();
RefreshServers();
} }
#endregion Init #endregion Init
#region Actions #region Actions
private async void OnNext(string x)
{
await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null);
}
private void Reload() private void Reload()
{ {
Locator.Current.GetService<MainWindowViewModel>()?.Reload(); Locator.Current.GetService<MainWindowViewModel>()?.Reload();
@ -534,7 +543,7 @@ namespace ServiceLib.ViewModels
} }
} }
private void ServerSelectedChanged(bool c) private async Task ServerSelectedChanged(bool c)
{ {
if (!c) if (!c)
{ {
@ -548,7 +557,7 @@ namespace ServiceLib.ViewModels
{ {
return; return;
} }
SetDefaultServer(SelectedServer.ID); await SetDefaultServer(SelectedServer.ID);
} }
public async Task ShareServerAsync() public async Task ShareServerAsync()

View file

@ -29,9 +29,13 @@ namespace ServiceLib.ViewModels
public RoutingRuleDetailsViewModel(RulesItem rulesItem, Func<EViewAction, object?, Task<bool>>? updateView) public RoutingRuleDetailsViewModel(RulesItem rulesItem, Func<EViewAction, object?, Task<bool>>? updateView)
{ {
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SaveRulesAsync();
});
if (rulesItem.id.IsNullOrEmpty()) if (rulesItem.id.IsNullOrEmpty())
{ {
rulesItem.id = Utils.GetGuid(false); rulesItem.id = Utils.GetGuid(false);
@ -47,11 +51,6 @@ namespace ServiceLib.ViewModels
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);
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SaveRulesAsync();
});
} }
private async Task SaveRulesAsync() private async Task SaveRulesAsync()

View file

@ -36,26 +36,11 @@ namespace ServiceLib.ViewModels
public RoutingRuleSettingViewModel(RoutingItem routingItem, Func<EViewAction, object?, Task<bool>>? updateView) public RoutingRuleSettingViewModel(RoutingItem routingItem, Func<EViewAction, object?, Task<bool>>? updateView)
{ {
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
SelectedSource = new();
if (routingItem.id.IsNullOrEmpty())
{
SelectedRouting = routingItem;
_rules = new();
}
else
{
SelectedRouting = routingItem;
_rules = JsonUtils.Deserialize<List<RulesItem>>(SelectedRouting.ruleSet);
}
RefreshRulesItems();
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 () =>
{ {
@ -104,6 +89,12 @@ namespace ServiceLib.ViewModels
{ {
await SaveRoutingAsync(); await SaveRoutingAsync();
}); });
SelectedSource = new();
SelectedRouting = routingItem;
_rules = routingItem.id.IsNullOrEmpty() ? new() : JsonUtils.Deserialize<List<RulesItem>>(SelectedRouting.ruleSet);
RefreshRulesItems();
} }
public void RefreshRulesItems() public void RefreshRulesItems()

View file

@ -67,27 +67,14 @@ namespace ServiceLib.ViewModels
public RoutingSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView) public RoutingSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
{ {
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
SelectedSource = new();
ConfigHandler.InitBuiltinRouting(_config);
enableRoutingAdvanced = _config.routingBasicItem.enableRoutingAdvanced;
domainStrategy = _config.routingBasicItem.domainStrategy;
domainMatcher = _config.routingBasicItem.domainMatcher;
domainStrategy4Singbox = _config.routingBasicItem.domainStrategy4Singbox;
RefreshRoutingItems();
BindingLockedData();
var canEditRemove = this.WhenAnyValue( var canEditRemove = this.WhenAnyValue(
x => x.SelectedSource, x => x.SelectedSource,
selectedSource => selectedSource != null && !selectedSource.remarks.IsNullOrEmpty()); selectedSource => selectedSource != null && !selectedSource.remarks.IsNullOrEmpty());
this.WhenAnyValue( this.WhenAnyValue(
x => x.enableRoutingAdvanced) x => x.enableRoutingAdvanced)
.Subscribe(c => enableRoutingBasic = !enableRoutingAdvanced); .Subscribe(c => enableRoutingBasic = !enableRoutingAdvanced);
RoutingBasicImportRulesCmd = ReactiveCommand.CreateFromTask(async () => RoutingBasicImportRulesCmd = ReactiveCommand.CreateFromTask(async () =>
@ -116,6 +103,22 @@ namespace ServiceLib.ViewModels
{ {
await SaveRoutingAsync(); await SaveRoutingAsync();
}); });
Init();
}
private async Task Init()
{
SelectedSource = new();
enableRoutingAdvanced = _config.routingBasicItem.enableRoutingAdvanced;
domainStrategy = _config.routingBasicItem.domainStrategy;
domainMatcher = _config.routingBasicItem.domainMatcher;
domainStrategy4Singbox = _config.routingBasicItem.domainStrategy4Singbox;
await ConfigHandler.InitBuiltinRouting(_config);
await RefreshRoutingItems();
await BindingLockedData();
} }
#region locked #region locked
@ -148,7 +151,7 @@ namespace ServiceLib.ViewModels
} }
} }
private void EndBindingLockedData() private async Task EndBindingLockedData()
{ {
if (_lockedItem != null) if (_lockedItem != null)
{ {
@ -163,7 +166,7 @@ namespace ServiceLib.ViewModels
_lockedItem.ruleSet = JsonUtils.Serialize(_lockedRules, false); _lockedItem.ruleSet = JsonUtils.Serialize(_lockedRules, false);
ConfigHandler.SaveRoutingItem(_config, _lockedItem); await ConfigHandler.SaveRoutingItem(_config, _lockedItem);
} }
} }
@ -206,7 +209,7 @@ namespace ServiceLib.ViewModels
_config.routingBasicItem.domainMatcher = domainMatcher; _config.routingBasicItem.domainMatcher = domainMatcher;
_config.routingBasicItem.domainStrategy4Singbox = domainStrategy4Singbox; _config.routingBasicItem.domainStrategy4Singbox = domainStrategy4Singbox;
EndBindingLockedData(); await EndBindingLockedData();
if (await ConfigHandler.SaveConfig(_config) == 0) if (await ConfigHandler.SaveConfig(_config) == 0)
{ {
@ -250,7 +253,7 @@ namespace ServiceLib.ViewModels
} }
if (await _updateView?.Invoke(EViewAction.RoutingRuleSettingWindow, item) == true) if (await _updateView?.Invoke(EViewAction.RoutingRuleSettingWindow, item) == true)
{ {
RefreshRoutingItems(); await RefreshRoutingItems();
IsModified = true; IsModified = true;
} }
} }
@ -271,11 +274,11 @@ namespace ServiceLib.ViewModels
var item = await AppHandler.Instance.GetRoutingItem(it?.id); var item = await AppHandler.Instance.GetRoutingItem(it?.id);
if (item != null) if (item != null)
{ {
ConfigHandler.RemoveRoutingItem(item); await ConfigHandler.RemoveRoutingItem(item);
} }
} }
RefreshRoutingItems(); await RefreshRoutingItems();
IsModified = true; IsModified = true;
} }
@ -290,7 +293,7 @@ namespace ServiceLib.ViewModels
if (await ConfigHandler.SetDefaultRouting(_config, item) == 0) if (await ConfigHandler.SetDefaultRouting(_config, item) == 0)
{ {
RefreshRoutingItems(); await RefreshRoutingItems();
IsModified = true; IsModified = true;
} }
} }
@ -299,7 +302,7 @@ namespace ServiceLib.ViewModels
{ {
if (await ConfigHandler.InitRouting(_config, true) == 0) if (await ConfigHandler.InitRouting(_config, true) == 0)
{ {
RefreshRoutingItems(); await RefreshRoutingItems();
IsModified = true; IsModified = true;
} }
} }

View file

@ -105,33 +105,12 @@ namespace ServiceLib.ViewModels
{ {
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
if (updateView != null)
{
Init(updateView);
}
SelectedRouting = new();
SelectedServer = new();
if (_config.tunModeItem.enableTun && AppHandler.Instance.IsAdministrator)
{
EnableTun = true;
}
else
{
_config.tunModeItem.enableTun = EnableTun = false;
}
RefreshRoutingsMenu();
InboundDisplayStatus();
ChangeSystemProxyAsync(_config.systemProxyItem.sysProxyType, true);
#region WhenAnyValue && ReactiveCommand #region WhenAnyValue && ReactiveCommand
this.WhenAnyValue( this.WhenAnyValue(
x => x.SelectedRouting, x => x.SelectedRouting,
y => y != null && !y.remarks.IsNullOrEmpty()) y => y != null && !y.remarks.IsNullOrEmpty())
.Subscribe(c => RoutingSelectedChangedAsync(c)); .Subscribe(async c => await RoutingSelectedChangedAsync(c));
this.WhenAnyValue( this.WhenAnyValue(
x => x.SelectedServer, x => x.SelectedServer,
@ -142,12 +121,12 @@ namespace ServiceLib.ViewModels
this.WhenAnyValue( this.WhenAnyValue(
x => x.SystemProxySelected, x => x.SystemProxySelected,
y => y >= 0) y => y >= 0)
.Subscribe(c => DoSystemProxySelected(c)); .Subscribe(async c => await DoSystemProxySelected(c));
this.WhenAnyValue( this.WhenAnyValue(
x => x.EnableTun, x => x.EnableTun,
y => y == true) y => y == true)
.Subscribe(c => DoEnableTun(c)); .Subscribe(async c => await DoEnableTun(c));
NotifyLeftClickCmd = ReactiveCommand.CreateFromTask(async () => NotifyLeftClickCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
@ -190,18 +169,47 @@ namespace ServiceLib.ViewModels
}); });
#endregion WhenAnyValue && ReactiveCommand #endregion WhenAnyValue && ReactiveCommand
if (updateView != null)
{
InitUpdateView(updateView);
}
Init();
} }
public void Init(Func<EViewAction, object?, Task<bool>>? updateView) private async Task Init()
{
SelectedRouting = new();
SelectedServer = new();
if (_config.tunModeItem.enableTun && AppHandler.Instance.IsAdministrator)
{
EnableTun = true;
}
else
{
_config.tunModeItem.enableTun = EnableTun = false;
}
await RefreshRoutingsMenu();
await InboundDisplayStatus();
await ChangeSystemProxyAsync(_config.systemProxyItem.sysProxyType, true);
}
public void InitUpdateView(Func<EViewAction, object?, Task<bool>>? updateView)
{ {
_updateView = updateView; _updateView = updateView;
if (_updateView != null) if (_updateView != null)
{ {
MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString()) MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString()).Subscribe(OnNext);
.Subscribe(async x => await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null));
} }
} }
private async void OnNext(string x)
{
await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null);
}
private async Task AddServerViaClipboard() private async Task AddServerViaClipboard()
{ {
var service = Locator.Current.GetService<MainWindowViewModel>(); var service = Locator.Current.GetService<MainWindowViewModel>();
@ -387,7 +395,7 @@ namespace ServiceLib.ViewModels
} }
} }
private void DoSystemProxySelected(bool c) private async Task DoSystemProxySelected(bool c)
{ {
if (!c) if (!c)
{ {
@ -397,10 +405,10 @@ namespace ServiceLib.ViewModels
{ {
return; return;
} }
SetListenerType((ESysProxyType)SystemProxySelected); await SetListenerType((ESysProxyType)SystemProxySelected);
} }
private void DoEnableTun(bool c) private async Task DoEnableTun(bool c)
{ {
if (_config.tunModeItem.enableTun != EnableTun) if (_config.tunModeItem.enableTun != EnableTun)
{ {
@ -412,7 +420,7 @@ namespace ServiceLib.ViewModels
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin(); Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
return; return;
} }
ConfigHandler.SaveConfig(_config); await ConfigHandler.SaveConfig(_config);
Locator.Current.GetService<MainWindowViewModel>()?.Reload(); Locator.Current.GetService<MainWindowViewModel>()?.Reload();
} }
} }
@ -421,7 +429,7 @@ namespace ServiceLib.ViewModels
#region UI #region UI
public void InboundDisplayStatus() public async Task InboundDisplayStatus()
{ {
StringBuilder sb = new(); StringBuilder sb = new();
sb.Append($"[{EInboundProtocol.socks}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.socks)}]"); sb.Append($"[{EInboundProtocol.socks}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.socks)}]");

View file

@ -14,27 +14,19 @@ namespace ServiceLib.ViewModels
public SubEditViewModel(SubItem subItem, Func<EViewAction, object?, Task<bool>>? updateView) public SubEditViewModel(SubItem subItem, Func<EViewAction, object?, Task<bool>>? updateView)
{ {
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
if (subItem.id.IsNullOrEmpty())
{
SelectedSource = subItem;
}
else
{
SelectedSource = JsonUtils.DeepCopy(subItem);
}
SaveCmd = ReactiveCommand.CreateFromTask(async () => SaveCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await SaveSubAsync(); await SaveSubAsync();
}); });
SelectedSource = subItem.id.IsNullOrEmpty() ? subItem : JsonUtils.DeepCopy(subItem);
} }
private async Task SaveSubAsync() private async Task SaveSubAsync()
{ {
string remarks = SelectedSource.remarks; var remarks = SelectedSource.remarks;
if (Utils.IsNullOrEmpty(remarks)) if (Utils.IsNullOrEmpty(remarks))
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks); NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks);

View file

@ -25,13 +25,8 @@ namespace ServiceLib.ViewModels
public SubSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView) public SubSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
{ {
_config = AppHandler.Instance.Config; _config = AppHandler.Instance.Config;
_updateView = updateView; _updateView = updateView;
SelectedSource = new();
RefreshSubItems();
var canEditRemove = this.WhenAnyValue( var canEditRemove = this.WhenAnyValue(
x => x.SelectedSource, x => x.SelectedSource,
selectedSource => selectedSource != null && !selectedSource.id.IsNullOrEmpty()); selectedSource => selectedSource != null && !selectedSource.id.IsNullOrEmpty());
@ -52,6 +47,15 @@ namespace ServiceLib.ViewModels
{ {
await _updateView?.Invoke(EViewAction.ShareSub, SelectedSource?.url); await _updateView?.Invoke(EViewAction.ShareSub, SelectedSource?.url);
}, canEditRemove); }, canEditRemove);
Init();
}
private async Task Init()
{
SelectedSource = new();
await RefreshSubItems();
} }
public async Task RefreshSubItems() public async Task RefreshSubItems()

View file

@ -19,7 +19,6 @@ namespace v2rayN.Desktop.Views
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.IsCheckUpdate, v => v.btnCheckUpdate.IsEnabled).DisposeWith(disposables);
}); });
} }

View file

@ -4,7 +4,6 @@ using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Notifications; using Avalonia.Controls.Notifications;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using Avalonia.Threading; using Avalonia.Threading;
using DialogHostAvalonia; using DialogHostAvalonia;
@ -40,7 +39,7 @@ namespace v2rayN.Desktop.Views
menuCheckUpdate.Click += MenuCheckUpdate_Click; menuCheckUpdate.Click += MenuCheckUpdate_Click;
menuBackupAndRestore.Click += MenuBackupAndRestore_Click; menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
MessageBus.Current.Listen<string>(EMsgCommand.SendSnackMsg.ToString()).Subscribe(x => DelegateSnackMsg(x)); MessageBus.Current.Listen<string>(EMsgCommand.SendSnackMsg.ToString()).Subscribe(DelegateSnackMsg);
ViewModel = new MainWindowViewModel(UpdateViewHandler); ViewModel = new MainWindowViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel)); Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
@ -123,6 +122,7 @@ namespace v2rayN.Desktop.Views
menuSettingsSetUWP.IsVisible = false; menuSettingsSetUWP.IsVisible = false;
menuGlobalHotkeySetting.IsVisible = false; menuGlobalHotkeySetting.IsVisible = false;
} }
menuAddServerViaScan.IsVisible = false;
switch (_config.uiItem.mainGirdOrientation) switch (_config.uiItem.mainGirdOrientation)
{ {
@ -289,7 +289,7 @@ namespace v2rayN.Desktop.Views
break; break;
case Key.S: case Key.S:
ScanScreenTaskAsync().ContinueWith(_ => { }); await ScanScreenTaskAsync();
break; break;
} }
} }

View file

@ -21,7 +21,7 @@ namespace v2rayN.Desktop.Views
//ViewModel = new StatusBarViewModel(UpdateViewHandler); //ViewModel = new StatusBarViewModel(UpdateViewHandler);
//Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel)); //Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel));
ViewModel = Locator.Current.GetService<StatusBarViewModel>(); ViewModel = Locator.Current.GetService<StatusBarViewModel>();
ViewModel?.Init(UpdateViewHandler); ViewModel?.InitUpdateView(UpdateViewHandler);
txtRunningServerDisplay.Tapped += TxtRunningServerDisplay_Tapped; txtRunningServerDisplay.Tapped += TxtRunningServerDisplay_Tapped;
txtRunningInfoDisplay.Tapped += TxtRunningServerDisplay_Tapped; txtRunningInfoDisplay.Tapped += TxtRunningServerDisplay_Tapped;

View file

@ -19,7 +19,6 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.IsCheckUpdate, v => v.btnCheckUpdate.IsEnabled).DisposeWith(disposables);
}); });
} }

View file

@ -36,7 +36,7 @@ namespace v2rayN.Views
menuCheckUpdate.Click += MenuCheckUpdate_Click; menuCheckUpdate.Click += MenuCheckUpdate_Click;
menuBackupAndRestore.Click += MenuBackupAndRestore_Click; menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
MessageBus.Current.Listen<string>(EMsgCommand.SendSnackMsg.ToString()).Subscribe(x => DelegateSnackMsg(x)); MessageBus.Current.Listen<string>(EMsgCommand.SendSnackMsg.ToString()).Subscribe(DelegateSnackMsg);
ViewModel = new MainWindowViewModel(UpdateViewHandler); ViewModel = new MainWindowViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel)); Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));