2727 <div class =" bg-gray-800 px-6 py-2 flex-shrink-0 border-b border-gray-700" >
2828 <div class =" flex items-center justify-between" >
2929 <div class =" text-white" >
30- <span class =" text-sm"
31- >Meeting: {{ meetingDoc?.data?.title || meetingId }}</span
30+ <span
31+ class =" text-sm cursor-pointer hover:text-gray-300 transition-colors"
32+ @click =" copyMeetingUrl"
33+ :title =" 'Click to copy meeting URL'"
3234 >
33- </div >
34- <div class =" text-white text-sm" >
35- {{ meetingTime }}
35+ {{ meetingDoc?.data?.title || meetingId }}
36+ </span >
3637 </div >
3738 </div >
3839 </div >
@@ -201,7 +202,6 @@ const meetingId = computed(() => route.params.meetingId);
201202const isMicOn = ref (true );
202203const isCameraOn = ref (true );
203204const isScreenSharing = ref (false );
204- const meetingTime = ref (" 00:00" );
205205const localVideo = ref (null );
206206const isConnecting = ref (true );
207207const connectionError = ref (null );
@@ -247,17 +247,6 @@ const participantsList = computed(() => {
247247
248248const meetingDoc = getCachedDocumentResource (" Sae Meeting" , meetingId .value );
249249
250- // Timer for meeting duration
251- const startTime = Date .now ();
252- let timer = null ;
253-
254- const updateMeetingTime = () => {
255- const elapsed = Date .now () - startTime;
256- const minutes = Math .floor (elapsed / 60000 );
257- const seconds = Math .floor ((elapsed % 60000 ) / 1000 );
258- meetingTime .value = ` ${ minutes .toString ().padStart (2 , " 0" )} :${ seconds .toString ().padStart (2 , " 0" )} ` ;
259- };
260-
261250// Control functions
262251const toggleMicrophone = async () => {
263252 try {
@@ -331,6 +320,16 @@ const endCall = async () => {
331320 }
332321};
333322
323+ const copyMeetingUrl = async () => {
324+ try {
325+ const meetingUrl = window .location .href ;
326+ await navigator .clipboard .writeText (meetingUrl);
327+ console .log (" Meeting URL copied to clipboard:" , meetingUrl);
328+ } catch (error) {
329+ console .error (" Failed to copy meeting URL:" , error);
330+ }
331+ };
332+
334333const initializeCamera = async () => {
335334 try {
336335 console .log (" Initializing camera and microphone..." );
@@ -395,15 +394,11 @@ const joinMeetingRoom = async () => {
395394 // Initialize camera/audio first to show local stream
396395 await initializeCamera ();
397396
398- // Step 1: Initialize Frappe socket connection for non-WebRTC events
399- const socket = initSocket ();
400- setupWebRTCEventHandlers ();
401-
402- // Step 2: Join the meeting in Frappe (authentication and permissions)
397+ // Step 1: Join the meeting in Frappe (authentication and permissions)
403398 const joinResult = await joinMeeting (meetingId .value );
404399 console .log (" ✅ Joined meeting in Frappe:" , joinResult);
405400
406- // Step 3 : Connect directly to SFU for WebRTC operations
401+ // Step 2 : Connect directly to SFU for WebRTC operations
407402 sfuManager = getSFUMeetingManager ();
408403 sfuManager .initialize ({
409404 meetingId: meetingId .value ,
@@ -445,16 +440,13 @@ const joinMeetingRoom = async () => {
445440
446441 await sfuManager .connect ();
447442
448- // Step 4: Set up legacy WebRTC event handlers (for backward compatibility)
449- setupWebRTCEventHandlers ();
450-
451443 // Hide loading indicator once we've joined
452444 isConnecting .value = false ;
453445
454- // Step 5 : Initialize mediasoup device with router capabilities from SFU
446+ // Step 3 : Initialize mediasoup device with router capabilities from SFU
455447 await sfuManager .initializeDevice ();
456448
457- // Step 6 : Start publishing media if we have local stream
449+ // Step 4 : Start publishing media if we have local stream
458450 if (localStream && sfuManager) {
459451 const publishOptions = {
460452 publishVideo: isCameraOn .value ,
@@ -469,7 +461,7 @@ const joinMeetingRoom = async () => {
469461 audioProducer = mediaResults .audioProducer ;
470462 }
471463
472- // Step 7 : Request existing participants and their media streams
464+ // Step 5 : Request existing participants and their media streams
473465 // This will create receive transport on-demand when needed
474466 await requestExistingParticipants ();
475467
@@ -485,94 +477,12 @@ const requestExistingParticipants = async () => {
485477 try {
486478 console .log (" Requesting existing participants and their streams..." );
487479
488- // Get existing participants from the meeting document
489- let existingMembers = [];
490- if (meetingDoc? .data ? .members ) {
491- existingMembers = meetingDoc .data .members ;
492- }
493-
494- // Use SFU manager to setup existing participants
495- if (sfuManager) {
496- await sfuManager .setupExistingParticipants (existingMembers);
497- }
480+ await sfuManager .setupExistingParticipants ();
498481 } catch (error) {
499482 console .error (" Error requesting existing participants:" , error);
500483 }
501484};
502485
503- const setupWebRTCEventHandlers = () => {
504- console .log (
505- " 🔧 Setting up legacy WebRTC event handlers for backward compatibility" ,
506- );
507-
508- registerWebRTCEventHandlers ({
509- onMeetingJoined : (data ) => {
510- console .log (" Meeting joined successfully:" , data);
511-
512- // Add existing members from the join response
513- if (data .members ) {
514- console .log (
515- " Processing existing members from join response:" ,
516- data .members ,
517- );
518- for (const member of data .members ) {
519- if (member .user !== currentUser .value ? .name ) {
520- const participant = {
521- user_id: member .user ,
522- user_name: member .full_name || member .user ,
523- initials: (member .full_name || member .user || " U" )
524- .split (" " )
525- .map ((n ) => n[0 ])
526- .join (" " )
527- .toUpperCase ()
528- .slice (0 , 2 ),
529- audio_enabled: true ,
530- video_enabled: true ,
531- };
532- participants .value .set (member .user , participant);
533- console .log (" Added member from join response:" , participant);
534- }
535- }
536- }
537- },
538-
539- onMeetingJoinError: (error ) => {
540- console .error (" Meeting join error:" , error);
541- connectionError .value = error .message || " Failed to join meeting" ;
542- },
543-
544- onParticipantJoined : (data ) => {
545- console .log (" Legacy participant joined:" , data);
546- // SFU manager handles this now
547- },
548-
549- onParticipantLeft : (data ) => {
550- console .log (" Legacy participant left:" , data);
551- // SFU manager handles this now
552- },
553-
554- onProducerCreated: async (data ) => {
555- console .log (" Legacy producer created:" , data);
556- // SFU manager handles this now
557- },
558-
559- onConsumerClosed : (data ) => {
560- console .log (" Legacy consumer closed:" , data);
561- // SFU manager handles this now
562- },
563-
564- onMediaControlUpdate : (data ) => {
565- console .log (" Legacy media control update:" , data);
566- // SFU manager handles this now
567- },
568-
569- onSFUError : (error ) => {
570- console .error (" SFU Error:" , error);
571- connectionError .value = " Connection error occurred" ;
572- },
573- });
574- };
575-
576486const handleKeyDown = (event ) => {
577487 if ((event .metaKey || event .ctrlKey ) && event .key === " d" ) {
578488 event .preventDefault ();
@@ -585,8 +495,6 @@ const handleKeyDown = (event) => {
585495};
586496
587497onMounted (async () => {
588- // Start the meeting time counter
589- timer = setInterval (updateMeetingTime, 1000 );
590498 window .addEventListener (" keydown" , handleKeyDown);
591499
592500 // Join the meeting room
@@ -612,10 +520,6 @@ watch(
612520);
613521
614522onUnmounted (async () => {
615- if (timer) {
616- clearInterval (timer);
617- }
618-
619523 // Clean up WebRTC event handlers
620524 unregisterWebRTCEventHandlers ();
621525
0 commit comments