Skip to content

Commit

Permalink
Merge pull request #363 from dorthl/mian
Browse files Browse the repository at this point in the history
fix admin
  • Loading branch information
dorthl committed Aug 16, 2023
2 parents 4c47557 + a89e23a commit 6a3859f
Show file tree
Hide file tree
Showing 59 changed files with 913 additions and 562 deletions.
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "7.0.304"
"version": "7.0.400"
}
}
8 changes: 4 additions & 4 deletions src/Blogifier.Admin/Blogifier.Admin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="7.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.9" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="7.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.10" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.10" />
<PackageReference Include="Sotsera.Blazor.Toaster" Version="3.0.0" />
</ItemGroup>

Expand Down
73 changes: 0 additions & 73 deletions src/Blogifier.Admin/Components/EditorComponent.razor

This file was deleted.

5 changes: 3 additions & 2 deletions src/Blogifier.Admin/Components/NavMenuComponent.razor
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@inject AuthenticationStateProvider _stateProvider
@inject IJSRuntime _jsRuntime
@inject IStringLocalizer<Resource> _localizer
@inject CommonJsInterop _commonJsInterop

@code {

Expand All @@ -20,7 +21,7 @@
{
if (firstRender)
{
await _jsRuntime.InvokeAsync<string>("commonJsFunctions.setTooltip", "");
await _commonJsInterop.SetTooltipAsync();
}
}
}
Expand Down Expand Up @@ -88,7 +89,7 @@
{
<li class="menu-item dropdown" title="@_claims.NickName" data-bs-toggle="tooltip">
<NavLink class="menu-link" href="/admin/profile/" role="button" id="profileDropdownMenu" data-bs-toggle="dropdown" aria-expanded="false">
<img class="rounded-circle profilePicture" width="32" height="32" src="@UserHelper.CheckGetAvatarUrl(_claims.Avatar)" alt="@_claims.NickName">
<img class="rounded-circle profilePicture" width="32" height="32" src="@PageHelper.CheckGetAvatarUrl(_claims.Avatar)" alt="@_claims.NickName">
</NavLink>
<div class="user-nav dropdown-menu dropdown-menu-end" aria-labelledby="profileDropdownMenu">
<div class="user-nav-info">
Expand Down
4 changes: 2 additions & 2 deletions src/Blogifier.Admin/Components/PageTitleComponent.razor
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
@inject IJSRuntime _jsRuntime;
@inject CommonJsInterop _commonJsInterop

@code {
[Parameter] public string Title { get; set; } = default!;

protected override async Task OnInitializedAsync()
{
await SetTitleAsync();
await _commonJsInterop.SetTitleAsync(Title);
}
private async Task SetTitleAsync() => await _jsRuntime.InvokeVoidAsync("commonJsFunctions.setTitle", Title);
}
102 changes: 82 additions & 20 deletions src/Blogifier.Admin/Components/PostEditorComponent.razor
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
@using System.Text.RegularExpressions;
@using System.Text;

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

<div class="bfeditor">
<div class="bfeditor-header">
<img class="bfeditor-cover" src="@Post.Cover" alt="@_localizer["cover"]" id="postCover">
<img class="bfeditor-cover" src="@PageHelper.CheckGetCoverrUrl(Post.Cover)" alt="@_localizer["cover"]">
<div class="bfeditor-actions">
<div class="container d-flex">
@if (string.IsNullOrEmpty(Post.Slug))
Expand Down Expand Up @@ -60,11 +66,11 @@
</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="() => ResetCoverAsync()">@_localizer["reset"]</button>
<button class="dropdown-item" type="button" @onclick="() => RemoveCoverAsync()">@_localizer["reset"]</button>
</li>
</ul>
</div>
Expand All @@ -73,7 +79,10 @@
</div>
</div>
</div>
<EditorComponent @ref="_editorComponent" Toolbar="fullToolbar" />
<div class="easymde-wrapper">
<textarea @ref="_textareaReference" tabindex="2" class="visually-hidden" placeholder="@_localizer["type-here"]"></textarea>
<InputFile @ref="_inputFileReference" OnChange="@LoadImageFiles" style="display:none;" accept="image/*" />
</div>
</div>

@code {
Expand All @@ -82,27 +91,74 @@
[Parameter] public EventCallback<PostEditorDto> OnSaveCallback { get; set; }
[Parameter] public EventCallback<int> OnRemoveCallback { get; set; }

private EditorComponent _editorComponent = default!;
private ElementReference? _textareaReference;
private InputFile? _inputFileReference;
private InputFile? _inputCovereference;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var element = _inputFileReference?.Element;
await _editorJsInterop.LoadEditorAsync(_textareaReference, element);
}
}

public async Task SetPostInfoAsync(PostEditorDto post)
{
var headTitle = _localizer["edit"] + " - " + post.Title;
await _jsruntime.InvokeVoidAsync("commonJsFunctions.setTitle", headTitle);
await _editorComponent.SetValueAsync(post.Content);
await _commonJsInterop.SetTitleAsync(headTitle);
await _editorJsInterop.SetEditorValueAsync(post.Content);
}

async ValueTask<string?> GetValueAsync()
{
var content = await _editorJsInterop.GetEditorValueAsync();
var imgsMatches = StringHelper.MarkdownImgBlobGeneratedRegex().Matches(content);

if (imgsMatches.Count > 0)
{
var contentStringBuilder = new StringBuilder(content);
foreach (Match match in imgsMatches)
{
var imageUrl = match.Groups[1].Value;
var imageBytes = await _httpClient.GetByteArrayAsync(imageUrl);
var base64String = Convert.ToBase64String(imageBytes);
contentStringBuilder.Replace(imageUrl, "data:image/png;base64," + base64String);
}
content = contentStringBuilder.ToString();
}
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 _editorComponent.GetValueAsync();
var content = await GetValueAsync();
if (string.IsNullOrEmpty(Post.Title) || string.IsNullOrEmpty(content))
{
_toaster.Error(_localizer["title-content-required"]);
return;
}
Post.Content = content;
Post.Cover = await _jsruntime.InvokeAsync<string>("commonJsFunctions.getSrcValue", "postCover");
Post.Cover = Post.Cover.Replace(_navigation.BaseUri, "");
if (string.IsNullOrEmpty(Post.Cover)) Post.Cover = BlogifierSharedConstant.DefaultCover;
if (!string.IsNullOrEmpty(Post.Cover))
{
var coverMatche = StringHelper.BlobUrlGeneratedRegex().Match(Post.Cover);
if (coverMatche.Success)
{
var imageUrl = coverMatche.Value;
var imageBytes = await _httpClient.GetByteArrayAsync(imageUrl);
var base64String = Convert.ToBase64String(imageBytes);
var dataString = "data:image/png;base64," + base64String;
Console.WriteLine(dataString);
Post.Cover = dataString;
}
}
if (string.IsNullOrEmpty(Post.Description)) Post.Description = Post.Title;
Post.State = postState;
await OnSaveCallback.InvokeAsync(Post);
Expand All @@ -125,22 +181,28 @@

protected async Task RemoveAsync(int id)
{
if (await _jsruntime.InvokeAsync<bool>("confirm", _localizer["confirm-delete"]))
if (await _jsRuntime.InvokeAsync<bool>("confirm", _localizer["confirm-delete"]))
{
await OnRemoveCallback.InvokeAsync(id);
}
}

protected async Task ResetCoverAsync()
protected async Task ChangeCoverAsync()
{
Post.Cover = BlogifierSharedConstant.DefaultCover;
await SaveAsync();
await _commonJsInterop.TriggerClickAsync(_inputCovereference?.Element);
}

protected async Task RemoveCoverAsync()
protected async Task LoadCovereFile(InputFileChangeEventArgs args)
{
Post.Cover = null;
await SaveAsync();
var element = _inputCovereference?.Element;
var blobInfo = await _commonJsInterop.GetInputFileBlobInfoAsync(element);
Post.Cover = blobInfo.Url;
}

protected Task RemoveCoverAsync()
{
Post.Cover = null;
StateHasChanged();
return Task.CompletedTask;
}
}
7 changes: 7 additions & 0 deletions src/Blogifier.Admin/Dtos/FrontBlobInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Blogifier.Admin;

public class FrontBlobInfo
{
public string FileName { get; set; } = default!;
public string Url { get; set; } = default!;
}
49 changes: 49 additions & 0 deletions src/Blogifier.Admin/Interop/CommonJsInterop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Microsoft.AspNetCore.Components;
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", "./admin/js/common.js").AsTask());
}

public async ValueTask SetTooltipAsync()
{
var module = await moduleTask.Value;
await module.InvokeVoidAsync("setTooltip");
}

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

public async ValueTask TriggerClickAsync(ElementReference? element)
{
var module = await moduleTask.Value;
await module.InvokeVoidAsync("triggerClick", element);
}

public async ValueTask<FrontBlobInfo> GetInputFileBlobInfoAsync(ElementReference? inputUpload)
{
var module = await moduleTask.Value;
return await module.InvokeAsync<FrontBlobInfo>("getInputFileBlobInfo", inputUpload);
}

public async ValueTask DisposeAsync()
{
if (moduleTask.IsValueCreated)
{
var module = await moduleTask.Value;
await module.DisposeAsync();
}
}
}
Loading

0 comments on commit 6a3859f

Please sign in to comment.