Compare commits

...

2 Commits

Author SHA1 Message Date
Oliver Booth d32d46e221
fix: fix tag links 2024-07-15 19:38:56 +01:00
Oliver Booth 0bebcb69fe
fix: fix display of single-page tabs 2024-07-15 19:38:34 +01:00
8 changed files with 61 additions and 22 deletions

View File

@ -24,8 +24,9 @@ public interface IBlogPostService
/// Returns the total number of blog posts. /// Returns the total number of blog posts.
/// </summary> /// </summary>
/// <param name="visibility">The post visibility filter.</param> /// <param name="visibility">The post visibility filter.</param>
/// <param name="tags">The tags of the posts to return.</param>
/// <returns>The total number of blog posts.</returns> /// <returns>The total number of blog posts.</returns>
int GetBlogPostCount(Visibility visibility = Visibility.None); int GetBlogPostCount(Visibility visibility = Visibility.None, string[]? tags = null);
/// <summary> /// <summary>
/// Returns a collection of blog posts from the specified page, optionally limiting the number of posts /// Returns a collection of blog posts from the specified page, optionally limiting the number of posts
@ -33,8 +34,9 @@ public interface IBlogPostService
/// </summary> /// </summary>
/// <param name="page">The zero-based index of the page to return.</param> /// <param name="page">The zero-based index of the page to return.</param>
/// <param name="pageSize">The maximum number of posts to return per page.</param> /// <param name="pageSize">The maximum number of posts to return per page.</param>
/// <param name="tags">The tags of the posts to return.</param>
/// <returns>A collection of blog posts.</returns> /// <returns>A collection of blog posts.</returns>
IReadOnlyList<IBlogPost> GetBlogPosts(int page, int pageSize = 10); IReadOnlyList<IBlogPost> GetBlogPosts(int page, int pageSize = 10, string[]? tags = null);
/// <summary> /// <summary>
/// Returns the number of legacy comments for the specified post. /// Returns the number of legacy comments for the specified post.
@ -70,8 +72,9 @@ public interface IBlogPostService
/// </summary> /// </summary>
/// <param name="pageSize">The page size. Defaults to 10.</param> /// <param name="pageSize">The page size. Defaults to 10.</param>
/// <param name="visibility">The post visibility filter.</param> /// <param name="visibility">The post visibility filter.</param>
/// <param name="tags">The tags of the posts to return.</param>
/// <returns>The page count.</returns> /// <returns>The page count.</returns>
int GetPageCount(int pageSize = 10, Visibility visibility = Visibility.None); int GetPageCount(int pageSize = 10, Visibility visibility = Visibility.None, string[]? tags = null);
/// <summary> /// <summary>
/// Returns the previous blog post from the specified blog post. /// Returns the previous blog post from the specified blog post.

View File

@ -12,7 +12,7 @@
@await Html.PartialAsync("Partials/_MastodonStatus") @await Html.PartialAsync("Partials/_MastodonStatus")
<div id="all-blog-posts"> <div id="all-blog-posts">
@foreach (IBlogPost post in BlogPostService.GetBlogPosts(0)) @foreach (IBlogPost post in BlogPostService.GetBlogPosts(0, tags: Model.Tag))
{ {
@await Html.PartialAsync("Partials/_BlogCard", post) @await Html.PartialAsync("Partials/_BlogCard", post)
} }
@ -22,5 +22,6 @@
{ {
["UrlRoot"] = "/blog", ["UrlRoot"] = "/blog",
["Page"] = 1, ["Page"] = 1,
["PageCount"] = BlogPostService.GetPageCount(visibility: Visibility.Published) ["Tags"] = Model.Tag,
["PageCount"] = BlogPostService.GetPageCount(visibility: Visibility.Published, tags: Model.Tag)
}) })

View File

@ -15,11 +15,15 @@ public class Index : PageModel
_blogPostService = blogPostService; _blogPostService = blogPostService;
} }
public string[] Tag { get; private set; } = [];
public IActionResult OnGet([FromQuery(Name = "pid")] Guid? postId = null, public IActionResult OnGet([FromQuery(Name = "pid")] Guid? postId = null,
[FromQuery(Name = "p")] int? wpPostId = null) [FromQuery(Name = "p")] int? wpPostId = null,
[FromQuery(Name = "tag")] string? tag = null)
{ {
if (postId.HasValue == wpPostId.HasValue) if (postId.HasValue == wpPostId.HasValue)
{ {
Tag = tag?.Split('+').Select(t => t.Replace("%20", " ")).ToArray() ?? [];
return Page(); return Page();
} }

View File

@ -9,7 +9,7 @@
@await Html.PartialAsync("Partials/_MastodonStatus") @await Html.PartialAsync("Partials/_MastodonStatus")
<div id="all-blog-posts"> <div id="all-blog-posts">
@foreach (IBlogPost post in BlogPostService.GetBlogPosts(Model.PageNumber - 1)) @foreach (IBlogPost post in BlogPostService.GetBlogPosts(Model.PageNumber - 1, tags: Model.Tag))
{ {
@await Html.PartialAsync("Partials/_BlogCard", post) @await Html.PartialAsync("Partials/_BlogCard", post)
} }
@ -19,5 +19,6 @@
{ {
["UrlRoot"] = "/blog", ["UrlRoot"] = "/blog",
["Page"] = Model.PageNumber, ["Page"] = Model.PageNumber,
["PageCount"] = BlogPostService.GetPageCount(visibility: Visibility.Published) ["Tags"] = Model.Tag,
["PageCount"] = BlogPostService.GetPageCount(visibility: Visibility.Published, tags: Model.Tag)
}) })

View File

@ -14,12 +14,15 @@ public class List : PageModel
/// <value>The requested page number.</value> /// <value>The requested page number.</value>
public int PageNumber { get; private set; } public int PageNumber { get; private set; }
public string[] Tag { get; private set; } = [];
/// <summary> /// <summary>
/// Handles the incoming GET request to the page. /// Handles the incoming GET request to the page.
/// </summary> /// </summary>
/// <param name="page">The requested page number, starting from 1.</param> /// <param name="page">The requested page number, starting from 1.</param>
/// <param name="tag">The tag by which to filter results.</param>
/// <returns></returns> /// <returns></returns>
public IActionResult OnGet([FromRoute(Name = "pageNumber")] int page = 1) public IActionResult OnGet([FromRoute(Name = "pageNumber")] int page = 1, [FromQuery(Name = "tag")] string? tag = null)
{ {
if (page < 2) if (page < 2)
{ {
@ -27,6 +30,7 @@ public class List : PageModel
} }
PageNumber = page; PageNumber = page;
Tag = tag?.Split('+').Select(t => t.Replace("%20", " ")).ToArray() ?? [];
return Page(); return Page();
} }
} }

View File

@ -32,6 +32,8 @@ public class PageTabsUtility
set => _urlRoot = string.IsNullOrWhiteSpace(value) ? string.Empty : value.Trim(); set => _urlRoot = string.IsNullOrWhiteSpace(value) ? string.Empty : value.Trim();
} }
public string[]? Tags { get; set; } = [];
/// <summary> /// <summary>
/// Shows the bound chevrons for the specified bounds type. /// Shows the bound chevrons for the specified bounds type.
/// </summary> /// </summary>
@ -129,7 +131,9 @@ public class PageTabsUtility
private string GetLinkForPage(int page) private string GetLinkForPage(int page)
{ {
// page 1 doesn't use /page/n route // page 1 doesn't use /page/n route
return page == 1 ? _urlRoot : $"{_urlRoot}/page/{page}"; return page == 1
? $"{_urlRoot}{(Tags is { Length: > 0 } ? $"?tag={string.Join('+', Tags)}" : "")}"
: $"{_urlRoot}/page/{page}{(Tags is { Length: > 0 } ? $"?tag={string.Join('+', Tags)}" : "")}";
} }
private string ShowLowerBound() private string ShowLowerBound()

View File

@ -7,15 +7,23 @@
{ {
CurrentPage = page, CurrentPage = page,
PageCount = pageCount, PageCount = pageCount,
UrlRoot = urlRoot UrlRoot = urlRoot,
Tags = ViewData["Tags"] as string[]
}; };
} }
<nav> <nav>
<ul class="pagination justify-content-center"> <ul class="pagination justify-content-center">
@Html.Raw(utility.ShowBounds(PageTabsUtility.BoundsType.Lower)) @if (pageCount == 1)
@Html.Raw(utility.ShowTab(1)) @* always visible *@ {
@Html.Raw(utility.ShowTabWindow()) @Html.Raw(utility.ShowTab(1)) @* always visible *@
@Html.Raw(utility.ShowTab(pageCount)) @* always visible *@ }
@Html.Raw(utility.ShowBounds(PageTabsUtility.BoundsType.Upper)) else
{
@Html.Raw(utility.ShowBounds(PageTabsUtility.BoundsType.Lower))
@Html.Raw(utility.ShowTab(1)) @* always visible *@
@Html.Raw(utility.ShowTabWindow())
@Html.Raw(utility.ShowTab(pageCount)) @* always visible *@
@Html.Raw(utility.ShowBounds(PageTabsUtility.BoundsType.Upper))
}
</ul> </ul>
</nav> </nav>

View File

@ -36,9 +36,16 @@ internal sealed class BlogPostService : IBlogPostService
} }
/// <inheritdoc /> /// <inheritdoc />
public int GetBlogPostCount(Visibility visibility = Visibility.None) public int GetBlogPostCount(Visibility visibility = Visibility.None, string[]? tags = null)
{ {
using BlogContext context = _dbContextFactory.CreateDbContext(); using BlogContext context = _dbContextFactory.CreateDbContext();
if (tags is { Length: > 0 })
{
return visibility == Visibility.None
? context.BlogPosts.AsEnumerable().Count(p => !p.IsRedirect && p.Tags.Intersect(tags).Any())
: context.BlogPosts.AsEnumerable().Count(p => !p.IsRedirect && p.Visibility == visibility && p.Tags.Intersect(tags).Any());
}
return visibility == Visibility.None return visibility == Visibility.None
? context.BlogPosts.Count(p => !p.IsRedirect) ? context.BlogPosts.Count(p => !p.IsRedirect)
: context.BlogPosts.Count(p => !p.IsRedirect && p.Visibility == visibility); : context.BlogPosts.Count(p => !p.IsRedirect && p.Visibility == visibility);
@ -60,13 +67,20 @@ internal sealed class BlogPostService : IBlogPostService
} }
/// <inheritdoc /> /// <inheritdoc />
public IReadOnlyList<IBlogPost> GetBlogPosts(int page, int pageSize = 10) public IReadOnlyList<IBlogPost> GetBlogPosts(int page, int pageSize = 10, string[]? tags = null)
{ {
using BlogContext context = _dbContextFactory.CreateDbContext(); using BlogContext context = _dbContextFactory.CreateDbContext();
return context.BlogPosts IEnumerable<BlogPost> posts = context.BlogPosts
.Where(p => p.Visibility == Visibility.Published && !p.IsRedirect) .Where(p => p.Visibility == Visibility.Published && !p.IsRedirect)
.OrderByDescending(post => post.Published) .OrderByDescending(post => post.Published)
.Skip(page * pageSize) .AsEnumerable();
if (tags is { Length: > 0 })
{
posts = posts.Where(p => p.Tags.Intersect(tags).Any());
}
return posts.Skip(page * pageSize)
.Take(pageSize) .Take(pageSize)
.ToArray().Select(CacheAuthor).ToArray(); .ToArray().Select(CacheAuthor).ToArray();
} }
@ -103,9 +117,9 @@ internal sealed class BlogPostService : IBlogPostService
} }
/// <inheritdoc /> /// <inheritdoc />
public int GetPageCount(int pageSize = 10, Visibility visibility = Visibility.None) public int GetPageCount(int pageSize = 10, Visibility visibility = Visibility.None, string[]? tags = null)
{ {
float postCount = GetBlogPostCount(visibility); float postCount = GetBlogPostCount(visibility, tags);
return (int)MathF.Ceiling(postCount / pageSize); return (int)MathF.Ceiling(postCount / pageSize);
} }