Iceshrimp.NET/Iceshrimp.Frontend/Core/Services/NoteStore/NoteActions.cs

217 lines
4.4 KiB
C#

using Iceshrimp.Frontend.Core.Miscellaneous;
using Iceshrimp.Shared.Schemas.Web;
namespace Iceshrimp.Frontend.Core.Services.NoteStore;
internal class NoteActions(
ApiService api,
ILogger<NoteActions> logger,
StateSynchronizer stateSynchronizer,
ComposeService composeService
)
{
private void Broadcast(NoteBase note)
{
stateSynchronizer.Broadcast(note);
}
public async Task RefetchNoteAsync(string id)
{
try
{
var res = await api.Notes.GetNoteAsync(id);
if (res == null) return;
Broadcast(res);
}
catch (ApiException e)
{
logger.LogError(e, "Failed to fetch note.");
}
}
public async Task RefetchRemoteNoteAsync(string id)
{
try
{
var res = await api.Notes.RefetchNoteAsync(id);
if (res != null)
{
if (res.Errors.Count != 0)
{
logger.LogError($"Failed to refetch note. {string.Join(", ", res.Errors)}");
return;
}
Broadcast(res.Note);
}
}
catch (ApiException e)
{
logger.LogError(e, "Failed to refetch note.");
}
}
public async Task ToggleLikeAsync(NoteBase note)
{
if (note.Liked)
{
try
{
note.Likes -= 1;
note.Liked = false;
Broadcast(note);
var res = await api.Notes.UnlikeNoteAsync(note.Id);
if (res is not null) { note.Likes = (int)res.Value;}
Broadcast(note);
}
catch (ApiException e)
{
logger.LogError(e, "Failed to like note");
note.Likes += 1;
note.Liked = true;
Broadcast(note);
}
}
else
{
try
{
note.Likes += 1;
note.Liked = true;
Broadcast(note);
var res = await api.Notes.LikeNoteAsync(note.Id);
if (res is not null) note.Likes = (int)res.Value;
Broadcast(note);
}
catch (ApiException e)
{
logger.LogError(e, "Failed to like note");
note.Likes -= 1;
note.Liked = false;
Broadcast(note);
}
}
}
public void Reply(NoteBase note)
{
composeService.ComposeDialog?.OpenDialog(note);
}
public void DoQuote(NoteBase note)
{
composeService.ComposeDialog?.OpenDialog(null, note);
}
public async Task BiteAsync(NoteBase note)
{
await api.Notes.BiteNoteAsync(note.Id);
}
public async Task MuteAsync(NoteBase note)
{
await api.Notes.MuteNoteAsync(note.Id);
}
public async Task RedraftAsync(NoteBase note)
{
try
{
var original = await api.Notes.GetNoteAsync(note.Id);
if (original is not null)
{
await api.Notes.DeleteNoteAsync(note.Id);
composeService.ComposeDialog?.OpenDialogRedraft(original);
}
}
catch (ApiException e)
{
logger.LogError(e, "Failed to redraft");
}
}
public async Task RenoteAsync(NoteBase note)
{
note.Renotes++;
Broadcast(note);
try
{
await api.Notes.RenoteNoteAsync(note.Id, note.Visibility);
}
catch (ApiException)
{
note.Renotes--;
Broadcast(note);
}
}
public void React(NoteBase target, EmojiResponse emoji)
{
var x = target.Reactions.FirstOrDefault(p => p.Name == emoji.Name);
if (x is null || x.Reacted == false) _ = AddReactAsync(target, emoji.Name, emoji.Sensitive, emoji.PublicUrl);
}
public async Task AddReactAsync(NoteBase target, string name, bool sensitive, string? url = null)
{
var x = target.Reactions.FirstOrDefault(p => p.Name == name);
if (x == null)
{
target.Reactions.Add(new NoteReactionSchema
{
NoteId = target.Id,
Name = name,
Count = 1,
Reacted = true,
Url = url,
Sensitive = sensitive
});
}
else x.Count++;
Broadcast(target);
try
{
await api.Notes.ReactToNoteAsync(target.Id, name);
}
catch (ApiException)
{
if (x!.Count > 1) x.Count--;
else target.Reactions.Remove(x);
Broadcast(target);
}
}
public async Task RemoveReactAsync(NoteBase target, string name)
{
var rollback = target.Reactions.First(p => p.Name == name);
if (rollback.Count > 1) rollback.Count--;
else target.Reactions.Remove(rollback);
Broadcast(target);
try
{
await api.Notes.RemoveReactionFromNoteAsync(target.Id, name);
}
catch (ApiException)
{
if (rollback.Count >= 1) rollback.Count++;
else target.Reactions.Add(rollback);
Broadcast(target);
}
}
public async Task AddPollVoteAsync(NotePollSchema target, List<int> choices)
{
var res = await api.Notes.AddPollVoteAsync(target.NoteId, choices);
if (res != null)
{
await RefetchNoteAsync(target.NoteId);
}
}
public async Task DeleteAsync(NoteBase note)
{
await api.Notes.DeleteNoteAsync(note.Id);
}
}