[backend/masto-client] Add bookmark endpoints, render note bookmark status (ISH-121)
This commit is contained in:
parent
d343c7f469
commit
c2f8f7ff31
3 changed files with 73 additions and 8 deletions
|
@ -35,6 +35,8 @@ public class NoteRenderer(
|
||||||
|
|
||||||
var liked = data?.LikedNotes?.Contains(note.Id) ??
|
var liked = data?.LikedNotes?.Contains(note.Id) ??
|
||||||
await db.NoteLikes.AnyAsync(p => p.Note == note && p.User == user);
|
await db.NoteLikes.AnyAsync(p => p.Note == note && p.User == user);
|
||||||
|
var bookmarked = data?.BookmarkedNotes?.Contains(note.Id) ??
|
||||||
|
await db.NoteBookmarks.AnyAsync(p => p.Note == note && p.User == user);
|
||||||
var renoted = data?.Renotes?.Contains(note.Id) ??
|
var renoted = data?.Renotes?.Contains(note.Id) ??
|
||||||
await db.Notes.AnyAsync(p => p.Renote == note && p.User == user && p.IsPureRenote);
|
await db.Notes.AnyAsync(p => p.Renote == note && p.User == user && p.IsPureRenote);
|
||||||
|
|
||||||
|
@ -83,8 +85,8 @@ public class NoteRenderer(
|
||||||
FavoriteCount = note.LikeCount,
|
FavoriteCount = note.LikeCount,
|
||||||
IsFavorited = liked,
|
IsFavorited = liked,
|
||||||
IsRenoted = renoted,
|
IsRenoted = renoted,
|
||||||
IsBookmarked = false, //FIXME
|
IsBookmarked = bookmarked,
|
||||||
IsMuted = null, //FIXME
|
IsMuted = null, //FIXME
|
||||||
IsSensitive = note.Cw != null,
|
IsSensitive = note.Cw != null,
|
||||||
ContentWarning = note.Cw ?? "",
|
ContentWarning = note.Cw ?? "",
|
||||||
Visibility = StatusEntity.EncodeVisibility(note.Visibility),
|
Visibility = StatusEntity.EncodeVisibility(note.Visibility),
|
||||||
|
@ -139,6 +141,14 @@ public class NoteRenderer(
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<List<string>> GetBookmarkedNotes(IEnumerable<Note> notes, User? user)
|
||||||
|
{
|
||||||
|
if (user == null) return [];
|
||||||
|
return await db.NoteBookmarks.Where(p => p.User == user && notes.Contains(p.Note))
|
||||||
|
.Select(p => p.NoteId)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<List<string>> GetRenotes(IEnumerable<Note> notes, User? user)
|
private async Task<List<string>> GetRenotes(IEnumerable<Note> notes, User? user)
|
||||||
{
|
{
|
||||||
if (user == null) return [];
|
if (user == null) return [];
|
||||||
|
@ -180,12 +190,13 @@ public class NoteRenderer(
|
||||||
|
|
||||||
var data = new NoteRendererDto
|
var data = new NoteRendererDto
|
||||||
{
|
{
|
||||||
Accounts = accounts ?? await GetAccounts(noteList.Select(p => p.User)),
|
Accounts = accounts ?? await GetAccounts(noteList.Select(p => p.User)),
|
||||||
Mentions = await GetMentions(noteList),
|
Mentions = await GetMentions(noteList),
|
||||||
Attachments = await GetAttachments(noteList),
|
Attachments = await GetAttachments(noteList),
|
||||||
LikedNotes = await GetLikedNotes(noteList, user),
|
LikedNotes = await GetLikedNotes(noteList, user),
|
||||||
Renotes = await GetRenotes(noteList, user),
|
BookmarkedNotes = await GetBookmarkedNotes(noteList, user),
|
||||||
Emoji = await GetEmoji(noteList)
|
Renotes = await GetRenotes(noteList, user),
|
||||||
|
Emoji = await GetEmoji(noteList)
|
||||||
};
|
};
|
||||||
|
|
||||||
return await noteList.Select(p => RenderAsync(p, user, data)).AwaitAllAsync();
|
return await noteList.Select(p => RenderAsync(p, user, data)).AwaitAllAsync();
|
||||||
|
@ -197,6 +208,7 @@ public class NoteRenderer(
|
||||||
public List<MentionEntity>? Mentions;
|
public List<MentionEntity>? Mentions;
|
||||||
public List<AttachmentEntity>? Attachments;
|
public List<AttachmentEntity>? Attachments;
|
||||||
public List<string>? LikedNotes;
|
public List<string>? LikedNotes;
|
||||||
|
public List<string>? BookmarkedNotes;
|
||||||
public List<string>? Renotes;
|
public List<string>? Renotes;
|
||||||
public List<EmojiEntity>? Emoji;
|
public List<EmojiEntity>? Emoji;
|
||||||
public bool Source;
|
public bool Source;
|
||||||
|
|
|
@ -118,6 +118,40 @@ public class StatusController(
|
||||||
return await GetNote(id);
|
return await GetNote(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("{id}/bookmark")]
|
||||||
|
[Authorize("write:bookmarks")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(StatusEntity))]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(MastodonErrorResponse))]
|
||||||
|
public async Task<IActionResult> BookmarkNote(string id)
|
||||||
|
{
|
||||||
|
var user = HttpContext.GetUserOrFail();
|
||||||
|
var note = await db.Notes.Where(p => p.Id == id)
|
||||||
|
.IncludeCommonProperties()
|
||||||
|
.EnsureVisibleFor(user)
|
||||||
|
.FirstOrDefaultAsync() ??
|
||||||
|
throw GracefulException.RecordNotFound();
|
||||||
|
|
||||||
|
await noteSvc.BookmarkNoteAsync(note, user);
|
||||||
|
return await GetNote(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("{id}/unbookmark")]
|
||||||
|
[Authorize("write:bookmarks")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(StatusEntity))]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(MastodonErrorResponse))]
|
||||||
|
public async Task<IActionResult> UnbookmarkNote(string id)
|
||||||
|
{
|
||||||
|
var user = HttpContext.GetUserOrFail();
|
||||||
|
var note = await db.Notes.Where(p => p.Id == id)
|
||||||
|
.IncludeCommonProperties()
|
||||||
|
.EnsureVisibleFor(user)
|
||||||
|
.FirstOrDefaultAsync() ??
|
||||||
|
throw GracefulException.RecordNotFound();
|
||||||
|
|
||||||
|
await noteSvc.BookmarkNoteAsync(note, user);
|
||||||
|
return await GetNote(id);
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost("{id}/reblog")]
|
[HttpPost("{id}/reblog")]
|
||||||
[Authorize("write:favourites")]
|
[Authorize("write:favourites")]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(StatusEntity))]
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(StatusEntity))]
|
||||||
|
|
|
@ -776,6 +776,25 @@ public class NoteService(
|
||||||
await UnlikeNoteAsync(dbNote, actor);
|
await UnlikeNoteAsync(dbNote, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task BookmarkNoteAsync(Note note, User user)
|
||||||
|
{
|
||||||
|
if (!await db.NoteBookmarks.AnyAsync(p => p.Note == note && p.User == user))
|
||||||
|
{
|
||||||
|
var bookmark = new NoteBookmark
|
||||||
|
{
|
||||||
|
Id = IdHelpers.GenerateSlowflakeId(), CreatedAt = DateTime.UtcNow, User = user, Note = note
|
||||||
|
};
|
||||||
|
|
||||||
|
await db.NoteBookmarks.AddAsync(bookmark);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UnbookmarkNoteAsync(Note note, User actor)
|
||||||
|
{
|
||||||
|
await db.NoteBookmarks.Where(p => p.Note == note && p.User == actor).ExecuteDeleteAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task UpdatePinnedNotesAsync(ASActor actor, User user)
|
public async Task UpdatePinnedNotesAsync(ASActor actor, User user)
|
||||||
{
|
{
|
||||||
logger.LogDebug("Updating pinned notes for user {user}", user.Id);
|
logger.LogDebug("Updating pinned notes for user {user}", user.Id);
|
||||||
|
|
Loading…
Add table
Reference in a new issue