feat(calls): native-call lifecycle endpoints + WebView steps aside (inc 1)
Complete the WebView/server side of native LiveKit calls: - routes.js: /api/calls/answered (markDmAnswered) + /api/calls/end (endCallByRoom) so the server learns a NATIVE call was answered/ended (native media runs over LiveKit, bypassing our mesh/WS lifecycle). Additive no-ops for WebView/mesh calls. - home.html: for native calls the WebView no longer joins the room (one connection per identity — the plugin holds it). answerCall -> POST /api/calls/answered + clear invite; endCall -> /api/calls/end (answered) or /api/calls/decline (still ringing). Outgoing DM/group calls fetch a LiveKit token and hand it to NativeCall.reportOutgoingCall instead of enterMeeting. Removed the old callHandoff mic-repush. Server deploys now; the plugin (native LiveKit) needs a Codemagic build. Still gated by CALLKIT_ENABLED=0 — flip to 1 only after the build is installed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1074,6 +1074,26 @@ route('POST', '/api/calls/decline', async (req, res) => {
|
||||
json(res, 200, await CALLS.declineDmCall(String(room), u));
|
||||
});
|
||||
|
||||
// --- Native-call lifecycle. NATIVE (CallKit + LiveKit) calls carry media over LiveKit, NOT our mesh/WS, so
|
||||
// the server can't learn from a room emptying that a native call was answered/ended. The app signals it
|
||||
// explicitly. (WebView/mesh calls keep using the WS room lifecycle — these are additive no-ops there.) ---
|
||||
route('POST', '/api/calls/answered', async (req, res) => {
|
||||
const u = await currentUser(req);
|
||||
if (!u) return json(res, 401, { error: 'unauthorized' });
|
||||
const { room } = await readBody(req);
|
||||
if (!room) return json(res, 400, { error: 'room required' });
|
||||
try { CALLS.markDmAnswered(String(room), u.id); } catch (_) {}
|
||||
json(res, 200, { ok: true });
|
||||
});
|
||||
route('POST', '/api/calls/end', async (req, res) => {
|
||||
const u = await currentUser(req);
|
||||
if (!u) return json(res, 401, { error: 'unauthorized' });
|
||||
const { room } = await readBody(req);
|
||||
if (!room) return json(res, 400, { error: 'room required' });
|
||||
try { await CALLS.endCallByRoom(String(room)); } catch (_) {}
|
||||
json(res, 200, { ok: true });
|
||||
});
|
||||
|
||||
// Toggle "only admins can add/remove members" (any admin).
|
||||
route('POST', '/api/groups/admin-only', async (req, res) => {
|
||||
const u = await currentUser(req);
|
||||
|
||||
Reference in New Issue
Block a user