[backend/core] Allow editing of locally originated polls (ISH-136)
This also improves the behavior of handling remotely originating poll edits.
This commit is contained in:
parent
84f7ac7051
commit
57ac4750ad
3 changed files with 62 additions and 13 deletions
|
@ -331,20 +331,29 @@ public class StatusController(
|
|||
public async Task<IActionResult> EditNote(string id, [FromHybrid] StatusSchemas.EditStatusRequest request)
|
||||
{
|
||||
var user = HttpContext.GetUserOrFail();
|
||||
var note = await db.Notes.IncludeCommonProperties().FirstOrDefaultAsync(p => p.Id == id && p.User == user) ??
|
||||
var note = await db.Notes
|
||||
.Include(p => p.Poll)
|
||||
.IncludeCommonProperties()
|
||||
.FirstOrDefaultAsync(p => p.Id == id && p.User == user) ??
|
||||
throw GracefulException.RecordNotFound();
|
||||
|
||||
if (request.Text == null && request.MediaIds is not { Count: > 0 } && request.Poll == null)
|
||||
throw GracefulException.BadRequest("Posts must have text, media or poll");
|
||||
|
||||
if (request.Poll != null)
|
||||
throw GracefulException.BadRequest("Poll edits haven't been implemented yet, please delete & redraft instead");
|
||||
var poll = request.Poll != null
|
||||
? new Poll
|
||||
{
|
||||
Choices = request.Poll.Options,
|
||||
Multiple = request.Poll.Multiple,
|
||||
ExpiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(request.Poll.ExpiresIn)
|
||||
}
|
||||
: null;
|
||||
|
||||
var attachments = request.MediaIds != null
|
||||
? await db.DriveFiles.Where(p => request.MediaIds.Contains(p.Id)).ToListAsync()
|
||||
: [];
|
||||
|
||||
note = await noteSvc.UpdateNoteAsync(note, request.Text, request.Cw, attachments);
|
||||
note = await noteSvc.UpdateNoteAsync(note, request.Text, request.Cw, attachments, poll);
|
||||
var res = await noteRenderer.RenderAsync(note, user);
|
||||
|
||||
return Ok(res);
|
||||
|
|
|
@ -144,7 +144,7 @@ public abstract class BackgroundTaskQueue
|
|||
var db = scope.GetRequiredService<DatabaseContext>();
|
||||
var poll = await db.Polls.FirstOrDefaultAsync(p => p.NoteId == job.NoteId, cancellationToken: token);
|
||||
if (poll == null) return;
|
||||
if (poll.ExpiresAt > DateTime.UtcNow + TimeSpan.FromMinutes(5)) return;
|
||||
if (poll.ExpiresAt > DateTime.UtcNow + TimeSpan.FromSeconds(30)) return;
|
||||
var note = await db.Notes.IncludeCommonProperties()
|
||||
.FirstOrDefaultAsync(p => p.Id == poll.NoteId, cancellationToken: token);
|
||||
if (note == null) return;
|
||||
|
|
|
@ -208,7 +208,8 @@ public class NoteService(
|
|||
}
|
||||
|
||||
public async Task<Note> UpdateNoteAsync(
|
||||
Note note, string? text = null, string? cw = null, IReadOnlyCollection<DriveFile>? attachments = null
|
||||
Note note, string? text = null, string? cw = null, IReadOnlyCollection<DriveFile>? attachments = null,
|
||||
Poll? poll = null
|
||||
)
|
||||
{
|
||||
var noteEdit = new NoteEdit
|
||||
|
@ -268,6 +269,38 @@ public class NoteService(
|
|||
|
||||
note.UpdatedAt = DateTime.UtcNow;
|
||||
|
||||
if (poll != null)
|
||||
{
|
||||
if (note.Poll != null)
|
||||
{
|
||||
if (note.Poll.ExpiresAt != poll.ExpiresAt)
|
||||
{
|
||||
note.Poll.ExpiresAt = poll.ExpiresAt;
|
||||
await EnqueuePollExpiryTask(note.Poll);
|
||||
}
|
||||
|
||||
if (!note.Poll.Choices.SequenceEqual(poll.Choices) || note.Poll.Multiple != poll.Multiple)
|
||||
{
|
||||
await db.PollVotes.Where(p => p.Note == note).ExecuteDeleteAsync();
|
||||
note.Poll.Choices = poll.Choices;
|
||||
note.Poll.Votes = poll.Choices.Select(p => 0).ToList();
|
||||
note.Poll.Multiple = poll.Multiple;
|
||||
db.Update(note.Poll);
|
||||
}
|
||||
}
|
||||
else {
|
||||
poll.Note = note;
|
||||
poll.UserId = note.User.Id;
|
||||
poll.UserHost = note.UserHost;
|
||||
poll.Votes = poll.Choices.Select(_ => 0).ToList();
|
||||
poll.NoteVisibility = note.Visibility;
|
||||
await db.AddAsync(poll);
|
||||
await EnqueuePollExpiryTask(poll);
|
||||
}
|
||||
|
||||
note.HasPoll = true;
|
||||
}
|
||||
|
||||
db.Update(note);
|
||||
await db.AddAsync(noteEdit);
|
||||
await db.SaveChangesAsync();
|
||||
|
@ -658,12 +691,19 @@ public class NoteService(
|
|||
|
||||
if (dbNote.Poll != null)
|
||||
{
|
||||
if (!dbNote.Poll.Choices.SequenceEqual(choices.Select(p => p.Name)))
|
||||
if (dbNote.Poll.ExpiresAt != (question.EndTime ?? question.Closed))
|
||||
{
|
||||
dbNote.Poll.ExpiresAt = question.EndTime ?? question.Closed;
|
||||
if (dbNote.Poll.ExpiresAt != null)
|
||||
await EnqueuePollExpiryTask(dbNote.Poll);
|
||||
}
|
||||
|
||||
if (!dbNote.Poll.Choices.SequenceEqual(choices.Select(p => p.Name)) ||
|
||||
dbNote.Poll.Multiple != (question.AnyOf != null))
|
||||
{
|
||||
await db.PollVotes.Where(p => p.Note == dbNote).ExecuteDeleteAsync();
|
||||
dbNote.Poll.Choices = choices.Select(p => p.Name).Cast<string>().ToList();
|
||||
dbNote.Poll.Votes = choices.Select(p => (int?)p.Replies?.TotalItems ?? 0).ToList();
|
||||
dbNote.Poll.ExpiresAt = question.EndTime ?? question.Closed;
|
||||
dbNote.Poll.Multiple = question.AnyOf != null;
|
||||
db.Update(dbNote.Poll);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue