From ce2fd2f8ad9bc127b7d2354227f7764d7fb01ab1 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Mon, 31 Jul 2023 16:52:20 +0800 Subject: [PATCH 01/31] update .net 8 --- global.json | 5 ----- src/Blogifier.Admin/Blogifier.Admin.csproj | 10 ++++----- src/Blogifier.Shared/Blogifier.Shared.csproj | 4 ++-- .../Blogifier.Themes.Standard.csproj | 2 +- src/Blogifier/Blogifier.csproj | 22 +++++++++---------- tests/Blogifier.Tests/Blogifier.Tests.csproj | 2 +- 6 files changed, 20 insertions(+), 25 deletions(-) delete mode 100644 global.json diff --git a/global.json b/global.json deleted file mode 100644 index e383752a1..000000000 --- a/global.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sdk": { - "version": "7.0.304" - } -} diff --git a/src/Blogifier.Admin/Blogifier.Admin.csproj b/src/Blogifier.Admin/Blogifier.Admin.csproj index e89e12a05..df9def5ed 100644 --- a/src/Blogifier.Admin/Blogifier.Admin.csproj +++ b/src/Blogifier.Admin/Blogifier.Admin.csproj @@ -1,6 +1,6 @@ <Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> + <TargetFramework>net8.0</TargetFramework> <Nullable>enable</Nullable> <!-- <BlazorEnableCompression>false</BlazorEnableCompression> --> <!--<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings> @@ -15,10 +15,10 @@ <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> <PackageReference Include="Blazored.Typeahead" Version="4.7.0" /> <PackageReference Include="ChartJs.Blazor.Fork" Version="2.0.2" /> - <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" /> - <PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.9" /> + <PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.0-preview.6.23329.11" /> + <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-preview.6.23329.11" /> + <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-preview.6.23329.11" /> + <PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0-preview.6.23329.11" /> <PackageReference Include="Sotsera.Blazor.Toaster" Version="3.0.0" /> </ItemGroup> diff --git a/src/Blogifier.Shared/Blogifier.Shared.csproj b/src/Blogifier.Shared/Blogifier.Shared.csproj index bc42f863d..91540bdeb 100644 --- a/src/Blogifier.Shared/Blogifier.Shared.csproj +++ b/src/Blogifier.Shared/Blogifier.Shared.csproj @@ -1,12 +1,12 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> + <TargetFramework>net8.0</TargetFramework> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.9" /> + <PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0-preview.6.23329.11" /> </ItemGroup> <ItemGroup> diff --git a/src/Blogifier.Themes.Standard/Blogifier.Themes.Standard.csproj b/src/Blogifier.Themes.Standard/Blogifier.Themes.Standard.csproj index 70a13b88c..fbfc7d793 100644 --- a/src/Blogifier.Themes.Standard/Blogifier.Themes.Standard.csproj +++ b/src/Blogifier.Themes.Standard/Blogifier.Themes.Standard.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk.Razor"> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> + <TargetFramework>net8.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> <AddRazorSupportForMvc>true</AddRazorSupportForMvc> diff --git a/src/Blogifier/Blogifier.csproj b/src/Blogifier/Blogifier.csproj index 7db59c99a..59d573268 100644 --- a/src/Blogifier/Blogifier.csproj +++ b/src/Blogifier/Blogifier.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> + <TargetFramework>net8.0</TargetFramework> <Nullable>enable</Nullable> <SelfContained>false</SelfContained> <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled> @@ -14,25 +14,25 @@ <ItemGroup> <PackageReference Include="AutoMapper" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> - <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.9" /> - <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="7.0.9" /> - <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="7.0.9" /> - <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.9" /> - <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.9"> + <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.0-preview.6.23329.11" /> + <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.0-preview.6.23329.11" /> + <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.0-preview.6.23329.11" /> + <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0-preview.6.23329.11" /> + <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0-preview.6.23329.4"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> - <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.9" /> - <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.9" /> - <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="7.0.9" /> - <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4" /> + <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0-preview.6.23329.4" /> + <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0-preview.6.23329.4" /> + <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.0-preview.6.23329.11" /> + <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0-preview.4" /> <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" /> <PackageReference Include="Minio" Version="5.0.0" /> <PackageReference Include="Serilog.AspNetCore" Version="7.0.0" /> <PackageReference Include="ReverseMarkdown" Version="3.25.0" /> <PackageReference Include="Markdig" Version="0.31.0" /> <PackageReference Include="NETCore.MailKit" Version="2.1.0" /> - <PackageReference Include="System.ServiceModel.Syndication" Version="7.0.0" /> + <PackageReference Include="System.ServiceModel.Syndication" Version="8.0.0-preview.6.23329.7" /> <PackageReference Include="Microsoft.SyndicationFeed.ReaderWriter" Version="1.0.2" /> </ItemGroup> diff --git a/tests/Blogifier.Tests/Blogifier.Tests.csproj b/tests/Blogifier.Tests/Blogifier.Tests.csproj index 1a87258bf..90ab84e4d 100644 --- a/tests/Blogifier.Tests/Blogifier.Tests.csproj +++ b/tests/Blogifier.Tests/Blogifier.Tests.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> + <TargetFramework>net8.0</TargetFramework> </PropertyGroup> <ItemGroup> From d775bb65fd2bc38eb936b6e508946711d6323a73 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Mon, 31 Jul 2023 17:58:33 +0800 Subject: [PATCH 02/31] docker build --- .dockerignore | 8 ++++---- Dockerfile | 4 ++-- docker.sh | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.dockerignore b/.dockerignore index 3bdd11108..0e89580c3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,8 +1,8 @@ .git -**/bin -**/obj -**/node_modules +**/bin/* +**/obj/* +**/node_modules/* Dockerfile docker-compose.yml -deploy/ +deploy/* **/package-lock.json diff --git a/Dockerfile b/Dockerfile index 3e237e2bb..8871a8749 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine as sdk +FROM mcr.microsoft.com/dotnet/sdk:8.0-preview-alpine as sdk # TOTO zh-CH RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories RUN apk add --no-cache npm @@ -7,7 +7,7 @@ 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.6-alpine3.18 as run # TOTO zh-CH RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories RUN apk add --no-cache icu-libs diff --git a/docker.sh b/docker.sh index 17697cc0a..16328b1bf 100644 --- a/docker.sh +++ b/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 From 2fbf13538569c1003b5e6b36d73c3be2df43189b Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Tue, 1 Aug 2023 09:24:15 +0800 Subject: [PATCH 03/31] remove nuget --- src/Blogifier.Admin/Blogifier.Admin.csproj | 2 -- src/Blogifier.Admin/_Imports.razor | 1 - src/Blogifier.Admin/wwwroot/index.html | 3 --- 3 files changed, 6 deletions(-) diff --git a/src/Blogifier.Admin/Blogifier.Admin.csproj b/src/Blogifier.Admin/Blogifier.Admin.csproj index df9def5ed..d6ae69bda 100644 --- a/src/Blogifier.Admin/Blogifier.Admin.csproj +++ b/src/Blogifier.Admin/Blogifier.Admin.csproj @@ -13,8 +13,6 @@ <ItemGroup> <PackageReference Include="AutoMapper" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> - <PackageReference Include="Blazored.Typeahead" Version="4.7.0" /> - <PackageReference Include="ChartJs.Blazor.Fork" Version="2.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.0-preview.6.23329.11" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-preview.6.23329.11" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-preview.6.23329.11" /> diff --git a/src/Blogifier.Admin/_Imports.razor b/src/Blogifier.Admin/_Imports.razor index d57b9c6aa..2a062649d 100644 --- a/src/Blogifier.Admin/_Imports.razor +++ b/src/Blogifier.Admin/_Imports.razor @@ -14,7 +14,6 @@ @using AutoMapper; -@using Blazored.Typeahead @using Sotsera.Blazor.Toaster @using Blogifier; diff --git a/src/Blogifier.Admin/wwwroot/index.html b/src/Blogifier.Admin/wwwroot/index.html index 03d58d1a6..628017365 100644 --- a/src/Blogifier.Admin/wwwroot/index.html +++ b/src/Blogifier.Admin/wwwroot/index.html @@ -10,7 +10,6 @@ TODO: for rtl: <link href="admin/css/blogifier.rtl.css" rel="stylesheet" /> --> - <link href="_content/Blazored.Typeahead/blazored-typeahead.css" rel="stylesheet" /> <link rel="apple-touch-icon" sizes="180x180" href="amdin/favicons/apple-touch-icon.png?v=2"> <link rel="icon" type="image/png" sizes="32x32" href="admin/favicons/favicon-32x32.png?v=2"> <link rel="icon" type="image/png" sizes="16x16" href="admin/favicons/favicon-16x16.png?v=2"> @@ -55,8 +54,6 @@ </form> <script src="_framework/blazor.webassembly.js"></script> - <script src="_content/ChartJs.Blazor.Fork/ChartJsBlazorInterop.js"></script> - <script src="_content/Blazored.Typeahead/blazored-typeahead.js"></script> <script src="admin/js/blogifier.js"></script> </body> </html> From 8d5facc5e057d6d89dd5c68ecbe7a6967cee168c Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Tue, 1 Aug 2023 09:30:02 +0800 Subject: [PATCH 04/31] ChartJs --- src/Blogifier.Admin/Pages/HomeView.razor | 108 +++++++++++------------ 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/src/Blogifier.Admin/Pages/HomeView.razor b/src/Blogifier.Admin/Pages/HomeView.razor index 6eb030280..6abf69271 100644 --- a/src/Blogifier.Admin/Pages/HomeView.razor +++ b/src/Blogifier.Admin/Pages/HomeView.razor @@ -1,8 +1,8 @@ -@using ChartJs.Blazor +@* @using ChartJs.Blazor @using ChartJs.Blazor.Common @using ChartJs.Blazor.Common.Enums @using ChartJs.Blazor.Util -@using ChartJs.Blazor.BarChart +@using ChartJs.Blazor.BarChart *@ @using System.Drawing @page "/admin" @@ -13,7 +13,7 @@ @code { - protected BarConfig _config = default!; + // protected BarConfig _config = default!; protected List<OptionItem> _dateOptions = default!; protected List<PostVisit> _visits = default!; protected bool _hideGraph = false; @@ -22,17 +22,17 @@ protected override async Task OnInitializedAsync() { - _config = new BarConfig - { - Options = new BarOptions - { - Responsive = true, - Legend = new Legend - { - Position = Position.Top - } - } - }; + // _config = new BarConfig + // { + // Options = new BarOptions + // { + // Responsive = true, + // Legend = new Legend + // { + // Position = Position.Top + // } + // } + // }; _dateOptions = new List<OptionItem> { new OptionItem { Id = 1, Title = _localizer["today"] }, @@ -41,58 +41,58 @@ new OptionItem { Id = 4, Title = _localizer["30-days"] }, new OptionItem { Id = 5, Title = _localizer["90-days"] }, }; - Load(); + // Load(); _analytics = await _http.GetFromJsonAsync<AnalyticsDto>("api/analytics"); } - protected void Load() - { - var dataset = new BarDataset<int>() - { - Label = "Latest Post Views", - BackgroundColor = ColorUtil.FromDrawingColor(Color.FromArgb(98, 42, 255)), - BorderWidth = 0 - }; + // protected void Load() + // { + // var dataset = new BarDataset<int>() + // { + // Label = "Latest Post Views", + // BackgroundColor = ColorUtil.FromDrawingColor(Color.FromArgb(98, 42, 255)), + // BorderWidth = 0 + // }; - if (_analytics == null || _analytics.LatestPostViews == null) - { - LoadData(dataset, TestData()); - } - else - { - _hideList = _analytics.DisplayType == AnalyticsListType.Graph; - _hideGraph = _analytics.DisplayType == AnalyticsListType.List; + // if (_analytics == null || _analytics.LatestPostViews == null) + // { + // LoadData(dataset, TestData()); + // } + // else + // { + // _hideList = _analytics.DisplayType == AnalyticsListType.Graph; + // _hideGraph = _analytics.DisplayType == AnalyticsListType.List; - LoadData(dataset, _analytics.LatestPostViews); - } + // LoadData(dataset, _analytics.LatestPostViews); + // } - if (_config.Data.Datasets.Count > 0) - { - _config.Data.Datasets.Clear(); - } + // if (_config.Data.Datasets.Count > 0) + // { + // _config.Data.Datasets.Clear(); + // } - _config.Data.Datasets.Add(dataset); - } + // _config.Data.Datasets.Add(dataset); + // } - protected void LoadData(IDataset<int> dataset, BarChartModel model) - { - _visits = new List<PostVisit>(); - var labels = model.Labels.ToList(); - var values = model.Data.ToList(); + // protected void LoadData(IDataset<int> dataset, BarChartModel model) + // { + // _visits = new List<PostVisit>(); + // var labels = model.Labels.ToList(); + // var values = model.Data.ToList(); - _config.Data.Labels.Clear(); + // _config.Data.Labels.Clear(); - for (int i = 0; i < labels.Count; i++) - { - _config.Data.Labels.Add(labels[i]); - dataset.Add(values[i]); + // for (int i = 0; i < labels.Count; i++) + // { + // _config.Data.Labels.Add(labels[i]); + // dataset.Add(values[i]); - _visits.Add(new PostVisit { Name = labels[i], Value = values[i] }); - } - _visits = _visits.OrderByDescending(v => v.Value).ToList(); - } + // _visits.Add(new PostVisit { Name = labels[i], Value = values[i] }); + // } + // _visits = _visits.OrderByDescending(v => v.Value).ToList(); + // } protected async Task ToggleAnalyticsView(bool isGraph) { @@ -272,7 +272,7 @@ <!-- Chart must show visits per day not by the title of the post. --> <div class="dash-pan-body" hidden="@_hideGraph"> - <Chart Config="_config"></Chart> + @* <Chart Config="_config"></Chart> *@ </div> </div> From 944331336d03f291ad5cf26a2f0f19cff6fbb53c Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Tue, 1 Aug 2023 09:35:18 +0800 Subject: [PATCH 05/31] ChartJs --- src/Blogifier.Admin/Blogifier.Admin.csproj | 1 + src/Blogifier.Admin/Pages/HomeView.razor | 126 ++++++++++----------- src/Blogifier.Admin/wwwroot/index.html | 1 + 3 files changed, 65 insertions(+), 63 deletions(-) diff --git a/src/Blogifier.Admin/Blogifier.Admin.csproj b/src/Blogifier.Admin/Blogifier.Admin.csproj index d6ae69bda..d47fbeffe 100644 --- a/src/Blogifier.Admin/Blogifier.Admin.csproj +++ b/src/Blogifier.Admin/Blogifier.Admin.csproj @@ -13,6 +13,7 @@ <ItemGroup> <PackageReference Include="AutoMapper" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> + <PackageReference Include="ChartJs.Blazor.Fork" Version="2.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.0-preview.6.23329.11" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-preview.6.23329.11" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-preview.6.23329.11" /> diff --git a/src/Blogifier.Admin/Pages/HomeView.razor b/src/Blogifier.Admin/Pages/HomeView.razor index 6abf69271..11025577f 100644 --- a/src/Blogifier.Admin/Pages/HomeView.razor +++ b/src/Blogifier.Admin/Pages/HomeView.razor @@ -1,8 +1,8 @@ -@* @using ChartJs.Blazor +@using ChartJs.Blazor @using ChartJs.Blazor.Common @using ChartJs.Blazor.Common.Enums @using ChartJs.Blazor.Util -@using ChartJs.Blazor.BarChart *@ +@using ChartJs.Blazor.BarChart @using System.Drawing @page "/admin" @@ -13,7 +13,7 @@ @code { - // protected BarConfig _config = default!; + protected BarConfig _config = default!; protected List<OptionItem> _dateOptions = default!; protected List<PostVisit> _visits = default!; protected bool _hideGraph = false; @@ -22,17 +22,17 @@ protected override async Task OnInitializedAsync() { - // _config = new BarConfig - // { - // Options = new BarOptions - // { - // Responsive = true, - // Legend = new Legend - // { - // Position = Position.Top - // } - // } - // }; + _config = new BarConfig + { + Options = new BarOptions + { + Responsive = true, + Legend = new Legend + { + Position = Position.Top + } + } + }; _dateOptions = new List<OptionItem> { new OptionItem { Id = 1, Title = _localizer["today"] }, @@ -41,58 +41,58 @@ new OptionItem { Id = 4, Title = _localizer["30-days"] }, new OptionItem { Id = 5, Title = _localizer["90-days"] }, }; - // Load(); + Load(); _analytics = await _http.GetFromJsonAsync<AnalyticsDto>("api/analytics"); } - // protected void Load() - // { - // var dataset = new BarDataset<int>() - // { - // Label = "Latest Post Views", - // BackgroundColor = ColorUtil.FromDrawingColor(Color.FromArgb(98, 42, 255)), - // BorderWidth = 0 - // }; - - // if (_analytics == null || _analytics.LatestPostViews == null) - // { - // LoadData(dataset, TestData()); - // } - // else - // { - // _hideList = _analytics.DisplayType == AnalyticsListType.Graph; - // _hideGraph = _analytics.DisplayType == AnalyticsListType.List; - - // LoadData(dataset, _analytics.LatestPostViews); - // } - - // if (_config.Data.Datasets.Count > 0) - // { - // _config.Data.Datasets.Clear(); - // } - - // _config.Data.Datasets.Add(dataset); - // } - - - - // protected void LoadData(IDataset<int> dataset, BarChartModel model) - // { - // _visits = new List<PostVisit>(); - // var labels = model.Labels.ToList(); - // var values = model.Data.ToList(); - - // _config.Data.Labels.Clear(); - - // for (int i = 0; i < labels.Count; i++) - // { - // _config.Data.Labels.Add(labels[i]); - // dataset.Add(values[i]); - - // _visits.Add(new PostVisit { Name = labels[i], Value = values[i] }); - // } - // _visits = _visits.OrderByDescending(v => v.Value).ToList(); - // } + protected void Load() + { + var dataset = new BarDataset<int>() + { + Label = "Latest Post Views", + BackgroundColor = ColorUtil.FromDrawingColor(Color.FromArgb(98, 42, 255)), + BorderWidth = 0 + }; + + if (_analytics == null || _analytics.LatestPostViews == null) + { + LoadData(dataset, TestData()); + } + else + { + _hideList = _analytics.DisplayType == AnalyticsListType.Graph; + _hideGraph = _analytics.DisplayType == AnalyticsListType.List; + + LoadData(dataset, _analytics.LatestPostViews); + } + + if (_config.Data.Datasets.Count > 0) + { + _config.Data.Datasets.Clear(); + } + + _config.Data.Datasets.Add(dataset); + } + + + + protected void LoadData(IDataset<int> dataset, BarChartModel model) + { + _visits = new List<PostVisit>(); + var labels = model.Labels.ToList(); + var values = model.Data.ToList(); + + _config.Data.Labels.Clear(); + + for (int i = 0; i < labels.Count; i++) + { + _config.Data.Labels.Add(labels[i]); + dataset.Add(values[i]); + + _visits.Add(new PostVisit { Name = labels[i], Value = values[i] }); + } + _visits = _visits.OrderByDescending(v => v.Value).ToList(); + } protected async Task ToggleAnalyticsView(bool isGraph) { diff --git a/src/Blogifier.Admin/wwwroot/index.html b/src/Blogifier.Admin/wwwroot/index.html index 628017365..84f14a0b0 100644 --- a/src/Blogifier.Admin/wwwroot/index.html +++ b/src/Blogifier.Admin/wwwroot/index.html @@ -54,6 +54,7 @@ </form> <script src="_framework/blazor.webassembly.js"></script> + <script src="_content/Blazored.Typeahead/blazored-typeahead.js"></script> <script src="admin/js/blogifier.js"></script> </body> </html> From 7b9f8bfcbd03a08496a05e9943e839d71546675a Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Tue, 1 Aug 2023 11:52:16 +0800 Subject: [PATCH 06/31] update test --- tests/Blogifier.Tests/Blogifier.Tests.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Blogifier.Tests/Blogifier.Tests.csproj b/tests/Blogifier.Tests/Blogifier.Tests.csproj index 90ab84e4d..310ae5c25 100644 --- a/tests/Blogifier.Tests/Blogifier.Tests.csproj +++ b/tests/Blogifier.Tests/Blogifier.Tests.csproj @@ -5,10 +5,10 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0-preview-23364-03" /> <PackageReference Include="Moq" Version="4.18.4" /> - <PackageReference Include="xunit" Version="2.5.0" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.5.0"> + <PackageReference Include="xunit" Version="2.5.1-pre.12" /> + <PackageReference Include="xunit.runner.visualstudio" Version="2.5.1-pre.4"> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PrivateAssets>all</PrivateAssets> </PackageReference> From b795231aa39536f0b312d53216a4f47ea0f67d40 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Tue, 1 Aug 2023 13:18:19 +0800 Subject: [PATCH 07/31] fix --- src/Blogifier.Admin/Blogifier.Admin.csproj | 3 +-- src/Blogifier/Blogifier.csproj | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Blogifier.Admin/Blogifier.Admin.csproj b/src/Blogifier.Admin/Blogifier.Admin.csproj index 6c829bb9e..ab514b1a7 100644 --- a/src/Blogifier.Admin/Blogifier.Admin.csproj +++ b/src/Blogifier.Admin/Blogifier.Admin.csproj @@ -13,8 +13,7 @@ <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.0-preview.6.23329.11" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-preview.6.23329.11" /> - <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-preview.6.23329.11" /> - <PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0-preview.6.23329.11" /> + <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-preview.6.23329.11" PrivateAssets="all" /> <PackageReference Include="Sotsera.Blazor.Toaster" Version="3.0.0" /> </ItemGroup> diff --git a/src/Blogifier/Blogifier.csproj b/src/Blogifier/Blogifier.csproj index 59d573268..168af66ee 100644 --- a/src/Blogifier/Blogifier.csproj +++ b/src/Blogifier/Blogifier.csproj @@ -7,10 +7,6 @@ <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled> </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)' == 'Release' "> - <BlazorWebAssemblyOmitDebugProxyOutput>true</BlazorWebAssemblyOmitDebugProxyOutput> - </PropertyGroup> - <ItemGroup> <PackageReference Include="AutoMapper" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> From 5917597f5327b28c381617a86514cc2d8165e681 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Tue, 1 Aug 2023 14:08:38 +0800 Subject: [PATCH 08/31] Webcil false --- src/Blogifier.Admin/Blogifier.Admin.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Blogifier.Admin/Blogifier.Admin.csproj b/src/Blogifier.Admin/Blogifier.Admin.csproj index ab514b1a7..12af8eadb 100644 --- a/src/Blogifier.Admin/Blogifier.Admin.csproj +++ b/src/Blogifier.Admin/Blogifier.Admin.csproj @@ -8,6 +8,9 @@ <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> From d3ca5632692fa8e197904d6e58131f3ec869fc50 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Tue, 1 Aug 2023 14:17:27 +0800 Subject: [PATCH 09/31] dockerignore --- .dockerignore | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.dockerignore b/.dockerignore index 0e89580c3..30c012657 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,8 +1,8 @@ -.git -**/bin/* -**/obj/* -**/node_modules/* +.git* +**/bin* +**/obj* +**/node_modules* Dockerfile docker-compose.yml -deploy/* +deploy* **/package-lock.json From 13deb93ec644cac46659e08b9f50c1a167c1c679 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Tue, 1 Aug 2023 15:09:15 +0800 Subject: [PATCH 10/31] BlazorWebAssemblyOmitDebugProxyOutput --- src/Blogifier/Blogifier.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Blogifier/Blogifier.csproj b/src/Blogifier/Blogifier.csproj index 168af66ee..59d573268 100644 --- a/src/Blogifier/Blogifier.csproj +++ b/src/Blogifier/Blogifier.csproj @@ -7,6 +7,10 @@ <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled> </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)' == 'Release' "> + <BlazorWebAssemblyOmitDebugProxyOutput>true</BlazorWebAssemblyOmitDebugProxyOutput> + </PropertyGroup> + <ItemGroup> <PackageReference Include="AutoMapper" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> From 36b7c4bb22b8c0d37ae9987e852cec9808ac20af Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Fri, 4 Aug 2023 16:26:04 +0800 Subject: [PATCH 11/31] config mirror --- Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Dockerfile b/Dockerfile index 8871a8749..b47639836 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,6 +2,9 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0-preview-alpine as sdk # TOTO zh-CH 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 From 047be82b09431f982b3b0629b19c19ccf7ea1054 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Fri, 4 Aug 2023 16:52:27 +0800 Subject: [PATCH 12/31] github workflows docker-image --- .github/workflows/docker-image.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/docker-image.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 000000000..dc973905a --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,28 @@ +name: build release docker + +on: + 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 From 66f99025750103c02d999314995590315094add3 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Fri, 4 Aug 2023 16:53:45 +0800 Subject: [PATCH 13/31] on up --- .github/workflows/docker-image.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index dc973905a..8853844c5 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -1,8 +1,11 @@ name: build release docker on: + push: + branches: + - 'preview' pull_request: - branches: [ "preview" ] + - 'preview' jobs: build: From 261b43695790665179b1df2f19fbd3696689e157 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Fri, 4 Aug 2023 16:54:47 +0800 Subject: [PATCH 14/31] fix on err --- .github/workflows/docker-image.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 8853844c5..baa40f1c7 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -5,6 +5,7 @@ on: branches: - 'preview' pull_request: + branches: - 'preview' jobs: From 607a9fd6fc9e1311f6a69e26d9fb40935a56baa4 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Fri, 4 Aug 2023 16:56:24 +0800 Subject: [PATCH 15/31] rm zh-CH mirror --- Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index b47639836..b8ca9d710 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0-preview-alpine 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" ] +# CMD [ "npm config set registry http://mirrors.cloud.tencent.com/npm" ] # Copy everything else and build COPY ./ /opt/blogifier WORKDIR /opt/blogifier @@ -12,7 +12,7 @@ RUN ["dotnet","publish", "-c", "Release","/p:RuntimeIdentifier=linux-musl-x64", FROM mcr.microsoft.com/dotnet/aspnet:8.0.0-preview.6-alpine3.18 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/ From 12ddea78ee793fac5e77c7aa11bf3457f06464de Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Mon, 7 Aug 2023 18:38:25 +0800 Subject: [PATCH 16/31] post cover def null --- .../Components/NavMenuComponent.razor | 2 +- .../Components/PostEditorComponent.razor | 21 +++++++------------ .../Pages/Blogs/EditorView.razor | 1 - .../BlogifierSharedConstant.cs | 2 +- .../Helper/{UserHelper.cs => PageHelper.cs} | 8 ++++++- .../Views/Themes/standard/page.cshtml | 2 +- .../Views/Themes/standard/post.cshtml | 4 ++-- .../Views/Themes/standard/post/author.cshtml | 2 +- .../Themes/standard/post/featured.cshtml | 4 ++-- .../Views/Themes/standard/post/related.cshtml | 4 ++-- .../Themes/standard/post/view-grid.cshtml | 4 ++-- .../Themes/standard/post/view-list.cshtml | 4 ++-- .../Views/Themes/standard/profile.cshtml | 2 +- src/Blogifier/Posts/ImportManager.cs | 3 ++- src/Blogifier/Posts/ImportRssProvider.cs | 1 - 15 files changed, 32 insertions(+), 32 deletions(-) rename src/Blogifier.Shared/Helper/{UserHelper.cs => PageHelper.cs} (50%) diff --git a/src/Blogifier.Admin/Components/NavMenuComponent.razor b/src/Blogifier.Admin/Components/NavMenuComponent.razor index dad13a69d..1f1065497 100644 --- a/src/Blogifier.Admin/Components/NavMenuComponent.razor +++ b/src/Blogifier.Admin/Components/NavMenuComponent.razor @@ -88,7 +88,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"> diff --git a/src/Blogifier.Admin/Components/PostEditorComponent.razor b/src/Blogifier.Admin/Components/PostEditorComponent.razor index 98b7bdcf8..434c9a3be 100644 --- a/src/Blogifier.Admin/Components/PostEditorComponent.razor +++ b/src/Blogifier.Admin/Components/PostEditorComponent.razor @@ -5,7 +5,7 @@ <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)) @@ -64,7 +64,7 @@ <input type="hidden" class="txt-upload" @bind="Post.Cover" name="cover" id="cover" readonly /> </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> @@ -100,9 +100,9 @@ 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; + //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.Description)) Post.Description = Post.Title; Post.State = postState; await OnSaveCallback.InvokeAsync(Post); @@ -131,16 +131,11 @@ } } - protected async Task ResetCoverAsync() - { - Post.Cover = BlogifierSharedConstant.DefaultCover; - await SaveAsync(); - } - - protected async Task RemoveCoverAsync() + protected Task RemoveCoverAsync() { Post.Cover = null; - await SaveAsync(); + StateHasChanged(); + return Task.CompletedTask; } } diff --git a/src/Blogifier.Admin/Pages/Blogs/EditorView.razor b/src/Blogifier.Admin/Pages/Blogs/EditorView.razor index b51c328c4..e808c15f2 100644 --- a/src/Blogifier.Admin/Pages/Blogs/EditorView.razor +++ b/src/Blogifier.Admin/Pages/Blogs/EditorView.razor @@ -22,7 +22,6 @@ Description = string.Empty, Content = string.Empty, PostType = PostType.Post, - Cover = BlogifierSharedConstant.DefaultCover, Categories = new List<CategoryDto>(), }; diff --git a/src/Blogifier.Shared/BlogifierSharedConstant.cs b/src/Blogifier.Shared/BlogifierSharedConstant.cs index ef8d7a568..e2d10ac82 100644 --- a/src/Blogifier.Shared/BlogifierSharedConstant.cs +++ b/src/Blogifier.Shared/BlogifierSharedConstant.cs @@ -8,7 +8,7 @@ public static class BlogifierSharedConstant public const string PolicyAdminName = "Administrator"; public static readonly string PolicyAdminValue = $"{((int)UserType.Administrator)}"; public static readonly string DefaultAvatar = "/img/avatar.jpg"; - public static readonly string DefaultCover = "img/cover.jpg"; + public static readonly string DefaultCover = "/img/cover.jpg"; public static readonly string DefaultLogo = "img/logo-sm.png"; public static readonly JsonSerializerOptions DefaultJsonSerializerOptions = new(JsonSerializerDefaults.Web); } diff --git a/src/Blogifier.Shared/Helper/UserHelper.cs b/src/Blogifier.Shared/Helper/PageHelper.cs similarity index 50% rename from src/Blogifier.Shared/Helper/UserHelper.cs rename to src/Blogifier.Shared/Helper/PageHelper.cs index 5a83fc028..18902f061 100644 --- a/src/Blogifier.Shared/Helper/UserHelper.cs +++ b/src/Blogifier.Shared/Helper/PageHelper.cs @@ -1,10 +1,16 @@ namespace Blogifier.Shared; -public static class UserHelper +public static class PageHelper { public static string CheckGetAvatarUrl(string? avatar) { if (!string.IsNullOrEmpty(avatar)) return avatar; return BlogifierSharedConstant.DefaultAvatar; } + + public static string CheckGetCoverrUrl(string? avatar) + { + if (!string.IsNullOrEmpty(avatar)) return avatar; + return BlogifierSharedConstant.DefaultCover; + } } diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/page.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/page.cshtml index 81f970c42..00204ca29 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/page.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/page.cshtml @@ -10,7 +10,7 @@ <main class="post-detail"> <article class="post"> <figure class="post-cover"> - <img class="post-cover-img" src="~/@Model.PostSlug.Post.Cover" alt="@Model.PostSlug.Post.Title"> + <img class="post-cover-img" src="@PageHelper.CheckGetCoverrUrl(Model.PostSlug.Post.Cover)" alt="@Model.PostSlug.Post.Title"> </figure> <header class="post-header post-container"> <h1 class="post-title">@Model.PostSlug.Post.Title</h1> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/post.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/post.cshtml index 4d14f2c84..adcc25ba9 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/post.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/post.cshtml @@ -8,13 +8,13 @@ <main class="post-detail"> <article class="post"> <figure class="post-cover"> - <img class="post-cover-img" src="~/@Model.PostSlug.Post.Cover" alt="@Model.PostSlug.Post.Title" aria-hidden="true"> + <img class="post-cover-img" src="@PageHelper.CheckGetCoverrUrl(Model.PostSlug.Post.Cover)" alt="@Model.PostSlug.Post.Title" aria-hidden="true"> </figure> <header class="post-header post-container"> <h1 class="post-title">@Model.PostSlug.Post.Title</h1> <div class="post-meta d-flex align-items-center"> <div class="post-meta-item post-meta-author"> - <img class="post-meta-author-img d-none d-md-block" width="32" height="32" src="@UserHelper.CheckGetAvatarUrl(Model.PostSlug.Post.User.Avatar)" + <img class="post-meta-author-img d-none d-md-block" width="32" height="32" src="@PageHelper.CheckGetAvatarUrl(Model.PostSlug.Post.User.Avatar)" alt="@Model.PostSlug.Post.User.NickName" aria-hidden="true" /> <div class="post-meta-author-details"> <span class="post-meta-label">@_localizer["author"]</span> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/post/author.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/post/author.cshtml index 88f4e4fb3..c9fa54f55 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/post/author.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/post/author.cshtml @@ -2,7 +2,7 @@ <section class="post-author d-md-flex align-items-md-center text-center text-md-start"> <figure class="post-author-cover mb-3 mb-md-0"> - <img class="post-author-img" width="96" height="96" src="@UserHelper.CheckGetAvatarUrl(Model.PostSlug.Post.User.Avatar)" alt="@Model.PostSlug.Post.User.NickName" /> + <img class="post-author-img" width="96" height="96" src="@PageHelper.CheckGetAvatarUrl(Model.PostSlug.Post.User.Avatar)" alt="@Model.PostSlug.Post.User.NickName" /> </figure> <div class="post-author-details"> <h5 class="post-author-name">@Model.PostSlug.Post.User.NickName</h5> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/post/featured.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/post/featured.cshtml index 0b00e4273..f42a85161 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/post/featured.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/post/featured.cshtml @@ -21,7 +21,7 @@ <section class="col-lg-7"> <figure class="featured-cover" aria-hidden="true"> <a href="~/post/@item.Slug" class="featured-cover-link" tabindex="-1"> - <img class="featured-cover-img" alt="POST_TITLE" src="~/@item.Cover"> + <img class="featured-cover-img" alt="POST_TITLE" src="@PageHelper.CheckGetCoverrUrl(item.Cover)"> </a> <figcaption class="visually-hidden">@item.Title</figcaption> </figure> @@ -32,7 +32,7 @@ </h2> <div class="featured-meta d-none d-md-flex"> <div class="featured-author"> - <img class="featured-author-img" src="@UserHelper.CheckGetAvatarUrl(item.User.Avatar)" width="16" height="16" alt="@item.User.NickName"> + <img class="featured-author-img" src="@PageHelper.CheckGetAvatarUrl(item.User.Avatar)" width="16" height="16" alt="@item.User.NickName"> <span class="featured-author-name">@item.User.NickName</span> </div> <div class="featured-date"> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/post/related.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/post/related.cshtml index 69b0ea7f0..affb8fddc 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/post/related.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/post/related.cshtml @@ -32,7 +32,7 @@ <div class="col-12 col-md mb-4 mb-md-0"> <article class="post-grid d-flex flex-column"> <figure class="post-grid-cover" aria-hidden="true"> - <img class="post-grid-img" src="~/@post.Cover" alt="@post.Title"> + <img class="post-grid-img" src="@PageHelper.CheckGetCoverrUrl(post.Cover)" alt="@post.Title"> </figure> @if (post.Categories != null) { @@ -51,7 +51,7 @@ </p> <div class="post-grid-meta d-flex"> <div class="post-grid-author"> - <img class="post-grid-author-img" src="@UserHelper.CheckGetAvatarUrl(post.User.Avatar)" width="16" height="16" alt="@post.User.NickName" aria-hidden="true"> + <img class="post-grid-author-img" src="@PageHelper.CheckGetAvatarUrl(post.User.Avatar)" width="16" height="16" alt="@post.User.NickName" aria-hidden="true"> <span class="post-grid-author-name">@post.User.NickName</span> </div> <div class="post-grid-date"> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/post/view-grid.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/post/view-grid.cshtml index 1a4c03326..c17ad76c7 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/post/view-grid.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/post/view-grid.cshtml @@ -10,7 +10,7 @@ <div class="col"> <article class="post-grid d-flex flex-column"> <figure class="post-grid-cover"> - <img class="post-grid-img" src="~/@post.Cover" alt="@post.Title"> + <img class="post-grid-img" src="@PageHelper.CheckGetCoverrUrl(post.Cover)" alt="@post.Title"> </figure> @if (post.Categories != null) { @@ -27,7 +27,7 @@ <p class="post-grid-desc">@Html.Raw(post.Description)</p> <div class="post-grid-meta d-flex"> <div class="post-grid-author"> - <img class="post-grid-author-img" src="@UserHelper.CheckGetAvatarUrl(post.User.Avatar)" width="16" height="16" alt="@post.User.NickName"> + <img class="post-grid-author-img" src="@PageHelper.CheckGetAvatarUrl(post.User.Avatar)" width="16" height="16" alt="@post.User.NickName"> <span class="post-grid-author-name">@post.User.NickName</span> </div> <div class="post-grid-date"> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/post/view-list.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/post/view-list.cshtml index 73e2e716a..ed9f89ee0 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/post/view-list.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/post/view-list.cshtml @@ -7,7 +7,7 @@ { <article class="post-list d-flex"> <figure class="post-list-cover"> - <img class="post-list-img" src="~/@post.Cover" alt="@post.Title"> + <img class="post-list-img" src="@PageHelper.CheckGetCoverrUrl(post.Cover)" alt="@post.Title"> </figure> <section class="post-list-details"> <h2 class="post-list-title"> @@ -15,7 +15,7 @@ </h2> <div class="post-list-meta d-flex"> <div class="post-list-meta-item post-list-author"> - <img class="post-list-author-img" src="@UserHelper.CheckGetAvatarUrl(post.User.Avatar)" width="16" height="16" + <img class="post-list-author-img" src="@PageHelper.CheckGetAvatarUrl(post.User.Avatar)" width="16" height="16" alt="@post.User.NickName"> <span class="post-list-author-name">@post.User.NickName</span> </div> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/profile.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/profile.cshtml index 418f99b23..222484eaf 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/profile.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/profile.cshtml @@ -21,7 +21,7 @@ <div class="form-item"> <label class="form-label mb-1">@_localizer["profile-picture"]</label> <div class="d-flex"> - <img src="@UserHelper.CheckGetAvatarUrl(Model.Avatar)" width="39" height="39" class="profilePicture rounded me-3" alt="@Model.NickName" /> + <img src="@PageHelper.CheckGetAvatarUrl(Model.Avatar)" width="39" height="39" class="profilePicture rounded me-3" alt="@Model.NickName" /> <button class="btn btn-link" onclick="return fileManager.uploadClick('@UploadType.Avatar');" type="button" title="@_localizer["upload"]" data-bs-toggle="tooltip"> <svg width="18" height="18" class="bi bi-arrow-up-circle"> <use xlink:href="/_content/@ThemesStandardConstant.AssemblyName/img/icon-sprites.svg#bi-arrow-up-circle"></use> diff --git a/src/Blogifier/Posts/ImportManager.cs b/src/Blogifier/Posts/ImportManager.cs index 34333766e..4286b2892 100644 --- a/src/Blogifier/Posts/ImportManager.cs +++ b/src/Blogifier/Posts/ImportManager.cs @@ -2,6 +2,7 @@ using Blogifier.Identity; using Blogifier.Shared; using Blogifier.Storages; +using Microsoft.IdentityModel.Tokens; using System; using System.Collections.Generic; using System.Linq; @@ -47,7 +48,7 @@ public async Task<IEnumerable<PostEditorDto>> WriteAsync(ImportDto request, int var publishedAt = post.PublishedAt!.Value.ToUniversalTime(); var baseAddress = new Uri(post.Slug!); - if (post.Cover != null && !post.Cover.Equals(BlogifierSharedConstant.DefaultCover, StringComparison.OrdinalIgnoreCase)) + if (!string.IsNullOrEmpty(post.Cover)) await _storageManager.UploadAsync(publishedAt, user.Id, baseAddress, post.Cover); var uploadeContent = await _storageManager.UploadsFoHtmlAsync(publishedAt, user.Id, baseAddress, post.Content); diff --git a/src/Blogifier/Posts/ImportRssProvider.cs b/src/Blogifier/Posts/ImportRssProvider.cs index 3e9288368..9d2a13538 100644 --- a/src/Blogifier/Posts/ImportRssProvider.cs +++ b/src/Blogifier/Posts/ImportRssProvider.cs @@ -29,7 +29,6 @@ public ImportDto Analysis(string feedUrl) Title = item.Title.Text, Description = GetDescription(item.Summary.Text), Content = content, - Cover = BlogifierSharedConstant.DefaultCover, PublishedAt = item.PublishDate.DateTime, PostType = PostType.Post, }; From f6a293384f9d0d229dcf6e0708835c4c86940f2b Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Tue, 8 Aug 2023 17:58:15 +0800 Subject: [PATCH 17/31] rm EditorComponent --- .../Components/EditorComponent.razor | 73 ------------------- .../Components/PageTitleComponent.razor | 3 +- .../Components/PostEditorComponent.razor | 71 ++++++++++++++++-- .../Pages/Blogs/EditorView.razor | 18 +---- .../Resources/Resource.zh-CN.resx | 3 + 5 files changed, 69 insertions(+), 99 deletions(-) delete mode 100644 src/Blogifier.Admin/Components/EditorComponent.razor diff --git a/src/Blogifier.Admin/Components/EditorComponent.razor b/src/Blogifier.Admin/Components/EditorComponent.razor deleted file mode 100644 index e9881bf67..000000000 --- a/src/Blogifier.Admin/Components/EditorComponent.razor +++ /dev/null @@ -1,73 +0,0 @@ -@using System.Text.RegularExpressions; -@using System.Text; - -@implements IAsyncDisposable - -@inject IStringLocalizer<Resource> _localizer -@inject IJSRuntime _jsRuntime -@inject HttpClient _httpClient - -<div class="easymde-wrapper"> - <textarea @ref="_textareaReference" tabindex="2" class="visually-hidden" placeholder="@_localizer["type-here"]"></textarea> -</div> -<InputFile @ref="_inputFileReference" OnChange="@LoadImageFiles" style="display:none;" accept="image/*" /> - -@code { - - [Parameter] public string Toolbar { get; set; } = default!; - - private ValueTask<IJSObjectReference> _taskModule; - private ElementReference? _textareaReference; - private InputFile? _inputFileReference; - - 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", Toolbar, _textareaReference, element); - } - } - - protected async Task LoadImageFiles(InputFileChangeEventArgs args) - { - var module = await _taskModule; - var element = _inputFileReference?.Element; - await module.InvokeVoidAsync("writeFrontFile", element); - } - - public async ValueTask SetValueAsync(string value) - { - var module = await _taskModule; - await module.InvokeVoidAsync("setEditorValue", value); - } - - public async ValueTask<string?> GetValueAsync() - { - var module = await _taskModule; - var content = await module.InvokeAsync<string>("getEditorValue"); - var imgsMatches = StringHelper.MatchesMarkdownImgBlob(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; - } - - async ValueTask IAsyncDisposable.DisposeAsync() - { - var module = await _taskModule; - await module.DisposeAsync(); - } -} diff --git a/src/Blogifier.Admin/Components/PageTitleComponent.razor b/src/Blogifier.Admin/Components/PageTitleComponent.razor index fba394574..369f9e00a 100644 --- a/src/Blogifier.Admin/Components/PageTitleComponent.razor +++ b/src/Blogifier.Admin/Components/PageTitleComponent.razor @@ -5,7 +5,6 @@ protected override async Task OnInitializedAsync() { - await SetTitleAsync(); + await _jsRuntime.InvokeVoidAsync("commonJsFunctions.setTitle", Title); } - private async Task SetTitleAsync() => await _jsRuntime.InvokeVoidAsync("commonJsFunctions.setTitle", Title); } diff --git a/src/Blogifier.Admin/Components/PostEditorComponent.razor b/src/Blogifier.Admin/Components/PostEditorComponent.razor index 434c9a3be..7f991f172 100644 --- a/src/Blogifier.Admin/Components/PostEditorComponent.razor +++ b/src/Blogifier.Admin/Components/PostEditorComponent.razor @@ -1,7 +1,13 @@ +@using System.Text.RegularExpressions; +@using System.Text; + +@implements IAsyncDisposable + @inject IStringLocalizer<Resource> _localizer -@inject IJSRuntime _jsruntime +@inject IJSRuntime _jsRuntime @inject NavigationManager _navigation @inject IToaster _toaster +@inject HttpClient _httpClient <div class="bfeditor"> <div class="bfeditor-header"> @@ -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 { @@ -82,18 +91,60 @@ [Parameter] public EventCallback<PostEditorDto> OnSaveCallback { get; set; } [Parameter] public EventCallback<int> OnRemoveCallback { get; set; } - private EditorComponent _editorComponent = default!; + private ValueTask<IJSObjectReference> _taskModule; + private ElementReference? _textareaReference; + private InputFile? _inputFileReference; + + 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); + } + } public async Task SetPostInfoAsync(PostEditorDto post) { var headTitle = _localizer["edit"] + " - " + post.Title; - await _jsruntime.InvokeVoidAsync("commonJsFunctions.setTitle", headTitle); - await _editorComponent.SetValueAsync(post.Content); + 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); + } + + async ValueTask<string?> GetValueAsync() + { + var module = await _taskModule; + var content = await module.InvokeAsync<string>("getEditorValue"); + var imgsMatches = StringHelper.MatchesMarkdownImgBlob(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 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"]); @@ -125,7 +176,7 @@ 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); } @@ -138,4 +189,10 @@ return Task.CompletedTask; } + async ValueTask IAsyncDisposable.DisposeAsync() + { + var module = await _taskModule; + await module.DisposeAsync(); + } + } diff --git a/src/Blogifier.Admin/Pages/Blogs/EditorView.razor b/src/Blogifier.Admin/Pages/Blogs/EditorView.razor index e808c15f2..e9b628a40 100644 --- a/src/Blogifier.Admin/Pages/Blogs/EditorView.razor +++ b/src/Blogifier.Admin/Pages/Blogs/EditorView.razor @@ -58,22 +58,6 @@ var result = await _httpClient.DeleteAsync($"api/post/{id}"); if (result.IsSuccessStatusCode) _toaster.Success(_localizer["completed"]); else _toaster.Error(_localizer["generic-error"]); - _navigation.NavigateTo($"admin"); + _navigation.NavigateTo("admin"); } - - //protected async Task OnFileUploadAsync(FrontFilePreviewDto file) - //{ - // using var fileContent = new StreamContent(file.BrowserFile.OpenReadStream()); - // fileContent.Headers.ContentType = new MediaTypeHeaderValue(file.BrowserFile.ContentType); - // using var content = new MultipartFormDataContent(); - // content.Add(content: fileContent, name: "\"file\"", fileName: file.BrowserFile.Name); - // var response = await _httpClient.PostAsync("api/storage/upload", content); - // if (response.IsSuccessStatusCode) - // { - // var stream = await response.Content.ReadAsStreamAsync(); - // var storage = JsonSerializer.Deserialize<StorageDto>(stream, BlogifierSharedConstant.DefaultJsonSerializerOptions)!; - // await _postEditorComponent.ReplaceSelectionAsync(file, storage); - // } - //} - } diff --git a/src/Blogifier.Shared/Resources/Resource.zh-CN.resx b/src/Blogifier.Shared/Resources/Resource.zh-CN.resx index f83ff6081..12731d74f 100644 --- a/src/Blogifier.Shared/Resources/Resource.zh-CN.resx +++ b/src/Blogifier.Shared/Resources/Resource.zh-CN.resx @@ -504,4 +504,7 @@ <data name="view-all" xml:space="preserve"> <value>查看所有</value> </data> + <data name="actions" xml:space="preserve"> + <value>操作</value> + </data> </root> \ No newline at end of file From 62ef7f2242635d5b9d9bf39a2b7f1bd49c6c2783 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Tue, 8 Aug 2023 18:33:17 +0800 Subject: [PATCH 18/31] editor js interop --- .../Components/PostEditorComponent.razor | 49 +++++++++--------- .../Interop/CommonJsInterop.cs | 25 ++++++++++ .../Interop/EditorJsInterop.cs | 50 +++++++++++++++++++ src/Blogifier.Admin/Program.cs | 2 + src/Blogifier.Admin/_Imports.razor | 1 + src/Blogifier.Admin/assets/js/blogifier.js | 4 +- 6 files changed, 104 insertions(+), 27 deletions(-) create mode 100644 src/Blogifier.Admin/Interop/CommonJsInterop.cs create mode 100644 src/Blogifier.Admin/Interop/EditorJsInterop.cs diff --git a/src/Blogifier.Admin/Components/PostEditorComponent.razor b/src/Blogifier.Admin/Components/PostEditorComponent.razor index 7f991f172..38fa73988 100644 --- a/src/Blogifier.Admin/Components/PostEditorComponent.razor +++ b/src/Blogifier.Admin/Components/PostEditorComponent.razor @@ -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"> @@ -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> @@ -91,18 +90,16 @@ [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); } } @@ -110,21 +107,12 @@ { 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) @@ -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(); @@ -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; + } } diff --git a/src/Blogifier.Admin/Interop/CommonJsInterop.cs b/src/Blogifier.Admin/Interop/CommonJsInterop.cs new file mode 100644 index 000000000..277ffa31e --- /dev/null +++ b/src/Blogifier.Admin/Interop/CommonJsInterop.cs @@ -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(); + } + } +} diff --git a/src/Blogifier.Admin/Interop/EditorJsInterop.cs b/src/Blogifier.Admin/Interop/EditorJsInterop.cs new file mode 100644 index 000000000..2af19b8c7 --- /dev/null +++ b/src/Blogifier.Admin/Interop/EditorJsInterop.cs @@ -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(); + } + } +} diff --git a/src/Blogifier.Admin/Program.cs b/src/Blogifier.Admin/Program.cs index 1f2d30da2..ef200e824 100644 --- a/src/Blogifier.Admin/Program.cs +++ b/src/Blogifier.Admin/Program.cs @@ -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; @@ -30,4 +31,5 @@ config.NewestOnTop = false; }); builder.Services.AddScoped<ToasterService>(); +builder.Services.AddScoped<EditorJsInterop>(); await builder.Build().RunAsync(); diff --git a/src/Blogifier.Admin/_Imports.razor b/src/Blogifier.Admin/_Imports.razor index f7552e5f3..8c1f38278 100644 --- a/src/Blogifier.Admin/_Imports.razor +++ b/src/Blogifier.Admin/_Imports.razor @@ -24,3 +24,4 @@ @using Blogifier.Helper; @using Blogifier.Identity @using Blogifier.Models +@using Blogifier.Admin.Interop diff --git a/src/Blogifier.Admin/assets/js/blogifier.js b/src/Blogifier.Admin/assets/js/blogifier.js index 9f1685ef1..2a8769d21 100644 --- a/src/Blogifier.Admin/assets/js/blogifier.js +++ b/src/Blogifier.Admin/assets/js/blogifier.js @@ -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"; }, @@ -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(); From 91f3ad4f412fb75a28ecea2420243e18b4512ad8 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 00:36:08 +0800 Subject: [PATCH 19/31] common js --- .../Interop/CommonJsInterop.cs | 3 +- src/Blogifier.Admin/assets/gulpfile.mjs | 46 +++++++++++ src/Blogifier.Admin/assets/js/blogifier.js | 2 +- src/Blogifier.Admin/assets/js/common.js | 78 +++++++++++++++++++ 4 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 src/Blogifier.Admin/assets/js/common.js diff --git a/src/Blogifier.Admin/Interop/CommonJsInterop.cs b/src/Blogifier.Admin/Interop/CommonJsInterop.cs index 277ffa31e..98dbbcdc3 100644 --- a/src/Blogifier.Admin/Interop/CommonJsInterop.cs +++ b/src/Blogifier.Admin/Interop/CommonJsInterop.cs @@ -10,8 +10,7 @@ public class CommonJsInterop : IAsyncDisposable public CommonJsInterop(IJSRuntime jsRuntime) { - moduleTask = new(() => jsRuntime.InvokeAsync<IJSObjectReference>( - "import", "./_content/RazorClassLibrary1/exampleJsInterop.js").AsTask()); + moduleTask = new(() => jsRuntime.InvokeAsync<IJSObjectReference>("import", "./admin/js/common.js").AsTask()); } public async ValueTask DisposeAsync() diff --git a/src/Blogifier.Admin/assets/gulpfile.mjs b/src/Blogifier.Admin/assets/gulpfile.mjs index 47ba6db96..205cbe932 100644 --- a/src/Blogifier.Admin/assets/gulpfile.mjs +++ b/src/Blogifier.Admin/assets/gulpfile.mjs @@ -134,6 +134,50 @@ const editorJs = () => { return stream.pipe(dest('dist/admin/js')); } +const commonJs = () => { + let outputOptions = { + sourcemap: true, + format: 'es' + } + + if (mode !== 'Debug') { + outputOptions.sourcemap = false; + outputOptions.minifyInternalExports = true; + outputOptions.plugins = [terser()]; + } + + let stream = rollupStream({ + input: 'js/common.js', + output: outputOptions, + plugins: [ + babel({ + exclude: 'node_modules/**', + presets: ['@babel/preset-env'], + babelHelpers: 'bundled', + }), + nodeResolve({ + browser: true, + preferBuiltins: false, + }), + commonjs({ + include: ['node_modules/**'], + exclude: [], + sourceMap: mode === 'Debug', + }), + ], + }) + + stream = stream.pipe(source('common.js')); + if (mode !== 'Debug') { + // JS Minify + stream = stream.pipe(buffer()) + stream = stream.pipe(plumber()) + stream = stream.pipe(uglify()) + } + return stream.pipe(dest('dist/admin/js')); +} + + // sass const scss = () => { let stream = src("./scss/**/*.scss") @@ -170,6 +214,7 @@ export default series( scss, blogifierJs, editorJs, + commonJs, watcher ) ); @@ -179,6 +224,7 @@ const build = series( scss, blogifierJs, editorJs, + commonJs, ); export { debug, release, build }; diff --git a/src/Blogifier.Admin/assets/js/blogifier.js b/src/Blogifier.Admin/assets/js/blogifier.js index 2a8769d21..94dbddb17 100644 --- a/src/Blogifier.Admin/assets/js/blogifier.js +++ b/src/Blogifier.Admin/assets/js/blogifier.js @@ -42,7 +42,6 @@ window.commonJsFunctions = { }, 500); }, writeCookie: function (name, value, days) { - var expires; if (days) { var date = new Date(); @@ -88,6 +87,7 @@ window.commonJsFunctions = { time(); setInterval(time, 60 * 1000); } + }; window.DataService = function () { diff --git a/src/Blogifier.Admin/assets/js/common.js b/src/Blogifier.Admin/assets/js/common.js new file mode 100644 index 000000000..1ea03f0a4 --- /dev/null +++ b/src/Blogifier.Admin/assets/js/common.js @@ -0,0 +1,78 @@ + +export function triggerClick(element) { + element.click(); +} + +export function setTitle(title) { + document.title = title + " - Blogifier"; +} + +export function setPageTitle() { + +} + +export function getFieldValue() { + if (field.type === 'checkbox') { + return document.getElementById(field.id).checked; + } + else { + return document.getElementById(field.id).value; + } +} + +export function getTxtValue(txt) { + return document.getElementById(txt).value; +} + +export function focusElement(id) { + setTimeout(function () { + const element = document.getElementById(id); + element.focus(); + }, 500); +} + +export function writeCookie() { + var expires; + if (days) { + var date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = "; expires=" + date.toGMTString(); + } + else { + expires = ""; + } + document.cookie = name + "=" + value + expires + "; path=/"; +} + +export function setTooltip(){ + setTimeout(function () { + let options = { "trigger": "hover", fallbackPlacements: ['bottom'] }; + let tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); + let tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { + return new Tooltip(tooltipTriggerEl, options) + }); + }, 1000); +} + +export function startClock() { + 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(); + var minutes = date.getMinutes(); + hours = hours % 12; + hours = hours ? hours : 12; + minutes = minutes < 10 ? '0' + minutes : minutes; + clock.textContent = hours + ':' + minutes; + + var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; + var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; + + clockDay.textContent = days[date.getDay()]; + clockMonth.textContent = months[date.getMonth()] + ' ' + date.getDate(); + } + time(); + setInterval(time, 60 * 1000); +} From 82702ae5b9fac5a7a776fb925d81a2e8a695525e Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 11:01:42 +0800 Subject: [PATCH 20/31] CommonJs --- .../Components/NavMenuComponent.razor | 3 +- .../Components/PageTitleComponent.razor | 3 +- .../Components/PostEditorComponent.razor | 5 +- .../Interop/CommonJsInterop.cs | 18 ++++ src/Blogifier.Admin/Program.cs | 1 + src/Blogifier.Admin/assets/js/blogifier.js | 88 ------------------- src/Blogifier.Admin/assets/js/common.js | 1 + 7 files changed, 27 insertions(+), 92 deletions(-) diff --git a/src/Blogifier.Admin/Components/NavMenuComponent.razor b/src/Blogifier.Admin/Components/NavMenuComponent.razor index 1f1065497..6a7b98856 100644 --- a/src/Blogifier.Admin/Components/NavMenuComponent.razor +++ b/src/Blogifier.Admin/Components/NavMenuComponent.razor @@ -3,6 +3,7 @@ @inject AuthenticationStateProvider _stateProvider @inject IJSRuntime _jsRuntime @inject IStringLocalizer<Resource> _localizer +@inject CommonJsInterop _commonJsInterop @code { @@ -20,7 +21,7 @@ { if (firstRender) { - await _jsRuntime.InvokeAsync<string>("commonJsFunctions.setTooltip", ""); + await _commonJsInterop.SetTooltipAsync(); } } } diff --git a/src/Blogifier.Admin/Components/PageTitleComponent.razor b/src/Blogifier.Admin/Components/PageTitleComponent.razor index 369f9e00a..4ddde8a07 100644 --- a/src/Blogifier.Admin/Components/PageTitleComponent.razor +++ b/src/Blogifier.Admin/Components/PageTitleComponent.razor @@ -1,10 +1,11 @@ @inject IJSRuntime _jsRuntime; +@inject CommonJsInterop _commonJsInterop @code { [Parameter] public string Title { get; set; } = default!; protected override async Task OnInitializedAsync() { - await _jsRuntime.InvokeVoidAsync("commonJsFunctions.setTitle", Title); + await _commonJsInterop.SetTitleAsync(Title); } } diff --git a/src/Blogifier.Admin/Components/PostEditorComponent.razor b/src/Blogifier.Admin/Components/PostEditorComponent.razor index 38fa73988..1cec425d9 100644 --- a/src/Blogifier.Admin/Components/PostEditorComponent.razor +++ b/src/Blogifier.Admin/Components/PostEditorComponent.razor @@ -7,6 +7,7 @@ @inject IToaster _toaster @inject HttpClient _httpClient @inject EditorJsInterop _editorJsInterop +@inject CommonJsInterop _commonJsInterop <div class="bfeditor"> <div class="bfeditor-header"> @@ -106,7 +107,7 @@ public async Task SetPostInfoAsync(PostEditorDto post) { var headTitle = _localizer["edit"] + " - " + post.Title; - await _jsRuntime.InvokeVoidAsync("commonJsFunctions.setTitle", headTitle); + await _commonJsInterop.SetTitleAsync(headTitle); await _editorJsInterop.SetEditorValueAsync(post.Content); } @@ -178,7 +179,7 @@ protected async Task ChangeCoverAsync() { - await _jsRuntime.InvokeVoidAsync("commonJsFunctions.triggerClick", _inputCovereference?.Element); + await _commonJsInterop.TriggerClickAsync(); } protected async Task LoadCovereFile(InputFileChangeEventArgs args) diff --git a/src/Blogifier.Admin/Interop/CommonJsInterop.cs b/src/Blogifier.Admin/Interop/CommonJsInterop.cs index 98dbbcdc3..e99fd9ad9 100644 --- a/src/Blogifier.Admin/Interop/CommonJsInterop.cs +++ b/src/Blogifier.Admin/Interop/CommonJsInterop.cs @@ -13,6 +13,24 @@ 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() + { + var module = await moduleTask.Value; + await module.InvokeVoidAsync("triggerClick"); + } + public async ValueTask DisposeAsync() { if (moduleTask.IsValueCreated) diff --git a/src/Blogifier.Admin/Program.cs b/src/Blogifier.Admin/Program.cs index ef200e824..9a91c4fcf 100644 --- a/src/Blogifier.Admin/Program.cs +++ b/src/Blogifier.Admin/Program.cs @@ -32,4 +32,5 @@ }); builder.Services.AddScoped<ToasterService>(); builder.Services.AddScoped<EditorJsInterop>(); +builder.Services.AddScoped<CommonJsInterop>(); await builder.Build().RunAsync(); diff --git a/src/Blogifier.Admin/assets/js/blogifier.js b/src/Blogifier.Admin/assets/js/blogifier.js index 94dbddb17..c54f2d3c5 100644 --- a/src/Blogifier.Admin/assets/js/blogifier.js +++ b/src/Blogifier.Admin/assets/js/blogifier.js @@ -1,95 +1,7 @@ -import { Tooltip } from 'bootstrap' - // Chart.js v2.9.4 import "chart.js" -window.commonJsFunctions = { - triggerClick: function (element) { - element.click(); - }, - setTitle: function (title) { - document.title = title + " - Blogifier"; - }, - setPageTitle: function () { - - }, - showPrompt: function (message) { - return prompt(message, 'Type anything here'); - }, - hideLoader: function (id) { - var el = document.getElementById(id); - el.style.display = 'none'; - }, - getFieldValue: function (field) { - if (field.type === 'checkbox') { - return document.getElementById(field.id).checked; - } - else { - return document.getElementById(field.id).value; - } - }, - getTxtValue: function (txt) { - return document.getElementById(txt).value; - }, - getSrcValue: function (src) { - return document.getElementById(src).src; - }, - focusElement: function (id) { - setTimeout(function () { - const element = document.getElementById(id); - element.focus(); - }, 500); - }, - writeCookie: function (name, value, days) { - var expires; - if (days) { - var date = new Date(); - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - expires = "; expires=" + date.toGMTString(); - } - else { - expires = ""; - } - document.cookie = name + "=" + value + expires + "; path=/"; - }, - setTooltip: function (args) { - setTimeout(function () { - let options = { "trigger": "hover", fallbackPlacements: ['bottom'] }; - let tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); - let tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { - return new Tooltip(tooltipTriggerEl, options) - }); - }, 1000); - }, - showModal: function (id) { - document.getElementById(id).showModal(); - }, - startClock: function () { - 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(); - var minutes = date.getMinutes(); - hours = hours % 12; - hours = hours ? hours : 12; - minutes = minutes < 10 ? '0' + minutes : minutes; - clock.textContent = hours + ':' + minutes; - - var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; - var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; - - clockDay.textContent = days[date.getDay()]; - clockMonth.textContent = months[date.getMonth()] + ' ' + date.getDate(); - } - time(); - setInterval(time, 60 * 1000); - } - -}; - window.DataService = function () { let upload = function (url, obj, success, fail) { fetch(url, { diff --git a/src/Blogifier.Admin/assets/js/common.js b/src/Blogifier.Admin/assets/js/common.js index 1ea03f0a4..e376a3d6b 100644 --- a/src/Blogifier.Admin/assets/js/common.js +++ b/src/Blogifier.Admin/assets/js/common.js @@ -1,3 +1,4 @@ +import { Tooltip } from 'bootstrap'; export function triggerClick(element) { element.click(); From 2a712be8280f1c353ac676e58ccf31c1a7bd96ee Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 11:10:18 +0800 Subject: [PATCH 21/31] admin assets --- src/Blogifier.Admin/assets/js/editor.js | 2 +- .../wwwroot/admin/favicons/browserconfig.xml | 12 +++---- .../wwwroot/admin/favicons/site.webmanifest | 34 +++++++++---------- src/Blogifier.Admin/wwwroot/index.html | 19 ++++------- 4 files changed, 31 insertions(+), 36 deletions(-) diff --git a/src/Blogifier.Admin/assets/js/editor.js b/src/Blogifier.Admin/assets/js/editor.js index c71cb2eca..64f10d058 100644 --- a/src/Blogifier.Admin/assets/js/editor.js +++ b/src/Blogifier.Admin/assets/js/editor.js @@ -204,7 +204,7 @@ function editorToolbarTooltip() { buttons[i].setAttribute('data-bs-placement', 'bottom'); } // TODO: remove this later: - commonJsFunctions.setTooltip(); + //commonJsFunctions.setTooltip(); } let easymde; diff --git a/src/Blogifier.Admin/wwwroot/admin/favicons/browserconfig.xml b/src/Blogifier.Admin/wwwroot/admin/favicons/browserconfig.xml index f4c19c27a..fa7e4a294 100644 --- a/src/Blogifier.Admin/wwwroot/admin/favicons/browserconfig.xml +++ b/src/Blogifier.Admin/wwwroot/admin/favicons/browserconfig.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <browserconfig> - <msapplication> - <tile> - <square150x150logo src="/mstile-150x150.png?v=3"/> - <TileColor>#ffffff</TileColor> - </tile> - </msapplication> + <msapplication> + <tile> + <square150x150logo src="/mstile-150x150.png?v=3"/> + <TileColor>#ffffff</TileColor> + </tile> + </msapplication> </browserconfig> diff --git a/src/Blogifier.Admin/wwwroot/admin/favicons/site.webmanifest b/src/Blogifier.Admin/wwwroot/admin/favicons/site.webmanifest index 0d4c82f8b..92f571f0c 100644 --- a/src/Blogifier.Admin/wwwroot/admin/favicons/site.webmanifest +++ b/src/Blogifier.Admin/wwwroot/admin/favicons/site.webmanifest @@ -1,19 +1,19 @@ { - "name": "Blogifier", - "short_name": "Blogifier", - "icons": [ - { - "src": "admin/favicons/android-chrome-192x192.png?v=3", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "admin/favicons/android-chrome-512x512.png?v=3", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#ffffff", - "background_color": "#ffffff", - "display": "standalone" + "name": "Blogifier", + "short_name": "Blogifier", + "icons": [ + { + "src": "admin/favicons/android-chrome-192x192.png?v=3", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "admin/favicons/android-chrome-512x512.png?v=3", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" } diff --git a/src/Blogifier.Admin/wwwroot/index.html b/src/Blogifier.Admin/wwwroot/index.html index 628017365..a6e34a242 100644 --- a/src/Blogifier.Admin/wwwroot/index.html +++ b/src/Blogifier.Admin/wwwroot/index.html @@ -10,16 +10,16 @@ TODO: for rtl: <link href="admin/css/blogifier.rtl.css" rel="stylesheet" /> --> - <link rel="apple-touch-icon" sizes="180x180" href="amdin/favicons/apple-touch-icon.png?v=2"> - <link rel="icon" type="image/png" sizes="32x32" href="admin/favicons/favicon-32x32.png?v=2"> - <link rel="icon" type="image/png" sizes="16x16" href="admin/favicons/favicon-16x16.png?v=2"> - <link rel="manifest" href="admin/favicons/site.webmanifest?v=2"> - <link rel="mask-icon" href="admin/favicons/safari-pinned-tab.svg?v=2" color="#622aff"> - <link rel="shortcut icon" href="admin/favicons/favicon.ico?v=2"> + <link rel="apple-touch-icon" sizes="180x180" href="amdin/favicons/apple-touch-icon.png"> + <link rel="icon" type="image/png" sizes="32x32" href="admin/favicons/favicon-32x32.png"> + <link rel="icon" type="image/png" sizes="16x16" href="admin/favicons/favicon-16x16.png"> + <link rel="manifest" href="admin/favicons/site.webmanifest"> + <link rel="mask-icon" href="admin/favicons/safari-pinned-tab.svg" color="#622aff"> + <link rel="shortcut icon" href="admin/favicons/favicon.ico"> <meta name="apple-mobile-web-app-title" content="Blogifier"> <meta name="application-name" content="Blogifier"> <meta name="msapplication-TileColor" content="#ffffff"> - <meta name="msapplication-config" content="admin/favicons/browserconfig.xml?v=2" /> + <meta name="msapplication-config" content="admin/favicons/browserconfig.xml" /> <meta name="theme-color" content="#ffffff"> </head> @@ -48,11 +48,6 @@ </div> </div> - <form class="d-none" method="post" name="frmUpload" id="frmUpload" action="upload" enctype="multipart/form-data"> - <input type="file" name="file" id="frmUploadFile" onchange="fileManager.uploadSubmit(); return false;" /> - <input type="submit" value="Upload" /> - </form> - <script src="_framework/blazor.webassembly.js"></script> <script src="admin/js/blogifier.js"></script> </body> From 2eeefb6739710b60a7a9760c1911e190cccde30e Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 11:44:29 +0800 Subject: [PATCH 22/31] fix regex matche --- .../Components/PostEditorComponent.razor | 8 +++++--- src/Blogifier.Admin/Dtos/FrontBlobInfo.cs | 7 +++++++ src/Blogifier.Admin/Interop/CommonJsInterop.cs | 11 +++++++++-- src/Blogifier.Admin/assets/js/common.js | 9 ++++++++- src/Blogifier.Shared/Helper/StringHelper.cs | 18 ++++-------------- .../Resources/Resource.zh-CN.resx | 6 ++++++ src/Blogifier/Storages/StorageManager.cs | 7 ++++--- 7 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 src/Blogifier.Admin/Dtos/FrontBlobInfo.cs diff --git a/src/Blogifier.Admin/Components/PostEditorComponent.razor b/src/Blogifier.Admin/Components/PostEditorComponent.razor index 1cec425d9..db14d458a 100644 --- a/src/Blogifier.Admin/Components/PostEditorComponent.razor +++ b/src/Blogifier.Admin/Components/PostEditorComponent.razor @@ -114,7 +114,7 @@ async ValueTask<string?> GetValueAsync() { var content = await _editorJsInterop.GetEditorValueAsync(); - var imgsMatches = StringHelper.MatchesMarkdownImgBlob(content); + var imgsMatches = StringHelper.MarkdownImgBlobGeneratedRegex().Matches(content); if (imgsMatches.Count > 0) { @@ -179,12 +179,14 @@ protected async Task ChangeCoverAsync() { - await _commonJsInterop.TriggerClickAsync(); + await _commonJsInterop.TriggerClickAsync(_inputCovereference?.Element); } protected async Task LoadCovereFile(InputFileChangeEventArgs args) { - + var element = _inputCovereference?.Element; + var blobInfo = await _commonJsInterop.GetInputFileBlobInfoAsync(element); + Post.Cover = blobInfo.Url; } protected Task RemoveCoverAsync() diff --git a/src/Blogifier.Admin/Dtos/FrontBlobInfo.cs b/src/Blogifier.Admin/Dtos/FrontBlobInfo.cs new file mode 100644 index 000000000..dabd575f9 --- /dev/null +++ b/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!; +} diff --git a/src/Blogifier.Admin/Interop/CommonJsInterop.cs b/src/Blogifier.Admin/Interop/CommonJsInterop.cs index e99fd9ad9..76d2dccb6 100644 --- a/src/Blogifier.Admin/Interop/CommonJsInterop.cs +++ b/src/Blogifier.Admin/Interop/CommonJsInterop.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using System; using System.Threading.Tasks; @@ -25,10 +26,16 @@ public async ValueTask SetTitleAsync(string content) await module.InvokeVoidAsync("setTitle", content); } - public async ValueTask TriggerClickAsync() + public async ValueTask TriggerClickAsync(ElementReference? element) { var module = await moduleTask.Value; - await module.InvokeVoidAsync("triggerClick"); + 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() diff --git a/src/Blogifier.Admin/assets/js/common.js b/src/Blogifier.Admin/assets/js/common.js index e376a3d6b..7cdd02f3e 100644 --- a/src/Blogifier.Admin/assets/js/common.js +++ b/src/Blogifier.Admin/assets/js/common.js @@ -45,7 +45,7 @@ export function writeCookie() { document.cookie = name + "=" + value + expires + "; path=/"; } -export function setTooltip(){ +export function setTooltip() { setTimeout(function () { let options = { "trigger": "hover", fallbackPlacements: ['bottom'] }; let tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); @@ -77,3 +77,10 @@ export function startClock() { time(); setInterval(time, 60 * 1000); } + +export function getInputFileBlobInfo(inputElement) { + const file = inputElement.files[0]; + const fileName = file.name; + const url = URL.createObjectURL(file); + return { fileName, url }; +} diff --git a/src/Blogifier.Shared/Helper/StringHelper.cs b/src/Blogifier.Shared/Helper/StringHelper.cs index 57d6bdf39..874bb17e8 100644 --- a/src/Blogifier.Shared/Helper/StringHelper.cs +++ b/src/Blogifier.Shared/Helper/StringHelper.cs @@ -4,35 +4,25 @@ namespace Blogifier.Helper; public static partial class StringHelper { - [GeneratedRegex("<script[^>]*>[\\s\\S]*?</script>", RegexOptions.Compiled)] private static partial Regex HtmlScriptGeneratedRegex(); public static string RemoveHtmlScriptTags(string input) => HtmlScriptGeneratedRegex().Replace(input, string.Empty); - [GeneratedRegex("<img[^>]*>[\\s\\S]*?>", RegexOptions.Compiled)] private static partial Regex HtmlImgGeneratedRegex(); public static string RemoveHtmlImgTags(string input) => HtmlImgGeneratedRegex().Replace(input, string.Empty); - [GeneratedRegex("<img.+?src=[\"'](.+?)[\"'].+?>", RegexOptions.Compiled)] - private static partial Regex HtmlImgSrcGeneratedRegex(); - public static Match MatchHtmlImgSrc(string input) => HtmlImgSrcGeneratedRegex().Match(input); + public static partial Regex HtmlImgSrcGeneratedRegex(); [GeneratedRegex("<img[^>]*?src\\s*=\\s*[\"']?([^'\" >]+?)[ '\"][^>]*?>", RegexOptions.Compiled)] - private static partial Regex HtmlImgTagsGeneratedRegex(); - public static MatchCollection MatchesHtmlImgTags(string input) => HtmlImgTagsGeneratedRegex().Matches(input); - + public static partial Regex HtmlImgTagsGeneratedRegex(); [GeneratedRegex("(?i)<a\\b[^>]*?>(?<text>.*?)</a>", RegexOptions.Compiled)] - private static partial Regex HtmlFileGeneratedRegex(); - public static MatchCollection MatchesHtmlFile(string input) => HtmlFileGeneratedRegex().Matches(input); - + public static partial Regex HtmlFileGeneratedRegex(); [GeneratedRegex("!\\[[^\\]]*\\]\\((blob:[^)]+)\\)", RegexOptions.Compiled)] - private static partial Regex MarkdownImgBlobGeneratedRegex(); - public static MatchCollection MatchesMarkdownImgBlob(string input) => MarkdownImgBlobGeneratedRegex().Matches(input); - + public static partial Regex MarkdownImgBlobGeneratedRegex(); [GeneratedRegex(@"!\[(?<filename>[^\]]+)\]\(data:image\/(?<type>.+);base64,(?<data>.+?)\)", RegexOptions.Compiled)] public static partial Regex MarkdownDataImageBase64BlobGeneratedRegex(); diff --git a/src/Blogifier.Shared/Resources/Resource.zh-CN.resx b/src/Blogifier.Shared/Resources/Resource.zh-CN.resx index 12731d74f..bf3c902be 100644 --- a/src/Blogifier.Shared/Resources/Resource.zh-CN.resx +++ b/src/Blogifier.Shared/Resources/Resource.zh-CN.resx @@ -507,4 +507,10 @@ <data name="actions" xml:space="preserve"> <value>操作</value> </data> + <data name="change" xml:space="preserve"> + <value>修改</value> + </data> + <data name="reset" xml:space="preserve"> + <value>重置</value> + </data> </root> \ No newline at end of file diff --git a/src/Blogifier/Storages/StorageManager.cs b/src/Blogifier/Storages/StorageManager.cs index 6487bdc44..60af6d68e 100644 --- a/src/Blogifier/Storages/StorageManager.cs +++ b/src/Blogifier/Storages/StorageManager.cs @@ -108,14 +108,15 @@ public async Task<string> UploadsFoHtmlAsync(DateTime uploadAt, int userid, Uri public async Task<string> UploadImagesFoHtml(DateTime uploadAt, int userid, Uri baseAddress, string content) { - var matches = StringHelper.MatchesHtmlImgTags(content); + var matches = StringHelper.HtmlImgTagsGeneratedRegex().Matches(content); if (matches.Any()) { var contentBuilder = new StringBuilder(content); + var htmlImgSrcRegex = StringHelper.HtmlImgSrcGeneratedRegex(); foreach (Match match in matches.Cast<Match>()) { var tag = match.Value; - var matchUrl = StringHelper.MatchHtmlImgSrc(tag); + var matchUrl = htmlImgSrcRegex.Match(tag); var urlString = matchUrl.Groups[1].Value; var storage = await UploadAsync(uploadAt, userid, baseAddress, urlString); var uploadTag = $""; @@ -128,7 +129,7 @@ public async Task<string> UploadImagesFoHtml(DateTime uploadAt, int userid, Uri public async Task<string> UploadFilesFoHtml(DateTime uploadAt, int userid, Uri baseAddress, string content) { - var matches = StringHelper.MatchesHtmlFile(content); + var matches = StringHelper.HtmlFileGeneratedRegex().Matches(content); if (matches.Any()) { var contentBuilder = new StringBuilder(content); From 4292759637368970636247b69cb0cdf919a97987 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 12:02:25 +0800 Subject: [PATCH 23/31] Cover Generated Data img --- .../Components/PostEditorComponent.razor | 18 +++++++++++++++++- src/Blogifier.Admin/assets/gulpfile.mjs | 1 - src/Blogifier.Admin/assets/js/common.js | 1 + src/Blogifier.Shared/Helper/StringHelper.cs | 3 +++ src/Blogifier/Storages/StorageManager.cs | 4 ---- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/Blogifier.Admin/Components/PostEditorComponent.razor b/src/Blogifier.Admin/Components/PostEditorComponent.razor index db14d458a..1ed41073f 100644 --- a/src/Blogifier.Admin/Components/PostEditorComponent.razor +++ b/src/Blogifier.Admin/Components/PostEditorComponent.razor @@ -146,12 +146,28 @@ return; } Post.Content = content; + if (!string.IsNullOrEmpty(Post.Cover)) + { + Console.WriteLine(Post.Cover); + var coverMatche = StringHelper.BlobUrlGeneratedRegex().Match(Post.Cover); + Console.WriteLine(coverMatche.Success); + 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; + Post.Cover = dataString; + Console.WriteLine(dataString); + } + } + //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.Description)) Post.Description = Post.Title; Post.State = postState; - await OnSaveCallback.InvokeAsync(Post); + //await OnSaveCallback.InvokeAsync(Post); } protected async Task SaveAsync() diff --git a/src/Blogifier.Admin/assets/gulpfile.mjs b/src/Blogifier.Admin/assets/gulpfile.mjs index 205cbe932..6202f7955 100644 --- a/src/Blogifier.Admin/assets/gulpfile.mjs +++ b/src/Blogifier.Admin/assets/gulpfile.mjs @@ -209,7 +209,6 @@ const watcher = () => { }; export default series( - clean, parallel( scss, blogifierJs, diff --git a/src/Blogifier.Admin/assets/js/common.js b/src/Blogifier.Admin/assets/js/common.js index 7cdd02f3e..765469dc3 100644 --- a/src/Blogifier.Admin/assets/js/common.js +++ b/src/Blogifier.Admin/assets/js/common.js @@ -82,5 +82,6 @@ export function getInputFileBlobInfo(inputElement) { const file = inputElement.files[0]; const fileName = file.name; const url = URL.createObjectURL(file); + console.log(url); return { fileName, url }; } diff --git a/src/Blogifier.Shared/Helper/StringHelper.cs b/src/Blogifier.Shared/Helper/StringHelper.cs index 874bb17e8..634c403e8 100644 --- a/src/Blogifier.Shared/Helper/StringHelper.cs +++ b/src/Blogifier.Shared/Helper/StringHelper.cs @@ -26,4 +26,7 @@ public static partial class StringHelper [GeneratedRegex(@"!\[(?<filename>[^\]]+)\]\(data:image\/(?<type>.+);base64,(?<data>.+?)\)", RegexOptions.Compiled)] public static partial Regex MarkdownDataImageBase64BlobGeneratedRegex(); + + [GeneratedRegex(@"blob:(https?://[^/]+/\S+)", RegexOptions.Compiled)] + public static partial Regex BlobUrlGeneratedRegex(); } diff --git a/src/Blogifier/Storages/StorageManager.cs b/src/Blogifier/Storages/StorageManager.cs index 60af6d68e..8c87a85d1 100644 --- a/src/Blogifier/Storages/StorageManager.cs +++ b/src/Blogifier/Storages/StorageManager.cs @@ -5,11 +5,7 @@ using Microsoft.AspNetCore.StaticFiles; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Microsoft.IdentityModel.Tokens; using System; -using System.Collections.Generic; -using System.IO; using System.Linq; using System.Net.Http; using System.Text; From 25da050955a366d3d921e8a27094b2456c8c2160 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 13:06:23 +0800 Subject: [PATCH 24/31] up cover --- .../Components/PostEditorComponent.razor | 10 ++-------- src/Blogifier.Shared/Helper/StringHelper.cs | 11 ++++++----- src/Blogifier/Interfaces/PostController.cs | 10 ++++++++++ src/Blogifier/Posts/PostProvider.cs | 16 ++++++++++++---- src/Blogifier/Storages/StorageManager.cs | 18 ++++++++++++++++++ 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/Blogifier.Admin/Components/PostEditorComponent.razor b/src/Blogifier.Admin/Components/PostEditorComponent.razor index 1ed41073f..e6a44eec0 100644 --- a/src/Blogifier.Admin/Components/PostEditorComponent.razor +++ b/src/Blogifier.Admin/Components/PostEditorComponent.razor @@ -148,26 +148,20 @@ Post.Content = content; if (!string.IsNullOrEmpty(Post.Cover)) { - Console.WriteLine(Post.Cover); var coverMatche = StringHelper.BlobUrlGeneratedRegex().Match(Post.Cover); - Console.WriteLine(coverMatche.Success); 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; - Post.Cover = dataString; Console.WriteLine(dataString); + Post.Cover = dataString; } } - - //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.Description)) Post.Description = Post.Title; Post.State = postState; - //await OnSaveCallback.InvokeAsync(Post); + await OnSaveCallback.InvokeAsync(Post); } protected async Task SaveAsync() diff --git a/src/Blogifier.Shared/Helper/StringHelper.cs b/src/Blogifier.Shared/Helper/StringHelper.cs index 634c403e8..1f9c3c34c 100644 --- a/src/Blogifier.Shared/Helper/StringHelper.cs +++ b/src/Blogifier.Shared/Helper/StringHelper.cs @@ -5,12 +5,10 @@ namespace Blogifier.Helper; public static partial class StringHelper { [GeneratedRegex("<script[^>]*>[\\s\\S]*?</script>", RegexOptions.Compiled)] - private static partial Regex HtmlScriptGeneratedRegex(); - public static string RemoveHtmlScriptTags(string input) => HtmlScriptGeneratedRegex().Replace(input, string.Empty); + public static partial Regex HtmlScriptGeneratedRegex(); [GeneratedRegex("<img[^>]*>[\\s\\S]*?>", RegexOptions.Compiled)] - private static partial Regex HtmlImgGeneratedRegex(); - public static string RemoveHtmlImgTags(string input) => HtmlImgGeneratedRegex().Replace(input, string.Empty); + public static partial Regex HtmlImgGeneratedRegex(); [GeneratedRegex("<img.+?src=[\"'](.+?)[\"'].+?>", RegexOptions.Compiled)] public static partial Regex HtmlImgSrcGeneratedRegex(); @@ -24,9 +22,12 @@ public static partial class StringHelper [GeneratedRegex("!\\[[^\\]]*\\]\\((blob:[^)]+)\\)", RegexOptions.Compiled)] public static partial Regex MarkdownImgBlobGeneratedRegex(); - [GeneratedRegex(@"!\[(?<filename>[^\]]+)\]\(data:image\/(?<type>.+);base64,(?<data>.+?)\)", RegexOptions.Compiled)] + [GeneratedRegex(@"!\[(?<filename>[^\]]+)\]\(data:image\/(?<type>.+);base64,(?<data>.*)\)", RegexOptions.Compiled)] public static partial Regex MarkdownDataImageBase64BlobGeneratedRegex(); [GeneratedRegex(@"blob:(https?://[^/]+/\S+)", RegexOptions.Compiled)] public static partial Regex BlobUrlGeneratedRegex(); + + [GeneratedRegex(@"data:image\/(?<type>.+);base64,(?<data>.*)", RegexOptions.Compiled)] + public static partial Regex DataImageBase64GeneratedRegex(); } diff --git a/src/Blogifier/Interfaces/PostController.cs b/src/Blogifier/Interfaces/PostController.cs index 9478b6da5..b70587f3b 100644 --- a/src/Blogifier/Interfaces/PostController.cs +++ b/src/Blogifier/Interfaces/PostController.cs @@ -46,6 +46,11 @@ public async Task<string> AddPostAsync([FromServices] StorageManager storageMana { var userId = User.FirstUserId(); var uploadAt = DateTime.UtcNow; + if (!string.IsNullOrEmpty(post.Cover)) + { + var coverUrl = await storageManager.UploadImagesBase64(uploadAt, userId, post.Cover); + post.Cover = coverUrl; + } var uploadContent = await storageManager.UploadImagesBase64FoHtml(uploadAt, userId, post.Content); post.Content = uploadContent; return await _postProvider.AddAsync(post, userId); @@ -57,6 +62,11 @@ public async Task UpdateAsync([FromServices] StorageManager storageManager, [Fro { var userId = User.FirstUserId(); var uploadAt = DateTime.UtcNow; + if (!string.IsNullOrEmpty(post.Cover)) + { + var coverUrl = await storageManager.UploadImagesBase64(uploadAt, userId, post.Cover); + post.Cover = coverUrl; + } var uploadContent = await storageManager.UploadImagesBase64FoHtml(uploadAt, userId, post.Content); post.Content = uploadContent; await _postProvider.UpdateAsync(post, userId); diff --git a/src/Blogifier/Posts/PostProvider.cs b/src/Blogifier/Posts/PostProvider.cs index 586a2583a..47dc587c9 100644 --- a/src/Blogifier/Posts/PostProvider.cs +++ b/src/Blogifier/Posts/PostProvider.cs @@ -256,8 +256,12 @@ private async Task<Post> AddInternalAsync(PostEditorDto postInput, int userId) { var slug = await GetSlugFromTitle(postInput.Title); var postCategories = await CheckPostCategories(postInput.Categories); - var contentFiltr = StringHelper.RemoveHtmlImgTags(StringHelper.RemoveHtmlScriptTags(postInput.Content)); - var descriptionFiltr = StringHelper.RemoveHtmlImgTags(StringHelper.RemoveHtmlScriptTags(postInput.Description)); + + var contentScriptFiltr = StringHelper.HtmlScriptGeneratedRegex().Replace(postInput.Content, string.Empty); + var descriptionScriptFiltr = StringHelper.HtmlScriptGeneratedRegex().Replace(postInput.Description, string.Empty); + var contentFiltr = StringHelper.HtmlImgGeneratedRegex().Replace(contentScriptFiltr, string.Empty); + var descriptionFiltr = StringHelper.HtmlImgGeneratedRegex().Replace(descriptionScriptFiltr, string.Empty); + var publishedAt = GetPublishedAt(postInput.PublishedAt, postInput.State); var post = new Post { @@ -316,8 +320,12 @@ public async Task UpdateAsync(PostEditorDto postInput, int userId) post.Slug = postInput.Slug!; post.Title = postInput.Title; - var contentFiltr = StringHelper.RemoveHtmlImgTags(StringHelper.RemoveHtmlScriptTags(postInput.Content)); - var descriptionFiltr = StringHelper.RemoveHtmlImgTags(StringHelper.RemoveHtmlScriptTags(postInput.Description)); + + var contentScriptFiltr = StringHelper.HtmlScriptGeneratedRegex().Replace(postInput.Content, string.Empty); + var descriptionScriptFiltr = StringHelper.HtmlScriptGeneratedRegex().Replace(postInput.Description, string.Empty); + var contentFiltr = StringHelper.HtmlImgGeneratedRegex().Replace(contentScriptFiltr, string.Empty); + var descriptionFiltr = StringHelper.HtmlImgGeneratedRegex().Replace(descriptionScriptFiltr, string.Empty); + post.Description = descriptionFiltr; post.Content = contentFiltr; post.Cover = postInput.Cover; diff --git a/src/Blogifier/Storages/StorageManager.cs b/src/Blogifier/Storages/StorageManager.cs index 8c87a85d1..4768ca6bd 100644 --- a/src/Blogifier/Storages/StorageManager.cs +++ b/src/Blogifier/Storages/StorageManager.cs @@ -171,6 +171,24 @@ public async Task<string> UploadImagesBase64FoHtml(DateTime uploadAt, int userid return content; } + public async Task<string> UploadImagesBase64(DateTime uploadAt, int userid, string dataOrUrl) + { + var match = StringHelper.DataImageBase64GeneratedRegex().Match(dataOrUrl); + if (match.Success) + { + var imageType = match.Groups["type"].Value; + var base64Data = match.Groups["data"].Value; + var imageDataBytes = Convert.FromBase64String(base64Data); + var fileName = Guid.NewGuid().ToString() + "." + imageType; + var path = $"{userid}/{uploadAt.Year}{uploadAt.Month}/{fileName}"; + if (!_contentTypeProvider.TryGetContentType(fileName, out var contentType)) + contentType = "text/html"; + var storage = await _storageProvider.AddAsync(uploadAt, userid, path, fileName, imageDataBytes, contentType); + return storage.Slug; + } + return dataOrUrl; + } + private bool InvalidFileName(string fileName) { var fileExtensions = _fileExtensions ?? BlogifierConstant.FileExtensions; From 2540942d68f685cc30aa57dc036b596ce4526776 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 14:25:01 +0800 Subject: [PATCH 25/31] preview.7 --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index b8ca9d710..48bcce740 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:8.0-preview-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 apk add --no-cache npm @@ -10,7 +10,7 @@ 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:8.0.0-preview.6-alpine3.18 as run +FROM mcr.microsoft.com/dotnet/aspnet:8.0.0-preview.7-alpine3.18 as run # TOTO zh-CH # RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories RUN apk add --no-cache icu-libs From 27b4672c94b450853535bc63793e01001ba68e27 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 14:31:18 +0800 Subject: [PATCH 26/31] dotnet sdk 7.0.400 --- global.json | 2 +- src/Blogifier.Admin/Blogifier.Admin.csproj | 8 ++++---- src/Blogifier.Shared/Blogifier.Shared.csproj | 2 +- src/Blogifier/Blogifier.csproj | 18 +++++++++--------- tests/Blogifier.Tests/Blogifier.Tests.csproj | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/global.json b/global.json index e383752a1..06ce1b485 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "7.0.304" + "version": "7.0.400" } } diff --git a/src/Blogifier.Admin/Blogifier.Admin.csproj b/src/Blogifier.Admin/Blogifier.Admin.csproj index 1b365811c..549470a1e 100644 --- a/src/Blogifier.Admin/Blogifier.Admin.csproj +++ b/src/Blogifier.Admin/Blogifier.Admin.csproj @@ -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> diff --git a/src/Blogifier.Shared/Blogifier.Shared.csproj b/src/Blogifier.Shared/Blogifier.Shared.csproj index bc42f863d..1a73688f7 100644 --- a/src/Blogifier.Shared/Blogifier.Shared.csproj +++ b/src/Blogifier.Shared/Blogifier.Shared.csproj @@ -6,7 +6,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.9" /> + <PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.10" /> </ItemGroup> <ItemGroup> diff --git a/src/Blogifier/Blogifier.csproj b/src/Blogifier/Blogifier.csproj index 7db59c99a..5e528df67 100644 --- a/src/Blogifier/Blogifier.csproj +++ b/src/Blogifier/Blogifier.csproj @@ -14,23 +14,23 @@ <ItemGroup> <PackageReference Include="AutoMapper" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> - <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.9" /> - <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="7.0.9" /> - <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="7.0.9" /> - <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.9" /> - <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.9"> + <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.10" /> + <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="7.0.10" /> + <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="7.0.10" /> + <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.10" /> + <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.10"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> - <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.9" /> - <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.9" /> - <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="7.0.9" /> + <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.10" /> + <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.10" /> + <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="7.0.10" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4" /> <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" /> <PackageReference Include="Minio" Version="5.0.0" /> <PackageReference Include="Serilog.AspNetCore" Version="7.0.0" /> <PackageReference Include="ReverseMarkdown" Version="3.25.0" /> - <PackageReference Include="Markdig" Version="0.31.0" /> + <PackageReference Include="Markdig" Version="0.32.0" /> <PackageReference Include="NETCore.MailKit" Version="2.1.0" /> <PackageReference Include="System.ServiceModel.Syndication" Version="7.0.0" /> <PackageReference Include="Microsoft.SyndicationFeed.ReaderWriter" Version="1.0.2" /> diff --git a/tests/Blogifier.Tests/Blogifier.Tests.csproj b/tests/Blogifier.Tests/Blogifier.Tests.csproj index 1a87258bf..431efe15b 100644 --- a/tests/Blogifier.Tests/Blogifier.Tests.csproj +++ b/tests/Blogifier.Tests/Blogifier.Tests.csproj @@ -5,8 +5,8 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" /> - <PackageReference Include="Moq" Version="4.18.4" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" /> + <PackageReference Include="Moq" Version="4.20.1" /> <PackageReference Include="xunit" Version="2.5.0" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.5.0"> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> From 6007e677590879211cba663cc303908d1c91e543 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 14:44:23 +0800 Subject: [PATCH 27/31] sdk preview.7 --- global.json | 5 +++++ src/Blogifier.Admin/Blogifier.Admin.csproj | 6 +++--- src/Blogifier.Shared/Blogifier.Shared.csproj | 2 +- src/Blogifier/Blogifier.csproj | 18 +++++++++--------- tests/Blogifier.Tests/Blogifier.Tests.csproj | 8 ++++---- 5 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 global.json diff --git a/global.json b/global.json new file mode 100644 index 000000000..4ba67068e --- /dev/null +++ b/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "8.0.100-preview.7.23376.3" + } +} diff --git a/src/Blogifier.Admin/Blogifier.Admin.csproj b/src/Blogifier.Admin/Blogifier.Admin.csproj index 625921847..e2496d344 100644 --- a/src/Blogifier.Admin/Blogifier.Admin.csproj +++ b/src/Blogifier.Admin/Blogifier.Admin.csproj @@ -14,9 +14,9 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.0-preview.6.23329.11" /> - <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-preview.6.23329.11" /> - <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-preview.6.23329.11" PrivateAssets="all" /> + <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> diff --git a/src/Blogifier.Shared/Blogifier.Shared.csproj b/src/Blogifier.Shared/Blogifier.Shared.csproj index 91540bdeb..0ffd8284e 100644 --- a/src/Blogifier.Shared/Blogifier.Shared.csproj +++ b/src/Blogifier.Shared/Blogifier.Shared.csproj @@ -6,7 +6,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0-preview.6.23329.11" /> + <PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0-preview.7.23375.9" /> </ItemGroup> <ItemGroup> diff --git a/src/Blogifier/Blogifier.csproj b/src/Blogifier/Blogifier.csproj index b4164cd61..0f8460e96 100644 --- a/src/Blogifier/Blogifier.csproj +++ b/src/Blogifier/Blogifier.csproj @@ -14,17 +14,17 @@ <ItemGroup> <PackageReference Include="AutoMapper" Version="12.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" /> - <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.0-preview.6.23329.11" /> - <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.0-preview.6.23329.11" /> - <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.0-preview.6.23329.11" /> - <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0-preview.6.23329.11" /> - <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0-preview.6.23329.4"> + <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.0-preview.7.23375.9" /> + <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.0-preview.7.23375.9" /> + <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.0-preview.7.23375.9" /> + <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0-preview.7.23375.9" /> + <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0-preview.7.23375.4"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> - <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0-preview.6.23329.4" /> - <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0-preview.6.23329.4" /> - <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.0-preview.6.23329.11" /> + <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0-preview.7.23375.4" /> + <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0-preview.7.23375.4" /> + <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.0-preview.7.23375.9" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0-preview.4" /> <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" /> <PackageReference Include="Minio" Version="5.0.0" /> @@ -32,7 +32,7 @@ <PackageReference Include="ReverseMarkdown" Version="3.25.0" /> <PackageReference Include="Markdig" Version="0.32.0" /> <PackageReference Include="NETCore.MailKit" Version="2.1.0" /> - <PackageReference Include="System.ServiceModel.Syndication" Version="8.0.0-preview.6.23329.7" /> + <PackageReference Include="System.ServiceModel.Syndication" Version="8.0.0-preview.7.23375.6" /> <PackageReference Include="Microsoft.SyndicationFeed.ReaderWriter" Version="1.0.2" /> </ItemGroup> diff --git a/tests/Blogifier.Tests/Blogifier.Tests.csproj b/tests/Blogifier.Tests/Blogifier.Tests.csproj index 310ae5c25..df1d2b36b 100644 --- a/tests/Blogifier.Tests/Blogifier.Tests.csproj +++ b/tests/Blogifier.Tests/Blogifier.Tests.csproj @@ -5,10 +5,10 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0-preview-23364-03" /> - <PackageReference Include="Moq" Version="4.18.4" /> - <PackageReference Include="xunit" Version="2.5.1-pre.12" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.5.1-pre.4"> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0-preview-23371-04" /> + <PackageReference Include="Moq" Version="4.20.1" /> + <PackageReference Include="xunit" Version="2.5.1-pre.20" /> + <PackageReference Include="xunit.runner.visualstudio" Version="2.5.1-pre.10"> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PrivateAssets>all</PrivateAssets> </PackageReference> From dc7a607093eaf13ada3e650ef810849f8541bd87 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 15:09:56 +0800 Subject: [PATCH 28/31] aspnet-composite --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 48bcce740..dc6a203ff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ 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:8.0.0-preview.7-alpine3.18 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 apk add --no-cache icu-libs From c66a888f6c3df832cfb8cc9f011ce2f65264f323 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 16:31:58 +0800 Subject: [PATCH 29/31] register user --- src/Blogifier.Shared/Resources/Resource.zh-CN.resx | 9 +++++++++ .../Views/Themes/standard/login.cshtml | 1 + .../Views/Themes/standard/register.cshtml | 1 + src/Blogifier.Themes.Standard/assets/gulpfile.mjs | 1 - src/Blogifier.Themes.Standard/assets/js/blogifier.js | 2 +- 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Blogifier.Shared/Resources/Resource.zh-CN.resx b/src/Blogifier.Shared/Resources/Resource.zh-CN.resx index bf3c902be..0477d126a 100644 --- a/src/Blogifier.Shared/Resources/Resource.zh-CN.resx +++ b/src/Blogifier.Shared/Resources/Resource.zh-CN.resx @@ -513,4 +513,13 @@ <data name="reset" xml:space="preserve"> <value>重置</value> </data> + <data name="edit-profile" xml:space="preserve"> + <value>编辑配置</value> + </data> + <data name="logout" xml:space="preserve"> + <value>退出登陆</value> + </data> + <data name="register" xml:space="preserve"> + <value>注册</value> + </data> </root> \ No newline at end of file diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/login.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/login.cshtml index 1c2e746db..e276eeb73 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/login.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/login.cshtml @@ -25,4 +25,5 @@ <span asp-validation-for="Password"></span> </div> <button type="submit" class="btn btn-blogifier btn-block btn-floating">@_localizer["login"]</button> + <a style="margin-top:8px" class="btn btn-default btn-block btn-floating" role="button" href="~/account/register">@_localizer["register"]</a> </form> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/register.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/register.cshtml index eedc8a484..f10df5fc6 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/register.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/register.cshtml @@ -44,4 +44,5 @@ <span class="validation-message" asp-validation-for="PasswordConfirm"></span> </div> <button type="submit" class="btn btn-blogifier btn-block btn-floating">@_localizer["register"]</button> + <a style="margin-top:8px" class="btn btn-default btn-block btn-floating" role="button" href="~/account/login">@_localizer["cancel"]</a> </form> diff --git a/src/Blogifier.Themes.Standard/assets/gulpfile.mjs b/src/Blogifier.Themes.Standard/assets/gulpfile.mjs index 5dcc1d51e..57dce4911 100644 --- a/src/Blogifier.Themes.Standard/assets/gulpfile.mjs +++ b/src/Blogifier.Themes.Standard/assets/gulpfile.mjs @@ -134,7 +134,6 @@ const watcher = () => { }; export default series( - clean, parallel( scss, rollupJs, diff --git a/src/Blogifier.Themes.Standard/assets/js/blogifier.js b/src/Blogifier.Themes.Standard/assets/js/blogifier.js index 7cbde4ed8..bdc88ffb8 100644 --- a/src/Blogifier.Themes.Standard/assets/js/blogifier.js +++ b/src/Blogifier.Themes.Standard/assets/js/blogifier.js @@ -5,10 +5,10 @@ hljs.initHighlightingOnLoad(); const form = document.getElementById("newsletter"); const form_email = document.getElementById("newsletter_email"); const form_status = document.getElementById("newsletter_status"); -const newsletterSucessMsg = form_status.dataset.success, newsletterErrorMsg = form_status.dataset.error; // Success, Loading and Error functions function successNewsletter() { + const newsletterSucessMsg = form_status.dataset.success, newsletterErrorMsg = form_status.dataset.error; form_status.innerHTML = `<div class="newsletter-msg bg-success"><div class="m-auto"> ${newsletterSucessMsg} </div></div>`; setTimeout(resetNewsletter, 2000); } From d0fb3095de113e2a00f6947d18e9d03ddfbe8f44 Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 17:56:27 +0800 Subject: [PATCH 30/31] fix themes assets --- src/Blogifier.Shared/Resources/Resource.resx | 3 + .../Resources/Resource.zh-CN.resx | 3 + .../Views/Themes/standard/404.cshtml | 88 +--------- .../Themes/standard/components/nav.cshtml | 2 +- .../Views/Themes/standard/initialize.cshtml | 2 +- .../Themes/standard/layouts/_account.cshtml | 6 +- .../Themes/standard/layouts/_base.cshtml | 5 +- .../Themes/standard/layouts/_main.cshtml | 6 +- .../Themes/standard/layouts/_profile.cshtml | 8 +- .../Views/Themes/standard/login.cshtml | 2 +- .../Views/Themes/standard/page.cshtml | 4 + .../Views/Themes/standard/password.cshtml | 2 +- .../Views/Themes/standard/post.cshtml | 5 + .../Views/Themes/standard/profile.cshtml | 12 +- .../Views/Themes/standard/register.cshtml | 2 +- .../assets/gulpfile.mjs | 155 +++++++++++++++++- .../assets/js/blogifier.js | 81 --------- .../assets/js/highlight.js | 2 + .../assets/js/main.js | 79 +++++++++ .../assets/js/profile.js | 15 ++ .../assets/scss/account.scss | 8 - .../assets/scss/base.scss | 84 ++++++++++ 22 files changed, 372 insertions(+), 202 deletions(-) create mode 100644 src/Blogifier.Themes.Standard/assets/js/highlight.js create mode 100644 src/Blogifier.Themes.Standard/assets/js/main.js create mode 100644 src/Blogifier.Themes.Standard/assets/js/profile.js create mode 100644 src/Blogifier.Themes.Standard/assets/scss/base.scss diff --git a/src/Blogifier.Shared/Resources/Resource.resx b/src/Blogifier.Shared/Resources/Resource.resx index a415c3dfb..536d0b30f 100644 --- a/src/Blogifier.Shared/Resources/Resource.resx +++ b/src/Blogifier.Shared/Resources/Resource.resx @@ -786,4 +786,7 @@ <data name="view-all" xml:space="preserve"> <value>View All</value> </data> + <data name="account-profile" xml:space="preserve"> + <value>Account Profile</value> + </data> </root> \ No newline at end of file diff --git a/src/Blogifier.Shared/Resources/Resource.zh-CN.resx b/src/Blogifier.Shared/Resources/Resource.zh-CN.resx index 0477d126a..465691f7e 100644 --- a/src/Blogifier.Shared/Resources/Resource.zh-CN.resx +++ b/src/Blogifier.Shared/Resources/Resource.zh-CN.resx @@ -522,4 +522,7 @@ <data name="register" xml:space="preserve"> <value>注册</value> </data> + <data name="account-profile" xml:space="preserve"> + <value>用户信息</value> + </data> </root> \ No newline at end of file diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/404.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/404.cshtml index ac79f4d21..d48bff059 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/404.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/404.cshtml @@ -3,93 +3,7 @@ Layout = "layouts/_base.cshtml"; } -@section HeadMeta{ - <style> - *, - *::before, - *::after { - box-sizing: border-box; - } - - html { - height: 100%; - } - - body { - margin: 0; - font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #000; - background-color: #f8f9fa; - display: flex; - height: 100%; - } - - p { - margin: 0; - } - - .container { - width: 32rem; - max-width: 100%; - padding: 2rem; - margin: auto; - } - - .title { - margin: 0 0 1rem; - font-weight: 500; - font-size: 2rem; - } - - .message { - margin-bottom: 2rem; - font-size: 1.25rem; - color: #727272; - } - - .button { - padding: 0 1.5rem 0 .75rem; - border-radius: .3rem; - display: inline-block; - background-color: #009e66; - color: #fff; - text-decoration: none; - font-size: .875rem; - font-weight: 500; - line-height: 2.5rem; - } - - .button:hover { - background-color: #009460; - } - - .button .icon { - vertical-align: middle; - } - - @@media screen and (min-width:480px) { - .title { - font-size: 2.5rem; - font-weight: 700; - } - - .message { - font-size: 1.5rem; - font-weight: 300; - } - - .message .br { - display: block; - } - - .button { - line-height: 2.75rem; - } - } - </style> +@section HeaderScript{ <title>@_localizer["page-not-found"]</title> <meta name="description" content="@_localizer["page-not-found-message"]"> } diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/components/nav.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/components/nav.cshtml index e3d4f9860..15fedd335 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/components/nav.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/components/nav.cshtml @@ -87,7 +87,7 @@ <li><a class="dropdown-item" href="~/admin/newsletter/">@_localizer["newsletter"]</a></li> <li><a class="dropdown-item" href="~/admin/settings/">@_localizer["settings"]</a></li> <li><a class="dropdown-item" href="~/admin/settings/customize/">@_localizer["customize"]</a></li> - <li><a class="dropdown-item" href="~/account/profile?redirecturi=@Model.Main.PathUrl">@_localizer["edit-profile"]</a></li> + <li><a class="dropdown-item" href="~/account/profile?redirecturi=@Model.Main.PathUrl">@_localizer["account-profile"]</a></li> <li> <hr class="dropdown-divider"> </li> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/initialize.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/initialize.cshtml index 9b8b68d9a..3d22500b6 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/initialize.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/initialize.cshtml @@ -4,7 +4,7 @@ Layout = "layouts/_account.cshtml"; } -@section HeadMeta{ +@section HeaderScript{ <title>@_localizer["initialize"]</title> } diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_account.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_account.cshtml index 201dbb63d..f43490f1f 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_account.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_account.cshtml @@ -6,9 +6,9 @@ <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> - @await RenderSectionAsync("HeadMeta",false) <!-- TODO: These variables comes from customfiedls --> - <link rel="stylesheet" href="~/_content/@ThemesStandardConstant.AssemblyName/css/account.css" asp-append-version="true"> + <link rel="stylesheet" href="~/_content/@ThemesStandardConstant.AssemblyName/css/account.css"> + @await RenderSectionAsync("HeaderScript", required: false) </head> <body> @@ -27,7 +27,7 @@ @RenderBody() </div> </main> - <script src="~/_content/@ThemesStandardConstant.AssemblyName/js/blogifier.js" asp-append-version="true"></script> + <script src="~/_content/@ThemesStandardConstant.AssemblyName/js/blogifier.js"></script> </body> </html> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_base.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_base.cshtml index b9ca833d4..f6350fc9a 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_base.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_base.cshtml @@ -4,7 +4,6 @@ <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> - @await RenderSectionAsync("HeadMeta",false) <!-- TODO: These variables comes from customfiedls --> <style> :root { @@ -24,12 +23,12 @@ --bf-radius: .5rem; } </style> - <link rel="stylesheet" href="~/_content/@ThemesStandardConstant.AssemblyName/css/blogifier.css" asp-append-version="true"> + <link rel="stylesheet" href="~/_content/@ThemesStandardConstant.AssemblyName/css/base.css"> + @await RenderSectionAsync("HeaderScript", required: false) </head> <body> @RenderBody() - <script src="~/_content/@ThemesStandardConstant.AssemblyName/js/blogifier.js" asp-append-version="true"></script> </body> </html> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_main.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_main.cshtml index 61581df89..4607be766 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_main.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_main.cshtml @@ -29,14 +29,16 @@ --bf-radius: .5rem; } </style> - <link rel="stylesheet" href="~/_content/@ThemesStandardConstant.AssemblyName/css/blogifier.css" asp-append-version="true"> + <link rel="stylesheet" href="~/_content/@ThemesStandardConstant.AssemblyName/css/blogifier.css"> @Html.Raw(Model.Main.HeaderScript) </head> <body> <partial name="../components/header.cshtml" /> @RenderBody() <partial name="../components/footer.cshtml" /> - <script src="~/_content/@ThemesStandardConstant.AssemblyName/js/blogifier.js" asp-append-version="true"></script> + <script src="~/_content/@ThemesStandardConstant.AssemblyName/js/blogifier.js"></script> + <script src="~/_content/@ThemesStandardConstant.AssemblyName/js/main.js"></script> + @RenderSection("FooterScript", required: false) @Html.Raw(Model.Main.FooterScript) </body> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_profile.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_profile.cshtml index 27cbb22da..addc7dc57 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_profile.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_profile.cshtml @@ -7,9 +7,8 @@ <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> - @await RenderSectionAsync("HeadMeta",false) - <!-- TODO: These variables comes from customfiedls --> - <link rel="stylesheet" href="~/_content/@ThemesStandardConstant.AssemblyName/css/account.css" asp-append-version="true"> + <link rel="stylesheet" href="~/_content/@ThemesStandardConstant.AssemblyName/css/account.css"> + @await RenderSectionAsync("HeaderScript",false) </head> <body> @@ -53,7 +52,8 @@ </div> </div> </main> - <script src="~/_content/@ThemesStandardConstant.AssemblyName/js/blogifier.js" asp-append-version="true"></script> + <script src="~/_content/@ThemesStandardConstant.AssemblyName/js/blogifier.js"></script> + @await RenderSectionAsync("FooterScript",false) </body> </html> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/login.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/login.cshtml index e276eeb73..33f3c6cff 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/login.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/login.cshtml @@ -4,7 +4,7 @@ } @inject IStringLocalizer<Resource> _localizer -@section HeadMeta{ +@section HeaderScript{ <title>@_localizer["login"]</title> } diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/page.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/page.cshtml index 00204ca29..e50ff1a9a 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/page.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/page.cshtml @@ -7,6 +7,10 @@ Layout = "layouts/_main.cshtml"; } +@section FooterScript { + <script src="~/_content/@ThemesStandardConstant.AssemblyName/js/highlight.js"></script> +} + <main class="post-detail"> <article class="post"> <figure class="post-cover"> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/password.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/password.cshtml index 2703d0e87..8b1333603 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/password.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/password.cshtml @@ -6,7 +6,7 @@ @inject IStringLocalizer<Resource> _localizer -@section HeadMeta{ +@section HeaderScript{ <title>@_localizer["edit-profile"]</title> } diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/post.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/post.cshtml index adcc25ba9..f5b798103 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/post.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/post.cshtml @@ -1,10 +1,15 @@ @model PostModel @inject IStringLocalizer<Resource> _localizer + @{ Layout = "layouts/_main.cshtml"; ; } +@section FooterScript { + <script src="~/_content/@ThemesStandardConstant.AssemblyName/js/highlight.js"></script> +} + <main class="post-detail"> <article class="post"> <figure class="post-cover"> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/profile.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/profile.cshtml index 222484eaf..dd1b15afb 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/profile.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/profile.cshtml @@ -4,11 +4,15 @@ } @inject IStringLocalizer<Resource> _localizer -@section HeadMeta{ - <title>@_localizer["edit-profile"]</title> +@section HeaderScript{ + <title>@_localizer["account-profile"]</title> } -<h1 class="section-title">@_localizer["edit-profile"]</h1> +@section FooterScript { + <script src="~/_content/@ThemesStandardConstant.AssemblyName/js/profile.js"></script> +} + +<h1 class="section-title">@_localizer["account-profile"]</h1> <div class="section-content -half"> @if (!string.IsNullOrEmpty(Model.Error)) { @@ -19,7 +23,7 @@ <input type="hidden" asp-for="IsProfile" /> <input type="hidden" asp-for="Avatar" /> <div class="form-item"> - <label class="form-label mb-1">@_localizer["profile-picture"]</label> + <label class="form-label mb-1">@_localizer["avatar"]</label> <div class="d-flex"> <img src="@PageHelper.CheckGetAvatarUrl(Model.Avatar)" width="39" height="39" class="profilePicture rounded me-3" alt="@Model.NickName" /> <button class="btn btn-link" onclick="return fileManager.uploadClick('@UploadType.Avatar');" type="button" title="@_localizer["upload"]" data-bs-toggle="tooltip"> diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/register.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/register.cshtml index f10df5fc6..c452e327e 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/register.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/register.cshtml @@ -4,7 +4,7 @@ Layout = "layouts/_account.cshtml"; } -@section HeadMeta{ +@section HeaderScript{ <title>@_localizer["register"]</title> } diff --git a/src/Blogifier.Themes.Standard/assets/gulpfile.mjs b/src/Blogifier.Themes.Standard/assets/gulpfile.mjs index 57dce4911..ce4bdea1e 100644 --- a/src/Blogifier.Themes.Standard/assets/gulpfile.mjs +++ b/src/Blogifier.Themes.Standard/assets/gulpfile.mjs @@ -45,8 +45,8 @@ const release = (done) => { done(); }; -// Rollup.js -const rollupJs = () => { +// blogifier.js +const blogifierJs = () => { let outputOptions = { sourcemap: true, format: 'iife' @@ -89,6 +89,140 @@ const rollupJs = () => { return stream.pipe(dest('dist/js')); } +// highlight.js +const highlightJs = () => { + let outputOptions = { + sourcemap: true, + format: 'iife' + } + + if (mode !== 'Debug') { + outputOptions.sourcemap = false; + outputOptions.minifyInternalExports = true; + outputOptions.plugins = [terser()]; + } + + let stream = rollupStream({ + input: 'js/highlight.js', + output: outputOptions, + plugins: [ + babel({ + exclude: 'node_modules/**', + presets: ['@babel/preset-env'], + babelHelpers: 'bundled', + }), + nodeResolve({ + browser: true, + preferBuiltins: false, + }), + commonjs({ + include: ['node_modules/**'], + exclude: [], + sourceMap: mode === 'Debug', + }), + ], + }) + + stream = stream.pipe(source('highlight.js')); + if (mode !== 'Debug') { + // JS Minify + stream = stream.pipe(buffer()) + stream = stream.pipe(plumber()) + stream = stream.pipe(uglify()) + } + return stream.pipe(dest('dist/js')); +} + + +// main.js +const mainJs = () => { + let outputOptions = { + sourcemap: true, + format: 'iife' + } + + if (mode !== 'Debug') { + outputOptions.sourcemap = false; + outputOptions.minifyInternalExports = true; + outputOptions.plugins = [terser()]; + } + + let stream = rollupStream({ + input: 'js/main.js', + output: outputOptions, + plugins: [ + babel({ + exclude: 'node_modules/**', + presets: ['@babel/preset-env'], + babelHelpers: 'bundled', + }), + nodeResolve({ + browser: true, + preferBuiltins: false, + }), + commonjs({ + include: ['node_modules/**'], + exclude: [], + sourceMap: mode === 'Debug', + }), + ], + }) + + stream = stream.pipe(source('main.js')); + if (mode !== 'Debug') { + // JS Minify + stream = stream.pipe(buffer()) + stream = stream.pipe(plumber()) + stream = stream.pipe(uglify()) + } + return stream.pipe(dest('dist/js')); +} + + +// profile.js +const profileJs = () => { + let outputOptions = { + sourcemap: true, + format: 'iife' + } + + if (mode !== 'Debug') { + outputOptions.sourcemap = false; + outputOptions.minifyInternalExports = true; + outputOptions.plugins = [terser()]; + } + + let stream = rollupStream({ + input: 'js/profile.js', + output: outputOptions, + plugins: [ + babel({ + exclude: 'node_modules/**', + presets: ['@babel/preset-env'], + babelHelpers: 'bundled', + }), + nodeResolve({ + browser: true, + preferBuiltins: false, + }), + commonjs({ + include: ['node_modules/**'], + exclude: [], + sourceMap: mode === 'Debug', + }), + ], + }) + + stream = stream.pipe(source('profile.js')); + if (mode !== 'Debug') { + // JS Minify + stream = stream.pipe(buffer()) + stream = stream.pipe(plumber()) + stream = stream.pipe(uglify()) + } + return stream.pipe(dest('dist/js')); +} + // sass const scss = () => { let stream = src("./scss/**/*.scss") @@ -129,14 +263,22 @@ const svgSprite = () => { } const watcher = () => { - watch('./js/**/*.js', series(rollupJs)); + watch('./js/**/*.js', series( + blogifierJs, + highlightJs, + mainJs, + profileJs, + )); watch('./scss/**/*.scss', series(scss)); }; export default series( parallel( scss, - rollupJs, + blogifierJs, + highlightJs, + mainJs, + profileJs, svgSprite, watcher ) @@ -145,7 +287,10 @@ export default series( const build = series( clean, scss, - rollupJs, + blogifierJs, + highlightJs, + mainJs, + profileJs, svgSprite, ); diff --git a/src/Blogifier.Themes.Standard/assets/js/blogifier.js b/src/Blogifier.Themes.Standard/assets/js/blogifier.js index bdc88ffb8..aa9524295 100644 --- a/src/Blogifier.Themes.Standard/assets/js/blogifier.js +++ b/src/Blogifier.Themes.Standard/assets/js/blogifier.js @@ -1,87 +1,6 @@ import "bootstrap"; -import hljs from 'highlight.js'; -hljs.initHighlightingOnLoad(); -// get the newsletter form elements -const form = document.getElementById("newsletter"); -const form_email = document.getElementById("newsletter_email"); -const form_status = document.getElementById("newsletter_status"); -// Success, Loading and Error functions -function successNewsletter() { - const newsletterSucessMsg = form_status.dataset.success, newsletterErrorMsg = form_status.dataset.error; - form_status.innerHTML = `<div class="newsletter-msg bg-success"><div class="m-auto"> ${newsletterSucessMsg} </div></div>`; - setTimeout(resetNewsletter, 2000); -} -function loadingNewsletter() { - form_status.innerHTML = '<div class="newsletter-msg"><div class="m-auto spinner-border" role="status"></div></div>' -} -function errorNewsletter(msg) { - form_status.innerHTML = `<div class="newsletter-msg bg-danger"><div class="m-auto">${newsletterErrorMsg} <br> ${msg}</div></div>`; -} -function resetNewsletter() { - form.reset(); - form_status.innerHTML = ""; -} -function subscribeNewsletter(url, data) { - var options = { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(data) - } - fetch(url, options) - .then((response) => { - if (response.status == 200) { - return response.json(); - } else { - throw new Error('The Newsletter is not working!'); - } - }) - .then(() => { - successNewsletter(); - }) - .catch((err) => { - errorNewsletter(err); - }); -} - -form.addEventListener("submit", function (e) { - e.preventDefault(); - loadingNewsletter(); - var subscriber_data = { - Email: form_email.value, - Ip: "unknown", - Country: "unknown", - Region: "unknown" - }; - fetch('https://ipapi.co/json/') - .then((response) => { - if (response.status == 200) { - return response.json(); - } else { - throw new Error('Not sure where you are!'); - } - }) - .then((loc) => { - subscriber_data.Ip = loc.ip; - subscriber_data.Country = loc.country_name; - subscriber_data.Region = loc.region; - subscribeNewsletter(form.action, subscriber_data); - }) - .catch((err) => { - subscribeNewsletter(form.action, subscriber_data); - }); -}); - - -// search modal auto focus -var myModal = document.getElementById('searchModal'); -var myInput = document.getElementById('searchFormInput'); -if (myModal) { - myModal.addEventListener('shown.bs.modal', function () { - myInput.focus() - }) -} // copy input function copyInput(elm) { diff --git a/src/Blogifier.Themes.Standard/assets/js/highlight.js b/src/Blogifier.Themes.Standard/assets/js/highlight.js new file mode 100644 index 000000000..2a5ed565e --- /dev/null +++ b/src/Blogifier.Themes.Standard/assets/js/highlight.js @@ -0,0 +1,2 @@ +import hljs from 'highlight.js'; +hljs.initHighlightingOnLoad(); diff --git a/src/Blogifier.Themes.Standard/assets/js/main.js b/src/Blogifier.Themes.Standard/assets/js/main.js new file mode 100644 index 000000000..b602c41dc --- /dev/null +++ b/src/Blogifier.Themes.Standard/assets/js/main.js @@ -0,0 +1,79 @@ +// get the newsletter form elements +const form = document.getElementById("newsletter"); +const form_email = document.getElementById("newsletter_email"); +const form_status = document.getElementById("newsletter_status"); + +// Success, Loading and Error functions +function successNewsletter() { + const newsletterSucessMsg = form_status.dataset.success, newsletterErrorMsg = form_status.dataset.error; + form_status.innerHTML = `<div class="newsletter-msg bg-success"><div class="m-auto"> ${newsletterSucessMsg} </div></div>`; + setTimeout(resetNewsletter, 2000); +} +function loadingNewsletter() { + form_status.innerHTML = '<div class="newsletter-msg"><div class="m-auto spinner-border" role="status"></div></div>' +} +function errorNewsletter(msg) { + form_status.innerHTML = `<div class="newsletter-msg bg-danger"><div class="m-auto">${newsletterErrorMsg} <br> ${msg}</div></div>`; +} +function resetNewsletter() { + form.reset(); + form_status.innerHTML = ""; +} + +function subscribeNewsletter(url, data) { + var options = { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(data) + } + fetch(url, options) + .then((response) => { + if (response.status == 200) { + return response.json(); + } else { + throw new Error('The Newsletter is not working!'); + } + }) + .then(() => { + successNewsletter(); + }) + .catch((err) => { + errorNewsletter(err); + }); +} + +form.addEventListener("submit", function (e) { + e.preventDefault(); + loadingNewsletter(); + var subscriber_data = { + Email: form_email.value, + Ip: "unknown", + Country: "unknown", + Region: "unknown" + }; + fetch('https://ipapi.co/json/') + .then((response) => { + if (response.status == 200) { + return response.json(); + } else { + throw new Error('Not sure where you are!'); + } + }) + .then((loc) => { + subscriber_data.Ip = loc.ip; + subscriber_data.Country = loc.country_name; + subscriber_data.Region = loc.region; + subscribeNewsletter(form.action, subscriber_data); + }) + .catch((err) => { + subscribeNewsletter(form.action, subscriber_data); + }); +}); + +// search modal auto focus +var myModal = document.getElementById('searchModal'); +if (myModal) { + myModal.addEventListener('shown.bs.modal', function () { + document.getElementById('searchFormInput').focus() + }) +} diff --git a/src/Blogifier.Themes.Standard/assets/js/profile.js b/src/Blogifier.Themes.Standard/assets/js/profile.js new file mode 100644 index 000000000..47eec7b47 --- /dev/null +++ b/src/Blogifier.Themes.Standard/assets/js/profile.js @@ -0,0 +1,15 @@ + +// copy input +function test(elm) { + var copyText = document.getElementById(elm); + var copyTextStore = copyText.dataset.link; + copyText.select(); + copyText.setSelectionRange(0, 99999); + document.execCommand("copy"); + copyText.value = "Copied!"; + copyText.classList.add("copied"); + setTimeout(function () { + copyText.value = copyTextStore; + copyText.classList.remove("copied"); + }, 500); +} diff --git a/src/Blogifier.Themes.Standard/assets/scss/account.scss b/src/Blogifier.Themes.Standard/assets/scss/account.scss index 40a2dc70b..b217a220e 100644 --- a/src/Blogifier.Themes.Standard/assets/scss/account.scss +++ b/src/Blogifier.Themes.Standard/assets/scss/account.scss @@ -143,11 +143,3 @@ body { display: flex; flex-direction: column; } - -// shared/MainLayout.razor -.content { -} - -// Components/NavMenuComponent.razor -.menu { -} diff --git a/src/Blogifier.Themes.Standard/assets/scss/base.scss b/src/Blogifier.Themes.Standard/assets/scss/base.scss new file mode 100644 index 000000000..7de07fe86 --- /dev/null +++ b/src/Blogifier.Themes.Standard/assets/scss/base.scss @@ -0,0 +1,84 @@ +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + height: 100%; +} + +body { + margin: 0; + font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #000; + background-color: #f8f9fa; + display: flex; + height: 100%; +} + +p { + margin: 0; +} + +.container { + width: 32rem; + max-width: 100%; + padding: 2rem; + margin: auto; +} + +.title { + margin: 0 0 1rem; + font-weight: 500; + font-size: 2rem; +} + +.message { + margin-bottom: 2rem; + font-size: 1.25rem; + color: #727272; +} + +.button { + padding: 0 1.5rem 0 .75rem; + border-radius: .3rem; + display: inline-block; + background-color: #009e66; + color: #fff; + text-decoration: none; + font-size: .875rem; + font-weight: 500; + line-height: 2.5rem; +} + + .button:hover { + background-color: #009460; + } + + .button .icon { + vertical-align: middle; + } + +@media screen and (min-width:480px) { + .title { + font-size: 2.5rem; + font-weight: 700; + } + + .message { + font-size: 1.5rem; + font-weight: 300; + } + + .message .br { + display: block; + } + + .button { + line-height: 2.75rem; + } +} From e42f0284099cd39bf0caae746d6891f3774a24bc Mon Sep 17 00:00:00 2001 From: dorthl <x344527085@outlook.com> Date: Wed, 9 Aug 2023 18:31:18 +0800 Subject: [PATCH 31/31] fix scss --- .../Themes/standard/layouts/_account.cshtml | 1 + .../assets/scss/account.scss | 5 +- .../assets/scss/blogifier.scss | 58 ++++++++++++++++++- .../assets/scss/helpers/_bootstrap.scss | 53 ----------------- 4 files changed, 62 insertions(+), 55 deletions(-) delete mode 100644 src/Blogifier.Themes.Standard/assets/scss/helpers/_bootstrap.scss diff --git a/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_account.cshtml b/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_account.cshtml index f43490f1f..32d238add 100644 --- a/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_account.cshtml +++ b/src/Blogifier.Themes.Standard/Views/Themes/standard/layouts/_account.cshtml @@ -7,6 +7,7 @@ <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- TODO: These variables comes from customfiedls --> + <link rel="stylesheet" href="~/_content/@ThemesStandardConstant.AssemblyName/css/blogifier.css"> <link rel="stylesheet" href="~/_content/@ThemesStandardConstant.AssemblyName/css/account.css"> @await RenderSectionAsync("HeaderScript", required: false) </head> diff --git a/src/Blogifier.Themes.Standard/assets/scss/account.scss b/src/Blogifier.Themes.Standard/assets/scss/account.scss index b217a220e..7b1f10a37 100644 --- a/src/Blogifier.Themes.Standard/assets/scss/account.scss +++ b/src/Blogifier.Themes.Standard/assets/scss/account.scss @@ -102,7 +102,10 @@ $form-floating-padding-y: .875rem; $form-floating-label-opacity: .65; $form-floating-label-transform: scale(.8) translateY(-.325rem) translateX(.15rem); -@import "helpers/bootstrap"; +@import "../node_modules/bootstrap/scss/functions"; +@import "../node_modules/bootstrap/scss/variables"; +@import "../node_modules/bootstrap/scss/root"; + @import "layout/sidebar"; @import "include/buttons"; @import "include/forms"; diff --git a/src/Blogifier.Themes.Standard/assets/scss/blogifier.scss b/src/Blogifier.Themes.Standard/assets/scss/blogifier.scss index f299d05da..af19e22c1 100644 --- a/src/Blogifier.Themes.Standard/assets/scss/blogifier.scss +++ b/src/Blogifier.Themes.Standard/assets/scss/blogifier.scss @@ -6,7 +6,63 @@ // helpers @import "helpers/variables"; -@import "helpers/bootstrap"; + +/* + * Bootstrap v5.0.0-beta3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ + +// scss-docs-start import-stack +// Configuration +@import "../node_modules/bootstrap/scss/functions"; +@import "../node_modules/bootstrap/scss/variables"; +@import "../node_modules/bootstrap/scss/mixins"; +@import "helpers/colors"; +@import "../node_modules/bootstrap/scss/utilities"; +@import "../node_modules/bootstrap/scss/root"; + +// Layout & components + +@import "../node_modules/bootstrap/scss/reboot"; +@import "../node_modules/bootstrap/scss/type"; +@import "../node_modules/bootstrap/scss/images"; +@import "../node_modules/bootstrap/scss/containers"; +@import "../node_modules/bootstrap/scss/grid"; +@import "../node_modules/bootstrap/scss/tables"; +@import "../node_modules/bootstrap/scss/forms"; +@import "../node_modules/bootstrap/scss/buttons"; +@import "../node_modules/bootstrap/scss/transitions"; +@import "../node_modules/bootstrap/scss/dropdown"; +@import "../node_modules/bootstrap/scss/button-group"; +// @import "../node_modules/bootstrap/scss/nav"; +// @import "../node_modules/bootstrap/scss/navbar"; +// @import "../node_modules/bootstrap/scss/card"; +@import "../node_modules/bootstrap/scss/accordion"; +// @import "../node_modules/bootstrap/scss/breadcrumb"; +@import "../node_modules/bootstrap/scss/pagination"; +@import "../node_modules/bootstrap/scss/badge"; +@import "../node_modules/bootstrap/scss/alert"; +// @import "../node_modules/bootstrap/scss/progress"; +@import "../node_modules/bootstrap/scss/list-group"; +@import "../node_modules/bootstrap/scss/close"; +// @import "../node_modules/bootstrap/scss/toasts"; +@import "../node_modules/bootstrap/scss/modal"; +@import "../node_modules/bootstrap/scss/tooltip"; +@import "../node_modules/bootstrap/scss/popover"; +@import "../node_modules/bootstrap/scss/carousel"; +@import "../node_modules/bootstrap/scss/spinners"; +// @import "../node_modules/bootstrap/scss/offcanvas"; + +// Helpers +@import "../node_modules/bootstrap/scss/helpers"; + +// Utilities +@import "../node_modules/bootstrap/scss/utilities/api"; +// scss-docs-end import-stack + + @import "helpers/mixins"; @import "helpers/reset"; @import "helpers/base"; diff --git a/src/Blogifier.Themes.Standard/assets/scss/helpers/_bootstrap.scss b/src/Blogifier.Themes.Standard/assets/scss/helpers/_bootstrap.scss deleted file mode 100644 index 759829d45..000000000 --- a/src/Blogifier.Themes.Standard/assets/scss/helpers/_bootstrap.scss +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Bootstrap v5.0.0-beta3 (https://getbootstrap.com/) - * Copyright 2011-2021 The Bootstrap Authors - * Copyright 2011-2021 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ - -// scss-docs-start import-stack -// Configuration -@import "../../node_modules/bootstrap/scss/functions"; -@import "../../node_modules/bootstrap/scss/variables"; -@import "../../node_modules/bootstrap/scss/mixins"; -@import "colors"; -@import "../../node_modules/bootstrap/scss/utilities"; - -// Layout & components -@import "../../node_modules/bootstrap/scss/root"; -@import "../../node_modules/bootstrap/scss/reboot"; -@import "../../node_modules/bootstrap/scss/type"; -@import "../../node_modules/bootstrap/scss/images"; -@import "../../node_modules/bootstrap/scss/containers"; -@import "../../node_modules/bootstrap/scss/grid"; -@import "../../node_modules/bootstrap/scss/tables"; -@import "../../node_modules/bootstrap/scss/forms"; -@import "../../node_modules/bootstrap/scss/buttons"; -@import "../../node_modules/bootstrap/scss/transitions"; -@import "../../node_modules/bootstrap/scss/dropdown"; -@import "../../node_modules/bootstrap/scss/button-group"; -// @import "../../node_modules/bootstrap/scss/nav"; -// @import "../../node_modules/bootstrap/scss/navbar"; -// @import "../../node_modules/bootstrap/scss/card"; -@import "../../node_modules/bootstrap/scss/accordion"; -// @import "../../node_modules/bootstrap/scss/breadcrumb"; -@import "../../node_modules/bootstrap/scss/pagination"; -@import "../../node_modules/bootstrap/scss/badge"; -@import "../../node_modules/bootstrap/scss/alert"; -// @import "../../node_modules/bootstrap/scss/progress"; -@import "../../node_modules/bootstrap/scss/list-group"; -@import "../../node_modules/bootstrap/scss/close"; -// @import "../../node_modules/bootstrap/scss/toasts"; -@import "../../node_modules/bootstrap/scss/modal"; -@import "../../node_modules/bootstrap/scss/tooltip"; -@import "../../node_modules/bootstrap/scss/popover"; -@import "../../node_modules/bootstrap/scss/carousel"; -@import "../../node_modules/bootstrap/scss/spinners"; -// @import "../../node_modules/bootstrap/scss/offcanvas"; - -// Helpers -@import "../../node_modules/bootstrap/scss/helpers"; - -// Utilities -@import "../../node_modules/bootstrap/scss/utilities/api"; -// scss-docs-end import-stack