diff --git a/lib/controllers/client_controller.dart b/lib/controllers/client_controller.dart index bbadd8ed..cc688711 100644 --- a/lib/controllers/client_controller.dart +++ b/lib/controllers/client_controller.dart @@ -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/room_chat_controller.dart"; +import "package:nexus/controllers/new_events_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,10 +82,11 @@ class ClientController extends AsyncNotifier { final event = Event.fromJson(decodedMuksEvent["event"]); if (event.type == "m.room.message") { - final provider = RoomChatController.provider(event.roomId); - if (ref.exists(provider)) { - ref.watch(provider.notifier).addEvent(event); - } + ref + .watch( + NewEventsController.provider(event.roomId).notifier, + ) + .add(IList([event])); } break; case "sync_complete": @@ -126,9 +127,9 @@ class ClientController extends AsyncNotifier { } debugPrint("Finished handling $muksEventType..."); } catch (error, stackTrace) { - debugPrintStack(stackTrace: stackTrace, label: error.toString()); debugger(); showError(error, stackTrace); + debugPrintStack(stackTrace: stackTrace, label: error.toString()); } }); diff --git a/lib/controllers/new_events_controller.dart b/lib/controllers/new_events_controller.dart new file mode 100644 index 00000000..215ebd32 --- /dev/null +++ b/lib/controllers/new_events_controller.dart @@ -0,0 +1,18 @@ +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> { + final String roomId; + NewEventsController(this.roomId); + + @override + IList build() => const IList.empty(); + + void add(IList newEvents) => state = newEvents; + + static final provider = NotifierProvider.autoDispose + .family, String>( + NewEventsController.new, + ); +} diff --git a/lib/controllers/room_chat_controller.dart b/lib/controllers/room_chat_controller.dart index 38b839d6..fa32bf85 100644 --- a/lib/controllers/room_chat_controller.dart +++ b/lib/controllers/room_chat_controller.dart @@ -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,6 +77,106 @@ class RoomChatController extends AsyncNotifier { ); 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. @@ -87,105 +187,6 @@ class RoomChatController extends AsyncNotifier { return controller; } - Future 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 insertMessage(Message message) async { final controller = await future; final oldMessage = message.metadata?["txnId"] == null diff --git a/lib/controllers/rooms_controller.dart b/lib/controllers/rooms_controller.dart index efdcfaad..7013de0c 100644 --- a/lib/controllers/rooms_controller.dart +++ b/lib/controllers/rooms_controller.dart @@ -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/room_chat_controller.dart"; +import "package:nexus/controllers/new_events_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,20 +34,18 @@ class RoomsController extends Notifier> { ); if (addToNewEvents) { - final provider = RoomChatController.provider(roomId); - if (ref.exists(provider)) { - for (final event - in incoming.timeline + ref + .watch(NewEventsController.provider(roomId).notifier) + .add( + incoming.timeline .map( (timelineTuple) => events?.firstWhereOrNull( (event) => timelineTuple.eventRowId == event.rowId, ), ) .nonNulls - .toIList()) { - ref.read(provider.notifier).addEvent(event); - } - } + .toIList(), + ); } return acc.add( diff --git a/pubspec.lock b/pubspec.lock index 4ff95ddf..984341b9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -983,54 +983,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" - permission_handler: - dependency: "direct main" - description: - name: permission_handler - sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1 - url: "https://pub.dev" - source: hosted - version: "12.0.1" - permission_handler_android: - dependency: transitive - description: - name: permission_handler_android - sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6" - url: "https://pub.dev" - source: hosted - version: "13.0.1" - permission_handler_apple: - dependency: transitive - description: - name: permission_handler_apple - sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023 - url: "https://pub.dev" - source: hosted - version: "9.4.7" - permission_handler_html: - dependency: transitive - description: - name: permission_handler_html - sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" - url: "https://pub.dev" - source: hosted - version: "0.1.3+5" - permission_handler_platform_interface: - dependency: transitive - description: - name: permission_handler_platform_interface - sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 - url: "https://pub.dev" - source: hosted - version: "4.3.0" - permission_handler_windows: - dependency: transitive - description: - name: permission_handler_windows - sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" - url: "https://pub.dev" - source: hosted - version: "0.2.1" petitparser: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1f413f1c..af0a446f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,7 +61,6 @@ dependencies: emoji_text_field: git: url: https://github.com/Henry-Hiles/emoji_text_field - permission_handler: ^12.0.1 dev_dependencies: build_runner: ^2.4.11 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 9fab8cb5..bde1c280 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -18,8 +17,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("DynamicColorPluginCApi")); FileSelectorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("FileSelectorWindows")); - PermissionHandlerWindowsPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 12066f6e..7b6b4259 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -5,7 +5,6 @@ list(APPEND FLUTTER_PLUGIN_LIST dynamic_system_colors file_selector_windows - permission_handler_windows screen_retriever_windows url_launcher_windows window_manager