
This makes sure the AngleSharp owner document is only created once per application lifecycle, and replaces all async calls with their synchronous counterparts (since the input is already loaded in memory, using async for this just creates overhead)
103 lines
No EOL
4.1 KiB
C#
103 lines
No EOL
4.1 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
using System.Net;
|
|
using System.Net.Mime;
|
|
using Iceshrimp.Backend.Controllers.Mastodon.Attributes;
|
|
using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;
|
|
using Iceshrimp.Backend.Controllers.Shared.Attributes;
|
|
using Iceshrimp.Backend.Core.Database;
|
|
using Iceshrimp.Backend.Core.Database.Tables;
|
|
using Iceshrimp.Backend.Core.Extensions;
|
|
using Iceshrimp.Backend.Core.Helpers;
|
|
using Iceshrimp.Backend.Core.Helpers.LibMfm.Conversion;
|
|
using Iceshrimp.Backend.Core.Middleware;
|
|
using Microsoft.AspNetCore.Cors;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.RateLimiting;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace Iceshrimp.Backend.Controllers.Mastodon;
|
|
|
|
[MastodonApiController]
|
|
[Route("/api/v1/announcements")]
|
|
[EnableCors("mastodon")]
|
|
[Authenticate]
|
|
[EnableRateLimiting("sliding")]
|
|
[Produces(MediaTypeNames.Application.Json)]
|
|
public class AnnouncementController(DatabaseContext db, MfmConverter mfmConverter) : ControllerBase
|
|
{
|
|
[HttpGet]
|
|
[Authorize]
|
|
[ProducesResults(HttpStatusCode.OK)]
|
|
[SuppressMessage("ReSharper", "EntityFramework.UnsupportedServerSideFunctionCall", Justification = "Projectables")]
|
|
public async Task<IEnumerable<AnnouncementEntity>> GetAnnouncements(
|
|
[FromQuery(Name = "with_dismissed")] bool withDismissed
|
|
)
|
|
{
|
|
var user = HttpContext.GetUserOrFail();
|
|
var announcements = db.Announcements.AsQueryable();
|
|
|
|
if (!withDismissed)
|
|
announcements = announcements.Where(p => p.IsReadBy(user));
|
|
|
|
var res = await announcements.OrderByDescending(p => p.UpdatedAt ?? p.CreatedAt)
|
|
.Select(p => new AnnouncementEntity
|
|
{
|
|
Id = p.Id,
|
|
PublishedAt = p.CreatedAt.ToStringIso8601Like(),
|
|
UpdatedAt = (p.UpdatedAt ?? p.CreatedAt).ToStringIso8601Like(),
|
|
IsRead = p.IsReadBy(user),
|
|
Content = $"""
|
|
**{p.Title}**
|
|
{p.Text}
|
|
""",
|
|
Mentions = new List<MentionEntity>(), //TODO
|
|
Emoji = new List<EmojiEntity>() //TODO
|
|
})
|
|
.ToListAsync();
|
|
|
|
res.ForEach(p => p.Content = mfmConverter.ToHtml(p.Content, [], null).Html);
|
|
return res;
|
|
}
|
|
|
|
[HttpPost("{id}/dismiss")]
|
|
[Authorize("write:accounts")]
|
|
[OverrideResultType<object>]
|
|
[ProducesResults(HttpStatusCode.OK)]
|
|
[ProducesErrors(HttpStatusCode.NotFound)]
|
|
[SuppressMessage("ReSharper", "EntityFramework.UnsupportedServerSideFunctionCall", Justification = "Projectables")]
|
|
public async Task<object> DismissAnnouncement(string id)
|
|
{
|
|
var user = HttpContext.GetUserOrFail();
|
|
var announcement = await db.Announcements.FirstOrDefaultAsync(p => p.Id == id) ??
|
|
throw GracefulException.NotFound("Announcement not found");
|
|
|
|
if (await db.Announcements.AnyAsync(p => p == announcement && !p.IsReadBy(user)))
|
|
{
|
|
var announcementRead = new AnnouncementRead
|
|
{
|
|
Id = IdHelpers.GenerateSnowflakeId(),
|
|
CreatedAt = DateTime.UtcNow,
|
|
Announcement = announcement,
|
|
User = user
|
|
};
|
|
await db.AnnouncementReads.AddAsync(announcementRead);
|
|
await db.SaveChangesAsync();
|
|
}
|
|
|
|
return new object();
|
|
}
|
|
|
|
[HttpPut("{id}/reactions/{name}")]
|
|
[Authorize("write:favourites")]
|
|
[ProducesErrors(HttpStatusCode.NotImplemented)]
|
|
public IActionResult ReactToAnnouncement(string id, string name) =>
|
|
throw new GracefulException(HttpStatusCode.NotImplemented,
|
|
"Iceshrimp.NET does not support this endpoint due to database schema differences to Mastodon");
|
|
|
|
[HttpDelete("{id}/reactions/{name}")]
|
|
[Authorize("write:favourites")]
|
|
[ProducesErrors(HttpStatusCode.NotImplemented)]
|
|
public IActionResult RemoveAnnouncementReaction(string id, string name) =>
|
|
throw new GracefulException(HttpStatusCode.NotImplemented,
|
|
"Iceshrimp.NET does not support this endpoint due to database schema differences to Mastodon");
|
|
} |