Use Rx event subscription instead of MessageBus to send information
Some checks are pending
release Linux / build (Release) (push) Waiting to run
release macOS / build (Release) (push) Waiting to run
release Windows desktop (Avalonia UI) / build (Release) (push) Waiting to run
release Windows / build (Release) (push) Waiting to run

This commit is contained in:
2dust 2025-08-29 15:46:09 +08:00
parent ea1d438e40
commit 058c6e4a85
9 changed files with 62 additions and 39 deletions

View file

@ -1,9 +0,0 @@
namespace ServiceLib.Enums;
public enum EMsgCommand
{
ClearMsg,
SendMsgView,
SendSnackMsg,
AppExit
}

View file

@ -6,4 +6,10 @@ namespace ServiceLib.Handler;
public static class AppEvents public static class AppEvents
{ {
public static readonly Subject<Unit> ProfilesRefreshRequested = new(); public static readonly Subject<Unit> ProfilesRefreshRequested = new();
public static readonly Subject<string> SendSnackMsgRequested = new();
public static readonly Subject<string> SendMsgViewRequested = new();
public static readonly Subject<Unit> AppExitRequested = new();
} }

View file

@ -1,5 +1,3 @@
using ReactiveUI;
namespace ServiceLib.Manager; namespace ServiceLib.Manager;
public class NoticeManager public class NoticeManager
@ -13,7 +11,7 @@ public class NoticeManager
{ {
return; return;
} }
MessageBus.Current.SendMessage(content, EMsgCommand.SendSnackMsg.ToString()); AppEvents.SendSnackMsgRequested.OnNext(content);
} }
public void SendMessage(string? content) public void SendMessage(string? content)
@ -22,7 +20,7 @@ public class NoticeManager
{ {
return; return;
} }
MessageBus.Current.SendMessage(content, EMsgCommand.SendMsgView.ToString()); AppEvents.SendMsgViewRequested.OnNext(content);
} }
public void SendMessageEx(string? content) public void SendMessageEx(string? content)

View file

@ -300,7 +300,7 @@ public class MainWindowViewModel : MyReactiveObject
Logging.SaveLog("MyAppExitAsync Begin"); Logging.SaveLog("MyAppExitAsync Begin");
await SysProxyHandler.UpdateSysProxy(_config, true); await SysProxyHandler.UpdateSysProxy(_config, true);
MessageBus.Current.SendMessage("", EMsgCommand.AppExit.ToString()); AppEvents.AppExitRequested.OnNext(Unit.Default);
await ConfigHandler.SaveConfig(_config); await ConfigHandler.SaveConfig(_config);
await ProfileExManager.Instance.SaveTo(); await ProfileExManager.Instance.SaveTo();

View file

@ -1,4 +1,5 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Reactive.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
@ -34,12 +35,10 @@ public class MsgViewModel : MyReactiveObject
y => y == true) y => y == true)
.Subscribe(c => { _config.MsgUIItem.AutoRefresh = AutoRefresh; }); .Subscribe(c => { _config.MsgUIItem.AutoRefresh = AutoRefresh; });
MessageBus.Current.Listen<string>(EMsgCommand.SendMsgView.ToString()).Subscribe(OnNext); AppEvents.SendMsgViewRequested
} .AsObservable()
//.ObserveOn(RxApp.MainThreadScheduler)
private async void OnNext(string x) .Subscribe(async content => await AppendQueueMsg(content));
{
await AppendQueueMsg(x);
} }
private async Task AppendQueueMsg(string msg) private async Task AppendQueueMsg(string msg)

View file

@ -1,4 +1,5 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Reactive.Linq;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
@ -39,7 +40,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
menuBackupAndRestore.Click += MenuBackupAndRestore_Click; menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
menuClose.Click += MenuClose_Click; menuClose.Click += MenuClose_Click;
MessageBus.Current.Listen<string>(EMsgCommand.SendSnackMsg.ToString()).Subscribe(DelegateSnackMsg);
ViewModel = new MainWindowViewModel(UpdateViewHandler); ViewModel = new MainWindowViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel)); Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
@ -136,6 +136,18 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain2.SelectedIndex).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain2.SelectedIndex).DisposeWith(disposables);
break; break;
} }
AppEvents.SendSnackMsgRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async content => await DelegateSnackMsg(content))
.DisposeWith(disposables);
AppEvents.AppExitRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => StorageUI())
.DisposeWith(disposables);
}); });
if (Utils.IsWindows()) if (Utils.IsWindows())
@ -156,7 +168,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
menuAddServerViaScan.IsVisible = false; menuAddServerViaScan.IsVisible = false;
AddHelpMenuItem(); AddHelpMenuItem();
MessageBus.Current.Listen<string>(EMsgCommand.AppExit.ToString()).Subscribe(StorageUI);
} }
#region Event #region Event
@ -168,11 +179,9 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
DispatcherPriority.Default); DispatcherPriority.Default);
} }
private void DelegateSnackMsg(string content) private async Task DelegateSnackMsg(string content)
{ {
Dispatcher.UIThread.Post(() => _manager?.Show(new Notification(null, content, NotificationType.Information));
_manager?.Show(new Notification(null, content, NotificationType.Information)),
DispatcherPriority.Normal);
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
@ -462,7 +471,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
} }
} }
private void StorageUI(string? n = null) private void StorageUI()
{ {
ConfigHandler.SaveWindowSizeItem(_config, GetType().Name, Width, Height); ConfigHandler.SaveWindowSizeItem(_config, GetType().Name, Width, Height);

View file

@ -1,4 +1,5 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Reactive.Linq;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
@ -96,11 +97,16 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
this.BindCommand(ViewModel, vm => vm.Export2ClientConfigClipboardCmd, v => v.menuExport2ClientConfigClipboard).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.Export2ClientConfigClipboardCmd, v => v.menuExport2ClientConfigClipboard).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.Export2ShareUrlCmd, v => v.menuExport2ShareUrl).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.Export2ShareUrlCmd, v => v.menuExport2ShareUrl).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.Export2ShareUrlBase64Cmd, v => v.menuExport2ShareUrlBase64).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.Export2ShareUrlBase64Cmd, v => v.menuExport2ShareUrlBase64).DisposeWith(disposables);
AppEvents.AppExitRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => StorageUI())
.DisposeWith(disposables);
}); });
RestoreUI(); RestoreUI();
ViewModel?.RefreshServers(); ViewModel?.RefreshServers();
MessageBus.Current.Listen<string>(EMsgCommand.AppExit.ToString()).Subscribe(StorageUI);
} }
private async void LstProfiles_Sorting(object? sender, DataGridColumnEventArgs e) private async void LstProfiles_Sorting(object? sender, DataGridColumnEventArgs e)
@ -412,7 +418,7 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
} }
} }
private void StorageUI(string? n = null) private void StorageUI()
{ {
List<ColumnItem> lvColumnItem = new(); List<ColumnItem> lvColumnItem = new();
foreach (var item2 in lstProfiles.Columns) foreach (var item2 in lstProfiles.Columns)

View file

@ -1,5 +1,6 @@
using System.ComponentModel; using System.ComponentModel;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
@ -36,7 +37,6 @@ public partial class MainWindow
menuCheckUpdate.Click += MenuCheckUpdate_Click; menuCheckUpdate.Click += MenuCheckUpdate_Click;
menuBackupAndRestore.Click += MenuBackupAndRestore_Click; menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
MessageBus.Current.Listen<string>(EMsgCommand.SendSnackMsg.ToString()).Subscribe(DelegateSnackMsg);
ViewModel = new MainWindowViewModel(UpdateViewHandler); ViewModel = new MainWindowViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel)); Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
@ -133,6 +133,18 @@ public partial class MainWindow
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain2.SelectedIndex).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain2.SelectedIndex).DisposeWith(disposables);
break; break;
} }
AppEvents.SendSnackMsgRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async content => await DelegateSnackMsg(content))
.DisposeWith(disposables);
AppEvents.AppExitRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => StorageUI())
.DisposeWith(disposables);
}); });
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}"; this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
@ -144,7 +156,6 @@ public partial class MainWindow
AddHelpMenuItem(); AddHelpMenuItem();
WindowsManager.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null); WindowsManager.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
MessageBus.Current.Listen<string>(EMsgCommand.AppExit.ToString()).Subscribe(StorageUI);
} }
#region Event #region Event
@ -157,12 +168,9 @@ public partial class MainWindow
})); }));
} }
private void DelegateSnackMsg(string content) private async Task DelegateSnackMsg(string content)
{
Application.Current?.Dispatcher.Invoke((() =>
{ {
MainSnackbar.MessageQueue?.Enqueue(content); MainSnackbar.MessageQueue?.Enqueue(content);
}), DispatcherPriority.Normal);
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
@ -423,7 +431,7 @@ public partial class MainWindow
} }
} }
private void StorageUI(string? n = null) private void StorageUI()
{ {
ConfigHandler.SaveWindowSizeItem(_config, GetType().Name, Width, Height); ConfigHandler.SaveWindowSizeItem(_config, GetType().Name, Width, Height);

View file

@ -1,4 +1,5 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
@ -90,11 +91,16 @@ public partial class ProfilesView
this.BindCommand(ViewModel, vm => vm.Export2ClientConfigClipboardCmd, v => v.menuExport2ClientConfigClipboard).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.Export2ClientConfigClipboardCmd, v => v.menuExport2ClientConfigClipboard).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.Export2ShareUrlCmd, v => v.menuExport2ShareUrl).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.Export2ShareUrlCmd, v => v.menuExport2ShareUrl).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.Export2ShareUrlBase64Cmd, v => v.menuExport2ShareUrlBase64).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.Export2ShareUrlBase64Cmd, v => v.menuExport2ShareUrlBase64).DisposeWith(disposables);
AppEvents.AppExitRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => StorageUI())
.DisposeWith(disposables);
}); });
RestoreUI(); RestoreUI();
ViewModel?.RefreshServers(); ViewModel?.RefreshServers();
MessageBus.Current.Listen<string>(EMsgCommand.AppExit.ToString()).Subscribe(StorageUI);
} }
#region Event #region Event
@ -369,7 +375,7 @@ public partial class ProfilesView
} }
} }
private void StorageUI(string? n = null) private void StorageUI()
{ {
List<ColumnItem> lvColumnItem = new(); List<ColumnItem> lvColumnItem = new();
foreach (var t in lstProfiles.Columns) foreach (var t in lstProfiles.Columns)