Connecting animation + audio that actually plays + ringtone unlock

Fixkamo-internal
Shipped
April 26, 2026 at 10:30 PM UTC
Author
kamo
Commit
31f3f84

Three coordinated fixes for the inbound-call path: 1. Visual feedback while accepting. Clicking Answer left both buttons responsive-looking but unresponsive — the SDP negotiation takes 1-3 s before the call goes live, and the UI gave no indication anything was happening. Added an isAccepting state on SoftphoneState (set in answer(), cleared by the **************** session events). The incoming-call overlay now morphs while accepting: - the Reject button shrinks and fades out - the Answer button slides into the center, swaps green→blue, drops its handset icon, and gains a rotating progress ring - the pulse-rings on the answer button stop - a "Connecting…" label fades in below Both buttons are also disabled and pointer-events are dropped so a double-click can't fire reject during the accept flight. 2. No audio after connect. WebRTC accept resolves before the remote audio track has been attached to the peer connection, so attachRemoteAudio() was scanning getReceivers() at a moment when no track existed. And by the time the track arrived (~1-3 s later), the user-gesture window had expired so audio.play() was silently rejected by the autoplay policy. Two fixes: - SipJsSession.accept() now calls primeRemoteAudio() within the Answer click's gesture context (a play() on an empty MediaStream is enough for browsers to flag the element as user-activated). - attachRemoteAudio() additionally hooks pc.ontrack so tracks that arrive after Established are added to the audio element on arrival, not just the snapshot at Established time. 3. Configured ringtone never played for inbound calls. The ringtone element was created at SoftphoneProvider mount but its first play() call was on an inbound INVITE — typically minutes/hours after the last user gesture, so the autoplay policy blocked it. Added a one-time audio-unlock helper that listens for the first click/keydown/touchstart on the document, primes both the ringtone element and the SIP remote audio element via a muted play→pause cycle, then removes itself. After that, both elements are user-activated for the rest of the page lifetime and inbound rings + call audio play immediately.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing