Skip to content

Commit

Permalink
editor js interop
Browse files Browse the repository at this point in the history
  • Loading branch information
dorthl committed Aug 8, 2023
1 parent f6a2933 commit 62ef7f2
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 27 deletions.
49 changes: 23 additions & 26 deletions src/Blogifier.Admin/Components/PostEditorComponent.razor
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
@using System.Text.RegularExpressions;
@using System.Text;

@implements IAsyncDisposable

@inject IStringLocalizer<Resource> _localizer
@inject IJSRuntime _jsRuntime
@inject NavigationManager _navigation
@inject IToaster _toaster
@inject HttpClient _httpClient
@inject EditorJsInterop _editorJsInterop

<div class="bfeditor">
<div class="bfeditor-header">
Expand Down Expand Up @@ -66,8 +65,8 @@
</a>
<ul class="dropdown-menu" aria-labelledby="coverDropdown">
<li>
<button class="dropdown-item" onclick="return fileManager.uploadClick('@UploadType.PostCover', @Post.Id);" type="button">@_localizer["change"]</button>
<input type="hidden" class="txt-upload" @bind="Post.Cover" name="cover" id="cover" readonly />
<button class="dropdown-item" type="button" @onclick="() => ChangeCoverAsync()">@_localizer["change"]</button>
<InputFile @ref="_inputCovereference" OnChange="@LoadCovereFile" style="display:none;" accept="image/*" />
</li>
<li>
<button class="dropdown-item" type="button" @onclick="() => RemoveCoverAsync()">@_localizer["reset"]</button>
Expand All @@ -91,40 +90,29 @@
[Parameter] public EventCallback<PostEditorDto> OnSaveCallback { get; set; }
[Parameter] public EventCallback<int> OnRemoveCallback { get; set; }

private ValueTask<IJSObjectReference> _taskModule;
private ElementReference? _textareaReference;
private InputFile? _inputFileReference;
private InputFile? _inputCovereference;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
_taskModule = _jsRuntime.InvokeAsync<IJSObjectReference>("import", "./admin/js/editor.js");
var module = await _taskModule;
var element = _inputFileReference?.Element;
await module.InvokeVoidAsync("loadEditor", "fullToolbar", _textareaReference, element);
await _editorJsInterop.LoadEditorAsync(_textareaReference, element);
}
}

public async Task SetPostInfoAsync(PostEditorDto post)
{
var headTitle = _localizer["edit"] + " - " + post.Title;
await _jsRuntime.InvokeVoidAsync("commonJsFunctions.setTitle", headTitle);
var module = await _taskModule;
await module.InvokeVoidAsync("setEditorValue", post.Content);
}

protected async Task LoadImageFiles(InputFileChangeEventArgs args)
{
var module = await _taskModule;
var element = _inputFileReference?.Element;
await module.InvokeVoidAsync("writeFrontFile", element);
await _editorJsInterop.SetEditorValueAsync(post.Content);
}

async ValueTask<string?> GetValueAsync()
{
var module = await _taskModule;
var content = await module.InvokeAsync<string>("getEditorValue");
var content = await _editorJsInterop.GetEditorValueAsync();
var imgsMatches = StringHelper.MatchesMarkdownImgBlob(content);

if (imgsMatches.Count > 0)
Expand All @@ -142,6 +130,12 @@
return content;
}

protected async Task LoadImageFiles(InputFileChangeEventArgs args)
{
var element = _inputFileReference?.Element;
await _editorJsInterop.WriteFrontFileAsync(element);
}

protected async Task SaveCoreAsync(PostState postState)
{
var content = await GetValueAsync();
Expand Down Expand Up @@ -182,17 +176,20 @@
}
}

protected Task RemoveCoverAsync()
protected async Task ChangeCoverAsync()
{
Post.Cover = null;
StateHasChanged();
return Task.CompletedTask;
await _jsRuntime.InvokeVoidAsync("commonJsFunctions.triggerClick", _inputCovereference?.Element);
}

async ValueTask IAsyncDisposable.DisposeAsync()
protected async Task LoadCovereFile(InputFileChangeEventArgs args)
{
var module = await _taskModule;
await module.DisposeAsync();

}

protected Task RemoveCoverAsync()
{
Post.Cover = null;
StateHasChanged();
return Task.CompletedTask;
}
}
25 changes: 25 additions & 0 deletions src/Blogifier.Admin/Interop/CommonJsInterop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.JSInterop;
using System;
using System.Threading.Tasks;

namespace Blogifier.Admin.Interop;

public class CommonJsInterop : IAsyncDisposable
{
private readonly Lazy<Task<IJSObjectReference>> moduleTask;

public CommonJsInterop(IJSRuntime jsRuntime)
{
moduleTask = new(() => jsRuntime.InvokeAsync<IJSObjectReference>(
"import", "./_content/RazorClassLibrary1/exampleJsInterop.js").AsTask());
}

public async ValueTask DisposeAsync()
{
if (moduleTask.IsValueCreated)
{
var module = await moduleTask.Value;
await module.DisposeAsync();
}
}
}
50 changes: 50 additions & 0 deletions src/Blogifier.Admin/Interop/EditorJsInterop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System;
using System.Threading.Tasks;

namespace Blogifier.Admin.Interop;

public class EditorJsInterop : IAsyncDisposable
{
private readonly Lazy<Task<IJSObjectReference>> moduleTask;

public EditorJsInterop(IJSRuntime jsRuntime)
{
moduleTask = new(() => jsRuntime.InvokeAsync<IJSObjectReference>("import", "./admin/js/editor.js").AsTask());
}

public async ValueTask LoadEditorAsync(ElementReference? textarea, ElementReference? imageUpload, string toolbar = "fullToolbar")
{
var module = await moduleTask.Value;
await module.InvokeVoidAsync("loadEditor", toolbar, textarea, imageUpload);
}

public async ValueTask SetEditorValueAsync(string content)
{
var module = await moduleTask.Value;
await module.InvokeVoidAsync("setEditorValue", content);
}

public async ValueTask<string> GetEditorValueAsync()
{
var module = await moduleTask.Value;
var content = await module.InvokeAsync<string>("getEditorValue");
return content;
}

public async ValueTask WriteFrontFileAsync(ElementReference? imageUpload)
{
var module = await moduleTask.Value;
await module.InvokeVoidAsync("writeFrontFile", imageUpload);
}

public async ValueTask DisposeAsync()
{
if (moduleTask.IsValueCreated)
{
var module = await moduleTask.Value;
await module.DisposeAsync();
}
}
}
2 changes: 2 additions & 0 deletions src/Blogifier.Admin/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Blogifier;
using Blogifier.Admin;
using Blogifier.Admin.Interop;
using Blogifier.Admin.Services;
using Blogifier.Identity;
using Microsoft.AspNetCore.Components.Authorization;
Expand Down Expand Up @@ -30,4 +31,5 @@
config.NewestOnTop = false;
});
builder.Services.AddScoped<ToasterService>();
builder.Services.AddScoped<EditorJsInterop>();
await builder.Build().RunAsync();
1 change: 1 addition & 0 deletions src/Blogifier.Admin/_Imports.razor
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@
@using Blogifier.Helper;
@using Blogifier.Identity
@using Blogifier.Models
@using Blogifier.Admin.Interop
4 changes: 3 additions & 1 deletion src/Blogifier.Admin/assets/js/blogifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { Tooltip } from 'bootstrap'
import "chart.js"

window.commonJsFunctions = {
triggerClick: function (element) {
element.click();
},
setTitle: function (title) {
document.title = title + " - Blogifier";
},
Expand Down Expand Up @@ -67,7 +70,6 @@ window.commonJsFunctions = {
var clock = document.getElementById('clock');
var clockDay = document.getElementById('clock-day');
var clockMonth = document.getElementById('clock-month');

function time() {
var date = new Date();
var hours = date.getHours();
Expand Down

0 comments on commit 62ef7f2

Please sign in to comment.