[backend/api] Add renote endpoints (ISH-341)
This commit is contained in:
parent
835796ac86
commit
167fd5f0d6
4 changed files with 78 additions and 15 deletions
|
@ -294,7 +294,6 @@ public class StatusController(
|
|||
var note = await db.Notes.Where(p => p.Id == id)
|
||||
.IncludeCommonProperties()
|
||||
.EnsureVisibleFor(user)
|
||||
.FilterHidden(user, db, filterMutes: false)
|
||||
.FirstOrDefaultAsync() ??
|
||||
throw GracefulException.RecordNotFound();
|
||||
|
||||
|
@ -302,10 +301,8 @@ public class StatusController(
|
|||
? StatusEntity.DecodeVisibility(request.Visibility)
|
||||
: user.UserSettings?.DefaultRenoteVisibility ?? Note.NoteVisibility.Public;
|
||||
|
||||
if (renoteVisibility == Note.NoteVisibility.Specified)
|
||||
throw GracefulException.BadRequest("Renote visibility must be one of: public, unlisted, private");
|
||||
|
||||
renote = await noteSvc.CreateNoteAsync(user, renoteVisibility, renote: note);
|
||||
renote = await noteSvc.RenoteNoteAsync(note, user, renoteVisibility) ??
|
||||
throw new Exception("Created renote was null");
|
||||
note.RenoteCount++; // we do not want to call save changes after this point
|
||||
}
|
||||
|
||||
|
@ -319,17 +316,14 @@ public class StatusController(
|
|||
public async Task<IActionResult> UndoRenote(string id)
|
||||
{
|
||||
var user = HttpContext.GetUserOrFail();
|
||||
if (!await db.Notes.Where(p => p.Id == id).EnsureVisibleFor(user).AnyAsync())
|
||||
throw GracefulException.RecordNotFound();
|
||||
|
||||
var renotes = await db.Notes.Where(p => p.RenoteId == id && p.IsPureRenote && p.User == user)
|
||||
.IncludeCommonProperties()
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var renote in renotes) await noteSvc.DeleteNoteAsync(renote);
|
||||
|
||||
renotes[0].Renote!.RenoteCount--; // we do not want to call save changes after this point
|
||||
var note = await db.Notes.Where(p => p.Id == id)
|
||||
.IncludeCommonProperties()
|
||||
.EnsureVisibleFor(user)
|
||||
.FirstOrDefaultAsync() ??
|
||||
throw GracefulException.RecordNotFound();
|
||||
|
||||
var count = await noteSvc.UnrenoteNoteAsync(note, user);
|
||||
note.RenoteCount -= (short)count; // we do not want to call save changes after this point
|
||||
return await GetNote(id);
|
||||
}
|
||||
|
||||
|
|
|
@ -170,6 +170,40 @@ public class NoteController(
|
|||
return Ok(new ValueResponse(success ? --note.LikeCount : note.LikeCount));
|
||||
}
|
||||
|
||||
[HttpPost("{id}/renote")]
|
||||
[Authenticate]
|
||||
[Authorize]
|
||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ValueResponse))]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ErrorResponse))]
|
||||
public async Task<IActionResult> RenoteNote(string id, [FromQuery] NoteVisibility? visibility = null)
|
||||
{
|
||||
var user = HttpContext.GetUserOrFail();
|
||||
var note = await db.Notes.Where(p => p.Id == id)
|
||||
.EnsureVisibleFor(user)
|
||||
.FirstOrDefaultAsync() ??
|
||||
throw GracefulException.NotFound("Note not found");
|
||||
|
||||
var success = await noteSvc.RenoteNoteAsync(note, user, (Note.NoteVisibility?)visibility);
|
||||
return Ok(new ValueResponse(success != null ? ++note.RenoteCount : note.RenoteCount));
|
||||
}
|
||||
|
||||
[HttpPost("{id}/unrenote")]
|
||||
[Authenticate]
|
||||
[Authorize]
|
||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ValueResponse))]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ErrorResponse))]
|
||||
public async Task<IActionResult> UnrenoteNote(string id)
|
||||
{
|
||||
var user = HttpContext.GetUserOrFail();
|
||||
var note = await db.Notes.Where(p => p.Id == id)
|
||||
.EnsureVisibleFor(user)
|
||||
.FirstOrDefaultAsync() ??
|
||||
throw GracefulException.NotFound("Note not found");
|
||||
|
||||
var count = await noteSvc.UnrenoteNoteAsync(note, user);
|
||||
return Ok(new ValueResponse(note.RenoteCount - count));
|
||||
}
|
||||
|
||||
[HttpPost("{id}/react/{name}")]
|
||||
[Authenticate]
|
||||
[Authorize]
|
||||
|
|
|
@ -1105,6 +1105,31 @@ public class NoteService(
|
|||
return true;
|
||||
}
|
||||
|
||||
public async Task<Note?> RenoteNoteAsync(Note note, User user, Note.NoteVisibility? visibility = null)
|
||||
{
|
||||
visibility ??= user.UserSettings?.DefaultRenoteVisibility ?? Note.NoteVisibility.Public;
|
||||
if (visibility == Note.NoteVisibility.Specified)
|
||||
throw GracefulException.BadRequest("Renote visibility must be one of: public, unlisted, private");
|
||||
if (note.IsPureRenote)
|
||||
throw GracefulException.BadRequest("Cannot renote a pure renote");
|
||||
|
||||
if (!await db.Notes.AnyAsync(p => p.Renote == note && p.IsPureRenote && p.User == user))
|
||||
return await CreateNoteAsync(user, visibility.Value, renote: note);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<int> UnrenoteNoteAsync(Note note, User user)
|
||||
{
|
||||
var renotes = await db.Notes.Where(p => p.Renote == note && p.IsPureRenote && p.User == user).ToListAsync();
|
||||
if (renotes.Count == 0) return 0;
|
||||
|
||||
foreach (var renote in renotes)
|
||||
await DeleteNoteAsync(renote);
|
||||
|
||||
return renotes.Count;
|
||||
}
|
||||
|
||||
public async Task LikeNoteAsync(ASNote note, User actor)
|
||||
{
|
||||
var dbNote = await ResolveNoteAsync(note) ?? throw new Exception("Cannot register like for unknown note");
|
||||
|
|
|
@ -34,6 +34,16 @@ internal class NoteControllerModel(ApiClient api)
|
|||
public Task<ValueResponse?> UnlikeNote(string id) =>
|
||||
api.CallNullable<ValueResponse>(HttpMethod.Post, $"/notes/{id}/unlike");
|
||||
|
||||
public Task<ValueResponse?> RenoteNote(string id, NoteVisibility? visibility = null)
|
||||
{
|
||||
var query = new QueryString();
|
||||
if (visibility.HasValue) query.Add("visibility", ((int)visibility.Value).ToString().ToLowerInvariant());
|
||||
return api.CallNullable<ValueResponse>(HttpMethod.Post, $"/notes/{id}/renote", query);
|
||||
}
|
||||
|
||||
public Task<ValueResponse?> UnrenoteNote(string id) =>
|
||||
api.CallNullable<ValueResponse>(HttpMethod.Post, $"/notes/{id}/unrenote");
|
||||
|
||||
public Task<ValueResponse?> ReactToNote(string id, string name) =>
|
||||
api.CallNullable<ValueResponse>(HttpMethod.Post, $"/notes/{id}/react/{name}");
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue