From 52d00baf2b93ecfadc09e7c95eba8cc890813930 Mon Sep 17 00:00:00 2001 From: Marcel Baumgartner Date: Tue, 20 Jun 2023 20:37:57 +0200 Subject: [PATCH] Added STRG+S support for editor and better saving --- .../Services/Sessions/KeyListenerService.cs | 38 +++++++++++++++++++ Moonlight/Program.cs | 1 + .../FileManagerPartials/FileEditor.razor | 21 ++++++++++ .../FileManagerPartials/FileManager.razor | 9 ++++- Moonlight/Shared/Layouts/MainLayout.razor | 17 +++++++-- Moonlight/wwwroot/assets/js/moonlight.js | 23 +++++++++++ 6 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 Moonlight/App/Services/Sessions/KeyListenerService.cs diff --git a/Moonlight/App/Services/Sessions/KeyListenerService.cs b/Moonlight/App/Services/Sessions/KeyListenerService.cs new file mode 100644 index 00000000..29b93ff7 --- /dev/null +++ b/Moonlight/App/Services/Sessions/KeyListenerService.cs @@ -0,0 +1,38 @@ +using Microsoft.JSInterop; + +namespace Moonlight.App.Services.Sessions; + +public class KeyListenerService +{ + private readonly IJSRuntime _jsRuntime; + private DotNetObjectReference _objRef; + + public event EventHandler KeyPressed; + + public KeyListenerService(IJSRuntime jsRuntime) + { + _jsRuntime = jsRuntime; + } + + public async Task Initialize() + { + _objRef = DotNetObjectReference.Create(this); + await _jsRuntime.InvokeVoidAsync("moonlight.keyListener.register", _objRef); + } + + [JSInvokable] + public void OnKeyPress(string key) + { + KeyPressed?.Invoke(this, key); + } + + public async ValueTask DisposeAsync() + { + try + { + await _jsRuntime.InvokeVoidAsync("moonlight.keyListener.unregister", _objRef); + _objRef.Dispose(); + } + catch (Exception) { /* ignored */} + } +} \ No newline at end of file diff --git a/Moonlight/Program.cs b/Moonlight/Program.cs index 89329146..1ca73465 100644 --- a/Moonlight/Program.cs +++ b/Moonlight/Program.cs @@ -134,6 +134,7 @@ namespace Moonlight builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/Moonlight/Shared/Components/FileManagerPartials/FileEditor.razor b/Moonlight/Shared/Components/FileManagerPartials/FileEditor.razor index 0c584993..31d7eaae 100644 --- a/Moonlight/Shared/Components/FileManagerPartials/FileEditor.razor +++ b/Moonlight/Shared/Components/FileManagerPartials/FileEditor.razor @@ -1,10 +1,15 @@ @using BlazorMonaco @using Moonlight.App.Services +@using Moonlight.App.Services.Interop +@using Moonlight.App.Services.Sessions @using Moonlight.Shared.Components.Partials @inject SmartTranslateService TranslationService +@inject KeyListenerService KeyListenerService @inject IJSRuntime JsRuntime +@implements IDisposable +
@@ -65,6 +70,16 @@ }, AutoIndent = true }; + + KeyListenerService.KeyPressed += KeyPressed; + } + + private async void KeyPressed(object? sender, string e) + { + if (e == "saveShortcut") + { + await Submit(); + } } protected override async Task OnAfterRenderAsync(bool firstRender) @@ -111,4 +126,10 @@ { return await Editor.GetValue(); } + + public void Dispose() + { + Editor.Dispose(); + KeyListenerService.KeyPressed -= KeyPressed; + } } diff --git a/Moonlight/Shared/Components/FileManagerPartials/FileManager.razor b/Moonlight/Shared/Components/FileManagerPartials/FileManager.razor index 5925c9d2..c47d90a2 100644 --- a/Moonlight/Shared/Components/FileManagerPartials/FileManager.razor +++ b/Moonlight/Shared/Components/FileManagerPartials/FileManager.razor @@ -17,7 +17,7 @@ InitialData="@EditorInitialData" Language="@EditorLanguage" OnCancel="() => Cancel()" - OnSubmit="(_) => Cancel(true)" + OnSubmit="(_) => Save()" HideControls="false"> } @@ -254,6 +254,13 @@ else await InvokeAsync(StateHasChanged); return false; } + + private async void Save() + { + var data = await Editor.GetData(); + await Access.Write(EditingFile, data); + await ToastService.Success(SmartTranslateService.Translate("Successfully saved file")); + } private async void Cancel(bool save = false) { diff --git a/Moonlight/Shared/Layouts/MainLayout.razor b/Moonlight/Shared/Layouts/MainLayout.razor index 19b5e254..040186ad 100644 --- a/Moonlight/Shared/Layouts/MainLayout.razor +++ b/Moonlight/Shared/Layouts/MainLayout.razor @@ -21,6 +21,7 @@ @inject SmartTranslateService SmartTranslateService @inject IpBanService IpBanService @inject DynamicBackgroundService DynamicBackgroundService +@inject KeyListenerService KeyListenerService @{ var uri = new Uri(NavigationManager.Uri); @@ -207,10 +208,14 @@ UserProcessed = true; await InvokeAsync(StateHasChanged); - await JsRuntime.InvokeVoidAsync("document.body.removeAttribute", "data-kt-app-reset-transition"); - await JsRuntime.InvokeVoidAsync("document.body.removeAttribute", "data-kt-app-page-loading"); - await JsRuntime.InvokeVoidAsync("KTMenu.createInstances"); - await JsRuntime.InvokeVoidAsync("KTDrawer.createInstances"); + try + { + await JsRuntime.InvokeVoidAsync("document.body.removeAttribute", "data-kt-app-reset-transition"); + await JsRuntime.InvokeVoidAsync("document.body.removeAttribute", "data-kt-app-page-loading"); + await JsRuntime.InvokeVoidAsync("KTMenu.createInstances"); + await JsRuntime.InvokeVoidAsync("KTDrawer.createInstances"); + } + catch (Exception){ /* ignore errors to make sure that the session call is executed */ } await SessionService.Register(); @@ -236,6 +241,8 @@ }); } + await KeyListenerService.Initialize(); + RunDelayedMenu(0); RunDelayedMenu(1); RunDelayedMenu(3); @@ -252,6 +259,8 @@ { SessionService.Close(); + await KeyListenerService.DisposeAsync(); + if (User != null) { await Event.Off($"supportChat.{User.Id}.message", this); diff --git a/Moonlight/wwwroot/assets/js/moonlight.js b/Moonlight/wwwroot/assets/js/moonlight.js index ca1bfa2b..3d129ec8 100644 --- a/Moonlight/wwwroot/assets/js/moonlight.js +++ b/Moonlight/wwwroot/assets/js/moonlight.js @@ -347,5 +347,28 @@ anchorElement.remove(); URL.revokeObjectURL(url); } + }, + keyListener: { + register: function (dotNetObjRef) + { + moonlight.keyListener.listener = (event) => + { + // filter here what key events should be sent to moonlight + + console.log(event); + + if(event.code === "KeyS" && event.ctrlKey) + { + event.preventDefault(); + dotNetObjRef.invokeMethodAsync('OnKeyPress', "saveShortcut"); + } + }; + + window.addEventListener('keydown', moonlight.keyListener.listener); + }, + unregister: function (dotNetObjRef) + { + window.removeEventListener('keydown', moonlight.keyListener.listener); + } } }; \ No newline at end of file