only refresh space view when room membership changes or on space child event
This commit is contained in:
parent
d2e5536cae
commit
26d2ca3f83
2 changed files with 127 additions and 23 deletions
|
|
@ -1,23 +1,23 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/pages/chat_list/chat_list.dart';
|
||||
import 'package:fluffychat/pages/chat_list/chat_list_item.dart';
|
||||
import 'package:fluffychat/pages/chat_list/search_title.dart';
|
||||
import 'package:fluffychat/pangea/constants/class_default_values.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/extensions/sync_update_extension.dart';
|
||||
import 'package:fluffychat/pangea/utils/archive_space.dart';
|
||||
import 'package:fluffychat/pangea/utils/chat_list_handle_space_tap.dart';
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import '../../utils/localized_exception_extension.dart';
|
||||
import '../../widgets/matrix.dart';
|
||||
import 'chat_list_header.dart';
|
||||
|
|
@ -83,6 +83,24 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
if (result.error != null) return;
|
||||
_refresh();
|
||||
}
|
||||
// #Pangea
|
||||
else {
|
||||
final room = client.getRoomById(spaceChild.roomId)!;
|
||||
if (room.membership != Membership.leave) return;
|
||||
final joinResult = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () async {
|
||||
final waitForRoom = room.client.waitForRoomInSync(
|
||||
room.id,
|
||||
join: true,
|
||||
);
|
||||
await room.join();
|
||||
await waitForRoom;
|
||||
},
|
||||
);
|
||||
if (joinResult.error != null) return;
|
||||
}
|
||||
// Pangea#
|
||||
if (spaceChild.roomType == 'm.space') {
|
||||
if (spaceChild.roomId == widget.controller.activeSpaceId) {
|
||||
// #Pangea
|
||||
|
|
@ -299,23 +317,18 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
}
|
||||
|
||||
// #Pangea
|
||||
_roomSubscription = client.onSync.stream
|
||||
.where((event) => event.rooms?.join?.isNotEmpty ?? false)
|
||||
.listen((event) {
|
||||
if (mounted) {
|
||||
final List<String> joinedRoomIds = event.rooms!.join!.keys.toList();
|
||||
final joinedRoomFutures = joinedRoomIds.map(
|
||||
(joinedRoomId) => client.waitForRoomInSync(
|
||||
joinedRoomId,
|
||||
join: true,
|
||||
),
|
||||
);
|
||||
Future.wait(joinedRoomFutures).then((_) {
|
||||
_refresh();
|
||||
});
|
||||
void refreshOnUpdate(SyncUpdate event) {
|
||||
if (event.isMembershipUpdate(Matrix.of(context).client.userID!) ||
|
||||
event.isSpaceChildUpdate(activeSpaceId)) {
|
||||
_refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_roomSubscription ??= client.onSync.stream
|
||||
.where((event) => event.hasRoomUpdate)
|
||||
.listen(refreshOnUpdate);
|
||||
// Pangea#
|
||||
|
||||
return FutureBuilder<GetSpaceHierarchyResponse>(
|
||||
future: getFuture(activeSpaceId),
|
||||
builder: (context, snapshot) {
|
||||
|
|
@ -448,7 +461,13 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
}
|
||||
final spaceChild = spaceChildren[i];
|
||||
final room = client.getRoomById(spaceChild.roomId);
|
||||
if (room != null && !room.isSpace) {
|
||||
if (room != null &&
|
||||
!room.isSpace
|
||||
// #Pangea
|
||||
&&
|
||||
room.membership != Membership.leave
|
||||
// Pangea#
|
||||
) {
|
||||
return ChatListItem(
|
||||
room,
|
||||
onLongPress: () =>
|
||||
|
|
|
|||
85
lib/pangea/extensions/sync_update_extension.dart
Normal file
85
lib/pangea/extensions/sync_update_extension.dart
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import 'package:matrix/matrix.dart';
|
||||
|
||||
extension MembershipUpdate on SyncUpdate {
|
||||
bool isMembershipUpdate(String userId) {
|
||||
return isMembershipUpdateByType(Membership.join, userId) ||
|
||||
isMembershipUpdateByType(Membership.leave, userId) ||
|
||||
isMembershipUpdateByType(Membership.invite, userId);
|
||||
}
|
||||
|
||||
bool isMembershipUpdateByType(Membership type, String userId) {
|
||||
final List<SyncRoomUpdate>? updates = getRoomUpdates(type);
|
||||
if (updates?.isEmpty ?? true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (final SyncRoomUpdate update in updates!) {
|
||||
final List<dynamic>? events = getRoomUpdateEvents(type, update);
|
||||
if (hasMembershipUpdate(
|
||||
events,
|
||||
type.name,
|
||||
userId,
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
List<SyncRoomUpdate>? getRoomUpdates(Membership type) {
|
||||
switch (type) {
|
||||
case Membership.join:
|
||||
return rooms?.join?.values.toList();
|
||||
case Membership.leave:
|
||||
return rooms?.leave?.values.toList();
|
||||
case Membership.invite:
|
||||
return rooms?.invite?.values.toList();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
bool isSpaceChildUpdate(String activeSpaceId) {
|
||||
if (rooms?.join?.isEmpty ?? true) {
|
||||
return false;
|
||||
}
|
||||
for (final update in rooms!.join!.entries) {
|
||||
final String spaceId = update.key;
|
||||
final List<MatrixEvent>? timelineEvents = update.value.timeline?.events;
|
||||
final bool isUpdate = timelineEvents != null &&
|
||||
spaceId == activeSpaceId &&
|
||||
timelineEvents.any((event) => event.type == EventTypes.spaceChild);
|
||||
if (isUpdate) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
List<dynamic>? getRoomUpdateEvents(Membership type, SyncRoomUpdate update) {
|
||||
switch (type) {
|
||||
case Membership.join:
|
||||
return (update as JoinedRoomUpdate).timeline?.events;
|
||||
case Membership.leave:
|
||||
return (update as LeftRoomUpdate).timeline?.events;
|
||||
case Membership.invite:
|
||||
return (update as InvitedRoomUpdate).inviteState;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
bool hasMembershipUpdate(
|
||||
List<dynamic>? events,
|
||||
String membershipType,
|
||||
String userId,
|
||||
) {
|
||||
if (events == null) {
|
||||
return false;
|
||||
}
|
||||
return events.any(
|
||||
(event) =>
|
||||
event.type == EventTypes.RoomMember &&
|
||||
event.stateKey == userId &&
|
||||
event.content['membership'] == membershipType,
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue