From a3d818a80a7eba14d0f1a8f98e3fe20b2487265c Mon Sep 17 00:00:00 2001 From: the1mason Date: Fri, 27 Sep 2024 04:03:02 +0500 Subject: [PATCH] Updated views, added static to gitignore properly --- .gitignore | 3 +- .../Repositories/Blogs/IBlogMetaRepository.cs | 1 + src/FastBlog.Core/DependencyInjection.cs | 2 +- .../Repositories/BlogMetaRepository.cs | 13 +++++++ src/FastBlog.Core/Services/BlogService.cs | 23 +++++++++-- .../Controllers/BlogsController.cs | 19 +++++++-- .../Controllers/FilesController.cs | 2 +- src/FastBlog.Web/Views/Blogs/Edit.cshtml | 2 +- src/FastBlog.Web/Views/Blogs/Index.cshtml | 36 +++++++++++++++++- src/FastBlog.Web/Views/Blogs/Preview.cshtml | 5 +-- src/FastBlog.Web/Views/Shared/_Layout.cshtml | 1 + src/FastBlog.Web/wwwroot/css/site.css | 3 ++ src/FastBlog.Web/wwwroot/static/denji512.png | Bin 19739 -> 0 bytes 13 files changed, 92 insertions(+), 18 deletions(-) delete mode 100644 src/FastBlog.Web/wwwroot/static/denji512.png diff --git a/.gitignore b/.gitignore index fde09aa..6593c43 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,7 @@ *.db # STATIC -wwwroot/static/ - +src/FastBlog.Web/wwwroot/static/ # BLOGS md/ diff --git a/src/FastBlog.Core/Abstractions/Repositories/Blogs/IBlogMetaRepository.cs b/src/FastBlog.Core/Abstractions/Repositories/Blogs/IBlogMetaRepository.cs index b5e2086..49fc381 100644 --- a/src/FastBlog.Core/Abstractions/Repositories/Blogs/IBlogMetaRepository.cs +++ b/src/FastBlog.Core/Abstractions/Repositories/Blogs/IBlogMetaRepository.cs @@ -7,6 +7,7 @@ public interface IBlogMetaRepository { Task Get(string? slug); Task GetForEdit(int id); + Task Delete(int id); Task> Add(BlogMeta meta); Task> Update(BlogMeta meta); } \ No newline at end of file diff --git a/src/FastBlog.Core/DependencyInjection.cs b/src/FastBlog.Core/DependencyInjection.cs index 9594c0a..13fc01d 100644 --- a/src/FastBlog.Core/DependencyInjection.cs +++ b/src/FastBlog.Core/DependencyInjection.cs @@ -58,7 +58,7 @@ public static class DependencyInjection if (mainPage is not null) return; - await blogService.UpdateBlog(new Blog + await blogService.Update(new Blog { Text = BlogDefaultBody, Metadata = new BlogMeta diff --git a/src/FastBlog.Core/Repositories/BlogMetaRepository.cs b/src/FastBlog.Core/Repositories/BlogMetaRepository.cs index 7d0354b..322dc38 100644 --- a/src/FastBlog.Core/Repositories/BlogMetaRepository.cs +++ b/src/FastBlog.Core/Repositories/BlogMetaRepository.cs @@ -44,6 +44,19 @@ public sealed class BlogMetaRepository(SqliteConnectionFactory connectionFactory return await connection.QueryFirstOrDefaultAsync(sql, new { id }); } + public async Task Delete(int id) + { + const string sql = """ + update Blogs + set Deleted = 1 + where id = @id + """; + + using var connection = connectionFactory.Create(); + + return await connection.ExecuteAsync(sql, new { id }) > 0; + } + public async Task> Add(BlogMeta meta) { using var connection = connectionFactory.Create(); diff --git a/src/FastBlog.Core/Services/BlogService.cs b/src/FastBlog.Core/Services/BlogService.cs index 71ae53d..05e2a77 100644 --- a/src/FastBlog.Core/Services/BlogService.cs +++ b/src/FastBlog.Core/Services/BlogService.cs @@ -47,12 +47,27 @@ public sealed class BlogService(IBlogMetaRepository metaRepository, IBlogFileRep } - public Task> UpdateBlog(Blog blog) + public Task> Update(Blog blog) { - return blog.Metadata.Id is null ? CreateBlog(blog) : UpdateBlogInternal(blog); + return blog.Metadata.Id is null ? Create(blog) : UpdateInternal(blog); } - private async Task> CreateBlog(Blog newBlog) + public async Task Delete(int id) + { + var meta = await metaRepository.GetForEdit(id); + if (meta is null) + return false; + + var toDelete = meta.SourceLocation; + + var result = await metaRepository.Delete(id); + if (!result) + return false; + + return await blogFileRepository.Delete(toDelete); + } + + private async Task> Create(Blog newBlog) { var metaResult = await metaRepository.Add(newBlog.Metadata); if (metaResult.IsError) @@ -71,7 +86,7 @@ public sealed class BlogService(IBlogMetaRepository metaRepository, IBlogFileRep } - private async Task> UpdateBlogInternal(Blog blog) + private async Task> UpdateInternal(Blog blog) { var oldMeta = await metaRepository.GetForEdit(blog.Metadata.Id!.Value); if (oldMeta is null) diff --git a/src/FastBlog.Web/Controllers/BlogsController.cs b/src/FastBlog.Web/Controllers/BlogsController.cs index af62e93..d58bed6 100644 --- a/src/FastBlog.Web/Controllers/BlogsController.cs +++ b/src/FastBlog.Web/Controllers/BlogsController.cs @@ -44,12 +44,12 @@ public class BlogsController(BlogService service) : Controller { if (!id.HasValue) { - var date = DateTime.Now; + var date = DateTime.UtcNow; return View( new EditBlog { Text = "# My new blog", - Title = "Blog from " + DateTime.Now.ToString("g"), + Title = "Blog from " + DateTime.UtcNow.ToString("g"), SourceLocation = $"{date:yyyy-MM-dd-HH-mm}_blog.md", CreatedAt = date, ModifiedAt = date, @@ -87,7 +87,7 @@ public class BlogsController(BlogService service) : Controller [Route("edit")] public async Task Edit([FromForm] EditBlog editBlog) { - var result = await service.UpdateBlog(new() + var result = await service.Update(new() { Text = editBlog.Text, Metadata = new() @@ -141,4 +141,17 @@ public class BlogsController(BlogService service) : Controller } }); } + + [HttpDelete] + [Route("{id:int}")] + public async Task Delete(int id) + { + var result = await service.Delete(id); + + if (!result) + return NotFound(); + + HttpContext.Response.Headers.Append("Hx-Redirect", "/"); + return Ok(); + } } \ No newline at end of file diff --git a/src/FastBlog.Web/Controllers/FilesController.cs b/src/FastBlog.Web/Controllers/FilesController.cs index 3293ed3..398f0b0 100644 --- a/src/FastBlog.Web/Controllers/FilesController.cs +++ b/src/FastBlog.Web/Controllers/FilesController.cs @@ -50,7 +50,7 @@ public class FilesController(FileService fileService) : Controller var meta = new FileMeta { SourceLocation = Path.Combine(sourcePath ?? "", file.FileName), - CreatedAt = DateTime.Now, + CreatedAt = DateTime.UtcNow, MimeType = file.ContentType }; diff --git a/src/FastBlog.Web/Views/Blogs/Edit.cshtml b/src/FastBlog.Web/Views/Blogs/Edit.cshtml index 9b2c793..7fce865 100644 --- a/src/FastBlog.Web/Views/Blogs/Edit.cshtml +++ b/src/FastBlog.Web/Views/Blogs/Edit.cshtml @@ -73,7 +73,7 @@ else
- +
diff --git a/src/FastBlog.Web/Views/Blogs/Index.cshtml b/src/FastBlog.Web/Views/Blogs/Index.cshtml index 21c5a18..64af888 100644 --- a/src/FastBlog.Web/Views/Blogs/Index.cshtml +++ b/src/FastBlog.Web/Views/Blogs/Index.cshtml @@ -5,7 +5,12 @@ @{ ViewBag.Title = Model.Metadata.Title; - var pipelineBuilder = new MarkdownPipelineBuilder().UseAdvancedExtensions().UseHighlightJs(); + var pipelineBuilder = new MarkdownPipelineBuilder() + .UseSmartyPants() + .UseEmojiAndSmiley() + .UseAlertBlocks() + .UseAdvancedExtensions() + .UseHighlightJs(); var sanitizer = new HtmlSanitizer(); sanitizer.AllowedAttributes.Add("class"); var pipeline = pipelineBuilder.Build(); @@ -37,4 +42,31 @@ } @Html.Raw(sanitizer.Sanitize(Markdown.ToHtml(Model.Text, pipeline))) - \ No newline at end of file + + +
+ +
+
+
+
+

Editor's controls

+
+ +
+ +
+ +
+
+ +
+
diff --git a/src/FastBlog.Web/Views/Blogs/Preview.cshtml b/src/FastBlog.Web/Views/Blogs/Preview.cshtml index dd49537..59db3e5 100644 --- a/src/FastBlog.Web/Views/Blogs/Preview.cshtml +++ b/src/FastBlog.Web/Views/Blogs/Preview.cshtml @@ -1,7 +1,4 @@ -@using Ganss.Xss -@using Markdig; -@using Pek.Markdig.HighlightJs -@model FastBlog.Core.Models.Blogs.Blog +@model FastBlog.Core.Models.Blogs.Blog @await Html.PartialAsync("Index", Model); diff --git a/src/FastBlog.Web/Views/Shared/_Layout.cshtml b/src/FastBlog.Web/Views/Shared/_Layout.cshtml index bd5deeb..c09e366 100644 --- a/src/FastBlog.Web/Views/Shared/_Layout.cshtml +++ b/src/FastBlog.Web/Views/Shared/_Layout.cshtml @@ -31,6 +31,7 @@ return;
    @foreach (var link in options.Value.Links) diff --git a/src/FastBlog.Web/wwwroot/css/site.css b/src/FastBlog.Web/wwwroot/css/site.css index dc67d3e..5065b7e 100644 --- a/src/FastBlog.Web/wwwroot/css/site.css +++ b/src/FastBlog.Web/wwwroot/css/site.css @@ -26,6 +26,9 @@ --pico-background-color: #0f1a27; --pico-card-background-color: #132232; --pico-card-sectioning-background-color: #17273a; + + --pico-form-element-background-color: #ffffff08; + --pico-form-element-active-background-color: #ffffff18; } h1, h2, h3, h4, h5, h6 { diff --git a/src/FastBlog.Web/wwwroot/static/denji512.png b/src/FastBlog.Web/wwwroot/static/denji512.png deleted file mode 100644 index 21fa831f570fa787766347757e78a400cda2abd8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19739 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