mirror of
https://github.com/2dust/v2rayN.git
synced 2025-04-19 21:52:25 +00:00
Refactor new StatusBarViewModel
This commit is contained in:
parent
d7bde77977
commit
7618f9f7d4
14 changed files with 1095 additions and 869 deletions
|
@ -1,41 +1,14 @@
|
||||||
using DynamicData.Binding;
|
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace ServiceLib.ViewModels
|
namespace ServiceLib.ViewModels
|
||||||
{
|
{
|
||||||
public class MainWindowViewModel : MyReactiveObject
|
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
|
#region Menu
|
||||||
|
|
||||||
//servers
|
//servers
|
||||||
|
@ -76,120 +49,27 @@ namespace ServiceLib.ViewModels
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public bool BlReloadEnabled { get; set; }
|
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]
|
[Reactive]
|
||||||
public bool ShowClashUI { get; set; }
|
public bool ShowClashUI { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public int TabMainSelectedIndex { get; set; }
|
public int TabMainSelectedIndex { get; set; }
|
||||||
|
|
||||||
#endregion UI
|
#endregion Menu
|
||||||
|
|
||||||
#region Init
|
#region Init
|
||||||
|
|
||||||
public MainWindowViewModel(bool isAdministrator, Func<EViewAction, object?, Task<bool>>? updateView)
|
public MainWindowViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||||
{
|
{
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
|
|
||||||
_updateView = updateView;
|
_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();
|
Init();
|
||||||
|
|
||||||
_config.uiItem.showInTaskbar = true;
|
_config.uiItem.showInTaskbar = true;
|
||||||
if (_config.tunModeItem.enableTun && _isAdministrator)
|
|
||||||
{
|
|
||||||
EnableTun = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_config.tunModeItem.enableTun = EnableTun = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region WhenAnyValue && ReactiveCommand
|
#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
|
//servers
|
||||||
AddVmessServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
AddVmessServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
|
@ -237,7 +117,7 @@ namespace ServiceLib.ViewModels
|
||||||
});
|
});
|
||||||
AddServerViaScanCmd = ReactiveCommand.CreateFromTask(async () =>
|
AddServerViaScanCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
await _updateView?.Invoke(EViewAction.ScanScreenTask, null);
|
await AddServerViaScanTaskAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
//Subscription
|
//Subscription
|
||||||
|
@ -301,29 +181,6 @@ namespace ServiceLib.ViewModels
|
||||||
await Reload();
|
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
|
#endregion WhenAnyValue && ReactiveCommand
|
||||||
|
|
||||||
AutoHideStartup();
|
AutoHideStartup();
|
||||||
|
@ -334,19 +191,14 @@ namespace ServiceLib.ViewModels
|
||||||
ConfigHandler.InitBuiltinRouting(_config);
|
ConfigHandler.InitBuiltinRouting(_config);
|
||||||
ConfigHandler.InitBuiltinDNS(_config);
|
ConfigHandler.InitBuiltinDNS(_config);
|
||||||
CoreHandler.Instance.Init(_config, UpdateHandler);
|
CoreHandler.Instance.Init(_config, UpdateHandler);
|
||||||
|
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
|
||||||
|
|
||||||
if (_config.guiItem.enableStatistics)
|
if (_config.guiItem.enableStatistics)
|
||||||
{
|
{
|
||||||
StatisticsHandler.Instance.Init(_config, UpdateStatisticsHandler);
|
StatisticsHandler.Instance.Init(_config, UpdateStatisticsHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
|
|
||||||
RefreshRoutingsMenu();
|
|
||||||
InboundDisplayStaus();
|
|
||||||
//RefreshServers();
|
|
||||||
|
|
||||||
Reload();
|
Reload();
|
||||||
ChangeSystemProxyStatusAsync(_config.systemProxyItem.sysProxyType, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Init
|
#endregion Init
|
||||||
|
@ -393,9 +245,7 @@ namespace ServiceLib.ViewModels
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SpeedProxyDisplay = string.Format(ResUI.SpeedDisplayText, Global.ProxyTag, Utils.HumanFy(update.proxyUp), Utils.HumanFy(update.proxyDown));
|
Locator.Current.GetService<StatusBarViewModel>()?.UpdateStatistics(update);
|
||||||
SpeedDirectDisplay = string.Format(ResUI.SpeedDisplayText, Global.DirectTag, Utils.HumanFy(update.directUp), Utils.HumanFy(update.directDown));
|
|
||||||
|
|
||||||
if ((update.proxyUp + update.proxyDown) > 0 && DateTime.Now.Second % 3 == 0)
|
if ((update.proxyUp + update.proxyDown) > 0 && DateTime.Now.Second % 3 == 0)
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
|
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
|
||||||
|
@ -448,6 +298,11 @@ namespace ServiceLib.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ShowHideWindow(bool? blShow)
|
||||||
|
{
|
||||||
|
_updateView?.Invoke(EViewAction.ShowHideWindow, blShow);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Actions
|
#endregion Actions
|
||||||
|
|
||||||
#region Servers && Groups
|
#region Servers && Groups
|
||||||
|
@ -457,50 +312,6 @@ namespace ServiceLib.ViewModels
|
||||||
MessageBus.Current.SendMessage("", EMsgCommand.RefreshProfiles.ToString());
|
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()
|
private void RefreshSubscriptions()
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<ProfilesViewModel>()?.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))
|
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
|
#endregion Add Servers
|
||||||
|
|
||||||
#region Subscription
|
#region Subscription
|
||||||
|
@ -658,8 +414,7 @@ namespace ServiceLib.ViewModels
|
||||||
var ret = await _updateView?.Invoke(EViewAction.OptionSettingWindow, null);
|
var ret = await _updateView?.Invoke(EViewAction.OptionSettingWindow, null);
|
||||||
if (ret == true)
|
if (ret == true)
|
||||||
{
|
{
|
||||||
InboundDisplayStaus();
|
Locator.Current.GetService<StatusBarViewModel>()?.InboundDisplayStaus();
|
||||||
//RefreshServers();
|
|
||||||
Reload();
|
Reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -670,8 +425,7 @@ namespace ServiceLib.ViewModels
|
||||||
if (ret == true)
|
if (ret == true)
|
||||||
{
|
{
|
||||||
ConfigHandler.InitBuiltinRouting(_config);
|
ConfigHandler.InitBuiltinRouting(_config);
|
||||||
RefreshRoutingsMenu();
|
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
|
||||||
//RefreshServers();
|
|
||||||
Reload();
|
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
|
try
|
||||||
{
|
{
|
||||||
|
ProcessStartInfo startInfo = new()
|
||||||
|
{
|
||||||
|
UseShellExecute = true,
|
||||||
|
Arguments = Global.RebootAs,
|
||||||
|
WorkingDirectory = Utils.StartupPath(),
|
||||||
|
FileName = Utils.GetExePath().AppendQuotes(),
|
||||||
|
Verb = "runas",
|
||||||
|
};
|
||||||
Process.Start(startInfo);
|
Process.Start(startInfo);
|
||||||
MyAppExitAsync(false);
|
await MyAppExitAsync(false);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
@ -730,13 +484,13 @@ namespace ServiceLib.ViewModels
|
||||||
BlReloadEnabled = false;
|
BlReloadEnabled = false;
|
||||||
|
|
||||||
await LoadCore();
|
await LoadCore();
|
||||||
await TestServerAvailability();
|
Locator.Current.GetService<StatusBarViewModel>()?.TestServerAvailability();
|
||||||
_updateView?.Invoke(EViewAction.DispatcherReload, null);
|
_updateView?.Invoke(EViewAction.DispatcherReload, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReloadResult()
|
public void ReloadResult()
|
||||||
{
|
{
|
||||||
ChangeSystemProxyStatusAsync(_config.systemProxyItem.sysProxyType, false);
|
//ChangeSystemProxyStatusAsync(_config.systemProxyItem.sysProxyType, false);
|
||||||
BlReloadEnabled = true;
|
BlReloadEnabled = true;
|
||||||
ShowClashUI = _config.IsRunningCore(ECoreType.sing_box);
|
ShowClashUI = _config.IsRunningCore(ECoreType.sing_box);
|
||||||
if (ShowClashUI)
|
if (ShowClashUI)
|
||||||
|
@ -764,180 +518,22 @@ namespace ServiceLib.ViewModels
|
||||||
public void CloseCore()
|
public void CloseCore()
|
||||||
{
|
{
|
||||||
ConfigHandler.SaveConfig(_config, false);
|
ConfigHandler.SaveConfig(_config, false);
|
||||||
|
|
||||||
ChangeSystemProxyStatusAsync(ESysProxyType.ForcedClear, false);
|
|
||||||
|
|
||||||
CoreHandler.Instance.CoreStop();
|
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()
|
private void AutoHideStartup()
|
||||||
{
|
{
|
||||||
if (_config.uiItem.autoHideStartup)
|
if (_config.uiItem.autoHideStartup)
|
||||||
{
|
{
|
||||||
Observable.Range(1, 1)
|
Observable.Range(1, 1)
|
||||||
.Delay(TimeSpan.FromSeconds(1))
|
.Delay(TimeSpan.FromSeconds(1))
|
||||||
.Subscribe(async x =>
|
.Subscribe(async x =>
|
||||||
{
|
{
|
||||||
await _updateView?.Invoke(EViewAction.ShowHideWindow, false);
|
ShowHideWindow(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion UI
|
#endregion core job
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -15,7 +15,6 @@ namespace ServiceLib.ViewModels
|
||||||
|
|
||||||
private List<ProfileItem> _lstProfile;
|
private List<ProfileItem> _lstProfile;
|
||||||
private string _serverFilter = string.Empty;
|
private string _serverFilter = string.Empty;
|
||||||
|
|
||||||
private Dictionary<string, bool> _dicHeaderSort = new();
|
private Dictionary<string, bool> _dicHeaderSort = new();
|
||||||
private SpeedtestService? _speedtestHandler;
|
private SpeedtestService? _speedtestHandler;
|
||||||
|
|
||||||
|
@ -57,7 +56,6 @@ namespace ServiceLib.ViewModels
|
||||||
|
|
||||||
//servers delete
|
//servers delete
|
||||||
public ReactiveCommand<Unit, Unit> EditServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> EditServerCmd { get; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> RemoveServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> RemoveServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> RemoveDuplicateServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> RemoveDuplicateServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> CopyServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> CopyServerCmd { get; }
|
||||||
|
@ -68,14 +66,12 @@ namespace ServiceLib.ViewModels
|
||||||
|
|
||||||
//servers move
|
//servers move
|
||||||
public ReactiveCommand<Unit, Unit> MoveTopCmd { get; }
|
public ReactiveCommand<Unit, Unit> MoveTopCmd { get; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> MoveUpCmd { get; }
|
public ReactiveCommand<Unit, Unit> MoveUpCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> MoveDownCmd { get; }
|
public ReactiveCommand<Unit, Unit> MoveDownCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> MoveBottomCmd { get; }
|
public ReactiveCommand<Unit, Unit> MoveBottomCmd { get; }
|
||||||
|
|
||||||
//servers ping
|
//servers ping
|
||||||
public ReactiveCommand<Unit, Unit> MixedTestServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> MixedTestServerCmd { get; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> TcpingServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> TcpingServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> RealPingServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> RealPingServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> SpeedServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> SpeedServerCmd { get; }
|
||||||
|
@ -83,7 +79,6 @@ namespace ServiceLib.ViewModels
|
||||||
|
|
||||||
//servers export
|
//servers export
|
||||||
public ReactiveCommand<Unit, Unit> Export2ClientConfigCmd { get; }
|
public ReactiveCommand<Unit, Unit> Export2ClientConfigCmd { get; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> Export2ClientConfigClipboardCmd { get; }
|
public ReactiveCommand<Unit, Unit> Export2ClientConfigClipboardCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> Export2ShareUrlCmd { get; }
|
public ReactiveCommand<Unit, Unit> Export2ShareUrlCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> Export2ShareUrlBase64Cmd { get; }
|
public ReactiveCommand<Unit, Unit> Export2ShareUrlBase64Cmd { get; }
|
||||||
|
@ -98,7 +93,6 @@ namespace ServiceLib.ViewModels
|
||||||
public ProfilesViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
public ProfilesViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||||
{
|
{
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
|
|
||||||
_updateView = updateView;
|
_updateView = updateView;
|
||||||
|
|
||||||
MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString()).Subscribe(async x => await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null));
|
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);
|
SetDefaultServer(SelectedProfile.indexId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SetDefaultServer(string indexId)
|
public async Task SetDefaultServer(string indexId)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(indexId))
|
if (Utils.IsNullOrEmpty(indexId))
|
||||||
{
|
{
|
||||||
|
|
459
v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
Normal file
459
v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs
Normal file
|
@ -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"
|
x:Class="v2rayN.Desktop.App"
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="using:v2rayN.Desktop.ViewModels"
|
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
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">
|
RequestedThemeVariant="Default">
|
||||||
<Application.Styles>
|
<Application.Styles>
|
||||||
<StyleInclude Source="Styles/GlobalStyles.axaml" />
|
<StyleInclude Source="Styles/GlobalStyles.axaml" />
|
||||||
|
@ -37,13 +37,13 @@
|
||||||
<NativeMenuItem Command="{Binding SystemProxySetCmd}" Header="{x:Static resx:ResUI.menuSystemProxySet}" />
|
<NativeMenuItem Command="{Binding SystemProxySetCmd}" Header="{x:Static resx:ResUI.menuSystemProxySet}" />
|
||||||
<NativeMenuItem Command="{Binding SystemProxyNothingCmd}" Header="{x:Static resx:ResUI.menuSystemProxyNothing}" />
|
<NativeMenuItem Command="{Binding SystemProxyNothingCmd}" Header="{x:Static resx:ResUI.menuSystemProxyNothing}" />
|
||||||
<NativeMenuItemSeparator />
|
<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 Header="{x:Static resx:ResUI.menuAddServerViaScan}" IsVisible="False" />
|
||||||
<NativeMenuItem Command="{Binding SubUpdateCmd}" Header="{x:Static resx:ResUI.menuSubUpdate}" />
|
<NativeMenuItem Command="{Binding SubUpdateCmd}" Header="{x:Static resx:ResUI.menuSubUpdate}" />
|
||||||
<NativeMenuItem Command="{Binding SubUpdateViaProxyCmd}" Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" />
|
<NativeMenuItem Command="{Binding SubUpdateViaProxyCmd}" Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" />
|
||||||
<NativeMenuItemSeparator />
|
<NativeMenuItemSeparator />
|
||||||
<NativeMenuItem Click="TrayIcon_Clicked" Header="{x:Static resx:ResUI.menuShowOrHideMainWindow}" />
|
<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>
|
</NativeMenu>
|
||||||
</TrayIcon.Menu>
|
</TrayIcon.Menu>
|
||||||
</TrayIcon>
|
</TrayIcon>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using v2rayN.Desktop.ViewModels;
|
using Splat;
|
||||||
|
using v2rayN.Desktop.Common;
|
||||||
using v2rayN.Desktop.Views;
|
using v2rayN.Desktop.Views;
|
||||||
|
|
||||||
namespace v2rayN.Desktop;
|
namespace v2rayN.Desktop;
|
||||||
|
@ -22,7 +23,9 @@ public partial class App : Application
|
||||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||||
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
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()
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
var service = Locator.Current.GetService<StatusBarViewModel>();
|
||||||
if (service != null) await service.SetListenerType(type);
|
if (service != null) await service.SetListenerType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
xmlns:dialogHost="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
|
xmlns:dialogHost="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
|
xmlns:view="using:v2rayN.Desktop.Views"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="v2rayN"
|
Title="v2rayN"
|
||||||
Width="900"
|
Width="900"
|
||||||
|
@ -118,72 +119,7 @@
|
||||||
</Menu>
|
</Menu>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
|
|
||||||
<StackPanel Height="50" DockPanel.Dock="Bottom">
|
<view:StatusBarView 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>
|
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid x:Name="gridMain" IsVisible="False">
|
<Grid x:Name="gridMain" IsVisible="False">
|
||||||
|
|
|
@ -12,7 +12,6 @@ using Splat;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using v2rayN.Desktop.Common;
|
using v2rayN.Desktop.Common;
|
||||||
using v2rayN.Desktop.Handler;
|
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Views
|
namespace v2rayN.Desktop.Views
|
||||||
{
|
{
|
||||||
|
@ -40,9 +39,8 @@ namespace v2rayN.Desktop.Views
|
||||||
menuCheckUpdate.Click += MenuCheckUpdate_Click;
|
menuCheckUpdate.Click += MenuCheckUpdate_Click;
|
||||||
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
||||||
|
|
||||||
var IsAdministrator = Utils.IsAdministrator();
|
|
||||||
MessageBus.Current.Listen<string>(EMsgCommand.SendSnackMsg.ToString()).Subscribe(x => DelegateSnackMsg(x));
|
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));
|
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
|
||||||
|
|
||||||
//WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
//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.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);
|
||||||
this.OneWayBind(ViewModel, vm => vm.BlReloadEnabled, v => v.menuReload.IsEnabled).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)
|
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
|
||||||
{
|
{
|
||||||
gridMain.IsVisible = true;
|
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())
|
if (Utils.IsWindows())
|
||||||
{
|
{
|
||||||
menuGlobalHotkeySetting.IsVisible = false;
|
menuGlobalHotkeySetting.IsVisible = false;
|
||||||
|
@ -128,10 +113,6 @@ namespace v2rayN.Desktop.Views
|
||||||
menuRebootAsAdmin.IsVisible = false;
|
menuRebootAsAdmin.IsVisible = false;
|
||||||
menuSettingsSetUWP.IsVisible = false;
|
menuSettingsSetUWP.IsVisible = false;
|
||||||
menuGlobalHotkeySetting.IsVisible = false;
|
menuGlobalHotkeySetting.IsVisible = false;
|
||||||
if (_config.tunModeItem.enableTun)
|
|
||||||
{
|
|
||||||
ViewModel.EnableTun = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
|
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
|
||||||
|
@ -215,33 +196,12 @@ namespace v2rayN.Desktop.Views
|
||||||
DispatcherPriority.Default);
|
DispatcherPriority.Default);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EViewAction.DispatcherServerAvailability:
|
|
||||||
if (obj is null) return false;
|
|
||||||
Dispatcher.UIThread.Post(() =>
|
|
||||||
ViewModel?.TestServerAvailabilityResult((string)obj),
|
|
||||||
DispatcherPriority.Default);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EViewAction.DispatcherReload:
|
case EViewAction.DispatcherReload:
|
||||||
Dispatcher.UIThread.Post(() =>
|
Dispatcher.UIThread.Post(() =>
|
||||||
ViewModel?.ReloadResult(),
|
ViewModel?.ReloadResult(),
|
||||||
DispatcherPriority.Default);
|
DispatcherPriority.Default);
|
||||||
break;
|
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:
|
case EViewAction.Shutdown:
|
||||||
StorageUI();
|
StorageUI();
|
||||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
|
@ -251,12 +211,7 @@ namespace v2rayN.Desktop.Views
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EViewAction.ScanScreenTask:
|
case EViewAction.ScanScreenTask:
|
||||||
ScanScreenTaskAsync().ContinueWith(_ => { });
|
await ScanScreenTaskAsync();
|
||||||
break;
|
|
||||||
|
|
||||||
case EViewAction.UpdateSysProxy:
|
|
||||||
if (obj is null) return false;
|
|
||||||
await SysProxyHandler.UpdateSysProxy(_config, (bool)obj);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EViewAction.AddServerViaClipboard:
|
case EViewAction.AddServerViaClipboard:
|
||||||
|
@ -282,21 +237,21 @@ namespace v2rayN.Desktop.Views
|
||||||
ShowHideWindow(null);
|
ShowHideWindow(null);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EGlobalHotkey.SystemProxyClear:
|
//case EGlobalHotkey.SystemProxyClear:
|
||||||
ViewModel?.SetListenerType(ESysProxyType.ForcedClear);
|
// ViewModel?.SetListenerType(ESysProxyType.ForcedClear);
|
||||||
break;
|
// break;
|
||||||
|
|
||||||
case EGlobalHotkey.SystemProxySet:
|
//case EGlobalHotkey.SystemProxySet:
|
||||||
ViewModel?.SetListenerType(ESysProxyType.ForcedChange);
|
// ViewModel?.SetListenerType(ESysProxyType.ForcedChange);
|
||||||
break;
|
// break;
|
||||||
|
|
||||||
case EGlobalHotkey.SystemProxyUnchanged:
|
//case EGlobalHotkey.SystemProxyUnchanged:
|
||||||
ViewModel?.SetListenerType(ESysProxyType.Unchanged);
|
// ViewModel?.SetListenerType(ESysProxyType.Unchanged);
|
||||||
break;
|
// break;
|
||||||
|
|
||||||
case EGlobalHotkey.SystemProxyPac:
|
//case EGlobalHotkey.SystemProxyPac:
|
||||||
ViewModel?.SetListenerType(ESysProxyType.Pac);
|
// ViewModel?.SetListenerType(ESysProxyType.Pac);
|
||||||
break;
|
// break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,11 +297,6 @@ namespace v2rayN.Desktop.Views
|
||||||
Utils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
|
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)
|
private void menuSettingsSetUWP_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
Utils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
||||||
|
|
81
v2rayN/v2rayN.Desktop/Views/StatusBarView.axaml
Normal file
81
v2rayN/v2rayN.Desktop/Views/StatusBarView.axaml
Normal file
|
@ -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>
|
136
v2rayN/v2rayN.Desktop/Views/StatusBarView.axaml.cs
Normal file
136
v2rayN/v2rayN.Desktop/Views/StatusBarView.axaml.cs
Normal file
|
@ -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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
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"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="v2rayN"
|
Title="v2rayN"
|
||||||
Width="900"
|
Width="900"
|
||||||
|
@ -276,84 +276,7 @@
|
||||||
</ToolBar>
|
</ToolBar>
|
||||||
</ToolBarTray>
|
</ToolBarTray>
|
||||||
|
|
||||||
<materialDesign:ColorZone
|
<view:StatusBarView DockPanel.Dock="Bottom" />
|
||||||
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>
|
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid x:Name="gridMain" Visibility="Collapsed">
|
<Grid x:Name="gridMain" Visibility="Collapsed">
|
||||||
|
@ -505,113 +428,6 @@
|
||||||
<materialDesign:Snackbar x:Name="MainSnackbar" MessageQueue="{materialDesign:MessageQueue}" />
|
<materialDesign:Snackbar x:Name="MainSnackbar" MessageQueue="{materialDesign:MessageQueue}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</DockPanel>
|
</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>
|
</Grid>
|
||||||
</materialDesign:DialogHost>
|
</materialDesign:DialogHost>
|
||||||
</reactiveui:ReactiveWindow>
|
</reactiveui:ReactiveWindow>
|
|
@ -26,19 +26,18 @@ namespace v2rayN.Views
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
|
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
|
||||||
|
|
||||||
|
Application.Current.Exit += Current_Exit;
|
||||||
App.Current.SessionEnding += Current_SessionEnding;
|
App.Current.SessionEnding += Current_SessionEnding;
|
||||||
this.Closing += MainWindow_Closing;
|
this.Closing += MainWindow_Closing;
|
||||||
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
|
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
|
||||||
menuSettingsSetUWP.Click += menuSettingsSetUWP_Click;
|
menuSettingsSetUWP.Click += menuSettingsSetUWP_Click;
|
||||||
menuPromotion.Click += menuPromotion_Click;
|
menuPromotion.Click += menuPromotion_Click;
|
||||||
menuClose.Click += menuClose_Click;
|
menuClose.Click += menuClose_Click;
|
||||||
menuExit.Click += menuExit_Click;
|
|
||||||
menuCheckUpdate.Click += MenuCheckUpdate_Click;
|
menuCheckUpdate.Click += MenuCheckUpdate_Click;
|
||||||
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
||||||
|
|
||||||
var IsAdministrator = Utils.IsAdministrator();
|
|
||||||
MessageBus.Current.Listen<string>(EMsgCommand.SendSnackMsg.ToString()).Subscribe(x => DelegateSnackMsg(x));
|
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));
|
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
|
||||||
|
|
||||||
WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
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.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);
|
||||||
this.OneWayBind(ViewModel, vm => vm.BlReloadEnabled, v => v.menuReload.IsEnabled).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)
|
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
|
||||||
{
|
{
|
||||||
gridMain.Visibility = Visibility.Visible;
|
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)
|
if (!_config.guiItem.enableHWA)
|
||||||
{
|
{
|
||||||
|
@ -237,14 +193,6 @@ namespace v2rayN.Views
|
||||||
}), DispatcherPriority.Normal);
|
}), DispatcherPriority.Normal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EViewAction.DispatcherServerAvailability:
|
|
||||||
if (obj is null) return false;
|
|
||||||
Application.Current?.Dispatcher.Invoke((() =>
|
|
||||||
{
|
|
||||||
ViewModel?.TestServerAvailabilityResult((string)obj);
|
|
||||||
}), DispatcherPriority.Normal);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EViewAction.DispatcherReload:
|
case EViewAction.DispatcherReload:
|
||||||
Application.Current?.Dispatcher.Invoke((() =>
|
Application.Current?.Dispatcher.Invoke((() =>
|
||||||
{
|
{
|
||||||
|
@ -252,21 +200,6 @@ namespace v2rayN.Views
|
||||||
}), DispatcherPriority.Normal);
|
}), DispatcherPriority.Normal);
|
||||||
break;
|
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:
|
case EViewAction.Shutdown:
|
||||||
Application.Current?.Dispatcher.Invoke((() =>
|
Application.Current?.Dispatcher.Invoke((() =>
|
||||||
{
|
{
|
||||||
|
@ -275,12 +208,7 @@ namespace v2rayN.Views
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EViewAction.ScanScreenTask:
|
case EViewAction.ScanScreenTask:
|
||||||
ScanScreenTaskAsync().ContinueWith(_ => { });
|
await ScanScreenTaskAsync();
|
||||||
break;
|
|
||||||
|
|
||||||
case EViewAction.UpdateSysProxy:
|
|
||||||
if (obj is null) return false;
|
|
||||||
SysProxyHandler.UpdateSysProxy(_config, (bool)obj);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EViewAction.AddServerViaClipboard:
|
case EViewAction.AddServerViaClipboard:
|
||||||
|
@ -308,19 +236,10 @@ namespace v2rayN.Views
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EGlobalHotkey.SystemProxyClear:
|
case EGlobalHotkey.SystemProxyClear:
|
||||||
ViewModel?.SetListenerType(ESysProxyType.ForcedClear);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EGlobalHotkey.SystemProxySet:
|
case EGlobalHotkey.SystemProxySet:
|
||||||
ViewModel?.SetListenerType(ESysProxyType.ForcedChange);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EGlobalHotkey.SystemProxyUnchanged:
|
case EGlobalHotkey.SystemProxyUnchanged:
|
||||||
ViewModel?.SetListenerType(ESysProxyType.Unchanged);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EGlobalHotkey.SystemProxyPac:
|
case EGlobalHotkey.SystemProxyPac:
|
||||||
ViewModel?.SetListenerType(ESysProxyType.Pac);
|
Locator.Current.GetService<StatusBarViewModel>()?.SetListenerType((ESysProxyType)((int)e - 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,13 +250,9 @@ namespace v2rayN.Views
|
||||||
ShowHideWindow(false);
|
ShowHideWindow(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void menuExit_Click(object sender, RoutedEventArgs e)
|
private void Current_Exit(object sender, ExitEventArgs e)
|
||||||
{
|
{
|
||||||
tabProfiles = null;
|
|
||||||
|
|
||||||
tbNotify.Dispose();
|
|
||||||
StorageUI();
|
StorageUI();
|
||||||
ViewModel?.MyAppExitAsync(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Current_SessionEnding(object sender, SessionEndingCancelEventArgs e)
|
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}");
|
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)
|
private void menuSettingsSetUWP_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
Utils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ScanScreenTaskAsync()
|
private async Task ScanScreenTaskAsync()
|
||||||
{
|
{
|
||||||
ShowHideWindow(false);
|
ShowHideWindow(false);
|
||||||
|
|
||||||
|
@ -405,7 +315,7 @@ namespace v2rayN.Views
|
||||||
|
|
||||||
ShowHideWindow(true);
|
ShowHideWindow(true);
|
||||||
|
|
||||||
ViewModel?.ScanScreenTaskAsync(result);
|
ViewModel?.ScanScreenResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MenuCheckUpdate_Click(object sender, RoutedEventArgs e)
|
private void MenuCheckUpdate_Click(object sender, RoutedEventArgs e)
|
||||||
|
|
198
v2rayN/v2rayN/Views/StatusBarView.xaml
Normal file
198
v2rayN/v2rayN/Views/StatusBarView.xaml
Normal file
|
@ -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>
|
124
v2rayN/v2rayN/Views/StatusBarView.xaml.cs
Normal file
124
v2rayN/v2rayN/Views/StatusBarView.xaml.cs
Normal file
|
@ -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 a new issue