* fix: show knock-accepted notification body when invite follows a knock (#5823) When Synapse accepts a knock it sends an m.room.member invite event. The client was displaying the generic 'You have been invited by X' push notification body because the invite event alone doesn't carry prev_content on the push path. Use KnockTracker (already used for auto-join) to detect knock-accepted invites and show a dedicated 'Your join request was accepted!' notification body instead. - Add knockAccepted string to intl_en.arb - Extract condition into isKnockAcceptedInvite() pure util for testability - Expose KnockTracker.getKnockedRoomIds() publicly (was _getKnockedRoomIds) - Override notification body in push_helper.dart (background) and local_notifications_extension.dart (foreground/web) - Unit tests for all isKnockAcceptedInvite() branches (9 tests) * formatting * fix up pangea comments * fix: avoid race condition with knocked room account data updates and local push notification content * translations --------- Co-authored-by: ggurdin <ggurdin@gmail.com>
36 lines
1.1 KiB
Dart
36 lines
1.1 KiB
Dart
import 'package:matrix/matrix.dart';
|
|
|
|
import 'package:fluffychat/pangea/join_codes/knock_room_extension.dart';
|
|
|
|
/// Returns true when a push notification event is an accepted-knock invite —
|
|
/// i.e. an m.room.member invite targeting the current user in a room the user
|
|
/// previously knocked on.
|
|
///
|
|
/// Extracted as a pure function so it can be unit-tested without a Flutter
|
|
/// environment or a live Matrix client.
|
|
bool isKnockAcceptedInvite({
|
|
required String eventType,
|
|
required String? newMembership,
|
|
required String? stateKey,
|
|
required String? currentUserId,
|
|
required bool hasKnocked,
|
|
}) {
|
|
return eventType == EventTypes.RoomMember &&
|
|
newMembership == 'invite' &&
|
|
stateKey == currentUserId &&
|
|
hasKnocked;
|
|
}
|
|
|
|
/// Convenience wrapper that reads [KnockTracker] state from a live [Client].
|
|
bool isKnockAcceptedInviteForClient({
|
|
required Event event,
|
|
required Client client,
|
|
}) {
|
|
return isKnockAcceptedInvite(
|
|
eventType: event.type,
|
|
newMembership: event.content.tryGet<String>('membership'),
|
|
stateKey: event.stateKey,
|
|
currentUserId: client.userID,
|
|
hasKnocked: client.hasEverKnockedRoom(event.room.id),
|
|
);
|
|
}
|