using Iceshrimp.Backend.Components.Helpers; using Iceshrimp.Backend.Components.PublicPreview.Renderers; using Iceshrimp.Backend.Components.PublicPreview.Schemas; using Iceshrimp.Backend.Core.Configuration; using Iceshrimp.Backend.Core.Extensions; using Iceshrimp.Backend.Core.Middleware; using Iceshrimp.Backend.Core.Services; using Microsoft.AspNetCore.Components; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace Iceshrimp.Backend.Pages; public partial class NotePreview( MetaService meta, NoteRenderer renderer, IOptions config, IOptionsSnapshot security ) : AsyncComponentBase { [Parameter] public required string Id { get; set; } private PreviewNote? _note; private string _instanceName = "Iceshrimp.NET"; private bool ShowMedia => security.Value.PublicPreview > Enums.PublicPreview.RestrictedNoMedia; private bool ShowRemoteReplies => security.Value.PublicPreview > Enums.PublicPreview.Restricted; protected override async Task OnInitializedAsync() { if (security.Value.PublicPreview == Enums.PublicPreview.Lockdown) throw new PublicPreviewDisabledException(); _instanceName = await meta.GetAsync(MetaEntity.InstanceName) ?? _instanceName; //TODO: show publish & edit timestamps //TODO: show quotes inline (enforce visibility by checking VisibilityIsPublicOrHome) //TODO: show parent post inline (enforce visibility by checking VisibilityIsPublicOrHome) //TODO: show avatar instead of image as fallback? can we do both? //TODO: thread view (respect public preview settings - don't show remote replies if set to restricted or lower) var note = await Database.Notes .IncludeCommonProperties() .EnsureVisibleFor(null) .FirstOrDefaultAsync(p => p.Id == Id); if (note is { IsPureRenote: true }) { var target = note.Renote?.Url ?? note.Renote?.Uri ?? note.Renote?.GetPublicUriOrNull(config.Value) ?? throw new Exception("Note is remote but has no uri"); Redirect(target); return; } if (note is { User.Host: not null }) { var target = note.Url ?? note.Uri ?? throw new Exception("Note is remote but has no uri"); Redirect(target); return; } _note = await renderer.RenderOne(note); } }