feat: add mastodon status card

This commit is contained in:
Oliver Booth 2024-02-23 03:23:57 +00:00
parent c7cd016baf
commit 279d824772
Signed by: oliverbooth
GPG Key ID: E60B570D1B7557B5
8 changed files with 114 additions and 0 deletions

View File

@ -0,0 +1,22 @@
namespace OliverBooth.Data;
public interface IMastodonStatus
{
/// <summary>
/// Gets the content of the status.
/// </summary>
/// <value>The content.</value>
string Content { get; }
/// <summary>
/// Gets the date and time at which this status was posted.
/// </summary>
/// <value>The post timestamp.</value>
DateTimeOffset CreatedAt { get; }
/// <summary>
/// Gets the original URI of the status.
/// </summary>
/// <value>The original URI.</value>
Uri OriginalUri { get; }
}

View File

@ -0,0 +1,18 @@
using System.Text.Json.Serialization;
namespace OliverBooth.Data;
internal sealed class MastodonStatus : IMastodonStatus
{
/// <inheritdoc />
[JsonPropertyName("content")]
public string Content { get; set; } = string.Empty;
/// <inheritdoc />
[JsonPropertyName("created_at")]
public DateTimeOffset CreatedAt { get; set; }
/// <inheritdoc />
[JsonPropertyName("url")]
public Uri OriginalUri { get; set; } = null!;
}

View File

@ -1,10 +1,26 @@
@page
@using Humanizer
@using OliverBooth.Data
@using OliverBooth.Services
@model Index
@inject IMastodonService MastodonService
@{
ViewData["Title"] = "Blog";
IMastodonStatus latestStatus = MastodonService.GetLatestStatus();
}
<div class="card text-center mastodon-update-card">
<div class="card-body">
@Html.Raw(latestStatus.Content)
</div>
<div class="card-footer text-muted">
<abbr title="@latestStatus.CreatedAt.ToString("F")">@latestStatus.CreatedAt.Humanize()</abbr>
&bull;
<a href="@latestStatus.OriginalUri" target="_blank">View on Mastodon</a>
</div>
</div>
<div id="all-blog-posts">
@await Html.PartialAsync("_LoadingSpinner")
</div>

View File

@ -32,11 +32,13 @@ builder.Services.AddSingleton(provider => new MarkdownPipelineBuilder()
builder.Services.AddDbContextFactory<BlogContext>();
builder.Services.AddDbContextFactory<WebContext>();
builder.Services.AddHttpClient();
builder.Services.AddSingleton<IContactService, ContactService>();
builder.Services.AddSingleton<ITemplateService, TemplateService>();
builder.Services.AddSingleton<IBlogPostService, BlogPostService>();
builder.Services.AddSingleton<IBlogUserService, BlogUserService>();
builder.Services.AddSingleton<IProjectService, ProjectService>();
builder.Services.AddSingleton<IMastodonService, MastodonService>();
builder.Services.AddSingleton<IReadingListService, ReadingListService>();
builder.Services.AddRazorPages().AddRazorRuntimeCompilation();
builder.Services.AddControllersWithViews();

View File

@ -0,0 +1,12 @@
using OliverBooth.Data;
namespace OliverBooth.Services;
public interface IMastodonService
{
/// <summary>
/// Gets the latest status posted to Mastodon.
/// </summary>
/// <returns>The latest status.</returns>
IMastodonStatus GetLatestStatus();
}

View File

@ -0,0 +1,29 @@
using System.Text.Json;
using OliverBooth.Data;
namespace OliverBooth.Services;
internal sealed class MastodonService : IMastodonService
{
private readonly HttpClient _httpClient;
public MastodonService(HttpClient httpClient)
{
_httpClient = httpClient;
}
/// <inheritdoc />
public IMastodonStatus GetLatestStatus()
{
string token = Environment.GetEnvironmentVariable("MASTODON_TOKEN") ?? string.Empty;
string account = Environment.GetEnvironmentVariable("MASTODON_ACCOUNT") ?? string.Empty;
using var request = new HttpRequestMessage();
request.Headers.Add("Authorization", $"Bearer {token}");
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();
var statuses = JsonSerializer.Deserialize<MastodonStatus[]>(stream) ?? Array.Empty<MastodonStatus>();
return statuses[0];
}
}

View File

@ -19,3 +19,5 @@ services:
environment:
- SSL_CERT_PATH=${SSL_CERT_PATH}
- SSL_KEY_PATH=${SSL_KEY_PATH}
- MASTODON_TOKEN=${MASTODON_TOKEN}
- MASTODON_ACCOUNT=${MASTODON_ACCOUNT}

View File

@ -402,4 +402,17 @@ td.trim-p p:last-child {
color: #03A9F4;
background-color: #1E1E1E !important;
}
}
.mastodon-update-card.card {
background-color: desaturate(darken(#6364FF, 50%), 50%);
margin-bottom: 50px;
p:last-child {
margin-bottom: 0;
}
button.btn.btn-mastodon {
background-color: #6364FF;
}
}