diff --git a/BlazingStory/Components/BlazingStoryApp.razor b/BlazingStory/Components/BlazingStoryApp.razor index f420f55..9d166c8 100644 --- a/BlazingStory/Components/BlazingStoryApp.razor +++ b/BlazingStory/Components/BlazingStoryApp.razor @@ -40,7 +40,7 @@
- + @@ -132,7 +132,7 @@ private int _InitLevel = 0; - private IServiceProvider? _ServiceProvider; + private AsyncServiceScope? _ServiceScope; private readonly JSModule _JSModule; @@ -161,10 +161,10 @@ protected override void OnInitialized() { - this._ServiceProvider = this.ConfigureServices(); + this._ServiceScope = this.ConfigureServices(); } - private IServiceProvider ConfigureServices() + private AsyncServiceScope ConfigureServices() { var services = new ServiceCollection() .AddSingleton(_ => this.JSRuntime) @@ -172,14 +172,14 @@ .AddSingleton(typeof(ILogger<>), typeof(Logger<>)) .AddSingleton(_ => this.GlobalServices.GetRequiredService()) .AddSingleton(_ => this.NavigationManager) - .AddHotKeys2() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton(_ => this._AddonsStore) - .AddSingleton(_ => this._Options) - .AddSingleton() .AddSingleton(_ => new(this.GlobalServices)) + .AddHotKeys2() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped(_ => this._AddonsStore) + .AddScoped(_ => this._Options) + .AddScoped() .AddTransient(); if (OperatingSystem.IsBrowser()) @@ -187,7 +187,8 @@ else services.AddSingleton(); - return services.BuildServiceProvider(); + var serviceProvider = services.BuildServiceProvider(); + return serviceProvider.CreateAsyncScope(); } protected override async Task OnParametersSetAsync() @@ -235,11 +236,11 @@ private async ValueTask UpdatePreferesColorSchemeAsync() { - if (this._ServiceProvider is null) throw new InvalidOperationException("The service provider is not initialized."); + if (!this._ServiceScope.HasValue) throw new InvalidOperationException("The service provider is not initialized."); if (this.AvailableColorSchemes == AvailableColorSchemes.Both) { - var helperScript = this._ServiceProvider.GetRequiredService(); + var helperScript = this._ServiceScope.Value.ServiceProvider.GetRequiredService(); var colorScheme = await helperScript.GetLocalStorageItemAsync("ColorScheme", defaultValue: "system"); if (colorScheme != "dark" && colorScheme != "light") { @@ -269,6 +270,7 @@ { await this._PreferesColorSchemeChangeSubscriber.DisposeIfConnectedAsync("dispose"); this._RefThis.Dispose(); - await _JSModule.DisposeAsync(); + await this._JSModule.DisposeAsync(); + if (this._ServiceScope.HasValue) await _ServiceScope.Value.DisposeAsync(); } } \ No newline at end of file diff --git a/BlazingStory/Internals/Services/Command/CommandService.cs b/BlazingStory/Internals/Services/Command/CommandService.cs index 8eb04dd..23ae122 100644 --- a/BlazingStory/Internals/Services/Command/CommandService.cs +++ b/BlazingStory/Internals/Services/Command/CommandService.cs @@ -1,5 +1,4 @@ -using BlazingStory.Internals.Extensions; -using BlazingStory.Internals.Utils; +using BlazingStory.Internals.Utils; using Microsoft.Extensions.Logging; using Toolbelt.Blazor.HotKeys2; @@ -7,8 +6,6 @@ namespace BlazingStory.Internals.Services.Command; internal class CommandService : IAsyncDisposable { - private readonly HotKeys _HotKeys; - private readonly HotKeysContext _HotKeysContext; private readonly ILogger _Logger; @@ -19,11 +16,9 @@ internal class CommandService : IAsyncDisposable public CommandService(HotKeys hotKeys, HelperScript helperScript, ILogger logger) { - this.Commands = new CommandSet(this.CommandStateKeyName, helperScript, logger); - this._HotKeys = hotKeys; this._Logger = logger; - this._HotKeysContext = this._HotKeys.CreateContext(); - this._HotKeys.KeyDown += this.HotKeys_OnKeyDown; + this._HotKeysContext = hotKeys.CreateContext(); + this.Commands = new CommandSet(this.CommandStateKeyName, this._HotKeysContext, helperScript, logger); } public Command? this[CommandType type] => this.Commands[type]; @@ -40,24 +35,9 @@ public IDisposable Subscribe(CommandType type, ValueTaskCallback callBack) return command.Subscribe(callBack); } - private void HotKeys_OnKeyDown(object? sender, HotKeyDownEventArgs args) - { - if (args.SrcElementTagName is "TEXTAREA" or "INPUT") return; - var commad = this.Commands - .Select(entry => entry.Command) - .FirstOrDefault(cmd => cmd.HotKey != null && cmd.HotKey.Code == args.Code && cmd.HotKey.Modifiers == args.Modifiers); - if (commad == null) return; - - // TODO: args.PreventDefault works only on Blazor WebAssembly. - args.PreventDefault = true; - - commad.InvokeAsync().AndLogException(this._Logger); - } - public async ValueTask DisposeAsync() { this.Commands.Dispose(); - this._HotKeys.KeyDown -= this.HotKeys_OnKeyDown; await this._HotKeysContext.DisposeAsync(); } } diff --git a/BlazingStory/Internals/Services/Command/CommandSet.cs b/BlazingStory/Internals/Services/Command/CommandSet.cs index a1b4a8f..0e59a05 100644 --- a/BlazingStory/Internals/Services/Command/CommandSet.cs +++ b/BlazingStory/Internals/Services/Command/CommandSet.cs @@ -3,6 +3,7 @@ using BlazingStory.Internals.Extensions; using BlazingStory.Internals.Utils; using Microsoft.Extensions.Logging; +using Toolbelt.Blazor.HotKeys2; namespace BlazingStory.Internals.Services.Command; @@ -11,6 +12,8 @@ internal class CommandSet : IDisposable, IEnumerable<(TKey Type, Command C { private readonly string _StorageKey; + private readonly HotKeysContext _HotKeysContext; + private readonly HelperScript _HelperScript; private readonly ILogger _Logger; @@ -21,9 +24,10 @@ internal class CommandSet : IDisposable, IEnumerable<(TKey Type, Command C public Command? this[TKey type] => this._Commands[(object)type] as Command; - internal CommandSet(string storageKey, HelperScript helperScript, ILogger logger) + internal CommandSet(string storageKey, HotKeysContext hotKeysContext, HelperScript helperScript, ILogger logger) { this._StorageKey = storageKey; + this._HotKeysContext = hotKeysContext; this._HelperScript = helperScript; this._Logger = logger; } @@ -34,11 +38,13 @@ internal async ValueTask EnsureInitializedAsync(Func()); - foreach (var cmdEntry in getCommandEntries()) + foreach (var (type, command) in getCommandEntries()) { - if (commandStates.TryGetValue(cmdEntry.Type, out var state)) state.Apply(cmdEntry.Command); - cmdEntry.Command.StateChanged += this.Command_StateChanged; - this._Commands.Add(cmdEntry.Type, cmdEntry.Command); + if (commandStates.TryGetValue(type, out var state)) state.Apply(command); + command.StateChanged += this.Command_StateChanged; + this._Commands.Add(type, command); + + if (command.HotKey != null) this._HotKeysContext.Add(command.HotKey.Modifiers, command.HotKey.Code, command.InvokeAsync); } }