diff --git a/lib/controllers/room_chat.dart b/lib/controllers/room_chat.dart index 5e58c0a..1576401 100644 --- a/lib/controllers/room_chat.dart +++ b/lib/controllers/room_chat.dart @@ -97,6 +97,25 @@ class RoomChatController(final ChatParams info) ), ); + void hideClientSticky(int eventRowId) => ref + .read(RoomsController.provider.notifier) + .update( + .new({ + info.roomId: Room( + resetClientSticky: true, + clientSticky: + ref + .read( + RoomsController.provider.select( + (rooms) => rooms[info.roomId]?.clientSticky, + ), + ) + ?.remove(eventRowId) ?? + .new(), + ), + }), + ); + Future paginate(Direction direction) async { if (state.isLoading) return; diff --git a/lib/controllers/rooms.dart b/lib/controllers/rooms.dart index 034f2f8..7b86f2a 100644 --- a/lib/controllers/rooms.dart +++ b/lib/controllers/rooms.dart @@ -46,13 +46,16 @@ class RoomsController extends Notifier> { roomId, existing?.copyWith( hasMore: incoming.hasMore, - clientSticky: - (incoming.clientSticky.isEmpty == true - ? existing.clientSticky - : existing.clientSticky.addAll(incoming.clientSticky)) - .removeWhere( - (rowId) => incoming.timeline.values.contains(rowId), - ), + clientSticky: incoming.resetClientSticky + ? incoming.clientSticky + : (incoming.clientSticky.isEmpty == true + ? existing.clientSticky + : existing.clientSticky.addAll( + incoming.clientSticky, + )) + .removeWhere( + (rowId) => incoming.timeline.values.contains(rowId), + ), metadata: incoming.metadata ?? existing.metadata, events: incoming.events.isEmpty ? existing.events @@ -64,6 +67,7 @@ class RoomsController extends Notifier> { (previousValue[event.key] ?? .new()).addAll(event.value), ), ), + resetClientSticky: false, reset: false, hasFetchedMembers: incoming.hasFetchedMembers || existing.hasFetchedMembers, diff --git a/lib/helpers/extensions/build_event_options.dart b/lib/helpers/extensions/build_event_options.dart index 3793b0a..e562d85 100644 --- a/lib/helpers/extensions/build_event_options.dart +++ b/lib/helpers/extensions/build_event_options.dart @@ -225,10 +225,11 @@ extension BuildEventOptions on Event { ), if (ref.watch( - PowerLevelController.provider( - .redaction(targetUser: sender, roomId: roomId), - ), - )) + PowerLevelController.provider( + .redaction(targetUser: sender, roomId: roomId), + ), + ) && + !eventId.startsWith("~")) PopupMenuItem( onTap: () => showReasonDialog( title: "Delete Message", @@ -245,6 +246,15 @@ extension BuildEventOptions on Event { ), ), + if (eventId.startsWith("~")) + PopupMenuItem( + onTap: () => ref.watch(notifier).hideClientSticky(rowId), + child: ListTile( + leading: Icon(Icons.delete, color: danger), + title: Text("Hide", style: .new(color: danger)), + ), + ), + PopupMenuItem( onTap: () => showReasonDialog( title: "Report", diff --git a/lib/models/room.dart b/lib/models/room.dart index 96b29b4..24b0c5e 100644 --- a/lib/models/room.dart +++ b/lib/models/room.dart @@ -25,6 +25,8 @@ class const Room({ final IMap events = const IMap.empty(), final bool reset = false, + @JsonKey(includeFromJson: false, includeToJson: false) + final bool resetClientSticky = false, @JsonKey(includeFromJson: false, includeToJson: false) final bool hasFetchedState = false, diff --git a/lib/widgets/renderers/event.dart b/lib/widgets/renderers/event.dart index da1f38d..8e023a8 100644 --- a/lib/widgets/renderers/event.dart +++ b/lib/widgets/renderers/event.dart @@ -4,6 +4,7 @@ import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/event.dart"; +import "package:nexus/controllers/room_chat.dart"; import "package:nexus/controllers/rooms.dart"; import "package:nexus/helpers/extensions/show_context_menu.dart"; import "package:nexus/helpers/hooks/chat_scroll.dart"; @@ -270,11 +271,34 @@ class const EventRenderer( if (event.sendError != null && event.sendError != "not sent") Padding( padding: .only(bottom: 4), - child: Text( - event.sendError!, - style: theme.textTheme.labelSmall?.copyWith( - color: theme.colorScheme.error, - ), + child: Row( + spacing: 4, + children: [ + Text( + event.sendError!, + style: theme.textTheme.labelSmall?.copyWith( + color: theme.colorScheme.error, + ), + ), + InkWell( + child: Text( + "Hide", + style: theme.textTheme.labelSmall?.copyWith( + color: theme.colorScheme.primary, + decoration: .underline, + decorationColor: theme.colorScheme.primary, + ), + ), + onTap: () => ref + .read( + RoomChatController.provider(( + roomId: roomId, + contextualEvent: null, + )).notifier, + ) + .hideClientSticky(event.rowId), + ), + ], ), ), ].map((child) => Padding(padding: .only(left: 4), child: child)),