mirror of https://github.com/2dust/v2rayN
Refactor new StatusBarViewModel
parent
d7bde77977
commit
7618f9f7d4
|
@ -1,41 +1,14 @@
|
|||
using DynamicData.Binding;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Splat;
|
||||
using System.Diagnostics;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ServiceLib.ViewModels
|
||||
{
|
||||
public class MainWindowViewModel : MyReactiveObject
|
||||
{
|
||||
#region private prop
|
||||
|
||||
private bool _isAdministrator { get; set; }
|
||||
|
||||
#endregion private prop
|
||||
|
||||
#region ObservableCollection
|
||||
|
||||
private IObservableCollection<RoutingItem> _routingItems = new ObservableCollectionExtended<RoutingItem>();
|
||||
public IObservableCollection<RoutingItem> RoutingItems => _routingItems;
|
||||
|
||||
private IObservableCollection<ComboItem> _servers = new ObservableCollectionExtended<ComboItem>();
|
||||
public IObservableCollection<ComboItem> Servers => _servers;
|
||||
|
||||
[Reactive]
|
||||
public RoutingItem SelectedRouting { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public ComboItem SelectedServer { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool BlServers { get; set; }
|
||||
|
||||
#endregion ObservableCollection
|
||||
|
||||
#region Menu
|
||||
|
||||
//servers
|
||||
|
@ -76,120 +49,27 @@ namespace ServiceLib.ViewModels
|
|||
[Reactive]
|
||||
public bool BlReloadEnabled { get; set; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> NotifyLeftClickCmd { get; }
|
||||
|
||||
#endregion Menu
|
||||
|
||||
#region System Proxy
|
||||
|
||||
[Reactive]
|
||||
public bool BlSystemProxyClear { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool BlSystemProxySet { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool BlSystemProxyNothing { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool BlSystemProxyPac { get; set; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> SystemProxyClearCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> SystemProxySetCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> SystemProxyNothingCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> SystemProxyPacCmd { get; }
|
||||
|
||||
[Reactive]
|
||||
public bool BlRouting { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public int SystemProxySelected { get; set; }
|
||||
|
||||
#endregion System Proxy
|
||||
|
||||
#region UI
|
||||
|
||||
[Reactive]
|
||||
public string InboundDisplay { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string InboundLanDisplay { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string RunningServerDisplay { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string RunningServerToolTipText { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string RunningInfoDisplay { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string SpeedProxyDisplay { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string SpeedDirectDisplay { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool EnableTun { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool ShowClashUI { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public int TabMainSelectedIndex { get; set; }
|
||||
|
||||
#endregion UI
|
||||
#endregion Menu
|
||||
|
||||
#region Init
|
||||
|
||||
public MainWindowViewModel(bool isAdministrator, Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
public MainWindowViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_config = AppHandler.Instance.Config;
|
||||
|
||||
_updateView = updateView;
|
||||
_isAdministrator = isAdministrator;
|
||||
|
||||
MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString()).Subscribe(async x => await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null));
|
||||
|
||||
SelectedRouting = new();
|
||||
SelectedServer = new();
|
||||
|
||||
Init();
|
||||
|
||||
_config.uiItem.showInTaskbar = true;
|
||||
if (_config.tunModeItem.enableTun && _isAdministrator)
|
||||
{
|
||||
EnableTun = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_config.tunModeItem.enableTun = EnableTun = false;
|
||||
}
|
||||
|
||||
#region WhenAnyValue && ReactiveCommand
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.SelectedRouting,
|
||||
y => y != null && !y.remarks.IsNullOrEmpty())
|
||||
.Subscribe(c => RoutingSelectedChangedAsync(c));
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.SelectedServer,
|
||||
y => y != null && !y.Text.IsNullOrEmpty())
|
||||
.Subscribe(c => ServerSelectedChanged(c));
|
||||
|
||||
SystemProxySelected = (int)_config.systemProxyItem.sysProxyType;
|
||||
this.WhenAnyValue(
|
||||
x => x.SystemProxySelected,
|
||||
y => y >= 0)
|
||||
.Subscribe(c => DoSystemProxySelected(c));
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.EnableTun,
|
||||
y => y == true)
|
||||
.Subscribe(c => DoEnableTun(c));
|
||||
|
||||
//servers
|
||||
AddVmessServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
|
@ -237,7 +117,7 @@ namespace ServiceLib.ViewModels
|
|||
});
|
||||
AddServerViaScanCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await _updateView?.Invoke(EViewAction.ScanScreenTask, null);
|
||||
await AddServerViaScanTaskAsync();
|
||||
});
|
||||
|
||||
//Subscription
|
||||
|
@ -301,29 +181,6 @@ namespace ServiceLib.ViewModels
|
|||
await Reload();
|
||||
});
|
||||
|
||||
NotifyLeftClickCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await _updateView?.Invoke(EViewAction.ShowHideWindow, null);
|
||||
});
|
||||
|
||||
//System proxy
|
||||
SystemProxyClearCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await SetListenerType(ESysProxyType.ForcedClear);
|
||||
});
|
||||
SystemProxySetCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await SetListenerType(ESysProxyType.ForcedChange);
|
||||
});
|
||||
SystemProxyNothingCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await SetListenerType(ESysProxyType.Unchanged);
|
||||
});
|
||||
SystemProxyPacCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await SetListenerType(ESysProxyType.Pac);
|
||||
});
|
||||
|
||||
#endregion WhenAnyValue && ReactiveCommand
|
||||
|
||||
AutoHideStartup();
|
||||
|
@ -334,19 +191,14 @@ namespace ServiceLib.ViewModels
|
|||
ConfigHandler.InitBuiltinRouting(_config);
|
||||
ConfigHandler.InitBuiltinDNS(_config);
|
||||
CoreHandler.Instance.Init(_config, UpdateHandler);
|
||||
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
|
||||
|
||||
if (_config.guiItem.enableStatistics)
|
||||
{
|
||||
StatisticsHandler.Instance.Init(_config, UpdateStatisticsHandler);
|
||||
}
|
||||
|
||||
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
|
||||
RefreshRoutingsMenu();
|
||||
InboundDisplayStaus();
|
||||
//RefreshServers();
|
||||
|
||||
Reload();
|
||||
ChangeSystemProxyStatusAsync(_config.systemProxyItem.sysProxyType, true);
|
||||
}
|
||||
|
||||
#endregion Init
|
||||
|
@ -393,9 +245,7 @@ namespace ServiceLib.ViewModels
|
|||
{
|
||||
try
|
||||
{
|
||||
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));
|
||||
|
||||
Locator.Current.GetService<StatusBarViewModel>()?.UpdateStatistics(update);
|
||||
if ((update.proxyUp + update.proxyDown) > 0 && DateTime.Now.Second % 3 == 0)
|
||||
{
|
||||
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
|
||||
|
@ -448,6 +298,11 @@ namespace ServiceLib.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public void ShowHideWindow(bool? blShow)
|
||||
{
|
||||
_updateView?.Invoke(EViewAction.ShowHideWindow, blShow);
|
||||
}
|
||||
|
||||
#endregion Actions
|
||||
|
||||
#region Servers && Groups
|
||||
|
@ -457,50 +312,6 @@ namespace ServiceLib.ViewModels
|
|||
MessageBus.Current.SendMessage("", EMsgCommand.RefreshProfiles.ToString());
|
||||
}
|
||||
|
||||
public void RefreshServersBiz()
|
||||
{
|
||||
RefreshServersMenu();
|
||||
|
||||
//display running server
|
||||
var running = ConfigHandler.GetDefaultServer(_config);
|
||||
if (running != null)
|
||||
{
|
||||
RunningServerDisplay =
|
||||
RunningServerToolTipText = running.GetSummary();
|
||||
}
|
||||
else
|
||||
{
|
||||
RunningServerDisplay =
|
||||
RunningServerToolTipText = ResUI.CheckServerSettings;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshServersMenu()
|
||||
{
|
||||
var lstModel = AppHandler.Instance.ProfileItems(_config.subIndexId, "");
|
||||
|
||||
_servers.Clear();
|
||||
if (lstModel.Count > _config.guiItem.trayMenuServersLimit)
|
||||
{
|
||||
BlServers = false;
|
||||
return;
|
||||
}
|
||||
|
||||
BlServers = true;
|
||||
for (int k = 0; k < lstModel.Count; k++)
|
||||
{
|
||||
ProfileItem it = lstModel[k];
|
||||
string name = it.GetSummary();
|
||||
|
||||
var item = new ComboItem() { ID = it.indexId, Text = name };
|
||||
_servers.Add(item);
|
||||
if (_config.indexId == it.indexId)
|
||||
{
|
||||
SelectedServer = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshSubscriptions()
|
||||
{
|
||||
Locator.Current.GetService<ProfilesViewModel>()?.RefreshSubscriptions();
|
||||
|
@ -554,7 +365,12 @@ namespace ServiceLib.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public void ScanScreenTaskAsync(string result)
|
||||
public async Task AddServerViaScanTaskAsync()
|
||||
{
|
||||
_updateView?.Invoke(EViewAction.ScanScreenTask, null);
|
||||
}
|
||||
|
||||
public void ScanScreenResult(string result)
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(result))
|
||||
{
|
||||
|
@ -572,66 +388,6 @@ namespace ServiceLib.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
private void SetDefaultServer(string indexId)
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(indexId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (indexId == _config.indexId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var item = AppHandler.Instance.GetProfileItem(indexId);
|
||||
if (item is null)
|
||||
{
|
||||
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ConfigHandler.SetDefaultServerIndex(_config, indexId) == 0)
|
||||
{
|
||||
RefreshServers();
|
||||
Reload();
|
||||
}
|
||||
}
|
||||
|
||||
private void ServerSelectedChanged(bool c)
|
||||
{
|
||||
if (!c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (SelectedServer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (Utils.IsNullOrEmpty(SelectedServer.ID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
SetDefaultServer(SelectedServer.ID);
|
||||
}
|
||||
|
||||
public async Task TestServerAvailability()
|
||||
{
|
||||
var item = ConfigHandler.GetDefaultServer(_config);
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await (new UpdateService()).RunAvailabilityCheck(async (bool success, string msg) =>
|
||||
{
|
||||
NoticeHandler.Instance.SendMessageEx(msg);
|
||||
_updateView?.Invoke(EViewAction.DispatcherServerAvailability, msg);
|
||||
});
|
||||
}
|
||||
|
||||
public void TestServerAvailabilityResult(string msg)
|
||||
{
|
||||
RunningInfoDisplay = msg;
|
||||
}
|
||||
|
||||
#endregion Add Servers
|
||||
|
||||
#region Subscription
|
||||
|
@ -658,8 +414,7 @@ namespace ServiceLib.ViewModels
|
|||
var ret = await _updateView?.Invoke(EViewAction.OptionSettingWindow, null);
|
||||
if (ret == true)
|
||||
{
|
||||
InboundDisplayStaus();
|
||||
//RefreshServers();
|
||||
Locator.Current.GetService<StatusBarViewModel>()?.InboundDisplayStaus();
|
||||
Reload();
|
||||
}
|
||||
}
|
||||
|
@ -670,8 +425,7 @@ namespace ServiceLib.ViewModels
|
|||
if (ret == true)
|
||||
{
|
||||
ConfigHandler.InitBuiltinRouting(_config);
|
||||
RefreshRoutingsMenu();
|
||||
//RefreshServers();
|
||||
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
|
||||
Reload();
|
||||
}
|
||||
}
|
||||
|
@ -685,20 +439,20 @@ namespace ServiceLib.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
private async Task RebootAsAdmin()
|
||||
public async Task RebootAsAdmin()
|
||||
{
|
||||
ProcessStartInfo startInfo = new()
|
||||
{
|
||||
UseShellExecute = true,
|
||||
Arguments = Global.RebootAs,
|
||||
WorkingDirectory = Utils.StartupPath(),
|
||||
FileName = Utils.GetExePath().AppendQuotes(),
|
||||
Verb = "runas",
|
||||
};
|
||||
try
|
||||
{
|
||||
ProcessStartInfo startInfo = new()
|
||||
{
|
||||
UseShellExecute = true,
|
||||
Arguments = Global.RebootAs,
|
||||
WorkingDirectory = Utils.StartupPath(),
|
||||
FileName = Utils.GetExePath().AppendQuotes(),
|
||||
Verb = "runas",
|
||||
};
|
||||
Process.Start(startInfo);
|
||||
MyAppExitAsync(false);
|
||||
await MyAppExitAsync(false);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
@ -730,13 +484,13 @@ namespace ServiceLib.ViewModels
|
|||
BlReloadEnabled = false;
|
||||
|
||||
await LoadCore();
|
||||
await TestServerAvailability();
|
||||
Locator.Current.GetService<StatusBarViewModel>()?.TestServerAvailability();
|
||||
_updateView?.Invoke(EViewAction.DispatcherReload, null);
|
||||
}
|
||||
|
||||
public void ReloadResult()
|
||||
{
|
||||
ChangeSystemProxyStatusAsync(_config.systemProxyItem.sysProxyType, false);
|
||||
//ChangeSystemProxyStatusAsync(_config.systemProxyItem.sysProxyType, false);
|
||||
BlReloadEnabled = true;
|
||||
ShowClashUI = _config.IsRunningCore(ECoreType.sing_box);
|
||||
if (ShowClashUI)
|
||||
|
@ -764,180 +518,22 @@ namespace ServiceLib.ViewModels
|
|||
public void CloseCore()
|
||||
{
|
||||
ConfigHandler.SaveConfig(_config, false);
|
||||
|
||||
ChangeSystemProxyStatusAsync(ESysProxyType.ForcedClear, false);
|
||||
|
||||
CoreHandler.Instance.CoreStop();
|
||||
}
|
||||
|
||||
#endregion core job
|
||||
|
||||
#region System proxy and Routings
|
||||
|
||||
public async Task SetListenerType(ESysProxyType type)
|
||||
{
|
||||
if (_config.systemProxyItem.sysProxyType == type)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_config.systemProxyItem.sysProxyType = type;
|
||||
ChangeSystemProxyStatusAsync(type, true);
|
||||
|
||||
SystemProxySelected = (int)_config.systemProxyItem.sysProxyType;
|
||||
ConfigHandler.SaveConfig(_config, false);
|
||||
}
|
||||
|
||||
private async Task ChangeSystemProxyStatusAsync(ESysProxyType type, bool blChange)
|
||||
{
|
||||
//await _updateView?.Invoke(EViewAction.UpdateSysProxy, _config.tunModeItem.enableTun ? true : false);
|
||||
_updateView?.Invoke(EViewAction.UpdateSysProxy, false);
|
||||
NoticeHandler.Instance.SendMessageEx($"{ResUI.TipChangeSystemProxy} - {_config.systemProxyItem.sysProxyType.ToString()}");
|
||||
|
||||
BlSystemProxyClear = (type == ESysProxyType.ForcedClear);
|
||||
BlSystemProxySet = (type == ESysProxyType.ForcedChange);
|
||||
BlSystemProxyNothing = (type == ESysProxyType.Unchanged);
|
||||
BlSystemProxyPac = (type == ESysProxyType.Pac);
|
||||
|
||||
if (blChange)
|
||||
{
|
||||
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshRoutingsMenu()
|
||||
{
|
||||
_routingItems.Clear();
|
||||
if (!_config.routingBasicItem.enableRoutingAdvanced)
|
||||
{
|
||||
BlRouting = false;
|
||||
return;
|
||||
}
|
||||
|
||||
BlRouting = true;
|
||||
var routings = AppHandler.Instance.RoutingItems();
|
||||
foreach (var item in routings)
|
||||
{
|
||||
_routingItems.Add(item);
|
||||
if (item.id == _config.routingBasicItem.routingIndexId)
|
||||
{
|
||||
SelectedRouting = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RoutingSelectedChangedAsync(bool c)
|
||||
{
|
||||
if (!c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SelectedRouting == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var item = AppHandler.Instance.GetRoutingItem(SelectedRouting?.id);
|
||||
if (item is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_config.routingBasicItem.routingIndexId == item.id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ConfigHandler.SetDefaultRouting(_config, item) == 0)
|
||||
{
|
||||
NoticeHandler.Instance.SendMessageEx(ResUI.TipChangeRouting);
|
||||
Reload();
|
||||
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void DoSystemProxySelected(bool c)
|
||||
{
|
||||
if (!c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_config.systemProxyItem.sysProxyType == (ESysProxyType)SystemProxySelected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SetListenerType((ESysProxyType)SystemProxySelected);
|
||||
}
|
||||
|
||||
private void DoEnableTun(bool c)
|
||||
{
|
||||
if (_config.tunModeItem.enableTun != EnableTun)
|
||||
{
|
||||
_config.tunModeItem.enableTun = EnableTun;
|
||||
// When running as a non-administrator, reboot to administrator mode
|
||||
if (EnableTun && !_isAdministrator)
|
||||
{
|
||||
_config.tunModeItem.enableTun = false;
|
||||
RebootAsAdmin();
|
||||
return;
|
||||
}
|
||||
ConfigHandler.SaveConfig(_config);
|
||||
Reload();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion System proxy and Routings
|
||||
|
||||
#region UI
|
||||
|
||||
public void InboundDisplayStaus()
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.Append($"[{EInboundProtocol.socks}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.socks)}]");
|
||||
sb.Append(" | ");
|
||||
//if (_config.systemProxyItem.sysProxyType == ESysProxyType.ForcedChange)
|
||||
//{
|
||||
// sb.Append($"[{Global.InboundHttp}({ResUI.SystemProxy}):{LazyConfig.Instance.GetLocalPort(Global.InboundHttp)}]");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
sb.Append($"[{EInboundProtocol.http}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.http)}]");
|
||||
//}
|
||||
InboundDisplay = $"{ResUI.LabLocal}:{sb}";
|
||||
|
||||
if (_config.inbound[0].allowLANConn)
|
||||
{
|
||||
if (_config.inbound[0].newPort4LAN)
|
||||
{
|
||||
StringBuilder sb2 = new();
|
||||
sb2.Append($"[{EInboundProtocol.socks}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.socks2)}]");
|
||||
sb2.Append(" | ");
|
||||
sb2.Append($"[{EInboundProtocol.http}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.http2)}]");
|
||||
InboundLanDisplay = $"{ResUI.LabLAN}:{sb2}";
|
||||
}
|
||||
else
|
||||
{
|
||||
InboundLanDisplay = $"{ResUI.LabLAN}:{sb}";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InboundLanDisplay = $"{ResUI.LabLAN}:None";
|
||||
}
|
||||
}
|
||||
|
||||
private void AutoHideStartup()
|
||||
{
|
||||
if (_config.uiItem.autoHideStartup)
|
||||
{
|
||||
Observable.Range(1, 1)
|
||||
.Delay(TimeSpan.FromSeconds(1))
|
||||
.Subscribe(async x =>
|
||||
{
|
||||
await _updateView?.Invoke(EViewAction.ShowHideWindow, false);
|
||||
});
|
||||
.Delay(TimeSpan.FromSeconds(1))
|
||||
.Subscribe(async x =>
|
||||
{
|
||||
ShowHideWindow(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#endregion UI
|
||||
#endregion core job
|
||||
}
|
||||
}
|
|
@ -15,7 +15,6 @@ namespace ServiceLib.ViewModels
|
|||
|
||||
private List<ProfileItem> _lstProfile;
|
||||
private string _serverFilter = string.Empty;
|
||||
|
||||
private Dictionary<string, bool> _dicHeaderSort = new();
|
||||
private SpeedtestService? _speedtestHandler;
|
||||
|
||||
|
@ -57,7 +56,6 @@ namespace ServiceLib.ViewModels
|
|||
|
||||
//servers delete
|
||||
public ReactiveCommand<Unit, Unit> EditServerCmd { get; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> RemoveServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> RemoveDuplicateServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> CopyServerCmd { get; }
|
||||
|
@ -68,14 +66,12 @@ namespace ServiceLib.ViewModels
|
|||
|
||||
//servers move
|
||||
public ReactiveCommand<Unit, Unit> MoveTopCmd { get; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> MoveUpCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> MoveDownCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> MoveBottomCmd { get; }
|
||||
|
||||
//servers ping
|
||||
public ReactiveCommand<Unit, Unit> MixedTestServerCmd { get; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> TcpingServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> RealPingServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> SpeedServerCmd { get; }
|
||||
|
@ -83,7 +79,6 @@ namespace ServiceLib.ViewModels
|
|||
|
||||
//servers export
|
||||
public ReactiveCommand<Unit, Unit> Export2ClientConfigCmd { get; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> Export2ClientConfigClipboardCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> Export2ShareUrlCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> Export2ShareUrlBase64Cmd { get; }
|
||||
|
@ -98,7 +93,6 @@ namespace ServiceLib.ViewModels
|
|||
public ProfilesViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_config = AppHandler.Instance.Config;
|
||||
|
||||
_updateView = updateView;
|
||||
|
||||
MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString()).Subscribe(async x => await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null));
|
||||
|
@ -505,7 +499,7 @@ namespace ServiceLib.ViewModels
|
|||
SetDefaultServer(SelectedProfile.indexId);
|
||||
}
|
||||
|
||||
private async Task SetDefaultServer(string indexId)
|
||||
public async Task SetDefaultServer(string indexId)
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(indexId))
|
||||
{
|
||||
|
|
|
@ -0,0 +1,459 @@
|
|||
using DynamicData.Binding;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Splat;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ServiceLib.ViewModels
|
||||
{
|
||||
public class StatusBarViewModel : MyReactiveObject
|
||||
{
|
||||
private bool _isAdministrator { get; set; }
|
||||
|
||||
#region ObservableCollection
|
||||
|
||||
private IObservableCollection<RoutingItem> _routingItems = new ObservableCollectionExtended<RoutingItem>();
|
||||
public IObservableCollection<RoutingItem> RoutingItems => _routingItems;
|
||||
|
||||
private IObservableCollection<ComboItem> _servers = new ObservableCollectionExtended<ComboItem>();
|
||||
public IObservableCollection<ComboItem> Servers => _servers;
|
||||
|
||||
[Reactive]
|
||||
public RoutingItem SelectedRouting { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public ComboItem SelectedServer { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool BlServers { get; set; }
|
||||
|
||||
#endregion ObservableCollection
|
||||
|
||||
public ReactiveCommand<Unit, Unit> AddServerViaClipboardCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> SubUpdateCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> SubUpdateViaProxyCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> NotifyLeftClickCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> ExitCmd { get; }
|
||||
|
||||
#region System Proxy
|
||||
|
||||
[Reactive]
|
||||
public bool BlSystemProxyClear { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool BlSystemProxySet { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool BlSystemProxyNothing { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool BlSystemProxyPac { get; set; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> SystemProxyClearCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> SystemProxySetCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> SystemProxyNothingCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> SystemProxyPacCmd { get; }
|
||||
|
||||
[Reactive]
|
||||
public bool BlRouting { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public int SystemProxySelected { get; set; }
|
||||
|
||||
#endregion System Proxy
|
||||
|
||||
#region UI
|
||||
|
||||
[Reactive]
|
||||
public string InboundDisplay { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string InboundLanDisplay { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string RunningServerDisplay { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string RunningServerToolTipText { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string RunningInfoDisplay { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string SpeedProxyDisplay { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string SpeedDirectDisplay { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool EnableTun { get; set; }
|
||||
|
||||
#endregion UI
|
||||
|
||||
public StatusBarViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_config = AppHandler.Instance.Config;
|
||||
_updateView = updateView;
|
||||
|
||||
if (_updateView != null)
|
||||
{
|
||||
MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString())
|
||||
.Subscribe(async x => await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null));
|
||||
}
|
||||
|
||||
SelectedRouting = new();
|
||||
SelectedServer = new();
|
||||
|
||||
_isAdministrator = Utils.IsAdministrator();
|
||||
if (_config.tunModeItem.enableTun && _isAdministrator)
|
||||
{
|
||||
EnableTun = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_config.tunModeItem.enableTun = EnableTun = false;
|
||||
}
|
||||
|
||||
RefreshRoutingsMenu();
|
||||
InboundDisplayStaus();
|
||||
ChangeSystemProxyAsync(_config.systemProxyItem.sysProxyType, true);
|
||||
|
||||
#region WhenAnyValue && ReactiveCommand
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.SelectedRouting,
|
||||
y => y != null && !y.remarks.IsNullOrEmpty())
|
||||
.Subscribe(c => RoutingSelectedChangedAsync(c));
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.SelectedServer,
|
||||
y => y != null && !y.Text.IsNullOrEmpty())
|
||||
.Subscribe(c => ServerSelectedChanged(c));
|
||||
|
||||
SystemProxySelected = (int)_config.systemProxyItem.sysProxyType;
|
||||
this.WhenAnyValue(
|
||||
x => x.SystemProxySelected,
|
||||
y => y >= 0)
|
||||
.Subscribe(c => DoSystemProxySelected(c));
|
||||
|
||||
this.WhenAnyValue(
|
||||
x => x.EnableTun,
|
||||
y => y == true)
|
||||
.Subscribe(c => DoEnableTun(c));
|
||||
|
||||
NotifyLeftClickCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(null);
|
||||
});
|
||||
|
||||
AddServerViaClipboardCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await AddServerViaClipboard();
|
||||
});
|
||||
AddServerViaScanCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await AddServerViaScan();
|
||||
});
|
||||
SubUpdateCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await UpdateSubscriptionProcess(false);
|
||||
});
|
||||
SubUpdateViaProxyCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await UpdateSubscriptionProcess(true);
|
||||
});
|
||||
|
||||
//System proxy
|
||||
SystemProxyClearCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await SetListenerType(ESysProxyType.ForcedClear);
|
||||
});
|
||||
SystemProxySetCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await SetListenerType(ESysProxyType.ForcedChange);
|
||||
});
|
||||
SystemProxyNothingCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await SetListenerType(ESysProxyType.Unchanged);
|
||||
});
|
||||
SystemProxyPacCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await SetListenerType(ESysProxyType.Pac);
|
||||
});
|
||||
|
||||
#endregion WhenAnyValue && ReactiveCommand
|
||||
}
|
||||
|
||||
public void Init(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_updateView = updateView;
|
||||
if (_updateView != null)
|
||||
{
|
||||
MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString())
|
||||
.Subscribe(async x => await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null));
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AddServerViaClipboard()
|
||||
{
|
||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||
if (service != null) await service.AddServerViaClipboardAsync(null);
|
||||
}
|
||||
|
||||
private async Task AddServerViaScan()
|
||||
{
|
||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||
if (service != null) await service.AddServerViaScanTaskAsync();
|
||||
}
|
||||
|
||||
private async Task UpdateSubscriptionProcess(bool blProxy)
|
||||
{
|
||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||
if (service != null) await service.UpdateSubscriptionProcess("", blProxy);
|
||||
}
|
||||
|
||||
public void RefreshServersBiz()
|
||||
{
|
||||
RefreshServersMenu();
|
||||
|
||||
//display running server
|
||||
var running = ConfigHandler.GetDefaultServer(_config);
|
||||
if (running != null)
|
||||
{
|
||||
RunningServerDisplay =
|
||||
RunningServerToolTipText = running.GetSummary();
|
||||
}
|
||||
else
|
||||
{
|
||||
RunningServerDisplay =
|
||||
RunningServerToolTipText = ResUI.CheckServerSettings;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshServersMenu()
|
||||
{
|
||||
var lstModel = AppHandler.Instance.ProfileItems(_config.subIndexId, "");
|
||||
|
||||
_servers.Clear();
|
||||
if (lstModel.Count > _config.guiItem.trayMenuServersLimit)
|
||||
{
|
||||
BlServers = false;
|
||||
return;
|
||||
}
|
||||
|
||||
BlServers = true;
|
||||
for (int k = 0; k < lstModel.Count; k++)
|
||||
{
|
||||
ProfileItem it = lstModel[k];
|
||||
string name = it.GetSummary();
|
||||
|
||||
var item = new ComboItem() { ID = it.indexId, Text = name };
|
||||
_servers.Add(item);
|
||||
if (_config.indexId == it.indexId)
|
||||
{
|
||||
SelectedServer = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ServerSelectedChanged(bool c)
|
||||
{
|
||||
if (!c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (SelectedServer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (Utils.IsNullOrEmpty(SelectedServer.ID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Locator.Current.GetService<ProfilesViewModel>()?.SetDefaultServer(SelectedServer.ID);
|
||||
}
|
||||
|
||||
public async Task TestServerAvailability()
|
||||
{
|
||||
var item = ConfigHandler.GetDefaultServer(_config);
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await (new UpdateService()).RunAvailabilityCheck(async (bool success, string msg) =>
|
||||
{
|
||||
NoticeHandler.Instance.SendMessageEx(msg);
|
||||
_updateView?.Invoke(EViewAction.DispatcherServerAvailability, msg);
|
||||
});
|
||||
}
|
||||
|
||||
public void TestServerAvailabilityResult(string msg)
|
||||
{
|
||||
RunningInfoDisplay = msg;
|
||||
}
|
||||
|
||||
#region System proxy and Routings
|
||||
|
||||
public async Task SetListenerType(ESysProxyType type)
|
||||
{
|
||||
if (_config.systemProxyItem.sysProxyType == type)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_config.systemProxyItem.sysProxyType = type;
|
||||
ChangeSystemProxyAsync(type, true);
|
||||
NoticeHandler.Instance.SendMessageEx($"{ResUI.TipChangeSystemProxy} - {_config.systemProxyItem.sysProxyType.ToString()}");
|
||||
|
||||
SystemProxySelected = (int)_config.systemProxyItem.sysProxyType;
|
||||
ConfigHandler.SaveConfig(_config, false);
|
||||
}
|
||||
|
||||
private async Task ChangeSystemProxyAsync(ESysProxyType type, bool blChange)
|
||||
{
|
||||
//await _updateView?.Invoke(EViewAction.UpdateSysProxy, _config.tunModeItem.enableTun ? true : false);
|
||||
_updateView?.Invoke(EViewAction.UpdateSysProxy, false);
|
||||
|
||||
BlSystemProxyClear = (type == ESysProxyType.ForcedClear);
|
||||
BlSystemProxySet = (type == ESysProxyType.ForcedChange);
|
||||
BlSystemProxyNothing = (type == ESysProxyType.Unchanged);
|
||||
BlSystemProxyPac = (type == ESysProxyType.Pac);
|
||||
|
||||
if (blChange)
|
||||
{
|
||||
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshRoutingsMenu()
|
||||
{
|
||||
_routingItems.Clear();
|
||||
if (!_config.routingBasicItem.enableRoutingAdvanced)
|
||||
{
|
||||
BlRouting = false;
|
||||
return;
|
||||
}
|
||||
|
||||
BlRouting = true;
|
||||
var routings = AppHandler.Instance.RoutingItems();
|
||||
foreach (var item in routings)
|
||||
{
|
||||
_routingItems.Add(item);
|
||||
if (item.id == _config.routingBasicItem.routingIndexId)
|
||||
{
|
||||
SelectedRouting = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RoutingSelectedChangedAsync(bool c)
|
||||
{
|
||||
if (!c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SelectedRouting == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var item = AppHandler.Instance.GetRoutingItem(SelectedRouting?.id);
|
||||
if (item is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_config.routingBasicItem.routingIndexId == item.id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ConfigHandler.SetDefaultRouting(_config, item) == 0)
|
||||
{
|
||||
NoticeHandler.Instance.SendMessageEx(ResUI.TipChangeRouting);
|
||||
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
|
||||
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void DoSystemProxySelected(bool c)
|
||||
{
|
||||
if (!c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_config.systemProxyItem.sysProxyType == (ESysProxyType)SystemProxySelected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SetListenerType((ESysProxyType)SystemProxySelected);
|
||||
}
|
||||
|
||||
private void DoEnableTun(bool c)
|
||||
{
|
||||
if (_config.tunModeItem.enableTun != EnableTun)
|
||||
{
|
||||
_config.tunModeItem.enableTun = EnableTun;
|
||||
// When running as a non-administrator, reboot to administrator mode
|
||||
if (EnableTun && !_isAdministrator)
|
||||
{
|
||||
_config.tunModeItem.enableTun = false;
|
||||
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
|
||||
return;
|
||||
}
|
||||
ConfigHandler.SaveConfig(_config);
|
||||
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion System proxy and Routings
|
||||
|
||||
#region UI
|
||||
|
||||
public void InboundDisplayStaus()
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.Append($"[{EInboundProtocol.socks}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.socks)}]");
|
||||
sb.Append(" | ");
|
||||
//if (_config.systemProxyItem.sysProxyType == ESysProxyType.ForcedChange)
|
||||
//{
|
||||
// sb.Append($"[{Global.InboundHttp}({ResUI.SystemProxy}):{LazyConfig.Instance.GetLocalPort(Global.InboundHttp)}]");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
sb.Append($"[{EInboundProtocol.http}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.http)}]");
|
||||
//}
|
||||
InboundDisplay = $"{ResUI.LabLocal}:{sb}";
|
||||
|
||||
if (_config.inbound[0].allowLANConn)
|
||||
{
|
||||
if (_config.inbound[0].newPort4LAN)
|
||||
{
|
||||
StringBuilder sb2 = new();
|
||||
sb2.Append($"[{EInboundProtocol.socks}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.socks2)}]");
|
||||
sb2.Append(" | ");
|
||||
sb2.Append($"[{EInboundProtocol.http}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.http2)}]");
|
||||
InboundLanDisplay = $"{ResUI.LabLAN}:{sb2}";
|
||||
}
|
||||
else
|
||||
{
|
||||
InboundLanDisplay = $"{ResUI.LabLAN}:{sb}";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InboundLanDisplay = $"{ResUI.LabLAN}:None";
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateStatistics(ServerSpeedItem update)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
#endregion UI
|
||||
}
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
x:Class="v2rayN.Desktop.App"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:v2rayN.Desktop.ViewModels"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
x:DataType="local:AppViewModel"
|
||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||
x:DataType="vms:StatusBarViewModel"
|
||||
RequestedThemeVariant="Default">
|
||||
<Application.Styles>
|
||||
<StyleInclude Source="Styles/GlobalStyles.axaml" />
|
||||
|
@ -37,13 +37,13 @@
|
|||
<NativeMenuItem Command="{Binding SystemProxySetCmd}" Header="{x:Static resx:ResUI.menuSystemProxySet}" />
|
||||
<NativeMenuItem Command="{Binding SystemProxyNothingCmd}" Header="{x:Static resx:ResUI.menuSystemProxyNothing}" />
|
||||
<NativeMenuItemSeparator />
|
||||
<NativeMenuItem Command="{Binding AddServerViaClipboardCmd}" Header="{x:Static resx:ResUI.menuAddServerViaClipboard}" />
|
||||
<NativeMenuItem Click="MenuAddServerViaClipboardClick" Header="{x:Static resx:ResUI.menuAddServerViaClipboard}" />
|
||||
<NativeMenuItem Header="{x:Static resx:ResUI.menuAddServerViaScan}" IsVisible="False" />
|
||||
<NativeMenuItem Command="{Binding SubUpdateCmd}" Header="{x:Static resx:ResUI.menuSubUpdate}" />
|
||||
<NativeMenuItem Command="{Binding SubUpdateViaProxyCmd}" Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" />
|
||||
<NativeMenuItemSeparator />
|
||||
<NativeMenuItem Click="TrayIcon_Clicked" Header="{x:Static resx:ResUI.menuShowOrHideMainWindow}" />
|
||||
<NativeMenuItem Command="{Binding ExitCmd}" Header="{x:Static resx:ResUI.menuExit}" />
|
||||
<NativeMenuItem Click="MenuExit_Click" Header="{x:Static resx:ResUI.menuExit}" />
|
||||
</NativeMenu>
|
||||
</TrayIcon.Menu>
|
||||
</TrayIcon>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using v2rayN.Desktop.ViewModels;
|
||||
using Splat;
|
||||
using v2rayN.Desktop.Common;
|
||||
using v2rayN.Desktop.Views;
|
||||
|
||||
namespace v2rayN.Desktop;
|
||||
|
@ -22,7 +23,9 @@ public partial class App : Application
|
|||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
||||
|
||||
this.DataContext = new AppViewModel();
|
||||
var ViewModel = new StatusBarViewModel(null);
|
||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel));
|
||||
this.DataContext = ViewModel;
|
||||
}
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
|
@ -85,4 +88,27 @@ public partial class App : Application
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MenuAddServerViaClipboardClick(object? sender, EventArgs e)
|
||||
{
|
||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
if (desktop.MainWindow != null)
|
||||
{
|
||||
var clipboardData = AvaUtils.GetClipboardData(desktop.MainWindow).Result;
|
||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||
if (service != null) _ = service.AddServerViaClipboardAsync(clipboardData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MenuExit_Click(object? sender, EventArgs e)
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
Locator.Current.GetService<MainWindowViewModel>()?.MyAppExitAsync(false);
|
||||
|
||||
desktop.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,7 +61,7 @@ namespace v2rayN.Desktop.ViewModels
|
|||
return;
|
||||
}
|
||||
|
||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||
var service = Locator.Current.GetService<StatusBarViewModel>();
|
||||
if (service != null) await service.SetListenerType(type);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
xmlns:dialogHost="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
xmlns:view="using:v2rayN.Desktop.Views"
|
||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||
Title="v2rayN"
|
||||
Width="900"
|
||||
|
@ -118,72 +119,7 @@
|
|||
</Menu>
|
||||
</DockPanel>
|
||||
|
||||
<StackPanel Height="50" DockPanel.Dock="Bottom">
|
||||
<DockPanel>
|
||||
<StackPanel
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Right">
|
||||
<TextBlock x:Name="txtSpeedProxyDisplay" />
|
||||
<Border Margin="2" />
|
||||
<TextBlock x:Name="txtSpeedDirectDisplay" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
Width="240"
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left">
|
||||
<TextBlock x:Name="txtInboundDisplay" />
|
||||
<Border Margin="2" />
|
||||
<TextBlock x:Name="txtInboundLanDisplay" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
x:Name="spEnableTun"
|
||||
Width="100"
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbEnableTunAs}" />
|
||||
<ToggleSwitch
|
||||
x:Name="togEnableTun"
|
||||
HorizontalAlignment="Left"
|
||||
Classes="Margin8"
|
||||
Theme="{StaticResource SimpleToggleSwitch}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left"
|
||||
Orientation="Horizontal">
|
||||
<ComboBox
|
||||
x:Name="cmbSystemProxy"
|
||||
Width="120"
|
||||
Margin="8,0"
|
||||
ToolTip.Tip="{x:Static resx:ResUI.menuSystemproxy}">
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyNothing}" />
|
||||
</ComboBox>
|
||||
|
||||
<ComboBox
|
||||
x:Name="cmbRoutings2"
|
||||
Width="150"
|
||||
Margin="8,0"
|
||||
DisplayMemberBinding="{Binding remarks}"
|
||||
ItemsSource="{Binding RoutingItems}"
|
||||
ToolTip.Tip="{x:Static resx:ResUI.menuRouting}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="8,0" VerticalAlignment="Center">
|
||||
<TextBlock x:Name="txtRunningServerDisplay" Tapped="TxtRunningServerDisplay_Tapped" />
|
||||
<Border Margin="2" />
|
||||
<TextBlock x:Name="txtRunningInfoDisplay" Tapped="TxtRunningServerDisplay_Tapped" />
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</StackPanel>
|
||||
<view:StatusBarView DockPanel.Dock="Bottom" />
|
||||
|
||||
<Grid>
|
||||
<Grid x:Name="gridMain" IsVisible="False">
|
||||
|
|
|
@ -12,7 +12,6 @@ using Splat;
|
|||
using System.ComponentModel;
|
||||
using System.Reactive.Disposables;
|
||||
using v2rayN.Desktop.Common;
|
||||
using v2rayN.Desktop.Handler;
|
||||
|
||||
namespace v2rayN.Desktop.Views
|
||||
{
|
||||
|
@ -40,9 +39,8 @@ namespace v2rayN.Desktop.Views
|
|||
menuCheckUpdate.Click += MenuCheckUpdate_Click;
|
||||
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
||||
|
||||
var IsAdministrator = Utils.IsAdministrator();
|
||||
MessageBus.Current.Listen<string>(EMsgCommand.SendSnackMsg.ToString()).Subscribe(x => DelegateSnackMsg(x));
|
||||
ViewModel = new MainWindowViewModel(IsAdministrator, UpdateViewHandler);
|
||||
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
|
||||
|
||||
//WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
||||
|
@ -82,19 +80,6 @@ namespace v2rayN.Desktop.Views
|
|||
this.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlReloadEnabled, v => v.menuReload.IsEnabled).DisposeWith(disposables);
|
||||
|
||||
//status bar
|
||||
this.OneWayBind(ViewModel, vm => vm.InboundDisplay, v => v.txtInboundDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.InboundLanDisplay, v => v.txtInboundLanDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.RunningServerDisplay, v => v.txtRunningServerDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.RunningInfoDisplay, v => v.txtRunningInfoDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.SpeedProxyDisplay, v => v.txtSpeedProxyDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.SpeedDirectDisplay, v => v.txtSpeedDirectDisplay.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.EnableTun, v => v.togEnableTun.IsChecked).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.SystemProxySelected, v => v.cmbSystemProxy.SelectedIndex).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.cmbRoutings2.ItemsSource).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings2.SelectedItem).DisposeWith(disposables);
|
||||
|
||||
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
|
||||
{
|
||||
gridMain.IsVisible = true;
|
||||
|
@ -118,7 +103,7 @@ namespace v2rayN.Desktop.Views
|
|||
}
|
||||
});
|
||||
|
||||
this.Title = $"{Utils.GetVersion()} - {(IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
if (Utils.IsWindows())
|
||||
{
|
||||
menuGlobalHotkeySetting.IsVisible = false;
|
||||
|
@ -128,10 +113,6 @@ namespace v2rayN.Desktop.Views
|
|||
menuRebootAsAdmin.IsVisible = false;
|
||||
menuSettingsSetUWP.IsVisible = false;
|
||||
menuGlobalHotkeySetting.IsVisible = false;
|
||||
if (_config.tunModeItem.enableTun)
|
||||
{
|
||||
ViewModel.EnableTun = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
|
||||
|
@ -215,33 +196,12 @@ namespace v2rayN.Desktop.Views
|
|||
DispatcherPriority.Default);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherServerAvailability:
|
||||
if (obj is null) return false;
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
ViewModel?.TestServerAvailabilityResult((string)obj),
|
||||
DispatcherPriority.Default);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherReload:
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
ViewModel?.ReloadResult(),
|
||||
DispatcherPriority.Default);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherRefreshServersBiz:
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
ViewModel?.RefreshServersBiz(),
|
||||
DispatcherPriority.Default);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherRefreshIcon:
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
this.Icon = AvaUtils.GetAppIcon(_config.systemProxyItem.sysProxyType);
|
||||
},
|
||||
DispatcherPriority.Default);
|
||||
break;
|
||||
|
||||
case EViewAction.Shutdown:
|
||||
StorageUI();
|
||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
|
@ -251,12 +211,7 @@ namespace v2rayN.Desktop.Views
|
|||
break;
|
||||
|
||||
case EViewAction.ScanScreenTask:
|
||||
ScanScreenTaskAsync().ContinueWith(_ => { });
|
||||
break;
|
||||
|
||||
case EViewAction.UpdateSysProxy:
|
||||
if (obj is null) return false;
|
||||
await SysProxyHandler.UpdateSysProxy(_config, (bool)obj);
|
||||
await ScanScreenTaskAsync();
|
||||
break;
|
||||
|
||||
case EViewAction.AddServerViaClipboard:
|
||||
|
@ -282,21 +237,21 @@ namespace v2rayN.Desktop.Views
|
|||
ShowHideWindow(null);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyClear:
|
||||
ViewModel?.SetListenerType(ESysProxyType.ForcedClear);
|
||||
break;
|
||||
//case EGlobalHotkey.SystemProxyClear:
|
||||
// ViewModel?.SetListenerType(ESysProxyType.ForcedClear);
|
||||
// break;
|
||||
|
||||
case EGlobalHotkey.SystemProxySet:
|
||||
ViewModel?.SetListenerType(ESysProxyType.ForcedChange);
|
||||
break;
|
||||
//case EGlobalHotkey.SystemProxySet:
|
||||
// ViewModel?.SetListenerType(ESysProxyType.ForcedChange);
|
||||
// break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyUnchanged:
|
||||
ViewModel?.SetListenerType(ESysProxyType.Unchanged);
|
||||
break;
|
||||
//case EGlobalHotkey.SystemProxyUnchanged:
|
||||
// ViewModel?.SetListenerType(ESysProxyType.Unchanged);
|
||||
// break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyPac:
|
||||
ViewModel?.SetListenerType(ESysProxyType.Pac);
|
||||
break;
|
||||
//case EGlobalHotkey.SystemProxyPac:
|
||||
// ViewModel?.SetListenerType(ESysProxyType.Pac);
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,11 +297,6 @@ namespace v2rayN.Desktop.Views
|
|||
Utils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
|
||||
}
|
||||
|
||||
private void TxtRunningServerDisplay_Tapped(object? sender, Avalonia.Input.TappedEventArgs e)
|
||||
{
|
||||
ViewModel?.TestServerAvailability();
|
||||
}
|
||||
|
||||
private void menuSettingsSetUWP_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
Utils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<UserControl
|
||||
x:Class="v2rayN.Desktop.Views.StatusBarView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
x:DataType="vms:StatusBarViewModel"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<StackPanel Height="50">
|
||||
<DockPanel>
|
||||
<StackPanel
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Right">
|
||||
<TextBlock x:Name="txtSpeedProxyDisplay" />
|
||||
<Border Margin="2" />
|
||||
<TextBlock x:Name="txtSpeedDirectDisplay" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
Width="240"
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left">
|
||||
<TextBlock x:Name="txtInboundDisplay" />
|
||||
<Border Margin="2" />
|
||||
<TextBlock x:Name="txtInboundLanDisplay" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
x:Name="spEnableTun"
|
||||
Width="100"
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbEnableTunAs}" />
|
||||
<ToggleSwitch
|
||||
x:Name="togEnableTun"
|
||||
HorizontalAlignment="Left"
|
||||
Classes="Margin8"
|
||||
Theme="{StaticResource SimpleToggleSwitch}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left"
|
||||
Orientation="Horizontal">
|
||||
<ComboBox
|
||||
x:Name="cmbSystemProxy"
|
||||
Width="120"
|
||||
Margin="8,0"
|
||||
ToolTip.Tip="{x:Static resx:ResUI.menuSystemproxy}">
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyNothing}" />
|
||||
</ComboBox>
|
||||
|
||||
<ComboBox
|
||||
x:Name="cmbRoutings2"
|
||||
Width="150"
|
||||
Margin="8,0"
|
||||
DisplayMemberBinding="{Binding remarks}"
|
||||
ItemsSource="{Binding RoutingItems}"
|
||||
ToolTip.Tip="{x:Static resx:ResUI.menuRouting}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="8,0" VerticalAlignment="Center">
|
||||
<TextBlock x:Name="txtRunningServerDisplay" />
|
||||
<Border Margin="2" />
|
||||
<TextBlock x:Name="txtRunningInfoDisplay" />
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -0,0 +1,136 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.ReactiveUI;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using Splat;
|
||||
using System.Reactive.Disposables;
|
||||
using v2rayN.Desktop.Common;
|
||||
using v2rayN.Desktop.Handler;
|
||||
|
||||
namespace v2rayN.Desktop.Views
|
||||
{
|
||||
public partial class StatusBarView : ReactiveUserControl<StatusBarViewModel>
|
||||
{
|
||||
private static Config _config;
|
||||
|
||||
public StatusBarView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_config = AppHandler.Instance.Config;
|
||||
//ViewModel = new StatusBarViewModel(UpdateViewHandler);
|
||||
//Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel));
|
||||
ViewModel = Locator.Current.GetService<StatusBarViewModel>();
|
||||
ViewModel?.Init(UpdateViewHandler);
|
||||
|
||||
txtRunningServerDisplay.Tapped += TxtRunningServerDisplay_Tapped;
|
||||
txtRunningInfoDisplay.Tapped += TxtRunningServerDisplay_Tapped;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
//status bar
|
||||
this.OneWayBind(ViewModel, vm => vm.InboundDisplay, v => v.txtInboundDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.InboundLanDisplay, v => v.txtInboundLanDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.RunningServerDisplay, v => v.txtRunningServerDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.RunningInfoDisplay, v => v.txtRunningInfoDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.SpeedProxyDisplay, v => v.txtSpeedProxyDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.SpeedDirectDisplay, v => v.txtSpeedDirectDisplay.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.EnableTun, v => v.togEnableTun.IsChecked).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.SystemProxySelected, v => v.cmbSystemProxy.SelectedIndex).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.cmbRoutings2.ItemsSource).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings2.SelectedItem).DisposeWith(disposables);
|
||||
|
||||
////system proxy
|
||||
//this.OneWayBind(ViewModel, vm => vm.BlSystemProxyClear, v => v.menuSystemProxyClear2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.BlSystemProxySet, v => v.menuSystemProxySet2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.BlSystemProxyNothing, v => v.menuSystemProxyNothing2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.BlSystemProxyPac, v => v.menuSystemProxyPac2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
||||
//this.BindCommand(ViewModel, vm => vm.SystemProxyClearCmd, v => v.menuSystemProxyClear).DisposeWith(disposables);
|
||||
//this.BindCommand(ViewModel, vm => vm.SystemProxySetCmd, v => v.menuSystemProxySet).DisposeWith(disposables);
|
||||
//this.BindCommand(ViewModel, vm => vm.SystemProxyPacCmd, v => v.menuSystemProxyPac).DisposeWith(disposables);
|
||||
//this.BindCommand(ViewModel, vm => vm.SystemProxyNothingCmd, v => v.menuSystemProxyNothing).DisposeWith(disposables);
|
||||
|
||||
////routings and servers
|
||||
//this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.cmbRoutings.ItemsSource).DisposeWith(disposables);
|
||||
//this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings.SelectedItem).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.menuRoutings.Visibility).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.sepRoutings.Visibility).DisposeWith(disposables);
|
||||
|
||||
//this.OneWayBind(ViewModel, vm => vm.Servers, v => v.cmbServers.ItemsSource).DisposeWith(disposables);
|
||||
//this.Bind(ViewModel, vm => vm.SelectedServer, v => v.cmbServers.SelectedItem).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.BlServers, v => v.cmbServers.Visibility).DisposeWith(disposables);
|
||||
|
||||
////tray menu
|
||||
//this.BindCommand(ViewModel, vm => vm.AddServerViaClipboardCmd, v => v.menuAddServerViaClipboard2).DisposeWith(disposables);
|
||||
//this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan2).DisposeWith(disposables);
|
||||
//this.BindCommand(ViewModel, vm => vm.SubUpdateCmd, v => v.menuSubUpdate2).DisposeWith(disposables);
|
||||
//this.BindCommand(ViewModel, vm => vm.SubUpdateViaProxyCmd, v => v.menuSubUpdateViaProxy2).DisposeWith(disposables);
|
||||
|
||||
//this.OneWayBind(ViewModel, vm => vm.RunningServerToolTipText, v => v.tbNotify.ToolTipText).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.NotifyLeftClickCmd, v => v.tbNotify.LeftClickCommand).DisposeWith(disposables);
|
||||
|
||||
////status bar
|
||||
//this.OneWayBind(ViewModel, vm => vm.InboundDisplay, v => v.txtInboundDisplay.Text).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.InboundLanDisplay, v => v.txtInboundLanDisplay.Text).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.RunningServerDisplay, v => v.txtRunningServerDisplay.Text).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.RunningInfoDisplay, v => v.txtRunningInfoDisplay.Text).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.SpeedProxyDisplay, v => v.txtSpeedProxyDisplay.Text).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.SpeedDirectDisplay, v => v.txtSpeedDirectDisplay.Text).DisposeWith(disposables);
|
||||
//this.Bind(ViewModel, vm => vm.EnableTun, v => v.togEnableTun.IsChecked).DisposeWith(disposables);
|
||||
|
||||
//this.Bind(ViewModel, vm => vm.SystemProxySelected, v => v.cmbSystemProxy.SelectedIndex).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.cmbRoutings2.ItemsSource).DisposeWith(disposables);
|
||||
//this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings2.SelectedItem).DisposeWith(disposables);
|
||||
//this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.cmbRoutings2.Visibility).DisposeWith(disposables);
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.UpdateSysProxy:
|
||||
if (obj is null) return false;
|
||||
await SysProxyHandler.UpdateSysProxy(_config, (bool)obj);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherServerAvailability:
|
||||
if (obj is null) return false;
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
ViewModel?.TestServerAvailabilityResult((string)obj),
|
||||
DispatcherPriority.Default);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherRefreshServersBiz:
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
ViewModel?.RefreshServersBiz(),
|
||||
DispatcherPriority.Default);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherRefreshIcon:
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
RefreshIcon();
|
||||
},
|
||||
DispatcherPriority.Default);
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
}
|
||||
|
||||
private void RefreshIcon()
|
||||
{
|
||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
desktop.MainWindow.Icon = AvaUtils.GetAppIcon(_config.systemProxyItem.sysProxyType);
|
||||
}
|
||||
}
|
||||
|
||||
private void TxtRunningServerDisplay_Tapped(object? sender, Avalonia.Input.TappedEventArgs e)
|
||||
{
|
||||
ViewModel?.TestServerAvailability();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:reactiveui="http://reactiveui.net"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
xmlns:tb="clr-namespace:H.NotifyIcon;assembly=H.NotifyIcon.Wpf"
|
||||
xmlns:view="clr-namespace:v2rayN.Views"
|
||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||
Title="v2rayN"
|
||||
Width="900"
|
||||
|
@ -276,84 +276,7 @@
|
|||
</ToolBar>
|
||||
</ToolBarTray>
|
||||
|
||||
<materialDesign:ColorZone
|
||||
Height="50"
|
||||
DockPanel.Dock="Bottom"
|
||||
Mode="Standard">
|
||||
<DockPanel>
|
||||
<StackPanel
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Right">
|
||||
<TextBlock x:Name="txtSpeedProxyDisplay" Style="{StaticResource StatusbarItem}" />
|
||||
<Border Margin="2" />
|
||||
<TextBlock x:Name="txtSpeedDirectDisplay" Style="{StaticResource StatusbarItem}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
Width="240"
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left">
|
||||
<TextBlock x:Name="txtInboundDisplay" Style="{StaticResource StatusbarItem}" />
|
||||
<Border Margin="2" />
|
||||
<TextBlock x:Name="txtInboundLanDisplay" Style="{StaticResource StatusbarItem}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
x:Name="spEnableTun"
|
||||
Width="auto"
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbEnableTunAs}" />
|
||||
<ToggleButton
|
||||
x:Name="togEnableTun"
|
||||
Margin="4"
|
||||
HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left"
|
||||
Orientation="Horizontal">
|
||||
<ComboBox
|
||||
x:Name="cmbSystemProxy"
|
||||
Width="120"
|
||||
Margin="8,0"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuSystemproxy}"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFloatingHintComboBox}">
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyNothing}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyPac}" />
|
||||
</ComboBox>
|
||||
|
||||
<ComboBox
|
||||
x:Name="cmbRoutings2"
|
||||
Width="150"
|
||||
Margin="8,0"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
|
||||
DisplayMemberPath="remarks"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFloatingHintComboBox}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="8,0" VerticalAlignment="Center">
|
||||
<TextBlock
|
||||
x:Name="txtRunningServerDisplay"
|
||||
PreviewMouseDown="txtRunningInfoDisplay_MouseDoubleClick"
|
||||
Style="{StaticResource StatusbarItem}" />
|
||||
<Border Margin="2" />
|
||||
<TextBlock
|
||||
x:Name="txtRunningInfoDisplay"
|
||||
PreviewMouseDown="txtRunningInfoDisplay_MouseDoubleClick"
|
||||
Style="{StaticResource StatusbarItem}" />
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</materialDesign:ColorZone>
|
||||
<view:StatusBarView DockPanel.Dock="Bottom" />
|
||||
|
||||
<Grid>
|
||||
<Grid x:Name="gridMain" Visibility="Collapsed">
|
||||
|
@ -505,113 +428,6 @@
|
|||
<materialDesign:Snackbar x:Name="MainSnackbar" MessageQueue="{materialDesign:MessageQueue}" />
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
<tb:TaskbarIcon
|
||||
x:Name="tbNotify"
|
||||
IconSource="/v2rayN.ico"
|
||||
NoLeftClickDelay="True"
|
||||
ToolTipText="v2rayN">
|
||||
<tb:TaskbarIcon.ContextMenu>
|
||||
<ContextMenu Style="{StaticResource DefContextMenu}">
|
||||
<MenuItem x:Name="menuSystemProxyClear" Height="{StaticResource MenuItemHeight}">
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
x:Name="menuSystemProxyClear2"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Check" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyClear}" />
|
||||
</StackPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="menuSystemProxySet" Height="{StaticResource MenuItemHeight}">
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
x:Name="menuSystemProxySet2"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Check" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxySet}" />
|
||||
</StackPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="menuSystemProxyNothing" Height="{StaticResource MenuItemHeight}">
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
x:Name="menuSystemProxyNothing2"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Check" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyNothing}" />
|
||||
</StackPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="menuSystemProxyPac" Height="{StaticResource MenuItemHeight}">
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
x:Name="menuSystemProxyPac2"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Check" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyPac}" />
|
||||
</StackPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<Separator x:Name="sepRoutings" />
|
||||
<MenuItem x:Name="menuRoutings" Height="Auto">
|
||||
<MenuItem.Header>
|
||||
<DockPanel>
|
||||
<ComboBox
|
||||
x:Name="cmbRoutings"
|
||||
MaxWidth="300"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
|
||||
DisplayMemberPath="remarks"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFilledComboBox}" />
|
||||
</DockPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<MenuItem Height="Auto">
|
||||
<MenuItem.Header>
|
||||
<DockPanel>
|
||||
<ComboBox
|
||||
x:Name="cmbServers"
|
||||
MaxWidth="300"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuServers}"
|
||||
DisplayMemberPath="Text"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFilledComboBox}" />
|
||||
</DockPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="menuAddServerViaClipboard2"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuAddServerViaClipboard}" />
|
||||
<MenuItem
|
||||
x:Name="menuAddServerViaScan2"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuAddServerViaScan}" />
|
||||
<MenuItem
|
||||
x:Name="menuSubUpdate2"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuSubUpdate}" />
|
||||
<MenuItem
|
||||
x:Name="menuSubUpdateViaProxy2"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="menuExit"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuExit}" />
|
||||
</ContextMenu>
|
||||
</tb:TaskbarIcon.ContextMenu>
|
||||
</tb:TaskbarIcon>
|
||||
</Grid>
|
||||
</materialDesign:DialogHost>
|
||||
</reactiveui:ReactiveWindow>
|
|
@ -26,19 +26,18 @@ namespace v2rayN.Views
|
|||
_config = AppHandler.Instance.Config;
|
||||
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
|
||||
|
||||
Application.Current.Exit += Current_Exit;
|
||||
App.Current.SessionEnding += Current_SessionEnding;
|
||||
this.Closing += MainWindow_Closing;
|
||||
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
|
||||
menuSettingsSetUWP.Click += menuSettingsSetUWP_Click;
|
||||
menuPromotion.Click += menuPromotion_Click;
|
||||
menuClose.Click += menuClose_Click;
|
||||
menuExit.Click += menuExit_Click;
|
||||
menuCheckUpdate.Click += MenuCheckUpdate_Click;
|
||||
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
||||
|
||||
var IsAdministrator = Utils.IsAdministrator();
|
||||
MessageBus.Current.Listen<string>(EMsgCommand.SendSnackMsg.ToString()).Subscribe(x => DelegateSnackMsg(x));
|
||||
ViewModel = new MainWindowViewModel(IsAdministrator, UpdateViewHandler);
|
||||
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
|
||||
|
||||
WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
||||
|
@ -100,49 +99,6 @@ namespace v2rayN.Views
|
|||
this.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlReloadEnabled, v => v.menuReload.IsEnabled).DisposeWith(disposables);
|
||||
|
||||
//system proxy
|
||||
this.OneWayBind(ViewModel, vm => vm.BlSystemProxyClear, v => v.menuSystemProxyClear2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlSystemProxySet, v => v.menuSystemProxySet2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlSystemProxyNothing, v => v.menuSystemProxyNothing2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlSystemProxyPac, v => v.menuSystemProxyPac2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SystemProxyClearCmd, v => v.menuSystemProxyClear).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SystemProxySetCmd, v => v.menuSystemProxySet).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SystemProxyPacCmd, v => v.menuSystemProxyPac).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SystemProxyNothingCmd, v => v.menuSystemProxyNothing).DisposeWith(disposables);
|
||||
|
||||
//routings and servers
|
||||
this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.cmbRoutings.ItemsSource).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings.SelectedItem).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.menuRoutings.Visibility).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.sepRoutings.Visibility).DisposeWith(disposables);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.Servers, v => v.cmbServers.ItemsSource).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedServer, v => v.cmbServers.SelectedItem).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlServers, v => v.cmbServers.Visibility).DisposeWith(disposables);
|
||||
|
||||
//tray menu
|
||||
this.BindCommand(ViewModel, vm => vm.AddServerViaClipboardCmd, v => v.menuAddServerViaClipboard2).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan2).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SubUpdateCmd, v => v.menuSubUpdate2).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SubUpdateViaProxyCmd, v => v.menuSubUpdateViaProxy2).DisposeWith(disposables);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.RunningServerToolTipText, v => v.tbNotify.ToolTipText).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.NotifyLeftClickCmd, v => v.tbNotify.LeftClickCommand).DisposeWith(disposables);
|
||||
|
||||
//status bar
|
||||
this.OneWayBind(ViewModel, vm => vm.InboundDisplay, v => v.txtInboundDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.InboundLanDisplay, v => v.txtInboundLanDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.RunningServerDisplay, v => v.txtRunningServerDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.RunningInfoDisplay, v => v.txtRunningInfoDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.SpeedProxyDisplay, v => v.txtSpeedProxyDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.SpeedDirectDisplay, v => v.txtSpeedDirectDisplay.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.EnableTun, v => v.togEnableTun.IsChecked).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.SystemProxySelected, v => v.cmbSystemProxy.SelectedIndex).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.cmbRoutings2.ItemsSource).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings2.SelectedItem).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.cmbRoutings2.Visibility).DisposeWith(disposables);
|
||||
|
||||
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
|
||||
{
|
||||
gridMain.Visibility = Visibility.Visible;
|
||||
|
@ -166,7 +122,7 @@ namespace v2rayN.Views
|
|||
}
|
||||
});
|
||||
|
||||
this.Title = $"{Utils.GetVersion()} - {(IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||
|
||||
if (!_config.guiItem.enableHWA)
|
||||
{
|
||||
|
@ -237,14 +193,6 @@ namespace v2rayN.Views
|
|||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherServerAvailability:
|
||||
if (obj is null) return false;
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.TestServerAvailabilityResult((string)obj);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherReload:
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
|
@ -252,21 +200,6 @@ namespace v2rayN.Views
|
|||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherRefreshServersBiz:
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.RefreshServersBiz();
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherRefreshIcon:
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
tbNotify.Icon = WindowsHandler.Instance.GetNotifyIcon(_config);
|
||||
this.Icon = WindowsHandler.Instance.GetAppIcon(_config);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.Shutdown:
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
|
@ -275,12 +208,7 @@ namespace v2rayN.Views
|
|||
break;
|
||||
|
||||
case EViewAction.ScanScreenTask:
|
||||
ScanScreenTaskAsync().ContinueWith(_ => { });
|
||||
break;
|
||||
|
||||
case EViewAction.UpdateSysProxy:
|
||||
if (obj is null) return false;
|
||||
SysProxyHandler.UpdateSysProxy(_config, (bool)obj);
|
||||
await ScanScreenTaskAsync();
|
||||
break;
|
||||
|
||||
case EViewAction.AddServerViaClipboard:
|
||||
|
@ -308,19 +236,10 @@ namespace v2rayN.Views
|
|||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyClear:
|
||||
ViewModel?.SetListenerType(ESysProxyType.ForcedClear);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxySet:
|
||||
ViewModel?.SetListenerType(ESysProxyType.ForcedChange);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyUnchanged:
|
||||
ViewModel?.SetListenerType(ESysProxyType.Unchanged);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyPac:
|
||||
ViewModel?.SetListenerType(ESysProxyType.Pac);
|
||||
Locator.Current.GetService<StatusBarViewModel>()?.SetListenerType((ESysProxyType)((int)e - 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -331,13 +250,9 @@ namespace v2rayN.Views
|
|||
ShowHideWindow(false);
|
||||
}
|
||||
|
||||
private void menuExit_Click(object sender, RoutedEventArgs e)
|
||||
private void Current_Exit(object sender, ExitEventArgs e)
|
||||
{
|
||||
tabProfiles = null;
|
||||
|
||||
tbNotify.Dispose();
|
||||
StorageUI();
|
||||
ViewModel?.MyAppExitAsync(false);
|
||||
}
|
||||
|
||||
private void Current_SessionEnding(object sender, SessionEndingCancelEventArgs e)
|
||||
|
@ -383,17 +298,12 @@ namespace v2rayN.Views
|
|||
Utils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
|
||||
}
|
||||
|
||||
private void txtRunningInfoDisplay_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ViewModel?.TestServerAvailability();
|
||||
}
|
||||
|
||||
private void menuSettingsSetUWP_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Utils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
||||
}
|
||||
|
||||
public async Task ScanScreenTaskAsync()
|
||||
private async Task ScanScreenTaskAsync()
|
||||
{
|
||||
ShowHideWindow(false);
|
||||
|
||||
|
@ -405,7 +315,7 @@ namespace v2rayN.Views
|
|||
|
||||
ShowHideWindow(true);
|
||||
|
||||
ViewModel?.ScanScreenTaskAsync(result);
|
||||
ViewModel?.ScanScreenResult(result);
|
||||
}
|
||||
|
||||
private void MenuCheckUpdate_Click(object sender, RoutedEventArgs e)
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
<reactiveui:ReactiveUserControl
|
||||
x:Class="v2rayN.Views.StatusBarView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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:reactiveui="http://reactiveui.net"
|
||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||
xmlns:tb="clr-namespace:H.NotifyIcon;assembly=H.NotifyIcon.Wpf"
|
||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
x:TypeArguments="vms:StatusBarViewModel"
|
||||
Style="{StaticResource ViewGlobal}"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<materialDesign:ColorZone Height="50" Mode="Standard">
|
||||
<DockPanel>
|
||||
<StackPanel
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Right">
|
||||
<TextBlock x:Name="txtSpeedProxyDisplay" Style="{StaticResource StatusbarItem}" />
|
||||
<Border Margin="2" />
|
||||
<TextBlock x:Name="txtSpeedDirectDisplay" Style="{StaticResource StatusbarItem}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
Width="240"
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left">
|
||||
<TextBlock x:Name="txtInboundDisplay" Style="{StaticResource StatusbarItem}" />
|
||||
<Border Margin="2" />
|
||||
<TextBlock x:Name="txtInboundLanDisplay" Style="{StaticResource StatusbarItem}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
x:Name="spEnableTun"
|
||||
Width="auto"
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbEnableTunAs}" />
|
||||
<ToggleButton
|
||||
x:Name="togEnableTun"
|
||||
Margin="4"
|
||||
HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
DockPanel.Dock="Left"
|
||||
Orientation="Horizontal">
|
||||
<ComboBox
|
||||
x:Name="cmbSystemProxy"
|
||||
Width="120"
|
||||
Margin="8,0"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuSystemproxy}"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFloatingHintComboBox}">
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyNothing}" />
|
||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyPac}" />
|
||||
</ComboBox>
|
||||
|
||||
<ComboBox
|
||||
x:Name="cmbRoutings2"
|
||||
Width="150"
|
||||
Margin="8,0"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
|
||||
DisplayMemberPath="remarks"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFloatingHintComboBox}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="8,0" VerticalAlignment="Center">
|
||||
<TextBlock x:Name="txtRunningServerDisplay" Style="{StaticResource StatusbarItem}" />
|
||||
<Border Margin="2" />
|
||||
<TextBlock x:Name="txtRunningInfoDisplay" Style="{StaticResource StatusbarItem}" />
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</materialDesign:ColorZone>
|
||||
|
||||
<tb:TaskbarIcon
|
||||
x:Name="tbNotify"
|
||||
NoLeftClickDelay="True"
|
||||
ToolTipText="v2rayN">
|
||||
<tb:TaskbarIcon.IconSource>
|
||||
<tb:GeneratedIconSource Foreground="Red" Text="❤️" />
|
||||
</tb:TaskbarIcon.IconSource>
|
||||
<tb:TaskbarIcon.ContextMenu>
|
||||
<ContextMenu Style="{StaticResource DefContextMenu}">
|
||||
<MenuItem x:Name="menuSystemProxyClear" Height="{StaticResource MenuItemHeight}">
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
x:Name="menuSystemProxyClear2"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Check" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyClear}" />
|
||||
</StackPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="menuSystemProxySet" Height="{StaticResource MenuItemHeight}">
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
x:Name="menuSystemProxySet2"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Check" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxySet}" />
|
||||
</StackPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="menuSystemProxyNothing" Height="{StaticResource MenuItemHeight}">
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
x:Name="menuSystemProxyNothing2"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Check" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyNothing}" />
|
||||
</StackPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="menuSystemProxyPac" Height="{StaticResource MenuItemHeight}">
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
x:Name="menuSystemProxyPac2"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Kind="Check" />
|
||||
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyPac}" />
|
||||
</StackPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<Separator x:Name="sepRoutings" />
|
||||
<MenuItem x:Name="menuRoutings" Height="Auto">
|
||||
<MenuItem.Header>
|
||||
<DockPanel>
|
||||
<ComboBox
|
||||
x:Name="cmbRoutings"
|
||||
MaxWidth="300"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
|
||||
DisplayMemberPath="remarks"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFilledComboBox}" />
|
||||
</DockPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<MenuItem Height="Auto">
|
||||
<MenuItem.Header>
|
||||
<DockPanel>
|
||||
<ComboBox
|
||||
x:Name="cmbServers"
|
||||
MaxWidth="300"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuServers}"
|
||||
DisplayMemberPath="Text"
|
||||
FontSize="{DynamicResource StdFontSize}"
|
||||
Style="{StaticResource MaterialDesignFilledComboBox}" />
|
||||
</DockPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="menuAddServerViaClipboard2"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuAddServerViaClipboard}" />
|
||||
<MenuItem
|
||||
x:Name="menuAddServerViaScan2"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuAddServerViaScan}" />
|
||||
<MenuItem
|
||||
x:Name="menuSubUpdate2"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuSubUpdate}" />
|
||||
<MenuItem
|
||||
x:Name="menuSubUpdateViaProxy2"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="menuExit"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuExit}" />
|
||||
</ContextMenu>
|
||||
</tb:TaskbarIcon.ContextMenu>
|
||||
</tb:TaskbarIcon>
|
||||
</Grid>
|
||||
</reactiveui:ReactiveUserControl>
|
|
@ -0,0 +1,124 @@
|
|||
using ReactiveUI;
|
||||
using Splat;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using v2rayN.Base;
|
||||
using v2rayN.Handler;
|
||||
|
||||
namespace v2rayN.Views
|
||||
{
|
||||
public partial class StatusBarView
|
||||
{
|
||||
private static Config _config;
|
||||
|
||||
public StatusBarView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_config = AppHandler.Instance.Config;
|
||||
ViewModel = new StatusBarViewModel(UpdateViewHandler);
|
||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel));
|
||||
|
||||
menuExit.Click += menuExit_Click;
|
||||
txtRunningServerDisplay.PreviewMouseDown += txtRunningInfoDisplay_MouseDoubleClick;
|
||||
txtRunningInfoDisplay.PreviewMouseDown += txtRunningInfoDisplay_MouseDoubleClick;
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
//system proxy
|
||||
this.OneWayBind(ViewModel, vm => vm.BlSystemProxyClear, v => v.menuSystemProxyClear2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlSystemProxySet, v => v.menuSystemProxySet2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlSystemProxyNothing, v => v.menuSystemProxyNothing2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlSystemProxyPac, v => v.menuSystemProxyPac2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SystemProxyClearCmd, v => v.menuSystemProxyClear).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SystemProxySetCmd, v => v.menuSystemProxySet).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SystemProxyPacCmd, v => v.menuSystemProxyPac).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SystemProxyNothingCmd, v => v.menuSystemProxyNothing).DisposeWith(disposables);
|
||||
|
||||
//routings and servers
|
||||
this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.cmbRoutings.ItemsSource).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings.SelectedItem).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.menuRoutings.Visibility).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.sepRoutings.Visibility).DisposeWith(disposables);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.Servers, v => v.cmbServers.ItemsSource).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedServer, v => v.cmbServers.SelectedItem).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlServers, v => v.cmbServers.Visibility).DisposeWith(disposables);
|
||||
|
||||
//tray menu
|
||||
this.BindCommand(ViewModel, vm => vm.AddServerViaClipboardCmd, v => v.menuAddServerViaClipboard2).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan2).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SubUpdateCmd, v => v.menuSubUpdate2).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SubUpdateViaProxyCmd, v => v.menuSubUpdateViaProxy2).DisposeWith(disposables);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.RunningServerToolTipText, v => v.tbNotify.ToolTipText).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.NotifyLeftClickCmd, v => v.tbNotify.LeftClickCommand).DisposeWith(disposables);
|
||||
|
||||
//status bar
|
||||
this.OneWayBind(ViewModel, vm => vm.InboundDisplay, v => v.txtInboundDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.InboundLanDisplay, v => v.txtInboundLanDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.RunningServerDisplay, v => v.txtRunningServerDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.RunningInfoDisplay, v => v.txtRunningInfoDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.SpeedProxyDisplay, v => v.txtSpeedProxyDisplay.Text).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.SpeedDirectDisplay, v => v.txtSpeedDirectDisplay.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.EnableTun, v => v.togEnableTun.IsChecked).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.SystemProxySelected, v => v.cmbSystemProxy.SelectedIndex).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.cmbRoutings2.ItemsSource).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings2.SelectedItem).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.cmbRoutings2.Visibility).DisposeWith(disposables);
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.DispatcherServerAvailability:
|
||||
if (obj is null) return false;
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.TestServerAvailabilityResult((string)obj);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherRefreshServersBiz:
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.RefreshServersBiz();
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherRefreshIcon:
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
tbNotify.Icon = WindowsHandler.Instance.GetNotifyIcon(_config);
|
||||
Application.Current.MainWindow.Icon = WindowsHandler.Instance.GetAppIcon(_config);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.UpdateSysProxy:
|
||||
if (obj is null) return false;
|
||||
SysProxyHandler.UpdateSysProxy(_config, (bool)obj);
|
||||
break;
|
||||
}
|
||||
return await Task.FromResult(true);
|
||||
}
|
||||
|
||||
private void menuExit_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
tbNotify.Dispose();
|
||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||
if (service != null) service.MyAppExitAsync(false);
|
||||
}
|
||||
|
||||
private void txtRunningInfoDisplay_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ViewModel?.TestServerAvailability();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue