Mobile calls: keep call memberships in memory; answering keeps the call screen
Found testing calls between two phones on the Compose call stack: - The famedly SDK keeps only "important" state in memory for a room that hasn't been opened, so call memberships of other rooms were invisible: no ring (it was cleared at once, the call looking empty), no room-list marker. org.matrix.msc3401.call.member is now important state. - The incoming-call card closed itself with Navigator.pop when the ring cleared, which popped the call screen pushed above it on Answer. The buttons now close the card first, and it closes itself only while it is the top route. Tested: a voice call in a room of two (ring, answer, both connected through LiveKit), and a video call in an encrypted room (to-device media keys, frame cryptors OK on both sides, each phone showing the other's video). The web client sees a phone's membership and rings for its notification. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
41f800ab0b
commit
b8ddbaacf3
2 files changed
+15
-3
No files matched your search
@@ -9,6 +9,7 @@ import 'package:path/path.dart' as p;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:sqflite/sqflite.dart' as sqflite;
|
||||
|
||||
import 'calls.dart';
|
||||
import 'sliding_sync.dart';
|
||||
|
||||
/// The name the session's device gets on the homeserver.
|
||||
@@ -60,7 +61,10 @@ Future<Client> createClient({bool startSync = true}) async {
|
||||
vodozemacInit: () => vod.init(),
|
||||
),
|
||||
logLevel: kReleaseMode ? Level.warning : Level.info,
|
||||
importantStateEvents: {'im.ponies.room_emotes'},
|
||||
// Kept in memory for every room, not just opened ones: the room list
|
||||
// marks rooms with a call going on, and a ring needs to know who is in
|
||||
// the call.
|
||||
importantStateEvents: {'im.ponies.room_emotes', Calls.memberType},
|
||||
// Refresh tokens: a soft logout (an expired access token) is answered by
|
||||
// refreshing it rather than by signing the user out.
|
||||
onSoftLogout: (client) => client.refreshAccessToken(),
|
||||
|
||||
@@ -427,8 +427,11 @@ Future<void> showIncomingCall(
|
||||
final call = calls.incoming;
|
||||
if (call == null) {
|
||||
// Answered elsewhere, declined, or it stopped ringing.
|
||||
// Only while the sheet is on top: after Answer, the call screen
|
||||
// is, and popping would close it instead.
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (Navigator.of(sheet).canPop()) Navigator.of(sheet).pop();
|
||||
final route = ModalRoute.of(sheet);
|
||||
if (route != null && route.isCurrent) Navigator.of(sheet).pop();
|
||||
});
|
||||
return const SizedBox(height: 200);
|
||||
}
|
||||
@@ -462,7 +465,10 @@ Future<void> showIncomingCall(
|
||||
icon: Icons.call_end,
|
||||
label: 'Decline',
|
||||
colour: c.danger,
|
||||
onTap: () => calls.decline(),
|
||||
onTap: () {
|
||||
Navigator.of(sheet).pop();
|
||||
calls.decline();
|
||||
},
|
||||
),
|
||||
if (call.video)
|
||||
_RoundButton(
|
||||
@@ -470,6 +476,7 @@ Future<void> showIncomingCall(
|
||||
label: 'Voice only',
|
||||
colour: c.tealStrong,
|
||||
onTap: () {
|
||||
Navigator.of(sheet).pop();
|
||||
calls.answer(withVideo: false);
|
||||
navigator.push(CallScreen.route());
|
||||
},
|
||||
@@ -479,6 +486,7 @@ Future<void> showIncomingCall(
|
||||
label: 'Answer',
|
||||
colour: c.tealStrong,
|
||||
onTap: () {
|
||||
Navigator.of(sheet).pop();
|
||||
calls.answer();
|
||||
navigator.push(CallScreen.route());
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user