From 5869fa2ce351efa485ae6547d618a216b09a47c1 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sun, 18 Oct 2026 09:48:13 -0700 Subject: A call from someone you don't follow and haven't written to no longer vanishes: it doesn't ring, but it's a missed call in your conversation with them, saying it didn't ring and why, a tap away from calling back (with the app shut, the worker notes it for the app, without a notification). A muted person's still leaves nothing. A logged call no longer counts as having written to someone. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg --- src/calls.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/calls.js') diff --git a/src/calls.js b/src/calls.js index 827d605..66d6f16 100644 --- a/src/calls.js +++ b/src/calls.js @@ -64,7 +64,8 @@ export const candidateJson = (c) => JSON.stringify({ candidate: c.candidate, sdp // send(peerPk, signed) wrap and publish to them (the app picks the relays) // iceServers() → RTCIceServer[] (TURN from coinos, STUN at least) // media(type, facing) → MediaStream: microphone, and camera for 'video' -// mayRing(pk) whether this person may ring us (followed, or a conversation) +// mayRing(pk) 'ring' (someone followed, or written to), 'quiet' (anyone else: +// no ring, but the call is told of, as missed), or null (muted: nothing) // changed() the call's state moved: draw it // ended(record) a call is over: { id, peer, type, dir, reason, connected, seconds, at } for its log // trickle() false for a signer that's slow or asks each time (a @@ -247,7 +248,14 @@ export function createCalls(env) { if (c.id !== id) { const s = await env.sign(callEvent(CALL.REJECT, from, id, 'busy')); env.send(from, s).catch(() => {}); } return; } - if (!(await env.mayRing(from))) return; + const may = await env.mayRing(from); + if (!may) return; + if (may === 'quiet') { + // not someone who rings us: no ring, but not nothing either — it's + // logged as a call that didn't ring + try { if (env.ended) env.ended({ id, peer: from, type: tagOf(ev, 'call-type') === 'video' ? 'video' : 'voice', dir: 'in', reason: 'unrung', connected: false, seconds: 0, at: ev.created_at * 1000 }); } catch {} + return; + } clearTimeout(endTimer); const type = tagOf(ev, 'call-type') === 'video' ? 'video' : 'voice'; const n = call = { id, peer: from, type, dir: 'in', state: 'incoming', offer: ev.content, ice: [], at: Date.now(), offerAt: ev.created_at * 1000, muted: false, camOff: false, facing: 'user' }; -- cgit v1.2.3