Compare commits
No commits in common. "main" and "feature/cleanup" have entirely different histories.
main
...
feature/cl
@ -24,9 +24,8 @@ public interface IBlogPostService
|
||||
/// Returns the total number of blog posts.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
int GetBlogPostCount(Visibility visibility = Visibility.None, string[]? tags = null);
|
||||
int GetBlogPostCount(Visibility visibility = Visibility.None);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a collection of blog posts from the specified page, optionally limiting the number of posts
|
||||
@ -34,9 +33,8 @@ public interface IBlogPostService
|
||||
/// </summary>
|
||||
/// <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="tags">The tags of the posts to return.</param>
|
||||
/// <returns>A collection of blog posts.</returns>
|
||||
IReadOnlyList<IBlogPost> GetBlogPosts(int page, int pageSize = 10, string[]? tags = null);
|
||||
IReadOnlyList<IBlogPost> GetBlogPosts(int page, int pageSize = 10);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of legacy comments for the specified post.
|
||||
@ -72,9 +70,8 @@ public interface IBlogPostService
|
||||
/// </summary>
|
||||
/// <param name="pageSize">The page size. Defaults to 10.</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>
|
||||
int GetPageCount(int pageSize = 10, Visibility visibility = Visibility.None, string[]? tags = null);
|
||||
int GetPageCount(int pageSize = 10, Visibility visibility = Visibility.None);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the previous blog post from the specified blog post.
|
||||
|
@ -12,7 +12,7 @@
|
||||
@await Html.PartialAsync("Partials/_MastodonStatus")
|
||||
|
||||
<div id="all-blog-posts">
|
||||
@foreach (IBlogPost post in BlogPostService.GetBlogPosts(0, tags: Model.Tag))
|
||||
@foreach (IBlogPost post in BlogPostService.GetBlogPosts(0))
|
||||
{
|
||||
@await Html.PartialAsync("Partials/_BlogCard", post)
|
||||
}
|
||||
@ -22,6 +22,5 @@
|
||||
{
|
||||
["UrlRoot"] = "/blog",
|
||||
["Page"] = 1,
|
||||
["Tags"] = Model.Tag,
|
||||
["PageCount"] = BlogPostService.GetPageCount(visibility: Visibility.Published, tags: Model.Tag)
|
||||
["PageCount"] = BlogPostService.GetPageCount(visibility: Visibility.Published)
|
||||
})
|
@ -1,4 +1,3 @@
|
||||
using System.Web;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using OliverBooth.Common.Data.Blog;
|
||||
@ -16,15 +15,11 @@ public class Index : PageModel
|
||||
_blogPostService = blogPostService;
|
||||
}
|
||||
|
||||
public string[] Tag { get; private set; } = [];
|
||||
|
||||
public IActionResult OnGet([FromQuery(Name = "pid")] Guid? postId = null,
|
||||
[FromQuery(Name = "p")] int? wpPostId = null,
|
||||
[FromQuery(Name = "tag")] string? tag = null)
|
||||
[FromQuery(Name = "p")] int? wpPostId = null)
|
||||
{
|
||||
if (postId.HasValue == wpPostId.HasValue)
|
||||
{
|
||||
Tag = (tag?.Split('+').Select(HttpUtility.UrlDecode).ToArray() ?? [])!;
|
||||
return Page();
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
@await Html.PartialAsync("Partials/_MastodonStatus")
|
||||
|
||||
<div id="all-blog-posts">
|
||||
@foreach (IBlogPost post in BlogPostService.GetBlogPosts(Model.PageNumber - 1, tags: Model.Tag))
|
||||
@foreach (IBlogPost post in BlogPostService.GetBlogPosts(Model.PageNumber))
|
||||
{
|
||||
@await Html.PartialAsync("Partials/_BlogCard", post)
|
||||
}
|
||||
@ -19,6 +19,5 @@
|
||||
{
|
||||
["UrlRoot"] = "/blog",
|
||||
["Page"] = Model.PageNumber,
|
||||
["Tags"] = Model.Tag,
|
||||
["PageCount"] = BlogPostService.GetPageCount(visibility: Visibility.Published, tags: Model.Tag)
|
||||
["PageCount"] = BlogPostService.GetPageCount(visibility: Visibility.Published)
|
||||
})
|
@ -1,4 +1,3 @@
|
||||
using System.Web;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
@ -15,15 +14,12 @@ public class List : PageModel
|
||||
/// <value>The requested page number.</value>
|
||||
public int PageNumber { get; private set; }
|
||||
|
||||
public string[] Tag { get; private set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Handles the incoming GET request to the page.
|
||||
/// </summary>
|
||||
/// <param name="page">The requested page number, starting from 1.</param>
|
||||
/// <param name="tag">The tag by which to filter results.</param>
|
||||
/// <returns></returns>
|
||||
public IActionResult OnGet([FromRoute(Name = "pageNumber")] int page = 1, [FromQuery(Name = "tag")] string? tag = null)
|
||||
public IActionResult OnGet([FromRoute(Name = "pageNumber")] int page = 1)
|
||||
{
|
||||
if (page < 2)
|
||||
{
|
||||
@ -31,7 +27,6 @@ public class List : PageModel
|
||||
}
|
||||
|
||||
PageNumber = page;
|
||||
Tag = (tag?.Split('+').Select(HttpUtility.UrlDecode).ToArray() ?? [])!;
|
||||
return Page();
|
||||
}
|
||||
}
|
||||
|
@ -15,11 +15,11 @@
|
||||
</div>
|
||||
|
||||
<p>
|
||||
I recently became a Computer Science student, aiming to get my bachelor's degree. My primary focus is C#, though
|
||||
I have dabbled in several other languages such as Java, Kotlin, VB, C++, Python, and others. Over the years I've
|
||||
built up a collection of projects. Some of which I'm extremely proud of, and others I've quietly abandoned and
|
||||
buried. I'm currently working on a few projects that I hope to release in the near future, but in the meantime,
|
||||
feel free to check out some of my <a asp-page="/Projects/Index">previous work</a>.
|
||||
My primary focus is C#, though I have dabbled in several other languages such as Java, Kotlin, VB, C/C++,
|
||||
Python, and others. Over the years I've built up a collection of projects. Some of which I'm extremely proud of,
|
||||
and others I've quietly abandoned and buried. I'm currently working on a few projects that I hope to release in
|
||||
the near future, but in the meantime, feel free to check out some of my
|
||||
<a asp-page="/Projects/Index">previous work</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -32,8 +32,6 @@ public class PageTabsUtility
|
||||
set => _urlRoot = string.IsNullOrWhiteSpace(value) ? string.Empty : value.Trim();
|
||||
}
|
||||
|
||||
public string[]? Tags { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Shows the bound chevrons for the specified bounds type.
|
||||
/// </summary>
|
||||
@ -131,9 +129,7 @@ public class PageTabsUtility
|
||||
private string GetLinkForPage(int page)
|
||||
{
|
||||
// page 1 doesn't use /page/n route
|
||||
return page == 1
|
||||
? $"{_urlRoot}{(Tags is { Length: > 0 } ? $"?tag={string.Join('+', Tags)}" : "")}"
|
||||
: $"{_urlRoot}/page/{page}{(Tags is { Length: > 0 } ? $"?tag={string.Join('+', Tags)}" : "")}";
|
||||
return page == 1 ? _urlRoot : $"{_urlRoot}/page/{page}";
|
||||
}
|
||||
|
||||
private string ShowLowerBound()
|
||||
|
@ -7,23 +7,15 @@
|
||||
{
|
||||
CurrentPage = page,
|
||||
PageCount = pageCount,
|
||||
UrlRoot = urlRoot,
|
||||
Tags = ViewData["Tags"] as string[]
|
||||
UrlRoot = urlRoot
|
||||
};
|
||||
}
|
||||
<nav>
|
||||
<ul class="pagination justify-content-center">
|
||||
@if (pageCount == 1)
|
||||
{
|
||||
@Html.Raw(utility.ShowTab(1)) @* always visible *@
|
||||
}
|
||||
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))
|
||||
}
|
||||
@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>
|
||||
</nav>
|
@ -5,7 +5,6 @@
|
||||
@using OliverBooth.Extensions
|
||||
@inject IBlogPostService BlogPostService
|
||||
@inject ITutorialService TutorialService
|
||||
@inject IConfiguration Configuration
|
||||
@{
|
||||
HttpRequest request = Context.Request;
|
||||
var url = new Uri($"{request.Scheme}://{request.Host}{request.Path}{request.QueryString}");
|
||||
@ -107,11 +106,7 @@
|
||||
<hr>
|
||||
|
||||
<ul class="footer-nav">
|
||||
@{
|
||||
string domain = Configuration.GetSection("Mastodon:Domain").Value ?? string.Empty;
|
||||
string username = Configuration.GetSection("Mastodon:Username").Value ?? string.Empty;
|
||||
}
|
||||
<li><a title="@($"@{username}@{domain}")" href="https://@domain/@@@username" rel="me" class="brand-mastodon"><i class="fa-brands fa-mastodon"></i></a></li>
|
||||
<li><a title="@("@oliver@mastodon.olivr.me")" href="https://mastodon.olivr.me/@@oliver" rel="me" class="brand-mastodon"><i class="fa-brands fa-mastodon"></i></a></li>
|
||||
<li><a title="LinkedIn/oliverlukebooth" href="https://www.linkedin.com/in/oliverlukebooth/" class="brand-linkedin"><i class="fa-brands fa-linkedin"></i></a></li>
|
||||
<li><a title="Blog RSS Feed" asp-controller="Rss" asp-action="OnGet"><i class="fa-solid fa-rss text-orange"></i></a></li>
|
||||
<li><a title="View Source" href="https://git.oliverbooth.dev/oliverbooth/oliverbooth.dev"><i class="fa-solid fa-code"></i></a></li>
|
||||
|
@ -36,19 +36,12 @@ internal sealed class BlogPostService : IBlogPostService
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int GetBlogPostCount(Visibility visibility = Visibility.None, string[]? tags = null)
|
||||
public int GetBlogPostCount(Visibility visibility = Visibility.None)
|
||||
{
|
||||
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
|
||||
? context.BlogPosts.Count(p => !p.IsRedirect)
|
||||
: context.BlogPosts.Count(p => !p.IsRedirect && p.Visibility == visibility);
|
||||
? context.BlogPosts.Count()
|
||||
: context.BlogPosts.Count(p => p.Visibility == visibility);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -67,20 +60,13 @@ internal sealed class BlogPostService : IBlogPostService
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<IBlogPost> GetBlogPosts(int page, int pageSize = 10, string[]? tags = null)
|
||||
public IReadOnlyList<IBlogPost> GetBlogPosts(int page, int pageSize = 10)
|
||||
{
|
||||
using BlogContext context = _dbContextFactory.CreateDbContext();
|
||||
IEnumerable<BlogPost> posts = context.BlogPosts
|
||||
return context.BlogPosts
|
||||
.Where(p => p.Visibility == Visibility.Published && !p.IsRedirect)
|
||||
.OrderByDescending(post => post.Published)
|
||||
.AsEnumerable();
|
||||
|
||||
if (tags is { Length: > 0 })
|
||||
{
|
||||
posts = posts.Where(p => p.Tags.Intersect(tags).Any());
|
||||
}
|
||||
|
||||
return posts.Skip(page * pageSize)
|
||||
.Skip(page * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToArray().Select(CacheAuthor).ToArray();
|
||||
}
|
||||
@ -117,9 +103,9 @@ internal sealed class BlogPostService : IBlogPostService
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int GetPageCount(int pageSize = 10, Visibility visibility = Visibility.None, string[]? tags = null)
|
||||
public int GetPageCount(int pageSize = 10, Visibility visibility = Visibility.None)
|
||||
{
|
||||
float postCount = GetBlogPostCount(visibility, tags);
|
||||
float postCount = GetBlogPostCount(visibility);
|
||||
return (int)MathF.Ceiling(postCount / pageSize);
|
||||
}
|
||||
|
||||
|
@ -27,13 +27,11 @@ internal sealed class MastodonService : IMastodonService
|
||||
/// <inheritdoc />
|
||||
public IMastodonStatus GetLatestStatus()
|
||||
{
|
||||
string domain = _configuration.GetSection("Mastodon:Domain").Value ?? string.Empty;
|
||||
string token = _configuration.GetSection("Mastodon:Token").Value ?? string.Empty;
|
||||
string account = _configuration.GetSection("Mastodon:Account").Value ?? string.Empty;
|
||||
|
||||
using var request = new HttpRequestMessage();
|
||||
request.Headers.Add("Authorization", $"Bearer {token}");
|
||||
request.RequestUri = new Uri($"https://{domain}/api/v1/accounts/{account}/statuses");
|
||||
request.RequestUri = new Uri($"https://mastodon.olivr.me/api/v1/accounts/{account}/statuses");
|
||||
|
||||
using HttpResponseMessage response = _httpClient.Send(request);
|
||||
using var stream = response.Content.ReadAsStream();
|
||||
|
@ -1,3 +1,4 @@
|
||||
version: '3.9'
|
||||
services:
|
||||
oliverbooth:
|
||||
container_name: oliverbooth.dev
|
||||
|
@ -1,11 +1,9 @@
|
||||
@use "sass:color";
|
||||
@import "colors";
|
||||
@import "markdown";
|
||||
@import "blog";
|
||||
|
||||
html, body {
|
||||
background: $background;
|
||||
color: $foreground;
|
||||
background: #121212;
|
||||
color: #f5f5f5;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@ -15,18 +13,8 @@ html, body {
|
||||
}
|
||||
}
|
||||
|
||||
.keystroke {
|
||||
background: color.adjust($foreground, $lightness: -20%);
|
||||
color: $background;
|
||||
border-radius: 2px;
|
||||
border: color.adjust($foreground, $lightness: -30%);
|
||||
box-shadow: #2b2b2b 2px 2px;
|
||||
font-size: 12px;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
|
||||
box-shadow: 0 0 0 0.1rem $ui-foreground, 0 0 0 0.25rem #258cfb;
|
||||
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
||||
}
|
||||
|
||||
html {
|
||||
@ -47,11 +35,11 @@ main.container {
|
||||
a {
|
||||
&:link, &:visited, &:hover, &:active {
|
||||
text-decoration: none;
|
||||
color: $link-text;
|
||||
color: #03A9F4;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $link-hover;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,19 +47,19 @@ a {
|
||||
a {
|
||||
&:link, &:visited, &:hover, &:active {
|
||||
text-decoration: none;
|
||||
color: $ui-foreground;
|
||||
color: white;
|
||||
|
||||
* {
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
text-decoration: none;
|
||||
color: $ui-foreground;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hr.page-separator {
|
||||
border-top: 5px dashed $ui-foreground;
|
||||
border-top: 5px dashed #ffffff;
|
||||
opacity: 1;
|
||||
margin: 50px 0;
|
||||
}
|
||||
@ -98,7 +86,7 @@ ul.contact-reasons {
|
||||
a {
|
||||
&:link, &:visited, &:hover, &:active {
|
||||
text-decoration: none;
|
||||
color: $ui-foreground;
|
||||
color: white;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@ -110,10 +98,10 @@ ul.contact-reasons {
|
||||
|
||||
.card {
|
||||
background: #212121;
|
||||
color: $ui-foreground;
|
||||
color: #ffffff;
|
||||
|
||||
a.btn, button {
|
||||
color: $ui-foreground;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +128,7 @@ nav {
|
||||
|
||||
&:link, &:visited, &:hover, &:active {
|
||||
text-decoration: none;
|
||||
color: $ui-foreground;
|
||||
color: white;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@ -156,7 +144,7 @@ nav {
|
||||
}
|
||||
|
||||
article {
|
||||
background: $content-background;
|
||||
background: #333333;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
|
||||
@ -165,7 +153,7 @@ article {
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 2px solid $blockquote;
|
||||
border-left: 2px solid #f03;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
@ -185,7 +173,7 @@ article {
|
||||
|
||||
abbr {
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted $link-hover;
|
||||
border-bottom: 1px dotted #ffffff;
|
||||
}
|
||||
|
||||
span.timestamp {
|
||||
@ -197,7 +185,7 @@ article {
|
||||
|
||||
.project-card {
|
||||
position: relative;
|
||||
background: $project-background;
|
||||
background: #000;
|
||||
box-shadow: 0 0 15px rgba(0, 0, 0, .1);
|
||||
|
||||
&:hover {
|
||||
@ -225,7 +213,7 @@ article {
|
||||
|
||||
a {
|
||||
&:link, &:visited, &:hover &:active {
|
||||
color: $ui-foreground;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,7 +225,7 @@ article {
|
||||
width: 100%;
|
||||
margin: -34px 0 0;
|
||||
padding: 5px;
|
||||
background-color: rgba($project-background, 50%);
|
||||
background-color: rgba(#000, 50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -426,7 +414,7 @@ td.trim-p p:last-child {
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $accent;
|
||||
color: #03A9F4;
|
||||
background-color: #1E1E1E !important;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
@use "sass:color";
|
||||
|
||||
$background: #121212;
|
||||
$foreground: #f5f5f5;
|
||||
$accent: #03a9f4;
|
||||
$ui-foreground: #ffffff;
|
||||
$content-background: #333333;
|
||||
$blockquote: #ff0033;
|
||||
$project-background: #000000;
|
||||
|
||||
$link-text: $accent;
|
||||
$link-hover: lighten($link-text, 50%);
|
Loading…
Reference in New Issue
Block a user