refactor(voice): unify inbound/outbound via orchestrator & message builder

- Add Voice::CallOrchestratorService to centralize flows
- Add Voice::CallMessageBuilder for consistent voice call messages
- Incoming/Outgoing services delegate to orchestrator; use CallStatus::Manager
- ConversationFinderService: phone optional; public call_sid lookup

feat(ui): simplify call widget + reliable incoming detection + ringtone

- Remove global widget toggling; rely on Vuex
- ActionCable: loosen created condition, backfill on updated
- Add ringtone on incoming via shared Audio helper
- Guard Twilio connect() to avoid duplicate active call errors

fix(voice): decline incoming ends call & updates status

- Reject call now completes Twilio call if in progress
- Update status via manager to no_answer with activity
This commit is contained in:
Sojan Jose
2025-08-14 16:50:38 +02:00
parent c0b201f169
commit af91b4af21
12 changed files with 334 additions and 502 deletions

View File

@@ -146,6 +146,19 @@ class VoiceAPI extends ApiClient {
joinClientCall({ To }) {
if (!this.device || !this.initialized) throw new Error('Twilio not ready');
if (!To) throw new Error('Missing To');
// Guard: if there is already an active/connecting call, return it instead of creating a new one
if (this.activeConnection) {
return this.activeConnection;
}
if (this.device.state === 'busy') {
const existing = (this.device.calls || [])[0];
if (existing) {
this.activeConnection = existing;
return existing;
}
}
const connection = this.device.connect({
params: { To: String(To), is_agent: 'true' },
});