@page "/blogPost/{blogPostId}/{slug?}" @using System.Text @using Markdig @using LinkDotNet.Blog.Domain @using LinkDotNet.Blog.Infrastructure.Persistence @using LinkDotNet.Blog.Web.Features.Bookmarks @using LinkDotNet.Blog.Web.Features.Services @using LinkDotNet.Blog.Web.Features.ShowBlogPost.Components @using LinkDotNet.Blog.Web.Features.SupportMe.Components @using LinkDotNet.Blog.Web.Features.Bookmarks.Components @inject IRepository BlogPostRepository @inject IRepository ShortCodeRepository @inject IJSRuntime JsRuntime @inject NavigationManager NavigationManager @inject IUserRecordService UserRecordService @inject IOptions AppConfiguration @inject IOptions ProfileInformation @inject IOptions SupportConfiguration @inject IBookmarkService BookmarkService @if (isLoading) { } else if (!isLoading && BlogPost is null) { } else if (BlogPost is not null) { @BlogPost.Title

@BlogPost.Title

@BlogPost.UpdatedDate.ToShortDateString()
@BlogPost.ReadingTimeInMinutes minute read
@if (AppConfiguration.Value.UseMultiAuthorMode && BlogPost.AuthorName is not null) {
@BlogPost.AuthorName
}
@if (BlogPost.Tags is not null && BlogPost.Tags.Any()) {
@foreach (var tag in BlogPost.Tags) { @tag }
}
@(EnrichWithShortCodes(BlogPost.Content))
@if (SupportConfiguration.Value.ShowUnderBlogPost) { } @if (AppConfiguration.Value.ShowSimilarPosts) { }
@if (AppConfiguration.Value.ShowReadingIndicator) { } } @code { [Parameter, EditorRequired] public required string BlogPostId { get; set; } [Parameter] public string? Slug { get; set; } private bool isLoading; private string OgDataImage => BlogPost!.PreviewImageUrlFallback ?? BlogPost.PreviewImageUrl; private string BlogPostCanoncialUrl => $"blogPost/{BlogPost?.Id}"; private IReadOnlyCollection shortCodes = []; private bool isBookmarked; private BlogPost? BlogPost { get; set; } protected override async Task OnInitializedAsync() { shortCodes = await ShortCodeRepository.GetAllAsync(); } protected override async Task OnParametersSetAsync() { isLoading = true; BlogPost = await BlogPostRepository.GetByIdAsync(BlogPostId); isLoading = false; } protected override async Task OnAfterRenderAsync(bool firstRender) { await JsRuntime.InvokeVoidAsync("hljs.highlightAll"); _ = UserRecordService.StoreUserRecordAsync(); if (BlogPost is not null && firstRender) { isBookmarked = await BookmarkService.IsBookmarked(BlogPost.Id); StateHasChanged(); } } private MarkupString EnrichWithShortCodes(string content) { if (shortCodes.Count == 0) { return MarkdownConverter.ToMarkupString(content); } var sb = new StringBuilder(content); foreach (var shortCode in shortCodes) { sb.Replace($"[[{shortCode.Name}]]", shortCode.MarkdownContent); } return MarkdownConverter.ToMarkupString(sb.ToString()); } private async Task UpdateLikes(bool hasLiked) { BlogPost = await BlogPostRepository.GetByIdAsync(BlogPostId) ?? throw new InvalidOperationException("Blog post not found"); BlogPost.Likes = hasLiked ? BlogPost.Likes + 1 : BlogPost.Likes - 1; await BlogPostRepository.StoreAsync(BlogPost); } private async Task BlogPostBookmarked() { if (BlogPost is null) { return; } isBookmarked = !isBookmarked; await BookmarkService.SetBookmark(BlogPost.Id, isBookmarked); StateHasChanged(); } }