Remove flutter chat #26
6 changed files with 82 additions and 45 deletions
commit
0653961f9c
|
|
@ -11,7 +11,9 @@ class EventController extends AsyncNotifier<Event?> {
|
|||
|
||||
@override
|
||||
Future<Event?> build() async {
|
||||
final room = ref.watch(RoomsController.provider)[request.roomId];
|
||||
final room = ref.watch(
|
||||
RoomsController.provider.select((value) => value[request.roomId]),
|
||||
);
|
||||
final event = room?.events.firstWhereOrNull(
|
||||
(event) => event.eventId == request.eventId,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
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_controller.dart";
|
||||
import "package:nexus/controllers/rooms_controller.dart";
|
||||
import "package:nexus/controllers/selected_room_controller.dart";
|
||||
import "package:nexus/models/content/content.dart";
|
||||
import "package:nexus/models/event.dart";
|
||||
|
|
@ -13,12 +15,17 @@ class MembersController extends AsyncNotifier<IList<Event>> {
|
|||
SelectedRoomController.provider.select(
|
||||
(value) => value?.metadata == null
|
||||
? null
|
||||
: (value!.metadata!.id, value.metadata!.hasMemberList),
|
||||
: (
|
||||
value!.metadata!.id,
|
||||
value.metadata!.hasMemberList,
|
||||
value.hasFetchedMembers,
|
||||
),
|
||||
),
|
||||
);
|
||||
if (data == null) return const IList.empty();
|
||||
|
||||
final state = await ref
|
||||
if (!data.$3) {
|
||||
final fetchedState = await ref
|
||||
.watch(ClientController.provider.notifier)
|
||||
.getRoomState(
|
||||
GetRoomStateRequest(
|
||||
|
|
@ -28,13 +35,27 @@ class MembersController extends AsyncNotifier<IList<Event>> {
|
|||
),
|
||||
);
|
||||
|
||||
return state
|
||||
.where((state) => state.type == EventType.membership.type)
|
||||
.toIList();
|
||||
ref
|
||||
.read(RoomsController.provider.notifier)
|
||||
.addState(data.$1, fetchedState, isMembers: true);
|
||||
}
|
||||
|
||||
final room = ref.watch(
|
||||
RoomsController.provider.select((value) => value[data.$1]),
|
||||
);
|
||||
|
||||
return room?.state[EventType.membership.type]?.values
|
||||
.map(
|
||||
(rowId) =>
|
||||
room.events.firstWhereOrNull((event) => event.rowId == rowId),
|
||||
)
|
||||
.nonNulls
|
||||
.toIList() ??
|
||||
const IList.empty();
|
||||
}
|
||||
|
||||
static final provider =
|
||||
AsyncNotifierProvider<MembersController, IList<Event>>(
|
||||
AsyncNotifierProvider.autoDispose<MembersController, IList<Event>>(
|
||||
MembersController.new,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,39 +23,19 @@ class RoomChatController extends AsyncNotifier<IList<Event>> {
|
|||
@override
|
||||
Future<IList<Event>> build() async {
|
||||
final client = ref.watch(ClientController.provider.notifier);
|
||||
|
||||
final state = await client.getRoomState(
|
||||
GetRoomStateRequest(roomId: roomId),
|
||||
);
|
||||
|
||||
ref
|
||||
.read(RoomsController.provider.notifier)
|
||||
.update(
|
||||
{
|
||||
roomId: Room(
|
||||
events: state,
|
||||
state: state.fold(
|
||||
const IMap.empty(),
|
||||
(previousValue, stateEvent) => previousValue.add(
|
||||
stateEvent.type,
|
||||
(previousValue[stateEvent.type] ?? const IMap.empty()).addAll(
|
||||
IMap({
|
||||
if (stateEvent.stateKey != null)
|
||||
stateEvent.stateKey!: stateEvent.rowId,
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
}.toIMap(),
|
||||
const ISet.empty(),
|
||||
);
|
||||
|
||||
final room = ref.watch(
|
||||
RoomsController.provider.select((rooms) => rooms[roomId]),
|
||||
);
|
||||
if (room == null) return const IList.empty();
|
||||
|
||||
if (!room.hasFetchedState) {
|
||||
final state = await client.getRoomState(
|
||||
GetRoomStateRequest(roomId: roomId),
|
||||
);
|
||||
|
||||
ref.read(RoomsController.provider.notifier).addState(roomId, state);
|
||||
}
|
||||
|
||||
// While there are under 30 messages, try up to load more messages until there's no more or we have 20 messages.
|
||||
if (room.hasMore && room.timeline.length < 30) {
|
||||
loadOlder();
|
||||
|
|
@ -98,7 +78,7 @@ class RoomChatController extends AsyncNotifier<IList<Event>> {
|
|||
PaginateRequest(
|
||||
roomId: roomId,
|
||||
maxTimelineId: ref
|
||||
.read(RoomsController.provider)[roomId]
|
||||
.read(RoomsController.provider.select((value) => value[roomId]))
|
||||
?.timeline
|
||||
.firstOrNull
|
||||
?.timelineRowId,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,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/models/event.dart";
|
||||
import "package:nexus/models/read_receipt.dart";
|
||||
import "package:nexus/models/room.dart";
|
||||
|
||||
|
|
@ -8,6 +9,30 @@ class RoomsController extends Notifier<IMap<String, Room>> {
|
|||
@override
|
||||
IMap<String, Room> build() => const IMap.empty();
|
||||
|
||||
void addState(String roomId, IList<Event> state, {bool isMembers = false}) =>
|
||||
update(
|
||||
{
|
||||
roomId: Room(
|
||||
events: state,
|
||||
hasFetchedState: true,
|
||||
hasFetchedMembers: isMembers,
|
||||
state: state.fold(
|
||||
const IMap.empty(),
|
||||
(previousValue, stateEvent) => previousValue.add(
|
||||
stateEvent.type,
|
||||
(previousValue[stateEvent.type] ?? const IMap.empty()).addAll(
|
||||
IMap({
|
||||
if (stateEvent.stateKey != null)
|
||||
stateEvent.stateKey!: stateEvent.rowId,
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
}.toIMap(),
|
||||
const ISet.empty(),
|
||||
);
|
||||
|
||||
void update(IMap<String, Room> rooms, ISet<String> leftRooms) {
|
||||
final merged = rooms.entries.fold(state, (acc, entry) {
|
||||
final roomId = entry.key;
|
||||
|
|
@ -34,6 +59,11 @@ class RoomsController extends Notifier<IMap<String, Room>> {
|
|||
),
|
||||
),
|
||||
),
|
||||
reset: false,
|
||||
hasFetchedMembers:
|
||||
incoming.hasFetchedMembers || existing.hasFetchedMembers,
|
||||
hasFetchedState:
|
||||
incoming.hasFetchedState || existing.hasFetchedState,
|
||||
timeline:
|
||||
(incoming.reset
|
||||
? incoming.timeline
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ abstract class Room with _$Room {
|
|||
@JsonKey(name: "meta") RoomMetadata? metadata,
|
||||
@Default(IList.empty()) IList<TimelineRowTuple> timeline,
|
||||
@Default(false) bool reset,
|
||||
@Default(false) bool hasFetchedState,
|
||||
@Default(false) bool hasFetchedMembers,
|
||||
@Default(IMap.empty()) IMap<String, IMap<String, int>> state,
|
||||
// required IMap<String, AccountData> accountData,
|
||||
@Default(IList.empty()) IList<Event> events,
|
||||
|
|
|
|||
|
|
@ -80,7 +80,9 @@ class RoomChat extends HookConsumerWidget {
|
|||
if (!scrollController.position.atEdge) return;
|
||||
|
||||
if (scrollController.position.pixels == 0) {
|
||||
final room = ref.watch(RoomsController.provider)[roomId];
|
||||
final room = ref.watch(
|
||||
RoomsController.provider.select((value) => value[roomId]),
|
||||
);
|
||||
if (room != null) client.markRead(room);
|
||||
} else {
|
||||
await notifier.loadOlder();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue