load old messages

This commit is contained in:
Henry Hiles 2025-11-15 17:10:41 -05:00
commit de561e0b95
No known key found for this signature in database
10 changed files with 130 additions and 73 deletions

View file

@ -0,0 +1,30 @@
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:matrix/matrix.dart";
import "package:nexus/controllers/from_controller.dart";
class EventsController extends AsyncNotifier<GetRoomEventsResponse> {
EventsController(this.room);
final Room room;
@override
Future<GetRoomEventsResponse> build({String? from}) async {
final response = await room.client.getRoomEvents(
room.id,
Direction.b,
from: from,
limit: 32,
);
ref.watch(FromController.provider(room).notifier).set(response.end);
return response;
}
Future<GetRoomEventsResponse> prev() async {
final resp = await build(from: ref.read(FromController.provider(room)));
return resp;
}
static final provider = AsyncNotifierProvider.autoDispose
.family<EventsController, GetRoomEventsResponse, Room>(
EventsController.new,
);
}

View file

@ -0,0 +1,15 @@
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:matrix/matrix.dart";
class FromController extends Notifier<String?> {
FromController(_);
@override
String? build() => null;
void set(String? value) => state = value;
static final provider =
NotifierProvider.family<FromController, String?, Room>(
FromController.new,
);
}

View file

@ -1,20 +1,22 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:matrix/matrix.dart";
class MembersController extends AsyncNotifier<List<MatrixEvent>> {
class MembersController extends AsyncNotifier<IList<MatrixEvent>> {
final Room room;
MembersController(this.room);
@override
Future<List<MatrixEvent>> build() async =>
(await room.client.getMembersByRoom(
room.id,
notMembership: Membership.leave,
)) ??
[];
Future<IList<MatrixEvent>> build() async => IList(
(await room.client.getMembersByRoom(
room.id,
notMembership: Membership.leave,
)) ??
[],
);
static final provider =
AsyncNotifierProvider.family<MembersController, List<MatrixEvent>, Room>(
AsyncNotifierProvider.family<MembersController, IList<MatrixEvent>, Room>(
MembersController.new,
);
}

View file

@ -3,7 +3,7 @@ import "package:flutter_chat_core/flutter_chat_core.dart";
import "package:flutter_chat_core/flutter_chat_core.dart" as chat;
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:matrix/matrix.dart";
import "package:nexus/controllers/timeline_controller.dart";
import "package:nexus/controllers/events_controller.dart";
import "package:nexus/helpers/extension_helper.dart";
class RoomChatController extends AsyncNotifier<ChatController> {
@ -12,7 +12,7 @@ class RoomChatController extends AsyncNotifier<ChatController> {
@override
Future<ChatController> build() async {
final timeline = await ref.watch(TimelineController.provider(room).future);
final response = await ref.watch(EventsController.provider(room).future);
ref.onDispose(
room.client.onTimelineEvent.stream.listen((event) async {
@ -26,8 +26,10 @@ class RoomChatController extends AsyncNotifier<ChatController> {
return InMemoryChatController(
messages: (await Future.wait(
timeline.events.map((event) => event.toMessage()),
)).toList().reversed.nonNulls.toList(),
response.chunk.map(
(event) => Event.fromMatrixEvent(event, room).toMessage(),
),
)).nonNulls.toList(),
);
}
@ -46,13 +48,22 @@ class RoomChatController extends AsyncNotifier<ChatController> {
}
Future<void> loadOlder() async {
await ref.watch(TimelineController.provider(room).notifier).prev();
final controller = await future;
final response = await ref
.watch(EventsController.provider(room).notifier)
.prev();
await controller.insertAllMessages(
(await Future.wait(
response.chunk.map(
(event) => Event.fromMatrixEvent(event, room).toMessage(),
),
)).nonNulls.toList().reversed.toList(),
index: 0,
);
}
Future<void> updateMessage(Message message, Message newMessage) async {
final controller = await future;
return controller.updateMessage(message, newMessage);
}
Future<void> updateMessage(Message message, Message newMessage) async =>
(await future).updateMessage(message, newMessage);
Future<void> send(String message, {Message? replyTo}) async =>
await room.sendTextEvent(

View file

@ -1,13 +1,14 @@
import "package:collection/collection.dart";
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter/material.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/client_controller.dart";
import "package:nexus/helpers/extension_helper.dart";
import "package:nexus/models/space.dart";
class SpacesController extends AsyncNotifier<List<Space>> {
class SpacesController extends AsyncNotifier<IList<Space>> {
@override
Future<List<Space>> build() async {
Future<IList<Space>> build() async {
final client = await ref.watch(ClientController.provider.future);
final topLevel = await Future.wait(
@ -28,7 +29,7 @@ class SpacesController extends AsyncNotifier<List<Space>> {
final topLevelSpaces = topLevel.where((r) => r.roomData.isSpace).toList();
final topLevelRooms = topLevel.where((r) => !r.roomData.isSpace).toList();
return [
return IList([
Space(
client: client,
title: "Home",
@ -66,10 +67,10 @@ class SpacesController extends AsyncNotifier<List<Space>> {
),
),
)),
];
]);
}
static final provider = AsyncNotifierProvider<SpacesController, List<Space>>(
static final provider = AsyncNotifierProvider<SpacesController, IList<Space>>(
SpacesController.new,
);
}

View file

@ -1,21 +0,0 @@
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:matrix/matrix.dart";
class TimelineController extends AsyncNotifier<Timeline> {
TimelineController(this.room);
final Room room;
@override
Future<Timeline> build() => room.getTimeline();
Future<void> prev() async {
final timeline = await future;
await timeline.requestHistory();
state = AsyncValue.data(timeline);
}
static final provider =
AsyncNotifierProvider.family<TimelineController, Timeline, Room>(
TimelineController.new,
);
}