[backend/masto-client] Add edit history endpoint (ISH-274)
This commit is contained in:
parent
10a1a13918
commit
5f86ffeffe
5 changed files with 109 additions and 4 deletions
|
@ -77,8 +77,9 @@ public class MediaController(DriveService driveSvc, DatabaseContext db) : Contro
|
|||
Blurhash = file.Blurhash,
|
||||
Description = file.Comment,
|
||||
PreviewUrl = file.ThumbnailUrl,
|
||||
RemoteUrl = file.Uri
|
||||
//Metadata = TODO
|
||||
RemoteUrl = file.Uri,
|
||||
Sensitive = file.IsSensitive,
|
||||
//Metadata = TODO,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -129,6 +129,57 @@ public class NoteRenderer(
|
|||
return res;
|
||||
}
|
||||
|
||||
public async Task<List<StatusEdit>> RenderHistoryAsync(Note note)
|
||||
{
|
||||
var edits = await db.NoteEdits.Where(p => p.Note == note).OrderBy(p => p.Id).ToListAsync();
|
||||
edits.Add(RenderEdit(note));
|
||||
|
||||
var attachments = await GetAttachments(note.FileIds.Concat(edits.SelectMany(p => p.FileIds)));
|
||||
var mentions = await GetMentions([note]);
|
||||
var mentionedUsers = mentions.Select(p => new Note.MentionedUser
|
||||
{
|
||||
Host = p.Host ?? config.Value.AccountDomain,
|
||||
Uri = p.Uri,
|
||||
Username = p.Username,
|
||||
Url = p.Url
|
||||
})
|
||||
.ToList();
|
||||
|
||||
var account = await userRenderer.RenderAsync(note.User);
|
||||
var lastDate = note.CreatedAt;
|
||||
|
||||
List<StatusEdit> history = [];
|
||||
foreach (var edit in edits)
|
||||
{
|
||||
var files = attachments.Where(p => edit.FileIds.Contains(p.Id)).ToList();
|
||||
var entry = new StatusEdit
|
||||
{
|
||||
Account = account,
|
||||
Content = await mfmConverter.ToHtmlAsync(edit.Text ?? "", mentionedUsers, note.UserHost),
|
||||
CreatedAt = lastDate.ToStringIso8601Like(),
|
||||
Emojis = [],
|
||||
IsSensitive = files.Any(p => p.Sensitive),
|
||||
Attachments = files,
|
||||
Poll = null,
|
||||
ContentWarning = edit.Cw ?? ""
|
||||
};
|
||||
history.Add(entry);
|
||||
}
|
||||
|
||||
return history;
|
||||
}
|
||||
|
||||
private NoteEdit RenderEdit(Note note)
|
||||
{
|
||||
return new NoteEdit
|
||||
{
|
||||
Text = note.Text,
|
||||
Cw = note.Cw,
|
||||
FileIds = note.FileIds,
|
||||
UpdatedAt = note.UpdatedAt ?? note.CreatedAt
|
||||
};
|
||||
}
|
||||
|
||||
private static List<FilterResultEntity> GetFilterResult((Filter filter, string keyword)? filtered)
|
||||
{
|
||||
if (filtered == null) return [];
|
||||
|
@ -161,7 +212,28 @@ public class NoteRenderer(
|
|||
Description = f.Comment,
|
||||
Metadata = null,
|
||||
RemoteUrl = f.Uri,
|
||||
Type = AttachmentEntity.GetType(f.Type)
|
||||
Type = AttachmentEntity.GetType(f.Type),
|
||||
Sensitive = f.IsSensitive
|
||||
})
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
private async Task<List<AttachmentEntity>> GetAttachments(IEnumerable<string> fileIds)
|
||||
{
|
||||
var ids = fileIds.Distinct().ToList();
|
||||
if (ids.Count == 0) return [];
|
||||
return await db.DriveFiles.Where(p => ids.Contains(p.Id))
|
||||
.Select(f => new AttachmentEntity
|
||||
{
|
||||
Id = f.Id,
|
||||
Url = f.PublicUrl,
|
||||
Blurhash = f.Blurhash,
|
||||
PreviewUrl = f.PublicThumbnailUrl,
|
||||
Description = f.Comment,
|
||||
Metadata = null,
|
||||
RemoteUrl = f.Uri,
|
||||
Type = AttachmentEntity.GetType(f.Type),
|
||||
Sensitive = f.IsSensitive
|
||||
})
|
||||
.ToListAsync();
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
using J = System.Text.Json.Serialization.JsonPropertyNameAttribute;
|
||||
using JI = System.Text.Json.Serialization.JsonIgnoreAttribute;
|
||||
|
||||
namespace Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;
|
||||
|
||||
public class AttachmentEntity
|
||||
{
|
||||
public required AttachmentType Type;
|
||||
[JI] public required bool Sensitive;
|
||||
[JI] public required AttachmentType Type;
|
||||
[J("id")] public required string Id { get; set; }
|
||||
[J("url")] public required string Url { get; set; }
|
||||
[J("remote_url")] public string? RemoteUrl { get; set; }
|
||||
|
|
|
@ -95,4 +95,16 @@ public class StatusSource
|
|||
[J("id")] public required string Id { get; set; }
|
||||
[J("text")] public required string Text { get; set; }
|
||||
[J("spoiler_text")] public required string ContentWarning { get; set; }
|
||||
}
|
||||
|
||||
public class StatusEdit
|
||||
{
|
||||
[J("content")] public required string? Content { get; set; }
|
||||
[J("spoiler_text")] public required string ContentWarning { get; set; }
|
||||
[J("sensitive")] public required bool IsSensitive { get; set; }
|
||||
[J("created_at")] public required string CreatedAt { get; set; }
|
||||
[J("account")] public required AccountEntity Account { get; set; }
|
||||
[J("poll")] public required PollEntity? Poll { get; set; }
|
||||
[J("media_attachments")] public required List<AttachmentEntity> Attachments { get; set; }
|
||||
[J("emojis")] public required List<EmojiEntity> Emojis { get; set; }
|
||||
}
|
|
@ -552,4 +552,22 @@ public class StatusController(
|
|||
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
[HttpGet("{id}/history")]
|
||||
[Authenticate("read:statuses")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<AccountEntity>))]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(MastodonErrorResponse))]
|
||||
public async Task<IActionResult> GetNoteEditHistory(string id)
|
||||
{
|
||||
var user = HttpContext.GetUser();
|
||||
var note = await db.Notes
|
||||
.Where(p => p.Id == id)
|
||||
.EnsureVisibleFor(user)
|
||||
.FilterHidden(user, db, filterMutes: false)
|
||||
.FirstOrDefaultAsync() ??
|
||||
throw GracefulException.RecordNotFound();
|
||||
|
||||
var res = await noteRenderer.RenderHistoryAsync(note);
|
||||
return Ok(res);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue