[frontend] Refactor MessageSvc to implement note deletion (ISH-404)

This commit is contained in:
Lilian 2024-07-21 22:27:32 +02:00
parent ce2be3d095
commit 854979b359
No known key found for this signature in database
5 changed files with 74 additions and 24 deletions

View file

@ -14,7 +14,8 @@ public partial class Note : IDisposable
[Parameter] [EditorRequired] public required NoteResponse NoteResponse { get; set; }
[Parameter] public bool Indented { get; set; }
private bool _shouldRender = false;
private bool _shouldRender = false;
private IDisposable _noteChangedHandler = null!;
public void React(EmojiResponse emoji)
{
@ -122,7 +123,7 @@ public partial class Note : IDisposable
protected override void OnInitialized()
{
MessageSvc.Register(NoteResponse.Id, OnNoteChanged);
_noteChangedHandler = MessageSvc.Register(NoteResponse.Id, OnNoteChanged, MessageService.Type.Updated);
}
public void Reply()
@ -176,10 +177,11 @@ public partial class Note : IDisposable
public async Task Delete()
{
await ApiService.Notes.DeleteNote(NoteResponse.Id);
await MessageSvc.DeleteNote(NoteResponse);
}
public void Dispose()
{
MessageSvc.Unregister(NoteResponse.Id, OnNoteChanged);
_noteChangedHandler.Dispose();
}
}

View file

@ -65,11 +65,12 @@
[Parameter] [EditorRequired] public required NoteResponse Note { get; set; }
[Parameter] [EditorRequired] public required int Depth { get; set; }
[Parameter] [EditorRequired] public required int MaxDepth { get; set; }
private bool _indented = false;
private bool _indented = false;
private IDisposable _noteChangedHandler = null!;
protected override void OnInitialized()
{
MessageService.Register(Note.Id, OnNoteChanged);
_noteChangedHandler = MessageService.Register(Note.Id, OnNoteChanged, MessageService.Type.Updated);
if (Depth > 0 || Note.Descendants?.Count > 0)
{
_indented = true;
@ -99,6 +100,6 @@
public void Dispose()
{
MessageService.Unregister(Note.Id, OnNoteChanged);
_noteChangedHandler.Dispose();
}
}

View file

@ -4,28 +4,39 @@ namespace Iceshrimp.Frontend.Core.Services;
internal class MessageService
{
public event EventHandler<NoteResponse>? AnyNoteChanged;
public event EventHandler<NoteResponse>? AnyNoteChanged;
public event EventHandler<NoteResponse>? AnyNoteDeleted;
public Dictionary<string, EventHandler<NoteResponse>> NoteChangedHandlers = new();
private readonly Dictionary<(string, Type), EventHandler<NoteResponse>> _noteChangedHandlers = new();
public void Register(string id, EventHandler<NoteResponse> func)
public enum Type
{
if (NoteChangedHandlers.ContainsKey(id))
Updated,
Deleted
}
public NoteMessageHandler Register(string id, EventHandler<NoteResponse> func, Type type)
{
var tuple = (id, type);
if (_noteChangedHandlers.ContainsKey(tuple))
{
NoteChangedHandlers[id] += func;
_noteChangedHandlers[tuple] += func;
}
else
{
NoteChangedHandlers.Add(id, func);
_noteChangedHandlers.Add(tuple, func);
}
return new NoteMessageHandler(func, id, type, this);
}
public void Unregister(string id, EventHandler<NoteResponse> func)
private void Unregister(string id, EventHandler<NoteResponse> func, Type type)
{
if (NoteChangedHandlers.ContainsKey(id))
var tuple = (id, type);
if (_noteChangedHandlers.ContainsKey(tuple))
{
#pragma warning disable CS8601
NoteChangedHandlers[id] -= func;
_noteChangedHandlers[tuple] -= func;
#pragma warning restore CS8601
}
else
@ -34,10 +45,39 @@ internal class MessageService
}
}
public class NoteMessageHandler : IDisposable
{
private readonly EventHandler<NoteResponse> _handler;
private readonly string _id;
private readonly Type _type;
private readonly MessageService _messageService;
public NoteMessageHandler(EventHandler<NoteResponse> handler, string id, Type type, MessageService messageService)
{
_handler = handler;
_id = id;
_type = type;
_messageService = messageService;
}
public void Dispose()
{
_messageService.Unregister(_id, _handler, _type);
}
}
public Task UpdateNote(NoteResponse note)
{
AnyNoteChanged?.Invoke(this, note);
NoteChangedHandlers.TryGetValue(note.Id, out var xHandler);
_noteChangedHandlers.TryGetValue((note.Id, Type.Updated), out var xHandler);
xHandler?.Invoke(this, note);
return Task.CompletedTask;
}
public Task DeleteNote(NoteResponse note)
{
AnyNoteDeleted?.Invoke(this, note);
_noteChangedHandlers.TryGetValue((note.Id, Type.Deleted), out var xHandler);
xHandler?.Invoke(this, note);
return Task.CompletedTask;
}

View file

@ -35,12 +35,12 @@ internal class TimelineState : IDisposable
[SetsRequiredMembers]
public TimelineState(List<NoteResponse> timeline, string? maxId, string? minId, MessageService messageService)
{
MaxId = maxId;
MinId = minId;
Timeline = timeline;
MessageService = messageService;
MaxId = maxId;
MinId = minId;
Timeline = timeline;
MessageService = messageService;
MessageService.AnyNoteChanged += OnNoteChanged;
MessageService.AnyNoteDeleted += OnNoteDeleted;
}
private void OnNoteChanged(object? _, NoteResponse note)
@ -48,12 +48,18 @@ internal class TimelineState : IDisposable
var i = Timeline.FindIndex(p => p.Id == note.Id);
if (i >= 0)
{
Timeline[i].Liked = note.Liked;
Timeline[i] = note;
}
}
private void OnNoteDeleted(object? _, NoteResponse note)
{
Timeline.Remove(note);
}
public void Dispose()
{
MessageService.AnyNoteChanged -= OnNoteChanged;
MessageService.AnyNoteDeleted -= OnNoteDeleted;
}
}

View file

@ -62,6 +62,7 @@ else
private int _depth = 20;
private ElementReference Scroller { get; set; }
private IDisposable? _locationChangingHandlerDisposable;
private IDisposable? _noteChangedHandler;
protected override async Task OnParametersSetAsync()
{
@ -88,7 +89,7 @@ else
protected override void OnInitialized()
{
if (NoteId != null) MessageService.Register(NoteId, OnNoteChanged);
if (NoteId != null) _noteChangedHandler = MessageService.Register(NoteId, OnNoteChanged, MessageService.Type.Updated);
_locationChangingHandlerDisposable = Navigation.RegisterLocationChangingHandler(LocationChangeHandler);
}
@ -142,7 +143,7 @@ else
public void Dispose()
{
if (NoteId != null) MessageService.Unregister(NoteId, OnNoteChanged);
if (_noteChangedHandler != null) _noteChangedHandler.Dispose();
SaveState();
_locationChangingHandlerDisposable?.Dispose();
}