named records, small fixes to last commit

This commit is contained in:
Henry Hiles 2026-09-28 13:17:15 -04:00
commit 07f8e58a4c
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
5 changed files with 48 additions and 35 deletions

View file

@ -18,22 +18,27 @@ import "package:nexus/models/requests/send_message.dart";
import "package:nexus/models/room.dart"; import "package:nexus/models/room.dart";
import "package:nexus/models/room_chat.dart"; import "package:nexus/models/room_chat.dart";
class RoomChatController( typedef ChatParams = ({
final (String roomId, (int rowId, String eventId)? contextualEvent) info, String roomId,
) extends AsyncNotifier<RoomChat?> { ({int rowId, String eventId})? contextualEvent,
});
class RoomChatController(final ChatParams info)
extends AsyncNotifier<RoomChat?> {
@override @override
Future<RoomChat?> build() async { Future<RoomChat?> build() async {
final (roomId, eventId) = info;
final client = ref.read(ClientController.provider.notifier); final client = ref.read(ClientController.provider.notifier);
final room = ref.read( final room = ref.read(
RoomsController.provider.select((rooms) => rooms[roomId]), RoomsController.provider.select((rooms) => rooms[info.roomId]),
); );
if (room == null) return null; if (room == null) return null;
if (!room.hasFetchedState) { if (!room.hasFetchedState) {
final state = await client.getRoomState(.new(roomId: roomId)); final state = await client.getRoomState(.new(roomId: info.roomId));
await ref.read(RoomsController.provider.notifier).addState(roomId, state); await ref
.read(RoomsController.provider.notifier)
.addState(info.roomId, state);
} }
final timeline = room.timeline final timeline = room.timeline
@ -43,9 +48,12 @@ class RoomChatController(
.addAll(room.clientSticky) .addAll(room.clientSticky)
.nonNulls .nonNulls
.toIList(); .toIList();
if (info.$2 == null || timeline.contains(info.$2!.$1)) { if (info.contextualEvent == null ||
timeline.contains(info.contextualEvent!.rowId)) {
ref.watch( ref.watch(
RoomsController.provider.select((rooms) => rooms[roomId]?.timeline), RoomsController.provider.select(
(rooms) => rooms[info.roomId]?.timeline,
),
); );
return .new( return .new(
@ -55,7 +63,7 @@ class RoomChatController(
); );
} else { } else {
final context = await client.getEventContext( final context = await client.getEventContext(
.new(roomId: roomId, eventId: info.$2!.$2), .new(roomId: info.roomId, eventId: info.contextualEvent!.eventId),
); );
final events = context.before.add(context.event).addAll(context.after); final events = context.before.add(context.event).addAll(context.after);
@ -63,7 +71,7 @@ class RoomChatController(
.read(RoomsController.provider.notifier) .read(RoomsController.provider.notifier)
.update( .update(
.new({ .new({
roomId: Room( info.roomId: Room(
events: IMap.fromIterable( events: IMap.fromIterable(
events, events,
keyMapper: (event) => event.rowId, keyMapper: (event) => event.rowId,
@ -86,7 +94,7 @@ class RoomChatController(
.redactEvent( .redactEvent(
RedactEventRequest( RedactEventRequest(
eventId: event.eventId, eventId: event.eventId,
roomId: info.$1, roomId: info.roomId,
reason: reason, reason: reason,
), ),
); );
@ -108,12 +116,12 @@ class RoomChatController(
if (chat?.historicalData == null) { if (chat?.historicalData == null) {
final timelineKeys = ref final timelineKeys = ref
.read(RoomsController.provider.select((value) => value[info.$1])) .read(RoomsController.provider.select((value) => value[info.roomId]))
?.timeline ?.timeline
.keys; .keys;
final response = await client.paginate( final response = await client.paginate(
.new( .new(
roomId: info.$1, roomId: info.roomId,
maxTimelineId: timelineKeys?.isNotEmpty == true maxTimelineId: timelineKeys?.isNotEmpty == true
? timelineKeys?.reduce(min) ? timelineKeys?.reduce(min)
: null, : null,
@ -128,7 +136,7 @@ class RoomChatController(
.read(RoomsController.provider.notifier) .read(RoomsController.provider.notifier)
.update( .update(
IMap({ IMap({
info.$1: Room( info.roomId: Room(
events: IMap.fromIterable( events: IMap.fromIterable(
response.events.addAll(response.relatedEvents), response.events.addAll(response.relatedEvents),
keyMapper: (event) => event.rowId, keyMapper: (event) => event.rowId,
@ -147,7 +155,7 @@ class RoomChatController(
} else { } else {
final paginationResponse = await client.paginateManual( final paginationResponse = await client.paginateManual(
.new( .new(
roomId: info.$1, roomId: info.roomId,
direction: direction, direction: direction,
since: direction == .forward since: direction == .forward
? chat!.historicalData!.end ? chat!.historicalData!.end
@ -159,7 +167,7 @@ class RoomChatController(
.read(RoomsController.provider.notifier) .read(RoomsController.provider.notifier)
.update( .update(
.new({ .new({
info.$1: Room( info.roomId: Room(
events: IMap.fromIterable( events: IMap.fromIterable(
paginationResponse.events, paginationResponse.events,
keyMapper: (event) => event.rowId, keyMapper: (event) => event.rowId,
@ -212,7 +220,7 @@ class RoomChatController(
if (relationType == .edit) { if (relationType == .edit) {
baseContent = relation?.content; baseContent = relation?.content;
} else { } else {
final provider = AttachmentController.provider(info.$1); final provider = AttachmentController.provider(info.roomId);
baseContent = ref.read(provider)?.$2; baseContent = ref.read(provider)?.$2;
ref.invalidate(provider); ref.invalidate(provider);
} }
@ -232,7 +240,7 @@ class RoomChatController(
final client = ref.read(ClientController.provider.notifier); final client = ref.read(ClientController.provider.notifier);
final event = await client.sendMessage( final event = await client.sendMessage(
SendMessageRequest( SendMessageRequest(
roomId: info.$1, roomId: info.roomId,
baseContent: baseContent, baseContent: baseContent,
mentions: Mentions( mentions: Mentions(
userIds: [ userIds: [
@ -254,7 +262,7 @@ class RoomChatController(
.read(RoomsController.provider.notifier) .read(RoomsController.provider.notifier)
.update( .update(
.new({ .new({
info.$1: .new( info.roomId: .new(
events: .new({event.rowId: event}), events: .new({event.rowId: event}),
clientSticky: .new({event.rowId}), clientSticky: .new({event.rowId}),
), ),
@ -271,7 +279,7 @@ class RoomChatController(
final client = ref.read(ClientController.provider.notifier); final client = ref.read(ClientController.provider.notifier);
final allReactionEvents = await client.getRelatedEvents( final allReactionEvents = await client.getRelatedEvents(
.new( .new(
roomId: info.$1, roomId: info.roomId,
eventId: event.eventId, eventId: event.eventId,
relationType: "m.annotation", relationType: "m.annotation",
), ),
@ -292,7 +300,9 @@ class RoomChatController(
if (reactionEvent != null) { if (reactionEvent != null) {
await ref await ref
.watch(ClientController.provider.notifier) .watch(ClientController.provider.notifier)
.redactEvent(.new(eventId: reactionEvent.eventId, roomId: info.$1)); .redactEvent(
.new(eventId: reactionEvent.eventId, roomId: info.roomId),
);
} }
} }
@ -301,7 +311,7 @@ class RoomChatController(
await client.sendEvent( await client.sendEvent(
.new( .new(
roomId: info.$1, roomId: info.roomId,
type: EventType.reaction.type, type: EventType.reaction.type,
content: ReactionContent(key: reaction), content: ReactionContent(key: reaction),
synchronous: true, synchronous: true,
@ -313,9 +323,7 @@ class RoomChatController(
} }
static final provider = AsyncNotifierProvider.family static final provider = AsyncNotifierProvider.family
.autoDispose< .autoDispose<RoomChatController, RoomChat?, ChatParams>(
RoomChatController, RoomChatController.new,
RoomChat?, );
(String, (int rowId, String eventId)?)
>(RoomChatController.new);
} }

View file

@ -27,7 +27,10 @@ extension BuildEventOptions on Event {
final theme = Theme.of(context); final theme = Theme.of(context);
final danger = theme.colorScheme.error; final danger = theme.colorScheme.error;
final notifier = RoomChatController.provider((roomId, null)).notifier; final notifier = RoomChatController.provider((
roomId: roomId,
contextualEvent: null,
)).notifier;
final isPinned = ref final isPinned = ref
.watch(PinnedIdsController.provider(roomId)) .watch(PinnedIdsController.provider(roomId))

View file

@ -1,6 +1,5 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/event.dart";
part "room_chat.freezed.dart"; part "room_chat.freezed.dart";
part "room_chat.g.dart"; part "room_chat.g.dart";

View file

@ -65,8 +65,8 @@ class const ReactionRow(final Event event, {super.key}) extends ConsumerWidget {
try { try {
final controller = ref.watch( final controller = ref.watch(
RoomChatController.provider(( RoomChatController.provider((
event.roomId, roomId: event.roomId,
null, contextualEvent: null,
)).notifier, )).notifier,
); );

View file

@ -62,10 +62,13 @@ final class const RoomChat({
final roomId = this.roomId!; final roomId = this.roomId!;
final controllerProvider = RoomChatController.provider(( final controllerProvider = RoomChatController.provider((
roomId, roomId: roomId,
contextualEvent.value == null contextualEvent: contextualEvent.value == null
? null ? null
: (contextualEvent.value!.rowId, contextualEvent.value!.eventId), : (
rowId: contextualEvent.value!.rowId,
eventId: contextualEvent.value!.eventId,
),
)); ));
final notifier = ref.watch(controllerProvider.notifier); final notifier = ref.watch(controllerProvider.notifier);