- Shipped
- April 26, 2026 at 9:18 PM UTC
- Author
- kamo
- Commit
- 6e267ce
The softphone used to register only while the popup tool window was open — close it and inbound calls were silently missed. Lift the session into a SoftphoneProvider mounted at AuthenticatedToolWrapper, so SIP REGISTER is held continuously while the operator is signed in and any inbound INVITE gets the operator's attention. - app/hooks/useSoftphone.ts: rename the implementation hook to useSoftphoneSession to reinforce that it must be mounted exactly once per session (it owns the SIP credentials and the REGISTER). - **************** new SoftphoneProvider runs the session hook once, exposes the state via context, and reacts to hasIncomingCall transitions — pops the softphone tool window via a tool:open custom event (single-instance, so it just focuses if already open) with caller ID in the title, and plays /sounds/ringtone.mp3 on a loop until the user accepts/rejects/the remote hangs up. Public useSoftphone() hook reads from the context. - **************** switch import to the context. - **************** wrap the tool tree with SoftphoneProvider so the session lives as long as auth state. classic NA cadence (440Hz + 480Hz, 2s on, 4s silence) so audio.loop=true yields a natural ring/pause/ring pattern. ~72 KB. Browsers may block the initial play() until the user has gestured on the page; the operator has typically clicked at least once by the time a call arrives, so this is rarely an issue in practice.