w.serviceWorkerRegistration = registration; return Notification.requestPermission(); }) .then(permission => { if (permission === 'granted') { return messaging.getToken({ vapidKey: 'BAP5t8Fxr-BzfbBanf9V6UyAA9vQE091jEd8iFHXQHtm4Qqi7o8qMpipL7wx7ioHRD6xxxLFFn9Ezz5Pj4IT7tw', }); } return null; }) .then(token => { if (token) { window.fcmToken = token; localStorage.setItem('fcmToken', token); console.log('✅ FCM Token:', token); } }) .catch(err => { console.error('🔥 FCM Setup Failed:', err); }); } let currentChannelId = null; let currentMeetingId = null; let agoraClient = null; let localAudioTrack = null; let localVideoTrack = null; function showCallPrompt() { document.getElementById('callPromptModal').classList.add('show'); } function hideCallPrompt() { document.getElementById('callPromptModal').classList.remove('show'); } function showVideoModal() { document.getElementById('videoCallModal').classList.add('show'); } function hideVideoModal() { document.getElementById('videoCallModal').classList.remove('show'); } messaging.onMessage(payload => { try { const rawData = payload?.data?.data; console.log("Payload data", rawData) if (!rawData) return; const data = JSON.parse(rawData); if (data.meeting_id) { currentChannelId = data.meeting_id; console.log("Meeting ID: " + currentChannelId); showCallPrompt(); } else if (data.content_type === 'prescription') { toastr.options = { closeButton: true, progressBar: true, positionClass: "toast-top-right", onclick: () => { window.location.href = `${window.location.origin}/get-prescription-list`; } }; toastr.info("আপনার নতুন প্রেসক্রিপশন এসেছে", "নতুন প্রেসক্রিপশন"); } else { console.warn("No meeting_id found in payload, skipping."); } } catch (e) { console.error("Error parsing FCM payload:", e); } }); document.getElementById('joinCallBtn').addEventListener('click', () => { hideCallPrompt(); showVideoModal(); startAgoraCall(currentChannelId); }); document.getElementById('declineCallBtn').addEventListener('click', () => { hideCallPrompt(); currentChannelId = null; }); /*function closeAgoraModal() { hideAgoraModal(); }*/ document.getElementById('endCallBtn').addEventListener('click', endCall); function endCall() { if (localAudioTrack) { localAudioTrack.stop(); localAudioTrack.close(); } if (localVideoTrack) { localVideoTrack.stop(); localVideoTrack.close(); } if (agoraClient) { agoraClient.leave().then(() => { console.log("Left channel"); }); } document.getElementById('agora-video').innerHTML = ''; hideVideoModal(); } document.getElementById('startCallBtn').addEventListener('click', () => { currentChannelId = 'test'; // Fixed channel name showCallPrompt(); }); async function startAgoraCall(channelName) { const appId = "b2cd4c68c28a4f1dadc57b2243a71a96"; const uid = Math.floor(Math.random() * 1000000); const container = document.getElementById('agora-video'); agoraClient = AgoraRTC.createClient({mode: "rtc", codec: "vp8"}); try { await agoraClient.join(appId, channelName, null, uid); console.log(`✅ Joined channel [${channelName}] as UID: ${uid}`); // Create and show local video/audio localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack(); localVideoTrack = await AgoraRTC.createCameraVideoTrack(); const localDiv = document.createElement("div"); localDiv.id = `local-video-${uid}`; container.appendChild(localDiv); localVideoTrack.play(localDiv.id); await agoraClient.publish([localAudioTrack, localVideoTrack]); console.log("📡 Local tracks published"); // Subscribe to existing users in channel (critical fix) for (const user of agoraClient.remoteUsers) { console.log("🔍 Found existing user:", user.uid); await subscribeAndRender(user, container); } // Handle new user publishes agoraClient.on("user-published", async (user, mediaType) => { console.log(`📢 user-published: ${user.uid}, ${mediaType}`); await subscribeAndRender(user, container, mediaType); }); // Clean up when user leaves agoraClient.on("user-unpublished", (user) => { console.log(`🚫 user-unpublished: ${user.uid}`); const remoteDiv = document.getElementById(`remote-video-${user.uid}`); if (remoteDiv) remoteDiv.remove(); }); agoraClient.on("user-left", (user) => { console.log(`👋 user-left: ${user.uid}`); const remoteDiv = document.getElementById(`remote-video-${user.uid}`); if (remoteDiv) remoteDiv.remove(); }); } catch (err) { console.error("❌ Agora join failed:", err); } } // Helper to subscribe and render async function subscribeAndRender(user, container, mediaTypeForced = null) { const mediaTypes = mediaTypeForced ? [mediaTypeForced] : ['video', 'audio']; for (const mediaType of mediaTypes) { await agoraClient.subscribe(user, mediaType).catch(console.error); console.log(`✅ Subscribed to ${user.uid} (${mediaType})`); if (mediaType === 'video' && user.videoTrack) { let remoteDiv = document.getElementById(`remote-video-${user.uid}`); if (!remoteDiv) { remoteDiv = document.createElement("div"); remoteDiv.id = `remote-video-${user.uid}`; container.appendChild(remoteDiv); } user.videoTrack.play(remoteDiv.id); console.log(`🎥 Remote video playing: ${user.uid}`); } if (mediaType === 'audio' && user.audioTrack) { user.audioTrack.play(); console.log(`🔊 Remote audio playing: ${user.uid}`); } } }