mirror of https://github.com/2dust/v2rayN
Refactor code to decouple view and viewmodel
parent
3dd75b17cf
commit
9e9808e489
|
@ -9,6 +9,7 @@
|
|||
ProfilesFocus,
|
||||
ShareSub,
|
||||
ShareServer,
|
||||
ShowHideWindow,
|
||||
SubEditWindow,
|
||||
RoutingRuleSettingWindow,
|
||||
RoutingRuleDetailsWindow,
|
||||
|
@ -19,5 +20,14 @@
|
|||
OptionSettingWindow,
|
||||
GlobalHotkeySettingWindow,
|
||||
SubSettingWindow,
|
||||
DispatcherSpeedTest,
|
||||
DispatcherRefreshConnections,
|
||||
DispatcherRefreshProxyGroups,
|
||||
DispatcherProxiesDelayTest,
|
||||
|
||||
DispatcherStatistics,
|
||||
DispatcherServerAvailability,
|
||||
DispatcherReload,
|
||||
DispatcherRefreshServersBiz,
|
||||
}
|
||||
}
|
|
@ -72,7 +72,7 @@ namespace v2rayN.Handler
|
|||
bool isSuccess = false;
|
||||
string msg;
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
Application.Current?.Dispatcher.Invoke(() =>
|
||||
{
|
||||
isSuccess = RegisterHotKey(IntPtr.Zero, _hotkeyCode, hotkeyInfo.fsModifiers, hotkeyInfo.vKey);
|
||||
});
|
||||
|
@ -96,7 +96,7 @@ namespace v2rayN.Handler
|
|||
{
|
||||
foreach (var hotkey in _hotkeyTriggerDic.Keys)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
Application.Current?.Dispatcher.Invoke(() =>
|
||||
{
|
||||
UnregisterHotKey(IntPtr.Zero, hotkey);
|
||||
});
|
||||
|
@ -137,7 +137,7 @@ namespace v2rayN.Handler
|
|||
var _hotKeyCode = (int)msg.lParam;
|
||||
if (IsPause)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
Application.Current?.Dispatcher.Invoke(() =>
|
||||
{
|
||||
UIElement? element = Keyboard.FocusedElement as UIElement;
|
||||
if (element != null)
|
||||
|
|
|
@ -14,14 +14,14 @@ namespace v2rayN.Handler
|
|||
private CoreHandler _coreHandler;
|
||||
private List<ServerTestItem> _selecteds;
|
||||
private ESpeedActionType _actionType;
|
||||
private Action<string, string, string> _updateFunc;
|
||||
private Action<SpeedTestResult> _updateFunc;
|
||||
|
||||
public SpeedtestHandler(Config config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public SpeedtestHandler(Config config, CoreHandler coreHandler, List<ProfileItem> selecteds, ESpeedActionType actionType, Action<string, string, string> update)
|
||||
public SpeedtestHandler(Config config, CoreHandler coreHandler, List<ProfileItem> selecteds, ESpeedActionType actionType, Action<SpeedTestResult> update)
|
||||
{
|
||||
_config = config;
|
||||
_coreHandler = coreHandler;
|
||||
|
@ -408,7 +408,7 @@ namespace v2rayN.Handler
|
|||
|
||||
private void UpdateFunc(string indexId, string delay, string speed = "")
|
||||
{
|
||||
_updateFunc(indexId, delay, speed);
|
||||
_updateFunc(new() { IndexId = indexId, Delay = delay, Speed = speed });
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace v2rayN.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class SpeedTestResult
|
||||
{
|
||||
public string? IndexId { get; set; }
|
||||
|
||||
public string? Delay { get; set; }
|
||||
|
||||
public string? Speed { get; set; }
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ using ReactiveUI;
|
|||
using ReactiveUI.Fody.Helpers;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
using v2rayN.Base;
|
||||
using v2rayN.Enums;
|
||||
using v2rayN.Handler;
|
||||
|
@ -30,9 +29,10 @@ namespace v2rayN.ViewModels
|
|||
[Reactive]
|
||||
public bool AutoRefresh { get; set; }
|
||||
|
||||
public ClashConnectionsViewModel()
|
||||
public ClashConnectionsViewModel(Func<EViewAction, object?, bool>? updateView)
|
||||
{
|
||||
_config = LazyConfig.Instance.GetConfig();
|
||||
_updateView = updateView;
|
||||
SortingSelected = _config.clashUIItem.connectionsSorting;
|
||||
AutoRefresh = _config.clashUIItem.connectionsAutoRefresh;
|
||||
|
||||
|
@ -110,14 +110,11 @@ namespace v2rayN.ViewModels
|
|||
return;
|
||||
}
|
||||
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
{
|
||||
RefreshConnections(it?.connections);
|
||||
}));
|
||||
_updateView?.Invoke(EViewAction.DispatcherRefreshConnections, it?.connections);
|
||||
});
|
||||
}
|
||||
|
||||
private void RefreshConnections(List<ConnectionItem>? connections)
|
||||
public void RefreshConnections(List<ConnectionItem>? connections)
|
||||
{
|
||||
_connectionItems.Clear();
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ using ReactiveUI.Fody.Helpers;
|
|||
using Splat;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
using v2rayN.Base;
|
||||
using v2rayN.Enums;
|
||||
using v2rayN.Handler;
|
||||
|
@ -48,10 +47,11 @@ namespace v2rayN.ViewModels
|
|||
[Reactive]
|
||||
public bool AutoRefresh { get; set; }
|
||||
|
||||
public ClashProxiesViewModel()
|
||||
public ClashProxiesViewModel(Func<EViewAction, object?, bool>? updateView)
|
||||
{
|
||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||
_config = LazyConfig.Instance.GetConfig();
|
||||
_updateView = updateView;
|
||||
|
||||
SelectedGroup = new();
|
||||
SelectedDetail = new();
|
||||
|
@ -149,20 +149,6 @@ namespace v2rayN.ViewModels
|
|||
ProxiesDelayTest();
|
||||
}
|
||||
|
||||
public void ProxiesClear()
|
||||
{
|
||||
proxies = null;
|
||||
providers = null;
|
||||
|
||||
ClashApiHandler.Instance.SetProxies(proxies);
|
||||
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
{
|
||||
_proxyGroups.Clear();
|
||||
_proxyDetails.Clear();
|
||||
}));
|
||||
}
|
||||
|
||||
public void ProxiesDelayTest()
|
||||
{
|
||||
ProxiesDelayTest(true);
|
||||
|
@ -197,15 +183,12 @@ namespace v2rayN.ViewModels
|
|||
}
|
||||
if (refreshUI)
|
||||
{
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
{
|
||||
RefreshProxyGroups();
|
||||
}));
|
||||
_updateView?.Invoke(EViewAction.DispatcherRefreshProxyGroups, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void RefreshProxyGroups()
|
||||
public void RefreshProxyGroups()
|
||||
{
|
||||
var selectedName = SelectedGroup?.name;
|
||||
_proxyGroups.Clear();
|
||||
|
@ -425,34 +408,37 @@ namespace v2rayN.ViewModels
|
|||
{
|
||||
return;
|
||||
}
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
{
|
||||
//UpdateHandler(false, $"{item.name}={result}");
|
||||
var detail = _proxyDetails.Where(it => it.name == item.name).FirstOrDefault();
|
||||
if (detail != null)
|
||||
{
|
||||
var dicResult = JsonUtils.Deserialize<Dictionary<string, object>>(result);
|
||||
if (dicResult != null && dicResult.ContainsKey("delay"))
|
||||
{
|
||||
detail.delay = Convert.ToInt32(dicResult["delay"].ToString());
|
||||
detail.delayName = $"{detail.delay}ms";
|
||||
}
|
||||
else if (dicResult != null && dicResult.ContainsKey("message"))
|
||||
{
|
||||
detail.delay = delayTimeout;
|
||||
detail.delayName = $"{dicResult["message"]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
detail.delay = delayTimeout;
|
||||
detail.delayName = String.Empty;
|
||||
}
|
||||
_proxyDetails.Replace(detail, JsonUtils.DeepCopy(detail));
|
||||
}
|
||||
}));
|
||||
|
||||
_updateView?.Invoke(EViewAction.DispatcherProxiesDelayTest, new SpeedTestResult() { IndexId = item.name, Delay = result });
|
||||
});
|
||||
}
|
||||
|
||||
public void ProxiesDelayTestResult(SpeedTestResult result)
|
||||
{
|
||||
//UpdateHandler(false, $"{item.name}={result}");
|
||||
var detail = _proxyDetails.Where(it => it.name == result.IndexId).FirstOrDefault();
|
||||
if (detail != null)
|
||||
{
|
||||
var dicResult = JsonUtils.Deserialize<Dictionary<string, object>>(result.Delay);
|
||||
if (dicResult != null && dicResult.ContainsKey("delay"))
|
||||
{
|
||||
detail.delay = Convert.ToInt32(dicResult["delay"].ToString());
|
||||
detail.delayName = $"{detail.delay}ms";
|
||||
}
|
||||
else if (dicResult != null && dicResult.ContainsKey("message"))
|
||||
{
|
||||
detail.delay = delayTimeout;
|
||||
detail.delayName = $"{dicResult["message"]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
detail.delay = delayTimeout;
|
||||
detail.delayName = String.Empty;
|
||||
}
|
||||
_proxyDetails.Replace(detail, JsonUtils.DeepCopy(detail));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion proxy function
|
||||
|
||||
#region task
|
||||
|
|
|
@ -25,8 +25,6 @@ namespace v2rayN.ViewModels
|
|||
|
||||
private CoreHandler _coreHandler;
|
||||
|
||||
private bool _showInTaskbar;
|
||||
|
||||
#endregion private prop
|
||||
|
||||
#region ObservableCollection
|
||||
|
@ -175,7 +173,7 @@ namespace v2rayN.ViewModels
|
|||
_updateView = updateView;
|
||||
|
||||
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
|
||||
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz());
|
||||
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null));
|
||||
|
||||
SelectedRouting = new();
|
||||
SelectedServer = new();
|
||||
|
@ -352,7 +350,7 @@ namespace v2rayN.ViewModels
|
|||
|
||||
NotifyLeftClickCmd = ReactiveCommand.Create(() =>
|
||||
{
|
||||
ShowHideWindow(null);
|
||||
_updateView?.Invoke(EViewAction.ShowHideWindow, null);
|
||||
});
|
||||
|
||||
//System proxy
|
||||
|
@ -377,8 +375,7 @@ namespace v2rayN.ViewModels
|
|||
|
||||
AutoHideStartup();
|
||||
|
||||
_showInTaskbar = true;
|
||||
_config.uiItem.showInTaskbar = _showInTaskbar;
|
||||
_config.uiItem.showInTaskbar = true;
|
||||
}
|
||||
|
||||
private void Init()
|
||||
|
@ -405,10 +402,7 @@ namespace v2rayN.ViewModels
|
|||
|
||||
private void OnProgramStarted(object state, bool timeout)
|
||||
{
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
{
|
||||
ShowHideWindow(true);
|
||||
}));
|
||||
_updateView?.Invoke(EViewAction.ShowHideWindow, true);
|
||||
}
|
||||
|
||||
#endregion Init
|
||||
|
@ -417,7 +411,7 @@ namespace v2rayN.ViewModels
|
|||
|
||||
private void UpdateHandler(bool notify, string msg)
|
||||
{
|
||||
if (!_showInTaskbar)
|
||||
if (!_config.uiItem.showInTaskbar)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -443,24 +437,25 @@ namespace v2rayN.ViewModels
|
|||
}
|
||||
|
||||
private void UpdateStatisticsHandler(ServerSpeedItem update)
|
||||
{
|
||||
if (!_config.uiItem.showInTaskbar)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_updateView?.Invoke(EViewAction.DispatcherStatistics, update);
|
||||
}
|
||||
|
||||
public void SetStatisticsResult(ServerSpeedItem update)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_showInTaskbar)
|
||||
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));
|
||||
|
||||
if ((update.proxyUp + update.proxyDown) > 0 && DateTime.Now.Second % 3 == 0)
|
||||
{
|
||||
return;
|
||||
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
|
||||
}
|
||||
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
{
|
||||
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));
|
||||
|
||||
if ((update.proxyUp + update.proxyDown) > 0 && DateTime.Now.Second % 3 == 0)
|
||||
{
|
||||
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
|
||||
}
|
||||
}));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -473,7 +468,7 @@ namespace v2rayN.ViewModels
|
|||
switch (e)
|
||||
{
|
||||
case EGlobalHotkey.ShowForm:
|
||||
ShowHideWindow(null);
|
||||
_updateView?.Invoke(EViewAction.ShowHideWindow, null);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyClear:
|
||||
|
@ -535,25 +530,22 @@ namespace v2rayN.ViewModels
|
|||
MessageBus.Current.SendMessage("", Global.CommandRefreshProfiles);
|
||||
}
|
||||
|
||||
private void RefreshServersBiz()
|
||||
public void RefreshServersBiz()
|
||||
{
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
{
|
||||
RefreshServersMenu();
|
||||
RefreshServersMenu();
|
||||
|
||||
//display running server
|
||||
var running = ConfigHandler.GetDefaultServer(_config);
|
||||
if (running != null)
|
||||
{
|
||||
RunningServerDisplay =
|
||||
RunningServerToolTipText = running.GetSummary();
|
||||
}
|
||||
else
|
||||
{
|
||||
RunningServerDisplay =
|
||||
RunningServerToolTipText = ResUI.CheckServerSettings;
|
||||
}
|
||||
}));
|
||||
//display running server
|
||||
var running = ConfigHandler.GetDefaultServer(_config);
|
||||
if (running != null)
|
||||
{
|
||||
RunningServerDisplay =
|
||||
RunningServerToolTipText = running.GetSummary();
|
||||
}
|
||||
else
|
||||
{
|
||||
RunningServerDisplay =
|
||||
RunningServerToolTipText = ResUI.CheckServerSettings;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshServersMenu()
|
||||
|
@ -633,7 +625,7 @@ namespace v2rayN.ViewModels
|
|||
|
||||
public async Task ScanScreenTaskAsync()
|
||||
{
|
||||
ShowHideWindow(false);
|
||||
_updateView?.Invoke(EViewAction.ShowHideWindow, false);
|
||||
|
||||
var dpiXY = QRCodeHelper.GetDpiXY(Application.Current.MainWindow);
|
||||
string result = await Task.Run(() =>
|
||||
|
@ -641,7 +633,7 @@ namespace v2rayN.ViewModels
|
|||
return QRCodeHelper.ScanScreen(dpiXY.Item1, dpiXY.Item2);
|
||||
});
|
||||
|
||||
ShowHideWindow(true);
|
||||
_updateView?.Invoke(EViewAction.ShowHideWindow, true);
|
||||
|
||||
if (Utils.IsNullOrEmpty(result))
|
||||
{
|
||||
|
@ -710,17 +702,20 @@ namespace v2rayN.ViewModels
|
|||
(new UpdateHandle()).RunAvailabilityCheck((bool success, string msg) =>
|
||||
{
|
||||
_noticeHandler?.SendMessage(msg, true);
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
|
||||
if (!_config.uiItem.showInTaskbar)
|
||||
{
|
||||
if (!_showInTaskbar)
|
||||
{
|
||||
return;
|
||||
}
|
||||
RunningInfoDisplay = msg;
|
||||
}));
|
||||
return;
|
||||
}
|
||||
_updateView?.Invoke(EViewAction.DispatcherServerAvailability, msg);
|
||||
});
|
||||
}
|
||||
|
||||
public void TestServerAvailabilityResult(string msg)
|
||||
{
|
||||
RunningInfoDisplay = msg;
|
||||
}
|
||||
|
||||
#endregion Add Servers
|
||||
|
||||
#region Subscription
|
||||
|
@ -854,29 +849,28 @@ namespace v2rayN.ViewModels
|
|||
{
|
||||
TestServerAvailability();
|
||||
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
{
|
||||
BlReloadEnabled = true;
|
||||
ShowClashUI = _config.IsRunningCore(ECoreType.clash);
|
||||
if (ShowClashUI)
|
||||
{
|
||||
Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload();
|
||||
}
|
||||
else { TabMainSelectedIndex = 0; }
|
||||
}));
|
||||
_updateView?.Invoke(EViewAction.DispatcherReload, null);
|
||||
});
|
||||
}
|
||||
|
||||
public void ReloadResult()
|
||||
{
|
||||
ChangeSystemProxyStatus(_config.systemProxyItem.sysProxyType, false);
|
||||
BlReloadEnabled = true;
|
||||
ShowClashUI = _config.IsRunningCore(ECoreType.clash);
|
||||
if (ShowClashUI)
|
||||
{
|
||||
Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload();
|
||||
}
|
||||
else { TabMainSelectedIndex = 0; }
|
||||
}
|
||||
|
||||
private async Task LoadCore()
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
var node = ConfigHandler.GetDefaultServer(_config);
|
||||
_coreHandler.LoadCore(node);
|
||||
|
||||
//ConfigHandler.SaveConfig(_config, false);
|
||||
|
||||
ChangeSystemProxyStatus(_config.systemProxyItem.sysProxyType, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -911,21 +905,18 @@ namespace v2rayN.ViewModels
|
|||
SysProxyHandle.UpdateSysProxy(_config, _config.tunModeItem.enableTun ? true : false);
|
||||
_noticeHandler?.SendMessage($"{ResUI.TipChangeSystemProxy} - {_config.systemProxyItem.sysProxyType.ToString()}", true);
|
||||
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
BlSystemProxyClear = (type == ESysProxyType.ForcedClear);
|
||||
BlSystemProxySet = (type == ESysProxyType.ForcedChange);
|
||||
BlSystemProxyNothing = (type == ESysProxyType.Unchanged);
|
||||
BlSystemProxyPac = (type == ESysProxyType.Pac);
|
||||
|
||||
InboundDisplayStaus();
|
||||
|
||||
if (blChange)
|
||||
{
|
||||
BlSystemProxyClear = (type == ESysProxyType.ForcedClear);
|
||||
BlSystemProxySet = (type == ESysProxyType.ForcedChange);
|
||||
BlSystemProxyNothing = (type == ESysProxyType.Unchanged);
|
||||
BlSystemProxyPac = (type == ESysProxyType.Pac);
|
||||
|
||||
InboundDisplayStaus();
|
||||
|
||||
if (blChange)
|
||||
{
|
||||
NotifyIcon = MainFormHandler.Instance.GetNotifyIcon(_config);
|
||||
AppIcon = MainFormHandler.Instance.GetAppIcon(_config);
|
||||
}
|
||||
}));
|
||||
NotifyIcon = MainFormHandler.Instance.GetNotifyIcon(_config);
|
||||
AppIcon = MainFormHandler.Instance.GetAppIcon(_config);
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshRoutingsMenu()
|
||||
|
@ -1013,27 +1004,6 @@ namespace v2rayN.ViewModels
|
|||
|
||||
#region UI
|
||||
|
||||
public void ShowHideWindow(bool? blShow)
|
||||
{
|
||||
var bl = blShow ?? !_showInTaskbar;
|
||||
if (bl)
|
||||
{
|
||||
Application.Current.MainWindow.Show();
|
||||
if (Application.Current.MainWindow.WindowState == WindowState.Minimized)
|
||||
{
|
||||
Application.Current.MainWindow.WindowState = WindowState.Normal;
|
||||
}
|
||||
Application.Current.MainWindow.Activate();
|
||||
Application.Current.MainWindow.Focus();
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.Current.MainWindow.Hide();
|
||||
}
|
||||
_showInTaskbar = bl;
|
||||
_config.uiItem.showInTaskbar = _showInTaskbar;
|
||||
}
|
||||
|
||||
public void InboundDisplayStaus()
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
|
@ -1078,10 +1048,7 @@ namespace v2rayN.ViewModels
|
|||
.Delay(TimeSpan.FromSeconds(1))
|
||||
.Subscribe(x =>
|
||||
{
|
||||
Application.Current?.Dispatcher.Invoke(() =>
|
||||
{
|
||||
ShowHideWindow(false);
|
||||
});
|
||||
_updateView?.Invoke(EViewAction.ShowHideWindow, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ using Splat;
|
|||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using v2rayN.Base;
|
||||
using v2rayN.Enums;
|
||||
using v2rayN.Handler;
|
||||
|
@ -106,7 +105,7 @@ namespace v2rayN.ViewModels
|
|||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||
_updateView = updateView;
|
||||
|
||||
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz());
|
||||
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null));
|
||||
|
||||
SelectedProfile = new();
|
||||
SelectedSub = new();
|
||||
|
@ -246,34 +245,31 @@ namespace v2rayN.ViewModels
|
|||
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
|
||||
}
|
||||
|
||||
private void UpdateSpeedtestHandler(string indexId, string delay, string speed)
|
||||
private void UpdateSpeedtestHandler(SpeedTestResult result)
|
||||
{
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
{
|
||||
SetTestResult(indexId, delay, speed);
|
||||
}));
|
||||
_updateView?.Invoke(EViewAction.DispatcherSpeedTest, result);
|
||||
}
|
||||
|
||||
private void SetTestResult(string indexId, string delay, string speed)
|
||||
public void SetSpeedTestResult(SpeedTestResult result)
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(indexId))
|
||||
if (Utils.IsNullOrEmpty(result.IndexId))
|
||||
{
|
||||
_noticeHandler?.SendMessage(delay, true);
|
||||
_noticeHandler?.Enqueue(delay);
|
||||
_noticeHandler?.SendMessage(result.Delay, true);
|
||||
_noticeHandler?.Enqueue(result.Delay);
|
||||
return;
|
||||
}
|
||||
var item = _profileItems.Where(it => it.indexId == indexId).FirstOrDefault();
|
||||
var item = _profileItems.Where(it => it.indexId == result.IndexId).FirstOrDefault();
|
||||
if (item != null)
|
||||
{
|
||||
if (!Utils.IsNullOrEmpty(delay))
|
||||
if (!Utils.IsNullOrEmpty(result.Delay))
|
||||
{
|
||||
int.TryParse(delay, out int temp);
|
||||
int.TryParse(result.Delay, out int temp);
|
||||
item.delay = temp;
|
||||
item.delayVal = $"{delay} {Global.DelayUnit}";
|
||||
item.delayVal = $"{result.Delay} {Global.DelayUnit}";
|
||||
}
|
||||
if (!Utils.IsNullOrEmpty(speed))
|
||||
if (!Utils.IsNullOrEmpty(result.Speed))
|
||||
{
|
||||
item.speedVal = $"{speed} {Global.SpeedUnit}";
|
||||
item.speedVal = $"{result.Speed} {Global.SpeedUnit}";
|
||||
}
|
||||
_profileItems.Replace(item, JsonUtils.DeepCopy(item));
|
||||
}
|
||||
|
@ -283,28 +279,25 @@ namespace v2rayN.ViewModels
|
|||
{
|
||||
try
|
||||
{
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
var item = _profileItems.Where(it => it.indexId == update.indexId).FirstOrDefault();
|
||||
if (item != null)
|
||||
{
|
||||
var item = _profileItems.Where(it => it.indexId == update.indexId).FirstOrDefault();
|
||||
if (item != null)
|
||||
{
|
||||
item.todayDown = Utils.HumanFy(update.todayDown);
|
||||
item.todayUp = Utils.HumanFy(update.todayUp);
|
||||
item.totalDown = Utils.HumanFy(update.totalDown);
|
||||
item.totalUp = Utils.HumanFy(update.totalUp);
|
||||
item.todayDown = Utils.HumanFy(update.todayDown);
|
||||
item.todayUp = Utils.HumanFy(update.todayUp);
|
||||
item.totalDown = Utils.HumanFy(update.totalDown);
|
||||
item.totalUp = Utils.HumanFy(update.totalUp);
|
||||
|
||||
if (SelectedProfile?.indexId == item.indexId)
|
||||
{
|
||||
var temp = JsonUtils.DeepCopy(item);
|
||||
_profileItems.Replace(item, temp);
|
||||
SelectedProfile = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
_profileItems.Replace(item, JsonUtils.DeepCopy(item));
|
||||
}
|
||||
if (SelectedProfile?.indexId == item.indexId)
|
||||
{
|
||||
var temp = JsonUtils.DeepCopy(item);
|
||||
_profileItems.Replace(item, temp);
|
||||
SelectedProfile = temp;
|
||||
}
|
||||
}));
|
||||
else
|
||||
{
|
||||
_profileItems.Replace(item, JsonUtils.DeepCopy(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -346,7 +339,7 @@ namespace v2rayN.ViewModels
|
|||
MessageBus.Current.SendMessage("", Global.CommandRefreshProfiles);
|
||||
}
|
||||
|
||||
private void RefreshServersBiz()
|
||||
public void RefreshServersBiz()
|
||||
{
|
||||
var lstModel = LazyConfig.Instance.ProfileItems(_config.subIndexId, _serverFilter);
|
||||
|
||||
|
@ -381,25 +374,22 @@ namespace v2rayN.ViewModels
|
|||
totalDown = t22 == null ? "" : Utils.HumanFy(t22.totalDown),
|
||||
totalUp = t22 == null ? "" : Utils.HumanFy(t22.totalUp)
|
||||
}).OrderBy(t => t.sort).ToList();
|
||||
_lstProfile = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(lstModel));
|
||||
_lstProfile = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(lstModel)) ?? [];
|
||||
|
||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||
_profileItems.Clear();
|
||||
_profileItems.AddRange(lstModel);
|
||||
if (lstModel.Count > 0)
|
||||
{
|
||||
_profileItems.Clear();
|
||||
_profileItems.AddRange(lstModel);
|
||||
if (lstModel.Count > 0)
|
||||
var selected = lstModel.FirstOrDefault(t => t.indexId == _config.indexId);
|
||||
if (selected != null)
|
||||
{
|
||||
var selected = lstModel.FirstOrDefault(t => t.indexId == _config.indexId);
|
||||
if (selected != null)
|
||||
{
|
||||
SelectedProfile = selected;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedProfile = lstModel[0];
|
||||
}
|
||||
SelectedProfile = selected;
|
||||
}
|
||||
}));
|
||||
else
|
||||
{
|
||||
SelectedProfile = lstModel[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshSubscriptions()
|
||||
|
|
|
@ -8,7 +8,6 @@ using v2rayN.Enums;
|
|||
using v2rayN.Handler;
|
||||
using v2rayN.Models;
|
||||
using v2rayN.Resx;
|
||||
using Application = System.Windows.Application;
|
||||
|
||||
namespace v2rayN.ViewModels
|
||||
{
|
||||
|
@ -76,9 +75,9 @@ namespace v2rayN.ViewModels
|
|||
{
|
||||
ImportRulesFromClipboard();
|
||||
});
|
||||
ImportRulesFromUrlCmd = ReactiveCommand.CreateFromTask(() =>
|
||||
ImportRulesFromUrlCmd = ReactiveCommand.Create(() =>
|
||||
{
|
||||
return ImportRulesFromUrl();
|
||||
ImportRulesFromUrl();
|
||||
});
|
||||
|
||||
RuleRemoveCmd = ReactiveCommand.Create(() =>
|
||||
|
@ -292,7 +291,7 @@ namespace v2rayN.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
private async Task ImportRulesFromUrl()
|
||||
private void ImportRulesFromUrl()
|
||||
{
|
||||
var url = SelectedRouting.url;
|
||||
if (Utils.IsNullOrEmpty(url))
|
||||
|
@ -302,13 +301,10 @@ namespace v2rayN.ViewModels
|
|||
}
|
||||
|
||||
DownloadHandle downloadHandle = new DownloadHandle();
|
||||
var result = await downloadHandle.TryDownloadString(url, true, "");
|
||||
var result = downloadHandle.TryDownloadString(url, true, "").Result;
|
||||
if (AddBatchRoutingRules(SelectedRouting, result) == 0)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke((Action)(() =>
|
||||
{
|
||||
RefreshRulesItems();
|
||||
}));
|
||||
RefreshRulesItems();
|
||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
using ReactiveUI;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
using v2rayN.Enums;
|
||||
using v2rayN.Models;
|
||||
using v2rayN.ViewModels;
|
||||
|
||||
namespace v2rayN.Views
|
||||
|
@ -12,7 +16,7 @@ namespace v2rayN.Views
|
|||
public ClashConnectionsView()
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = new ClashConnectionsViewModel();
|
||||
ViewModel = new ClashConnectionsViewModel(UpdateViewHandler);
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
|
@ -28,6 +32,22 @@ namespace v2rayN.Views
|
|||
});
|
||||
}
|
||||
|
||||
private bool UpdateViewHandler(EViewAction action, object? obj)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.DispatcherRefreshConnections:
|
||||
if (obj is null) return false;
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.RefreshConnections((List<ConnectionItem>?)obj);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void btnClose_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
ViewModel?.ClashConnectionClose(false);
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
using ReactiveUI;
|
||||
using Splat;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using v2rayN.Enums;
|
||||
using v2rayN.Models;
|
||||
using v2rayN.ViewModels;
|
||||
|
||||
namespace v2rayN.Views
|
||||
|
@ -14,7 +18,7 @@ namespace v2rayN.Views
|
|||
public ClashProxiesView()
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = new ClashProxiesViewModel();
|
||||
ViewModel = new ClashProxiesViewModel(UpdateViewHandler);
|
||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(ClashProxiesViewModel));
|
||||
lstProxyDetails.PreviewMouseDoubleClick += lstProxyDetails_PreviewMouseDoubleClick;
|
||||
|
||||
|
@ -38,6 +42,30 @@ namespace v2rayN.Views
|
|||
});
|
||||
}
|
||||
|
||||
private bool UpdateViewHandler(EViewAction action, object? obj)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case EViewAction.DispatcherRefreshProxyGroups:
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.RefreshProxyGroups();
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherProxiesDelayTest:
|
||||
|
||||
if (obj is null) return false;
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.ProxiesDelayTestResult((SpeedTestResult)obj);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ProxiesView_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
switch (e.Key)
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Windows.Controls;
|
|||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using v2rayN.Enums;
|
||||
using v2rayN.Handler;
|
||||
using v2rayN.Models;
|
||||
|
@ -184,35 +185,67 @@ namespace v2rayN.Views
|
|||
|
||||
private bool UpdateViewHandler(EViewAction action, object? obj)
|
||||
{
|
||||
if (action == EViewAction.AddServerWindow)
|
||||
switch (action)
|
||||
{
|
||||
if (obj is null) return false;
|
||||
return (new AddServerWindow((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
}
|
||||
else if (action == EViewAction.AddServer2Window)
|
||||
{
|
||||
if (obj is null) return false;
|
||||
return (new AddServer2Window((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
}
|
||||
else if (action == EViewAction.DNSSettingWindow)
|
||||
{
|
||||
return (new DNSSettingWindow().ShowDialog() ?? false);
|
||||
}
|
||||
else if (action == EViewAction.RoutingSettingWindow)
|
||||
{
|
||||
return (new RoutingSettingWindow().ShowDialog() ?? false);
|
||||
}
|
||||
else if (action == EViewAction.OptionSettingWindow)
|
||||
{
|
||||
return (new OptionSettingWindow().ShowDialog() ?? false);
|
||||
}
|
||||
else if (action == EViewAction.GlobalHotkeySettingWindow)
|
||||
{
|
||||
return (new GlobalHotkeySettingWindow().ShowDialog() ?? false);
|
||||
}
|
||||
else if (action == EViewAction.SubSettingWindow)
|
||||
{
|
||||
return (new SubSettingWindow().ShowDialog() ?? false);
|
||||
case EViewAction.AddServerWindow:
|
||||
if (obj is null) return false;
|
||||
return (new AddServerWindow((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.AddServer2Window:
|
||||
if (obj is null) return false;
|
||||
return (new AddServer2Window((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.DNSSettingWindow:
|
||||
return (new DNSSettingWindow().ShowDialog() ?? false);
|
||||
|
||||
case EViewAction.RoutingSettingWindow:
|
||||
return (new RoutingSettingWindow().ShowDialog() ?? false);
|
||||
|
||||
case EViewAction.OptionSettingWindow:
|
||||
return (new OptionSettingWindow().ShowDialog() ?? false);
|
||||
|
||||
case EViewAction.GlobalHotkeySettingWindow:
|
||||
return (new GlobalHotkeySettingWindow().ShowDialog() ?? false);
|
||||
|
||||
case EViewAction.SubSettingWindow:
|
||||
return (new SubSettingWindow().ShowDialog() ?? false);
|
||||
|
||||
case EViewAction.ShowHideWindow:
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ShowHideWindow((bool?)obj);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherStatistics:
|
||||
if (obj is null) return false;
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.SetStatisticsResult((ServerSpeedItem)obj);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherServerAvailability:
|
||||
if (obj is null) return false;
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.TestServerAvailabilityResult((string)obj);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherReload:
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.ReloadResult();
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherRefreshServersBiz:
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.RefreshServersBiz();
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -223,7 +256,7 @@ namespace v2rayN.Views
|
|||
private void MainWindow_Closing(object? sender, CancelEventArgs e)
|
||||
{
|
||||
e.Cancel = true;
|
||||
ViewModel?.ShowHideWindow(false);
|
||||
ShowHideWindow(false);
|
||||
}
|
||||
|
||||
private void menuExit_Click(object sender, RoutedEventArgs e)
|
||||
|
@ -269,7 +302,7 @@ namespace v2rayN.Views
|
|||
private void menuClose_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
StorageUI();
|
||||
ViewModel?.ShowHideWindow(false);
|
||||
ShowHideWindow(false);
|
||||
}
|
||||
|
||||
private void menuPromotion_Click(object sender, RoutedEventArgs e)
|
||||
|
@ -291,6 +324,26 @@ namespace v2rayN.Views
|
|||
|
||||
#region UI
|
||||
|
||||
public void ShowHideWindow(bool? blShow)
|
||||
{
|
||||
var bl = blShow ?? !_config.uiItem.showInTaskbar;
|
||||
if (bl)
|
||||
{
|
||||
Application.Current.MainWindow.Show();
|
||||
if (Application.Current.MainWindow.WindowState == WindowState.Minimized)
|
||||
{
|
||||
Application.Current.MainWindow.WindowState = WindowState.Normal;
|
||||
}
|
||||
Application.Current.MainWindow.Activate();
|
||||
Application.Current.MainWindow.Focus();
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.Current.MainWindow.Hide();
|
||||
}
|
||||
_config.uiItem.showInTaskbar = bl;
|
||||
}
|
||||
|
||||
private void RestoreUI()
|
||||
{
|
||||
if (_config.uiItem.mainWidth > 0 && _config.uiItem.mainHeight > 0)
|
||||
|
|
|
@ -7,6 +7,7 @@ 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.Enums;
|
||||
using v2rayN.Handler;
|
||||
|
@ -89,6 +90,7 @@ namespace v2rayN.Views
|
|||
});
|
||||
|
||||
RestoreUI();
|
||||
ViewModel?.RefreshServers();
|
||||
}
|
||||
|
||||
#region Event
|
||||
|
@ -100,36 +102,50 @@ namespace v2rayN.Views
|
|||
|
||||
private bool UpdateViewHandler(EViewAction action, object? obj)
|
||||
{
|
||||
if (action == EViewAction.ProfilesFocus)
|
||||
switch (action)
|
||||
{
|
||||
lstProfiles.Focus();
|
||||
}
|
||||
else if (action == EViewAction.ShowYesNo)
|
||||
{
|
||||
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (action == EViewAction.AddServerWindow)
|
||||
{
|
||||
if (obj is null) return false;
|
||||
return (new AddServerWindow((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
}
|
||||
else if (action == EViewAction.AddServer2Window)
|
||||
{
|
||||
if (obj is null) return false;
|
||||
return (new AddServer2Window((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
}
|
||||
else if (action == EViewAction.ShareServer)
|
||||
{
|
||||
if (obj is null) return false;
|
||||
ShareServer((string)obj);
|
||||
}
|
||||
else if (action == EViewAction.SubEditWindow)
|
||||
{
|
||||
if (obj is null) return false;
|
||||
return (new SubEditWindow((SubItem)obj)).ShowDialog() ?? false;
|
||||
case EViewAction.ProfilesFocus:
|
||||
lstProfiles.Focus();
|
||||
break;
|
||||
|
||||
case EViewAction.ShowYesNo:
|
||||
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case EViewAction.AddServerWindow:
|
||||
if (obj is null) return false;
|
||||
return (new AddServerWindow((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.AddServer2Window:
|
||||
if (obj is null) return false;
|
||||
return (new AddServer2Window((ProfileItem)obj)).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.ShareServer:
|
||||
if (obj is null) return false;
|
||||
ShareServer((string)obj);
|
||||
break;
|
||||
|
||||
case EViewAction.SubEditWindow:
|
||||
if (obj is null) return false;
|
||||
return (new SubEditWindow((SubItem)obj)).ShowDialog() ?? false;
|
||||
|
||||
case EViewAction.DispatcherSpeedTest:
|
||||
if (obj is null) return false;
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.SetSpeedTestResult((SpeedTestResult)obj);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherRefreshServersBiz:
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
ViewModel?.RefreshServersBiz();
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue