1
0
Fork 0
forked from Nexus/nexus

WIP removal of new_events_controller [skip ci]

This commit is contained in:
Henry Hiles 2026-04-28 20:44:12 -04:00
commit 5a99616e9c
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
8 changed files with 168 additions and 133 deletions

View file

@ -9,7 +9,7 @@ import "package:flutter/foundation.dart";
import "package:nexus/controllers/account_data_controller.dart";
import "package:nexus/controllers/client_state_controller.dart";
import "package:nexus/controllers/init_complete_controller.dart";
import "package:nexus/controllers/new_events_controller.dart";
import "package:nexus/controllers/room_chat_controller.dart";
import "package:nexus/controllers/rooms_controller.dart";
import "package:nexus/controllers/space_edges_controller.dart";
import "package:nexus/controllers/sync_status_controller.dart";
@ -82,11 +82,10 @@ class ClientController extends AsyncNotifier<int> {
final event = Event.fromJson(decodedMuksEvent["event"]);
if (event.type == "m.room.message") {
ref
.watch(
NewEventsController.provider(event.roomId).notifier,
)
.add(IList([event]));
final provider = RoomChatController.provider(event.roomId);
if (ref.exists(provider)) {
ref.watch(provider.notifier).addEvent(event);
}
}
break;
case "sync_complete":
@ -127,9 +126,9 @@ class ClientController extends AsyncNotifier<int> {
}
debugPrint("Finished handling $muksEventType...");
} catch (error, stackTrace) {
debugPrintStack(stackTrace: stackTrace, label: error.toString());
debugger();
showError(error, stackTrace);
debugPrintStack(stackTrace: stackTrace, label: error.toString());
}
});

View file

@ -1,18 +0,0 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/models/event.dart";
class NewEventsController extends Notifier<IList<Event>> {
final String roomId;
NewEventsController(this.roomId);
@override
IList<Event> build() => const IList.empty();
void add(IList<Event> newEvents) => state = newEvents;
static final provider = NotifierProvider.autoDispose
.family<NewEventsController, IList<Event>, String>(
NewEventsController.new,
);
}

View file

@ -7,11 +7,11 @@ import "package:fluttertagger/fluttertagger.dart";
import "package:nexus/controllers/client_controller.dart";
import "package:nexus/controllers/message_controller.dart";
import "package:nexus/controllers/messages_controller.dart";
import "package:nexus/controllers/new_events_controller.dart";
import "package:nexus/controllers/rooms_controller.dart";
import "package:nexus/controllers/selected_room_controller.dart";
import "package:nexus/models/configs/messages_config.dart";
import "package:nexus/models/configs/message_config.dart";
import "package:nexus/models/event.dart";
import "package:nexus/models/requests/get_related_events_request.dart";
import "package:nexus/models/requests/get_room_state_request.dart";
import "package:nexus/models/requests/paginate_request.dart";
@ -77,106 +77,6 @@ class RoomChatController extends AsyncNotifier<InMemoryChatController> {
);
final controller = InMemoryChatController(messages: messages.toList());
ref.onDispose(
ref.listen(NewEventsController.provider(roomId), (_, next) async {
for (final event in next) {
if (event.type == "m.reaction") {
final message = controller.messages.firstWhereOrNull(
(message) =>
message.id == event.content["m.relates_to"]?["event_id"],
);
final key = event.content["m.relates_to"]?["key"];
if (message == null || key == null || !ref.mounted) return;
return await controller.updateMessage(
message,
message.copyWith(
reactions: IMap(message.reactions)
.update(
key,
(reactors) => [...reactors, event.authorId],
ifAbsent: () => [event.authorId],
)
.unlock,
),
);
}
if (event.type == "m.room.redaction") {
final controller = await future;
final redactsId = event.content["redacts"];
final originalMessage = controller.messages.firstWhereOrNull(
(message) => message.id == redactsId,
);
if (!ref.mounted) return;
if (originalMessage != null) {
return await controller.removeMessage(originalMessage);
}
final redacts = ref
.read(SelectedRoomController.provider)
?.events
.firstWhere((event) => event.eventId == redactsId);
if (redacts?.type == "m.reaction") {
final message = controller.messages.firstWhereOrNull(
(message) =>
message.id == redacts!.content["m.relates_to"]?["event_id"],
);
final key = redacts!.content["m.relates_to"]?["key"];
if (message == null || key == null || !ref.mounted) return;
return await controller.updateMessage(
message,
message.copyWith(
reactions: IMap(message.reactions)
.update(
key,
(reactors) =>
IList(reactors).remove(redacts.authorId).unlock,
)
.where((_, value) => value.isNotEmpty)
.unlock,
),
);
}
} else {
final message = await ref.watch(
MessageController.provider(
MessageConfig(event: event, room: room!, includeEdits: true),
).future,
);
if (event.relationType == "m.replace") {
final controller = await future;
final oldMessage = controller.messages.firstWhereOrNull(
(element) => element.id == event.relatesTo,
);
if (oldMessage == null || message == null || !ref.mounted) return;
return await controller.updateMessage(
oldMessage,
message.copyWith(
id: oldMessage.id,
replyToMessageId: oldMessage.replyToMessageId,
metadata: {
...(oldMessage.metadata ?? {}),
...(message.metadata ?? {})
.toIMap()
.where((key, value) => value != null)
.unlock,
},
),
);
}
if (message != null && ref.mounted) {
await insertMessage(message);
}
}
}
}, weak: true).close,
);
ref.onDispose(controller.dispose);
// While there are under 20 messages, try up to load more messages until theres no more or we have 20 messages.
@ -187,6 +87,105 @@ class RoomChatController extends AsyncNotifier<InMemoryChatController> {
return controller;
}
Future<void> addEvent(Event event) async {
final controller = await future;
if (event.type == "m.reaction") {
final message = controller.messages.firstWhereOrNull(
(message) => message.id == event.content["m.relates_to"]?["event_id"],
);
final key = event.content["m.relates_to"]?["key"];
if (message == null || key == null || !ref.mounted) return;
return await controller.updateMessage(
message,
message.copyWith(
reactions: IMap(message.reactions)
.update(
key,
(reactors) => [...reactors, event.authorId],
ifAbsent: () => [event.authorId],
)
.unlock,
),
);
}
if (event.type == "m.room.redaction") {
final controller = await future;
final redactsId = event.content["redacts"];
final originalMessage = controller.messages.firstWhereOrNull(
(message) => message.id == redactsId,
);
if (!ref.mounted) return;
if (originalMessage != null) {
return await controller.removeMessage(originalMessage);
}
final redacts = ref
.read(SelectedRoomController.provider)
?.events
.firstWhere((event) => event.eventId == redactsId);
if (redacts?.type == "m.reaction") {
final message = controller.messages.firstWhereOrNull(
(message) =>
message.id == redacts!.content["m.relates_to"]?["event_id"],
);
final key = redacts!.content["m.relates_to"]?["key"];
if (message == null || key == null || !ref.mounted) return;
return await controller.updateMessage(
message,
message.copyWith(
reactions: IMap(message.reactions)
.update(
key,
(reactors) => IList(reactors).remove(redacts.authorId).unlock,
)
.where((_, value) => value.isNotEmpty)
.unlock,
),
);
}
} else {
final message = await ref.watch(
MessageController.provider(
MessageConfig(
event: event,
room: ref.read(RoomsController.provider)[roomId]!,
includeEdits: true,
),
).future,
);
if (event.relationType == "m.replace") {
final controller = await future;
final oldMessage = controller.messages.firstWhereOrNull(
(element) => element.id == event.relatesTo,
);
if (oldMessage == null || message == null || !ref.mounted) return;
return await controller.updateMessage(
oldMessage,
message.copyWith(
id: oldMessage.id,
replyToMessageId: oldMessage.replyToMessageId,
metadata: {
...(oldMessage.metadata ?? {}),
...(message.metadata ?? {})
.toIMap()
.where((key, value) => value != null)
.unlock,
},
),
);
}
if (message != null && ref.mounted) {
await insertMessage(message);
}
}
}
Future<void> insertMessage(Message message) async {
final controller = await future;
final oldMessage = message.metadata?["txnId"] == null

View file

@ -2,7 +2,7 @@ import "package:collection/collection.dart";
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/client_state_controller.dart";
import "package:nexus/controllers/new_events_controller.dart";
import "package:nexus/controllers/room_chat_controller.dart";
import "package:nexus/helpers/extensions/mxc_to_https.dart";
import "package:nexus/models/read_receipt.dart";
import "package:nexus/models/room.dart";
@ -34,18 +34,20 @@ class RoomsController extends Notifier<IMap<String, Room>> {
);
if (addToNewEvents) {
ref
.watch(NewEventsController.provider(roomId).notifier)
.add(
incoming.timeline
final provider = RoomChatController.provider(roomId);
if (ref.exists(provider)) {
for (final event
in incoming.timeline
.map(
(timelineTuple) => events?.firstWhereOrNull(
(event) => timelineTuple.eventRowId == event.rowId,
),
)
.nonNulls
.toIList(),
);
.toIList()) {
ref.read(provider.notifier).addEvent(event);
}
}
}
return acc.add(