Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.Net 8 Preview #360

Open
wants to merge 46 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
ce2fd2f
update .net 8
dorthl Jul 31, 2023
d775bb6
docker build
dorthl Jul 31, 2023
2fbf135
remove nuget
dorthl Aug 1, 2023
8d5facc
ChartJs
dorthl Aug 1, 2023
9443313
ChartJs
dorthl Aug 1, 2023
57d9830
Merge branch 'mian' into preview
dorthl Aug 1, 2023
7b9f8bf
update test
dorthl Aug 1, 2023
37e2e98
Merge remote-tracking branch 'origin/mian' into preview
dorthl Aug 1, 2023
b795231
fix
dorthl Aug 1, 2023
5917597
Webcil false
dorthl Aug 1, 2023
d3ca563
dockerignore
dorthl Aug 1, 2023
7ff7950
Merge branch 'mian' into preview
dorthl Aug 1, 2023
13deb93
BlazorWebAssemblyOmitDebugProxyOutput
dorthl Aug 1, 2023
876e882
Merge branch 'mian' into preview
dorthl Aug 1, 2023
36f9cd5
Merge branch 'mian' into preview
dorthl Aug 2, 2023
f65eee9
Merge branch 'mian' into preview
dorthl Aug 2, 2023
2d41f21
Merge branch 'mian' into preview
dorthl Aug 3, 2023
5c319d4
Merge branch 'mian' into preview
dorthl Aug 4, 2023
efebd36
Merge branch 'mian' into preview
dorthl Aug 4, 2023
36b7c4b
config mirror
dorthl Aug 4, 2023
22e70df
Merge branch 'blogifierdotnet:main' into preview
dorthl Aug 4, 2023
047be82
github workflows docker-image
dorthl Aug 4, 2023
66f9902
on up
dorthl Aug 4, 2023
261b436
fix on err
dorthl Aug 4, 2023
607a9fd
rm zh-CH mirror
dorthl Aug 4, 2023
1c77d4b
Merge branch 'mian' into preview
dorthl Aug 7, 2023
12ddea7
post cover def null
dorthl Aug 7, 2023
f6a2933
rm EditorComponent
dorthl Aug 8, 2023
62ef7f2
editor js interop
dorthl Aug 8, 2023
91f3ad4
common js
dorthl Aug 8, 2023
82702ae
CommonJs
dorthl Aug 9, 2023
2a712be
admin assets
dorthl Aug 9, 2023
bb33040
Merge branch 'blogifierdotnet:main' into mian
dorthl Aug 9, 2023
2eeefb6
fix regex matche
dorthl Aug 9, 2023
4292759
Cover Generated Data img
dorthl Aug 9, 2023
25da050
up cover
dorthl Aug 9, 2023
25f0f58
Merge branch 'mian' into preview
dorthl Aug 9, 2023
2540942
preview.7
dorthl Aug 9, 2023
27b4672
dotnet sdk 7.0.400
dorthl Aug 9, 2023
b503a49
Merge branch 'mian' into preview
dorthl Aug 9, 2023
6007e67
sdk preview.7
dorthl Aug 9, 2023
dc7a607
aspnet-composite
dorthl Aug 9, 2023
c66a888
register user
dorthl Aug 9, 2023
d0fb309
fix themes assets
dorthl Aug 9, 2023
e42f028
fix scss
dorthl Aug 9, 2023
3c1216f
Merge branch 'mian' into preview
dorthl Aug 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 5 additions & 5 deletions .dockerignore
@@ -1,8 +1,8 @@
.git
**/bin
**/obj
**/node_modules
.git*
**/bin*
**/obj*
**/node_modules*
Dockerfile
docker-compose.yml
deploy/
deploy*
**/package-lock.json
32 changes: 32 additions & 0 deletions .github/workflows/docker-image.yml
@@ -0,0 +1,32 @@
name: build release docker

on:
push:
branches:
- 'preview'
pull_request:
branches:
- 'preview'

jobs:
build:
runs-on: ubuntu-latest
steps:
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
push: true
tags: dorthl/blogifier:preview
11 changes: 7 additions & 4 deletions Dockerfile
@@ -1,15 +1,18 @@
FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine as sdk
FROM mcr.microsoft.com/dotnet/sdk:8.0.100-preview.7-alpine3.18 as sdk
# TOTO zh-CH
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache npm
# VOLUME ["/root/.nuget","/root/.local/share/NuGet","/root/.npm"]
# TOTO zh-CH
# CMD [ "npm config set registry http://mirrors.cloud.tencent.com/npm" ]
# Copy everything else and build
COPY ./ /opt/blogifier
WORKDIR /opt/blogifier
RUN ["dotnet","publish", "-c", "Release","/p:RuntimeIdentifier=linux-musl-x64", "./src/Blogifier/Blogifier.csproj","-o","dist" ]

FROM mcr.microsoft.com/dotnet/aspnet:7.0-alpine as run
FROM mcr.microsoft.com/dotnet/aspnet:8.0.0-preview.7-alpine3.18-composite as run
# TOTO zh-CH
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache icu-libs
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
COPY --from=sdk /opt/blogifier/dist /opt/blogifier/
Expand Down
4 changes: 2 additions & 2 deletions docker.sh
@@ -1,3 +1,3 @@
# docker
docker build -t dorthl/blogifier:latest .
docker push dorthl/blogifier:latest
docker build -t dorthl/blogifier:preview .
docker push dorthl/blogifier:preview
2 changes: 1 addition & 1 deletion global.json
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "7.0.304"
"version": "8.0.100-preview.7.23376.3"
}
}
12 changes: 7 additions & 5 deletions src/Blogifier.Admin/Blogifier.Admin.csproj
@@ -1,20 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<!-- <BlazorEnableCompression>false</BlazorEnableCompression> -->
<!--<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>-->
<ClientAssetsDirectory>assets\</ClientAssetsDirectory>
<ClientAssetsRestoreCommand>npm i</ClientAssetsRestoreCommand>
<ClientAssetsBuildCommand>npm run build:$(Configuration)</ClientAssetsBuildCommand>

<!-- https://github.com/dotnet/runtime/issues/89234 -->
<WasmEnableWebcil>false</WasmEnableWebcil>
</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="8.0.0-preview.7.23375.9" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-preview.7.23375.9" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-preview.7.23375.9" PrivateAssets="all" />
<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
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
@@ -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
@@ -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
@@ -0,0 +1,7 @@
namespace Blogifier.Admin;

public class FrontBlobInfo
{
public string FileName { get; set; } = default!;
public string Url { get; set; } = default!;
}