feat: add mastodon status card
This commit is contained in:
parent
c7cd016baf
commit
279d824772
|
@ -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; }
|
||||||
|
}
|
|
@ -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!;
|
||||||
|
}
|
|
@ -1,10 +1,26 @@
|
||||||
@page
|
@page
|
||||||
|
@using Humanizer
|
||||||
|
@using OliverBooth.Data
|
||||||
|
@using OliverBooth.Services
|
||||||
@model Index
|
@model Index
|
||||||
|
@inject IMastodonService MastodonService
|
||||||
|
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Blog";
|
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>
|
||||||
|
•
|
||||||
|
<a href="@latestStatus.OriginalUri" target="_blank">View on Mastodon</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="all-blog-posts">
|
<div id="all-blog-posts">
|
||||||
@await Html.PartialAsync("_LoadingSpinner")
|
@await Html.PartialAsync("_LoadingSpinner")
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -32,11 +32,13 @@ builder.Services.AddSingleton(provider => new MarkdownPipelineBuilder()
|
||||||
|
|
||||||
builder.Services.AddDbContextFactory<BlogContext>();
|
builder.Services.AddDbContextFactory<BlogContext>();
|
||||||
builder.Services.AddDbContextFactory<WebContext>();
|
builder.Services.AddDbContextFactory<WebContext>();
|
||||||
|
builder.Services.AddHttpClient();
|
||||||
builder.Services.AddSingleton<IContactService, ContactService>();
|
builder.Services.AddSingleton<IContactService, ContactService>();
|
||||||
builder.Services.AddSingleton<ITemplateService, TemplateService>();
|
builder.Services.AddSingleton<ITemplateService, TemplateService>();
|
||||||
builder.Services.AddSingleton<IBlogPostService, BlogPostService>();
|
builder.Services.AddSingleton<IBlogPostService, BlogPostService>();
|
||||||
builder.Services.AddSingleton<IBlogUserService, BlogUserService>();
|
builder.Services.AddSingleton<IBlogUserService, BlogUserService>();
|
||||||
builder.Services.AddSingleton<IProjectService, ProjectService>();
|
builder.Services.AddSingleton<IProjectService, ProjectService>();
|
||||||
|
builder.Services.AddSingleton<IMastodonService, MastodonService>();
|
||||||
builder.Services.AddSingleton<IReadingListService, ReadingListService>();
|
builder.Services.AddSingleton<IReadingListService, ReadingListService>();
|
||||||
builder.Services.AddRazorPages().AddRazorRuntimeCompilation();
|
builder.Services.AddRazorPages().AddRazorRuntimeCompilation();
|
||||||
builder.Services.AddControllersWithViews();
|
builder.Services.AddControllersWithViews();
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
|
@ -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];
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,3 +19,5 @@ services:
|
||||||
environment:
|
environment:
|
||||||
- SSL_CERT_PATH=${SSL_CERT_PATH}
|
- SSL_CERT_PATH=${SSL_CERT_PATH}
|
||||||
- SSL_KEY_PATH=${SSL_KEY_PATH}
|
- SSL_KEY_PATH=${SSL_KEY_PATH}
|
||||||
|
- MASTODON_TOKEN=${MASTODON_TOKEN}
|
||||||
|
- MASTODON_ACCOUNT=${MASTODON_ACCOUNT}
|
||||||
|
|
|
@ -403,3 +403,16 @@ td.trim-p p:last-child {
|
||||||
background-color: #1E1E1E !important;
|
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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue