Compare commits

..

No commits in common. "e3a63db96687401dc1d647a805e073fe04c53760" and "058c6e4a85ff03aefe908b2e1b65942407b3a139" have entirely different histories.

26 changed files with 262 additions and 128 deletions

View file

@ -6,6 +6,7 @@ public enum EViewAction
ShowYesNo,
SaveFileDialog,
AddBatchRoutingRulesYesNo,
AdjustMainLvColWidth,
SetClipboardData,
AddServerViaClipboard,
ImportRulesFromClipboard,
@ -31,7 +32,16 @@ public enum EViewAction
FullConfigTemplateWindow,
GlobalHotkeySettingWindow,
SubSettingWindow,
DispatcherSpeedTest,
DispatcherRefreshConnections,
DispatcherRefreshProxyGroups,
DispatcherProxiesDelayTest,
DispatcherStatistics,
DispatcherServerAvailability,
DispatcherReload,
DispatcherRefreshServersBiz,
DispatcherRefreshIcon,
DispatcherCheckUpdate,
DispatcherCheckUpdateFinished,
DispatcherShowMsg,
}

View file

@ -12,8 +12,4 @@ public static class AppEvents
public static readonly Subject<string> SendMsgViewRequested = new();
public static readonly Subject<Unit> AppExitRequested = new();
public static readonly Subject<Unit> AdjustMainLvColWidthRequested = new();
public static readonly Subject<ServerSpeedItem> DispatcherStatisticsRequested = new();
}

View file

@ -125,15 +125,15 @@ public sealed class CoreInfoManager
new CoreInfo
{
CoreType = ECoreType.mihomo,
CoreExes = ["mihomo-windows-amd64-v1", "mihomo-windows-amd64-compatible", "mihomo-windows-amd64", "mihomo-linux-amd64", "clash", "mihomo"],
CoreExes = ["mihomo-windows-amd64-compatible", "mihomo-windows-amd64", "mihomo-linux-amd64", "clash", "mihomo"],
Arguments = "-f {0}" + PortableMode(),
Url = GetCoreUrl(ECoreType.mihomo),
ReleaseApiUrl = urlMihomo.Replace(Global.GithubUrl, Global.GithubApiUrl),
DownloadUrlWin64 = urlMihomo + "/download/{0}/mihomo-windows-amd64-v1-{0}.zip",
DownloadUrlWin64 = urlMihomo + "/download/{0}/mihomo-windows-amd64-compatible-{0}.zip",
DownloadUrlWinArm64 = urlMihomo + "/download/{0}/mihomo-windows-arm64-{0}.zip",
DownloadUrlLinux64 = urlMihomo + "/download/{0}/mihomo-linux-amd64-v1-{0}.gz",
DownloadUrlLinux64 = urlMihomo + "/download/{0}/mihomo-linux-amd64-compatible-{0}.gz",
DownloadUrlLinuxArm64 = urlMihomo + "/download/{0}/mihomo-linux-arm64-{0}.gz",
DownloadUrlOSX64 = urlMihomo + "/download/{0}/mihomo-darwin-amd64-v1-{0}.gz",
DownloadUrlOSX64 = urlMihomo + "/download/{0}/mihomo-darwin-amd64-compatible-{0}.gz",
DownloadUrlOSXArm64 = urlMihomo + "/download/{0}/mihomo-darwin-arm64-{0}.gz",
Match = "Mihomo",
VersionArg = "-v",

View file

@ -1,6 +1,4 @@
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Runtime.InteropServices;
using DynamicData;
using DynamicData.Binding;
@ -190,7 +188,7 @@ public class CheckUpdateViewModel : MyReactiveObject
{
if (_lstUpdated.Count > 0 && _lstUpdated.Count(x => x.IsFinished == true) == _lstUpdated.Count)
{
await UpdateFinishedSub(false);
_updateView?.Invoke(EViewAction.DispatcherCheckUpdateFinished, false);
await Task.Delay(2000);
await UpgradeCore();
@ -200,20 +198,11 @@ public class CheckUpdateViewModel : MyReactiveObject
await UpgradeN();
}
await Task.Delay(1000);
await UpdateFinishedSub(true);
_updateView?.Invoke(EViewAction.DispatcherCheckUpdateFinished, true);
}
}
private async Task UpdateFinishedSub(bool blReload)
{
RxApp.MainThreadScheduler.Schedule(blReload, (scheduler, blReload) =>
{
_ = UpdateFinishedResult(blReload);
return Disposable.Empty;
});
}
public async Task UpdateFinishedResult(bool blReload)
public void UpdateFinishedResult(bool blReload)
{
if (blReload)
{
@ -310,15 +299,10 @@ public class CheckUpdateViewModel : MyReactiveObject
CoreType = coreType,
Remarks = msg,
};
RxApp.MainThreadScheduler.Schedule(item, (scheduler, model) =>
{
_ = UpdateViewResult(model);
return Disposable.Empty;
});
await _updateView?.Invoke(EViewAction.DispatcherCheckUpdate, item);
}
public async Task UpdateViewResult(CheckUpdateModel model)
public void UpdateViewResult(CheckUpdateModel model)
{
var found = _checkUpdateModel.FirstOrDefault(t => t.CoreType == model.CoreType);
if (found == null)

View file

@ -1,5 +1,4 @@
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using DynamicData;
using DynamicData.Binding;
@ -65,14 +64,10 @@ public class ClashConnectionsViewModel : MyReactiveObject
return;
}
RxApp.MainThreadScheduler.Schedule(ret?.connections, (scheduler, model) =>
{
_ = RefreshConnections(model);
return Disposable.Empty;
});
_ = _updateView?.Invoke(EViewAction.DispatcherRefreshConnections, ret?.connections);
}
public async Task RefreshConnections(List<ConnectionItem>? connections)
public void RefreshConnections(List<ConnectionItem>? connections)
{
_connectionItems.Clear();

View file

@ -1,6 +1,4 @@
using System.Reactive;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using DynamicData;
using DynamicData.Binding;
@ -170,11 +168,11 @@ public class ClashProxiesViewModel : MyReactiveObject
if (refreshUI)
{
RxApp.MainThreadScheduler.Schedule(() => _ = RefreshProxyGroups());
_updateView?.Invoke(EViewAction.DispatcherRefreshProxyGroups, null);
}
}
public async Task RefreshProxyGroups()
public void RefreshProxyGroups()
{
if (_proxies == null)
{
@ -382,17 +380,12 @@ public class ClashProxiesViewModel : MyReactiveObject
return;
}
var model = new SpeedTestResult() { IndexId = item.Name, Delay = result };
RxApp.MainThreadScheduler.Schedule(model, (scheduler, model) =>
{
_ = ProxiesDelayTestResult(model);
return Disposable.Empty;
});
await _updateView?.Invoke(EViewAction.DispatcherProxiesDelayTest, new SpeedTestResult() { IndexId = item.Name, Delay = result });
});
await Task.CompletedTask;
}
public async Task ProxiesDelayTestResult(SpeedTestResult result)
public void ProxiesDelayTestResult(SpeedTestResult result)
{
//UpdateHandler(false, $"{item.name}={result}");
var detail = _proxyDetails.FirstOrDefault(it => it.Name == result.IndexId);

View file

@ -1,5 +1,4 @@
using System.Reactive;
using System.Reactive.Concurrency;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
@ -268,7 +267,7 @@ public class MainWindowViewModel : MyReactiveObject
}
if (_config.UiItem.EnableAutoAdjustMainLvColWidth)
{
AppEvents.AdjustMainLvColWidthRequested.OnNext(Unit.Default);
_updateView?.Invoke(EViewAction.AdjustMainLvColWidth, null);
}
}
}
@ -279,7 +278,19 @@ public class MainWindowViewModel : MyReactiveObject
{
return;
}
AppEvents.DispatcherStatisticsRequested.OnNext(update);
await _updateView?.Invoke(EViewAction.DispatcherStatistics, update);
}
public void SetStatisticsResult(ServerSpeedItem update)
{
if (_config.GuiItem.DisplayRealTimeSpeed)
{
Locator.Current.GetService<StatusBarViewModel>()?.UpdateStatistics(update);
}
if (_config.GuiItem.EnableStatistics && (update.ProxyUp + update.ProxyDown) > 0 && DateTime.Now.Second % 9 == 0)
{
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
}
}
public async Task MyAppExitAsync(bool blWindowsShutDown)
@ -567,7 +578,7 @@ public class MainWindowViewModel : MyReactiveObject
});
Locator.Current.GetService<StatusBarViewModel>()?.TestServerAvailability();
RxApp.MainThreadScheduler.Schedule(() => _ = ReloadResult());
_updateView?.Invoke(EViewAction.DispatcherReload, null);
BlReloadEnabled = true;
if (_hasNextReloadJob)
@ -577,7 +588,7 @@ public class MainWindowViewModel : MyReactiveObject
}
}
public async Task ReloadResult()
public void ReloadResult()
{
// BlReloadEnabled = true;
//Locator.Current.GetService<StatusBarViewModel>()?.ChangeSystemProxyAsync(_config.systemProxyItem.sysProxyType, false);

View file

@ -1,5 +1,4 @@
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Text;
using DynamicData;
@ -248,19 +247,13 @@ public class ProfilesViewModel : MyReactiveObject
#endregion WhenAnyValue && ReactiveCommand
#region AppEvents
AppEvents.ProfilesRefreshRequested
if (_updateView != null)
{
AppEvents.ProfilesRefreshRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async _ => await RefreshServersBiz());
AppEvents.DispatcherStatisticsRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async result => await UpdateStatistics(result));
#endregion AppEvents
.Subscribe(async _ => await RefreshServersBiz());//.DisposeWith(_disposables);
}
_ = Init();
}
@ -285,7 +278,7 @@ public class ProfilesViewModel : MyReactiveObject
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
}
public async Task SetSpeedTestResult(SpeedTestResult result)
public void SetSpeedTestResult(SpeedTestResult result)
{
if (result.IndexId.IsNullOrEmpty())
{
@ -312,15 +305,8 @@ public class ProfilesViewModel : MyReactiveObject
//_profileItems.Replace(item, JsonUtils.DeepCopy(item));
}
public async Task UpdateStatistics(ServerSpeedItem update)
public void UpdateStatistics(ServerSpeedItem update)
{
if (!_config.GuiItem.EnableStatistics
|| (update.ProxyUp + update.ProxyDown) <= 0
|| DateTime.Now.Second % 3 != 0)
{
return;
}
try
{
var item = _profileItems.FirstOrDefault(it => it.IndexId == update.IndexId);
@ -348,6 +334,11 @@ public class ProfilesViewModel : MyReactiveObject
}
}
public async Task AutofitColumnWidthAsync()
{
await _updateView?.Invoke(EViewAction.AdjustMainLvColWidth, null);
}
#endregion Actions
#region Servers && Groups
@ -762,14 +753,7 @@ public class ProfilesViewModel : MyReactiveObject
return;
}
_speedtestService ??= new SpeedtestService(_config, async (SpeedTestResult result) =>
{
RxApp.MainThreadScheduler.Schedule(result, (scheduler, result) =>
{
_ = SetSpeedTestResult(result);
return Disposable.Empty;
});
});
_speedtestService ??= new SpeedtestService(_config, (SpeedTestResult result) => _updateView?.Invoke(EViewAction.DispatcherSpeedTest, result));
_speedtestService?.RunLoop(actionType, lstSelected);
}

View file

@ -1,5 +1,4 @@
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Text;
using DynamicData.Binding;
@ -199,20 +198,10 @@ public class StatusBarViewModel : MyReactiveObject
#endregion WhenAnyValue && ReactiveCommand
#region AppEvents
if (updateView != null)
{
InitUpdateView(updateView);
}
AppEvents.DispatcherStatisticsRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async result => await UpdateStatistics(result));
#endregion AppEvents
_ = Init();
}
@ -342,24 +331,15 @@ public class StatusBarViewModel : MyReactiveObject
return;
}
await TestServerAvailabilitySub(ResUI.Speedtesting);
_updateView?.Invoke(EViewAction.DispatcherServerAvailability, ResUI.Speedtesting);
var msg = await Task.Run(ConnectionHandler.RunAvailabilityCheck);
NoticeManager.Instance.SendMessageEx(msg);
await TestServerAvailabilitySub(msg);
_updateView?.Invoke(EViewAction.DispatcherServerAvailability, msg);
}
private async Task TestServerAvailabilitySub(string msg)
{
RxApp.MainThreadScheduler.Schedule(msg, (scheduler, msg) =>
{
_ = TestServerAvailabilityResult(msg);
return Disposable.Empty;
});
}
public async Task TestServerAvailabilityResult(string msg)
public void TestServerAvailabilityResult(string msg)
{
RunningInfoDisplay = msg;
}
@ -528,13 +508,8 @@ public class StatusBarViewModel : MyReactiveObject
await Task.CompletedTask;
}
public async Task UpdateStatistics(ServerSpeedItem update)
public void UpdateStatistics(ServerSpeedItem update)
{
if (!_config.GuiItem.DisplayRealTimeSpeed)
{
return;
}
try
{
if (_config.IsRunningCore(ECoreType.sing_box))

View file

@ -1,5 +1,6 @@
using System.Reactive.Disposables;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
using ReactiveUI;
namespace v2rayN.Desktop.Views;
@ -23,6 +24,25 @@ public partial class CheckUpdateView : ReactiveUserControl<CheckUpdateViewModel>
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
{
switch (action)
{
case EViewAction.DispatcherCheckUpdate:
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.UpdateViewResult((CheckUpdateModel)obj),
DispatcherPriority.Default);
break;
case EViewAction.DispatcherCheckUpdateFinished:
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.UpdateFinishedResult((bool)obj),
DispatcherPriority.Default);
break;
}
return await Task.FromResult(true);
}
}

View file

@ -2,6 +2,7 @@ using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
using ReactiveUI;
namespace v2rayN.Desktop.Views;
@ -30,6 +31,17 @@ public partial class ClashConnectionsView : ReactiveUserControl<ClashConnections
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
{
switch (action)
{
case EViewAction.DispatcherRefreshConnections:
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.RefreshConnections((List<ConnectionItem>?)obj),
DispatcherPriority.Default);
break;
}
return await Task.FromResult(true);
}

View file

@ -1,6 +1,7 @@
using System.Reactive.Disposables;
using Avalonia.Input;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
using DynamicData;
using ReactiveUI;
using Splat;
@ -39,6 +40,23 @@ public partial class ClashProxiesView : ReactiveUserControl<ClashProxiesViewMode
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
{
switch (action)
{
case EViewAction.DispatcherRefreshProxyGroups:
Dispatcher.UIThread.Post(() =>
ViewModel?.RefreshProxyGroups(),
DispatcherPriority.Default);
break;
case EViewAction.DispatcherProxiesDelayTest:
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.ProxiesDelayTestResult((SpeedTestResult)obj),
DispatcherPriority.Default);
break;
}
return await Task.FromResult(true);
}

View file

@ -50,7 +50,6 @@ public partial class FullConfigTemplateWindow : WindowBase<FullConfigTemplateVie
{
ProcUtils.ProcessStart("https://github.com/2dust/v2rayN/wiki/Description-of-some-ui#%E5%AE%8C%E6%95%B4%E9%85%8D%E7%BD%AE%E6%A8%A1%E6%9D%BF%E8%AE%BE%E7%BD%AE");
}
private void Window_Loaded(object? sender, RoutedEventArgs e)
{
btnCancel.Focus();

View file

@ -135,7 +135,6 @@ public partial class GlobalHotkeySettingWindow : WindowBase<GlobalHotkeySettingV
return res.ToString();
}
private void Window_Loaded(object? sender, RoutedEventArgs e)
{
btnCancel.Focus();

View file

@ -222,6 +222,20 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
DispatcherPriority.Default);
break;
case EViewAction.DispatcherStatistics:
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.SetStatisticsResult((ServerSpeedItem)obj),
DispatcherPriority.Default);
break;
case EViewAction.DispatcherReload:
Dispatcher.UIThread.Post(() =>
ViewModel?.ReloadResult(),
DispatcherPriority.Default);
break;
case EViewAction.Shutdown:
if (obj != null && _blCloseByUser == false)
{
@ -250,6 +264,12 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
await ViewModel.AddServerViaClipboardAsync(clipboardData);
}
break;
case EViewAction.AdjustMainLvColWidth:
Dispatcher.UIThread.Post(() =>
Locator.Current.GetService<ProfilesViewModel>()?.AutofitColumnWidthAsync(),
DispatcherPriority.Default);
break;
}
return await Task.FromResult(true);

View file

@ -211,7 +211,6 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
ViewModel.destOverride = clbdestOverride.SelectedItems.Cast<string>().ToList();
}
}
private void Window_Loaded(object? sender, RoutedEventArgs e)
{
btnCancel.Focus();

View file

@ -103,12 +103,6 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => StorageUI())
.DisposeWith(disposables);
AppEvents.AdjustMainLvColWidthRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => AutofitColumnWidth())
.DisposeWith(disposables);
});
RestoreUI();
@ -139,6 +133,13 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
await AvaUtils.SetClipboardData(this, (string)obj);
break;
case EViewAction.AdjustMainLvColWidth:
Dispatcher.UIThread.Post(() =>
AutofitColumnWidth(),
DispatcherPriority.Default);
break;
case EViewAction.ProfilesFocus:
lstProfiles.Focus();
break;
@ -182,6 +183,15 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
return false;
return await new SubEditWindow((SubItem)obj).ShowDialog<bool>(_window);
case EViewAction.DispatcherSpeedTest:
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.SetSpeedTestResult((SpeedTestResult)obj),
DispatcherPriority.Default);
break;
case EViewAction.DispatcherRefreshServersBiz:
Dispatcher.UIThread.Post(RefreshServersBiz, DispatcherPriority.Default);
break;

View file

@ -135,7 +135,6 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
}
}
}
private void Window_Loaded(object? sender, RoutedEventArgs e)
{
btnCancel.Focus();

View file

@ -56,6 +56,15 @@ public partial class StatusBarView : ReactiveUserControl<StatusBarViewModel>
{
switch (action)
{
case EViewAction.DispatcherServerAvailability:
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.TestServerAvailabilityResult((string)obj),
DispatcherPriority.Default);
break;
case EViewAction.DispatcherRefreshIcon:
Dispatcher.UIThread.Post(() =>
{

View file

@ -117,7 +117,6 @@ public partial class SubSettingWindow : WindowBase<SubSettingViewModel>
menuClose_Click(null, null);
}
}
private void Window_Loaded(object? sender, RoutedEventArgs e)
{
lstSubscription.Focus();

View file

@ -1,4 +1,6 @@
using System.Reactive.Disposables;
using System.Windows;
using System.Windows.Threading;
using ReactiveUI;
namespace v2rayN.Views;
@ -22,6 +24,27 @@ public partial class CheckUpdateView
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
{
switch (action)
{
case EViewAction.DispatcherCheckUpdate:
if (obj is null)
return false;
Application.Current?.Dispatcher.Invoke((() =>
{
ViewModel?.UpdateViewResult((CheckUpdateModel)obj);
}), DispatcherPriority.Normal);
break;
case EViewAction.DispatcherCheckUpdateFinished:
if (obj is null)
return false;
Application.Current?.Dispatcher.Invoke((() =>
{
ViewModel?.UpdateFinishedResult((bool)obj);
}), DispatcherPriority.Normal);
break;
}
return await Task.FromResult(true);
}
}

View file

@ -1,6 +1,7 @@
using System.Reactive.Disposables;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using ReactiveUI;
namespace v2rayN.Views;
@ -32,6 +33,18 @@ public partial class ClashConnectionsView
private async Task<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 await Task.FromResult(true);
}

View file

@ -1,5 +1,7 @@
using System.Reactive.Disposables;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using ReactiveUI;
using Splat;
@ -39,6 +41,26 @@ public partial class ClashProxiesView
private async Task<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 await Task.FromResult(true);
}

View file

@ -212,6 +212,22 @@ public partial class MainWindow
}), 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.DispatcherReload:
Application.Current?.Dispatcher.Invoke((() =>
{
ViewModel?.ReloadResult();
}), DispatcherPriority.Normal);
break;
case EViewAction.Shutdown:
Application.Current?.Dispatcher.Invoke((() =>
{
@ -234,6 +250,13 @@ public partial class MainWindow
ViewModel?.AddServerViaClipboardAsync(clipboardData);
}
break;
case EViewAction.AdjustMainLvColWidth:
Application.Current?.Dispatcher.Invoke((() =>
{
Locator.Current.GetService<ProfilesViewModel>()?.AutofitColumnWidthAsync();
}), DispatcherPriority.Normal);
break;
}
return await Task.FromResult(true);

View file

@ -97,12 +97,6 @@ public partial class ProfilesView
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => StorageUI())
.DisposeWith(disposables);
AppEvents.AdjustMainLvColWidthRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => AutofitColumnWidth())
.DisposeWith(disposables);
});
RestoreUI();
@ -119,7 +113,14 @@ public partial class ProfilesView
if (obj is null)
return false;
WindowsUtils.SetClipboardData((string)obj);
break;
break;
case EViewAction.AdjustMainLvColWidth:
Application.Current?.Dispatcher.Invoke((() =>
{
AutofitColumnWidth();
}), DispatcherPriority.Normal);
break;
case EViewAction.ProfilesFocus:
lstProfiles.Focus();
@ -163,6 +164,15 @@ public partial class ProfilesView
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(RefreshServersBiz, DispatcherPriority.Normal);
break;

View file

@ -77,6 +77,17 @@ public partial class StatusBarView
{
switch (action)
{
case EViewAction.DispatcherServerAvailability:
if (obj is null)
return false;
Application.Current?.Dispatcher.Invoke((() =>
{
ViewModel?.TestServerAvailabilityResult((string)obj);
}), DispatcherPriority.Normal);
break;
case EViewAction.DispatcherRefreshIcon:
Application.Current?.Dispatcher.Invoke((async () =>
{