update
This commit is contained in:
parent
3d7d3042ed
commit
c67ee1fceb
@ -533,6 +533,14 @@ public function getActiveCalls(Request $request)
|
|||||||
$activeCalls = [];
|
$activeCalls = [];
|
||||||
|
|
||||||
foreach ($accessible as $interview) {
|
foreach ($accessible as $interview) {
|
||||||
|
// Auto-terminate call session if interview timeline has expired
|
||||||
|
if ($interview->isExpired()) {
|
||||||
|
if ($interview->call_status === 'active') {
|
||||||
|
$interview->update(['call_status' => 'ended']);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ($interview->call_status === 'active') {
|
if ($interview->call_status === 'active') {
|
||||||
$starterName = 'Panelist';
|
$starterName = 'Panelist';
|
||||||
if ($interview->call_started_by) {
|
if ($interview->call_started_by) {
|
||||||
@ -570,6 +578,14 @@ public function getPollData($id)
|
|||||||
->where('id', $id)
|
->where('id', $id)
|
||||||
->orWhere('submission_unique_id', $id)
|
->orWhere('submission_unique_id', $id)
|
||||||
->firstOrFail();
|
->firstOrFail();
|
||||||
|
|
||||||
|
// Enforce expiration: ended call status if timeline is expired
|
||||||
|
if ($interview->isExpired()) {
|
||||||
|
if ($interview->call_status === 'active') {
|
||||||
|
$interview->update(['call_status' => 'ended']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$formattedRecordings = $this->getFormattedRecordings($interview);
|
$formattedRecordings = $this->getFormattedRecordings($interview);
|
||||||
|
|
||||||
$starterName = $interview->callStarter ? $interview->callStarter->name : null;
|
$starterName = $interview->callStarter ? $interview->callStarter->name : null;
|
||||||
@ -580,7 +596,7 @@ public function getPollData($id)
|
|||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'status' => $interview->status,
|
'status' => $interview->status,
|
||||||
'call_status' => $interview->call_status ?? 'idle',
|
'call_status' => $interview->isExpired() ? 'ended' : ($interview->call_status ?? 'idle'),
|
||||||
'call_started_by' => $interview->call_started_by,
|
'call_started_by' => $interview->call_started_by,
|
||||||
'starter_name' => $starterName,
|
'starter_name' => $starterName,
|
||||||
'call_started_at' => $interview->call_started_at ? $interview->call_started_at->toIso8601String() : null,
|
'call_started_at' => $interview->call_started_at ? $interview->call_started_at->toIso8601String() : null,
|
||||||
|
|||||||
@ -1029,17 +1029,24 @@ class CallRingtoneEngine {
|
|||||||
const endedCallIds = new Set();
|
const endedCallIds = new Set();
|
||||||
const currentUserId = {{ Auth::id() }};
|
const currentUserId = {{ Auth::id() }};
|
||||||
const globalCallChannel = new BroadcastChannel('global_call_alerts');
|
const globalCallChannel = new BroadcastChannel('global_call_alerts');
|
||||||
|
const adminPageLoadTimestamp = Date.now();
|
||||||
|
|
||||||
function triggerIncomingCallRing(callData) {
|
function triggerIncomingCallRing(callData, isRealtimeBroadcast = false) {
|
||||||
if (endedCallIds.has(callData.id) || dismissedCallIds.has(callData.id)) return;
|
if (endedCallIds.has(callData.id) || dismissedCallIds.has(callData.id)) return;
|
||||||
if (iAmTheCaller && currentInterviewId == callData.id) return;
|
if (iAmTheCaller && currentInterviewId == callData.id) return;
|
||||||
if (interviewerLocalStream && currentInterviewId == callData.id) return;
|
if (interviewerLocalStream && currentInterviewId == callData.id) return;
|
||||||
|
|
||||||
// Check ring 10-second threshold based on call_started_at
|
// Only play ringtone for real-time fresh calls initiated within the last 8 seconds
|
||||||
if (callData.call_started_at) {
|
if (callData.call_started_at) {
|
||||||
const startedTime = new Date(callData.call_started_at).getTime();
|
const startedTime = new Date(callData.call_started_at).getTime();
|
||||||
const elapsedMs = Date.now() - startedTime;
|
const elapsedMs = Date.now() - startedTime;
|
||||||
if (elapsedMs > 10000) return;
|
if (elapsedMs > 8000 && !isRealtimeBroadcast) {
|
||||||
|
dismissedCallIds.add(callData.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (!isRealtimeBroadcast) {
|
||||||
|
dismissedCallIds.add(callData.id);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
activeIncomingCall = callData;
|
activeIncomingCall = callData;
|
||||||
@ -1048,13 +1055,13 @@ function triggerIncomingCallRing(callData) {
|
|||||||
document.getElementById('incoming-call-modal').classList.add('active');
|
document.getElementById('incoming-call-modal').classList.add('active');
|
||||||
callRingtone.start();
|
callRingtone.start();
|
||||||
|
|
||||||
// Set 10-second auto-stop ring timeout
|
// Set 8-second auto-stop ring timeout
|
||||||
if (ringTimeoutTimer) clearTimeout(ringTimeoutTimer);
|
if (ringTimeoutTimer) clearTimeout(ringTimeoutTimer);
|
||||||
let remainingMs = 10000;
|
let remainingMs = 8000;
|
||||||
if (callData.call_started_at) {
|
if (callData.call_started_at) {
|
||||||
const startedTime = new Date(callData.call_started_at).getTime();
|
const startedTime = new Date(callData.call_started_at).getTime();
|
||||||
const elapsedMs = Date.now() - startedTime;
|
const elapsedMs = Date.now() - startedTime;
|
||||||
remainingMs = Math.max(1000, 10000 - elapsedMs);
|
remainingMs = Math.max(1000, 8000 - elapsedMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
ringTimeoutTimer = setTimeout(() => {
|
ringTimeoutTimer = setTimeout(() => {
|
||||||
@ -1073,7 +1080,7 @@ function triggerIncomingCallRing(callData) {
|
|||||||
submission_unique_id: data.submission_unique_id,
|
submission_unique_id: data.submission_unique_id,
|
||||||
starter_name: data.starter_name,
|
starter_name: data.starter_name,
|
||||||
call_started_at: data.call_started_at || new Date().toISOString()
|
call_started_at: data.call_started_at || new Date().toISOString()
|
||||||
});
|
}, true);
|
||||||
} else if (data.type === 'call_ended') {
|
} else if (data.type === 'call_ended') {
|
||||||
endedCallIds.add(data.interview_id);
|
endedCallIds.add(data.interview_id);
|
||||||
dismissedCallIds.add(data.interview_id);
|
dismissedCallIds.add(data.interview_id);
|
||||||
@ -1111,8 +1118,16 @@ function pollGlobalActiveCalls() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (incoming) {
|
if (incoming) {
|
||||||
|
// Check if call was started before page refresh
|
||||||
|
const startedTime = incoming.call_started_at ? new Date(incoming.call_started_at).getTime() : 0;
|
||||||
|
if (startedTime > 0 && startedTime < (adminPageLoadTimestamp - 4000)) {
|
||||||
|
// Ongoing call from before page reload: silent status update without ringtone
|
||||||
|
dismissedCallIds.add(incoming.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!activeIncomingCall || activeIncomingCall.id !== incoming.id) {
|
if (!activeIncomingCall || activeIncomingCall.id !== incoming.id) {
|
||||||
triggerIncomingCallRing(incoming);
|
triggerIncomingCallRing(incoming, false);
|
||||||
}
|
}
|
||||||
} else if (activeIncomingCall) {
|
} else if (activeIncomingCall) {
|
||||||
declineIncomingCall(true);
|
declineIncomingCall(true);
|
||||||
@ -1121,8 +1136,8 @@ function pollGlobalActiveCalls() {
|
|||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Poll for active calls every 1 second for instant ring notification
|
// Poll for active calls every 1.5 seconds
|
||||||
setInterval(pollGlobalActiveCalls, 1000);
|
setInterval(pollGlobalActiveCalls, 1500);
|
||||||
|
|
||||||
function acceptIncomingCall() {
|
function acceptIncomingCall() {
|
||||||
callRingtone.stop();
|
callRingtone.stop();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user