Merge pull request #499 from pangeachat/show-new-rooms-in-spaces
Show new rooms in spaces
This commit is contained in:
commit
bd9b9b9f48
2 changed files with 63 additions and 52 deletions
|
|
@ -476,6 +476,8 @@ class ChatListController extends State<ChatList>
|
|||
StreamSubscription? classStream;
|
||||
StreamSubscription? _invitedSpaceSubscription;
|
||||
StreamSubscription? _subscriptionStatusStream;
|
||||
StreamSubscription? _spaceChildSubscription;
|
||||
final Set<String> hasUpdates = {};
|
||||
//Pangea#
|
||||
|
||||
@override
|
||||
|
|
@ -567,6 +569,16 @@ class ChatListController extends State<ChatList>
|
|||
showSubscribedSnackbar(context);
|
||||
}
|
||||
});
|
||||
|
||||
// listen for space child updates for any space that is not the active space
|
||||
// so that when the user navigates to the space that was updated, it will
|
||||
// reload any rooms that have been added / removed
|
||||
final client = pangeaController.matrixState.client;
|
||||
_spaceChildSubscription ??= client.onRoomState.stream.where((u) {
|
||||
return u.state.type == EventTypes.SpaceChild && u.roomId != activeSpaceId;
|
||||
}).listen((update) {
|
||||
hasUpdates.add(update.roomId);
|
||||
});
|
||||
//Pangea#
|
||||
|
||||
super.initState();
|
||||
|
|
@ -581,6 +593,7 @@ class ChatListController extends State<ChatList>
|
|||
classStream?.cancel();
|
||||
_invitedSpaceSubscription?.cancel();
|
||||
_subscriptionStatusStream?.cancel();
|
||||
_spaceChildSubscription?.cancel();
|
||||
//Pangea#
|
||||
scrollController.removeListener(_onScroll);
|
||||
super.dispose();
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import 'package:fluffychat/pages/chat_list/utils/on_chat_tap.dart';
|
|||
import 'package:fluffychat/pangea/constants/class_default_values.dart';
|
||||
import 'package:fluffychat/pangea/constants/pangea_room_types.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/extensions/sync_update_extension.dart';
|
||||
import 'package:fluffychat/pangea/utils/chat_list_handle_space_tap.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
|
|
@ -46,8 +45,8 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
Object? error;
|
||||
bool loading = false;
|
||||
// #Pangea
|
||||
StreamSubscription<SyncUpdate>? _roomSubscription;
|
||||
bool refreshing = false;
|
||||
StreamSubscription? _roomSubscription;
|
||||
|
||||
final String _chatCountsKey = 'chatCounts';
|
||||
Map<String, int> get chatCounts => Map.from(
|
||||
|
|
@ -58,9 +57,33 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
loadHierarchy();
|
||||
// #Pangea
|
||||
// loadHierarchy();
|
||||
|
||||
// If, on launch, this room has had updates to its children,
|
||||
// ensure the hierarchy is properly reloaded
|
||||
final bool hasUpdate = widget.controller.hasUpdates.contains(
|
||||
widget.controller.activeSpaceId,
|
||||
);
|
||||
|
||||
loadHierarchy(hasUpdate: hasUpdate).then(
|
||||
// remove this space ID from the set of space IDs with updates
|
||||
(_) => widget.controller.hasUpdates.remove(
|
||||
widget.controller.activeSpaceId,
|
||||
),
|
||||
);
|
||||
|
||||
loadChatCounts();
|
||||
|
||||
// Listen for changes to the activeSpace's hierarchy,
|
||||
// and reload the hierarchy when they come through
|
||||
final client = Matrix.of(context).client;
|
||||
_roomSubscription ??= client.onRoomState.stream.where((u) {
|
||||
return u.state.type == EventTypes.SpaceChild &&
|
||||
u.roomId == widget.controller.activeSpaceId;
|
||||
}).listen((update) {
|
||||
loadHierarchy(hasUpdate: true);
|
||||
});
|
||||
// Pangea#
|
||||
super.initState();
|
||||
}
|
||||
|
|
@ -76,11 +99,11 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
void _refresh() {
|
||||
// #Pangea
|
||||
// _lastResponse.remove(widget.controller.activseSpaceId);
|
||||
if (mounted) {
|
||||
// Pangea#
|
||||
loadHierarchy();
|
||||
// #Pangea
|
||||
}
|
||||
// loadHierarchy();
|
||||
if (mounted) setState(() => refreshing = true);
|
||||
loadHierarchy(hasUpdate: true).whenComplete(() {
|
||||
if (mounted) setState(() => refreshing = false);
|
||||
});
|
||||
// Pangea#
|
||||
}
|
||||
|
||||
|
|
@ -129,8 +152,10 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
/// spaceId, it will try to load the next batch and add the new rooms to the
|
||||
/// already loaded ones. Displays a loading indicator while loading, and an error
|
||||
/// message if an error occurs.
|
||||
/// If hasUpdate is true, it will force the hierarchy to be reloaded.
|
||||
Future<void> loadHierarchy({
|
||||
String? spaceId,
|
||||
bool hasUpdate = false,
|
||||
}) async {
|
||||
if ((widget.controller.activeSpaceId == null && spaceId == null) ||
|
||||
loading) {
|
||||
|
|
@ -142,7 +167,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
setState(() {});
|
||||
|
||||
try {
|
||||
await _loadHierarchy(spaceId: spaceId);
|
||||
await _loadHierarchy(spaceId: spaceId, hasUpdate: hasUpdate);
|
||||
} catch (e, s) {
|
||||
if (mounted) {
|
||||
setState(() => error = e);
|
||||
|
|
@ -159,6 +184,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
/// the active space id (or specified spaceId).
|
||||
Future<void> _loadHierarchy({
|
||||
String? spaceId,
|
||||
bool hasUpdate = false,
|
||||
}) async {
|
||||
final client = Matrix.of(context).client;
|
||||
final activeSpaceId = (widget.controller.activeSpaceId ?? spaceId)!;
|
||||
|
|
@ -177,7 +203,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
await activeSpace.postLoad();
|
||||
|
||||
// The current number of rooms loaded for this space that are visible in the UI
|
||||
final int prevLength = _lastResponse[activeSpaceId] != null
|
||||
final int prevLength = _lastResponse[activeSpaceId] != null && !hasUpdate
|
||||
? filterHierarchyResponse(
|
||||
activeSpace,
|
||||
_lastResponse[activeSpaceId]!.rooms,
|
||||
|
|
@ -187,6 +213,9 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
// Failsafe to prevent too many calls to the server in a row
|
||||
int callsToServer = 0;
|
||||
|
||||
GetSpaceHierarchyResponse? currentHierarchy =
|
||||
hasUpdate ? null : _lastResponse[activeSpaceId];
|
||||
|
||||
// Makes repeated calls to the server until 10 new visible rooms have
|
||||
// been loaded, or there are no rooms left to load. Using a loop here,
|
||||
// rather than one single call to the endpoint, because some spaces have
|
||||
|
|
@ -195,16 +224,15 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
// coming through from those calls are analytics rooms).
|
||||
while (callsToServer < 5) {
|
||||
// if this space has been loaded and there are no more rooms to load, break
|
||||
if (_lastResponse[activeSpaceId] != null &&
|
||||
_lastResponse[activeSpaceId]!.nextBatch == null) {
|
||||
if (currentHierarchy != null && currentHierarchy.nextBatch == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
// if this space has been loaded and 10 new rooms have been loaded, break
|
||||
if (_lastResponse[activeSpaceId] != null) {
|
||||
if (currentHierarchy != null) {
|
||||
final int currentLength = filterHierarchyResponse(
|
||||
activeSpace,
|
||||
_lastResponse[activeSpaceId]!.rooms,
|
||||
currentHierarchy.rooms,
|
||||
).length;
|
||||
|
||||
if (currentLength - prevLength >= 10) {
|
||||
|
|
@ -216,22 +244,26 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
final response = await client.getSpaceHierarchy(
|
||||
activeSpaceId,
|
||||
maxDepth: 1,
|
||||
from: _lastResponse[activeSpaceId]?.nextBatch,
|
||||
from: currentHierarchy?.nextBatch,
|
||||
limit: 100,
|
||||
);
|
||||
callsToServer++;
|
||||
|
||||
// if rooms have earlier been loaded for this space, add those
|
||||
// previously loaded rooms to the front of the response list
|
||||
if (_lastResponse[activeSpaceId] != null) {
|
||||
if (currentHierarchy != null) {
|
||||
response.rooms.insertAll(
|
||||
0,
|
||||
_lastResponse[activeSpaceId]?.rooms ?? [],
|
||||
currentHierarchy.rooms,
|
||||
);
|
||||
}
|
||||
|
||||
// finally, set the response to the last response for this space
|
||||
_lastResponse[activeSpaceId] = response;
|
||||
currentHierarchy = response;
|
||||
}
|
||||
|
||||
if (currentHierarchy != null) {
|
||||
_lastResponse[activeSpaceId] = currentHierarchy;
|
||||
}
|
||||
|
||||
// After making those calls to the server, set the chat count for
|
||||
|
|
@ -560,34 +592,6 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
}
|
||||
}
|
||||
|
||||
void refreshOnUpdate(SyncUpdate event) {
|
||||
/* refresh on leave, invite, and space child update
|
||||
not join events, because there's already a listener on
|
||||
onTapSpaceChild, and they interfere with each other */
|
||||
if (widget.controller.activeSpaceId == null || !mounted || refreshing) {
|
||||
return;
|
||||
}
|
||||
setState(() => refreshing = true);
|
||||
final client = Matrix.of(context).client;
|
||||
if (mounted &&
|
||||
event.isMembershipUpdateByType(
|
||||
Membership.leave,
|
||||
client.userID!,
|
||||
) ||
|
||||
event.isMembershipUpdateByType(
|
||||
Membership.invite,
|
||||
client.userID!,
|
||||
) ||
|
||||
event.isSpaceChildUpdate(
|
||||
widget.controller.activeSpaceId!,
|
||||
)) {
|
||||
debugPrint("refresh on update");
|
||||
loadHierarchy().whenComplete(() {
|
||||
if (mounted) setState(() => refreshing = false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool includeSpaceChild(
|
||||
Room space,
|
||||
SpaceRoomsChunk hierarchyMember,
|
||||
|
|
@ -769,12 +773,6 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
);
|
||||
}
|
||||
|
||||
// #Pangea
|
||||
_roomSubscription ??= client.onSync.stream
|
||||
.where((event) => event.hasRoomUpdate)
|
||||
.listen(refreshOnUpdate);
|
||||
// Pangea#
|
||||
|
||||
final parentSpace = allSpaces.firstWhereOrNull(
|
||||
(space) =>
|
||||
space.spaceChildren.any((child) => child.roomId == activeSpaceId),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue