Explorar o código

Merge branch 'dev-vj-agora-v2' of rav.triplestart.com:jmudaka/stagfe2 into dev-vj-agora-v2

Josh %!s(int64=4) %!d(string=hai) anos
pai
achega
79e4e688c8
Modificáronse 1 ficheiros con 91 adicións e 14 borrados
  1. 91 14
      resources/views/app/video/call-agora-v2.blade.php

+ 91 - 14
resources/views/app/video/call-agora-v2.blade.php

@@ -27,13 +27,14 @@
 
         <div class="d-flex px-2 border-bottom mb-2 {{ $client ? '' : 'justify-content-center' }}">
             @if($client)
-            <div class="py-2 font-weight-normal mcp-theme-1 flex-grow-1">
-                <i class="fa fa-user-injured small mr-2"></i><a href="#" onclick="return window.top.openInLHS('/patients/view/{{$client->uid}}')">
+            <div class="py-2 font-weight-normal mcp-theme-1 d-inline-flex align-items-center flex-grow-1">
+                <i class="fa fa-user-injured small mr-2"></i>
+                <a href="#" onclick="return window.top.openInLHS('/patients/view/{{$client->uid}}')">
                     <span class="font-weight-bold">{{ $client->displayName() }}</span>
-                    <span class="text-secondary ml-3">{{ $pro->displayName() }}</span>
-                    <span class="text-secondary ml-3">{{ $session->uid }}</span>
-                    <span class="text-secondary ml-3">{{ date('H:i:s') }}</span>
                 </a>
+                <span class="text-secondary ml-3">{{ $pro->displayName() }}</span>
+                <span class="text-secondary ml-3">{{ $session->uid }}</span>
+                <span class="text-secondary ml-3">{{ date('H:i:s') }}</span>
             </div>
             @endif
 
@@ -54,15 +55,33 @@
         @if($client)
         <div class="">
             <div class="main-view mx-auto">
-                <div id="self-view" class="full-view" :data-uid="myMediaServiceIdentifier" data-name="You" data-type="PRO"></div>
+                <div id="self-view" class="full-view"
+                     :data-self="mainViewParticipant.self"
+                     :data-uid="mainViewParticipant.uid"
+                     :data-name="mainViewParticipant.name"
+                     :data-type="mainViewParticipant.type"></div>
                 <div class="thumbs">
+                    <div v-if="mainViewParticipant.uid !== myMediaServiceIdentifier"
+                         :id="'remote-view-' + myMediaServiceIdentifier"
+                         :data-self="true"
+                         :data-uid="myMediaServiceIdentifier"
+                         :data-name="'You'"
+                         :data-type="'PRO'"   {{-- TODO: change in FE4 --}}
+                         :data-audio="myMedia && myMedia.isMicrophoneOn ? 'on' : 'off'"
+                         v-on:click.prevent="showInCenterView(true, myMediaServiceIdentifier, 'You', 'PRO')"
+                         class="remote-view thumb-view c-pointer">
+                        <i v-show="!myMedia || !myMedia.isMicrophoneOn" class="fa fa-microphone-slash muted"></i>
+                    </div>
                     <div v-for="participant in otherParticipants"
-                         :id="'remote-view-' + participant.uid"
+                         v-if="mainViewParticipant.uid !== (+participant.mediaServiceIdentifier)"
+                         :id="'remote-view-' + participant.mediaServiceIdentifier"
+                         :data-self="false"
                          :data-uid="participant.mediaServiceIdentifier"
                          :data-name="participant.displayName"
                          :data-type="participant.participantType"
                          :data-audio="participant.media && participant.media.isMicrophoneOn ? 'on' : 'off'"
-                         class="remote-view thumb-view">
+                         v-on:click.prevent="showInCenterView(false, participant.mediaServiceIdentifier, participant.displayName, participant.participantType)"
+                         class="remote-view thumb-view c-pointer">
                         <i v-show="!participant.media || !participant.media.isMicrophoneOn" class="fa fa-microphone-slash muted"></i>
                     </div>
                 </div>
@@ -182,6 +201,14 @@
                     unresolvedParticipants: [],     // does not exist in otherParticipants, but came in via Agora
                     unrenderedParticipantsTimer: false,
                     unresolvedParticipantsTimer: false,
+
+                    // main-view & thumb views
+                    mainViewParticipant: {
+                        self: true,
+                        uid: '',
+                        type: 'PRO',
+                        name: 'You',
+                    },
                 },
                 methods: {
 
@@ -249,10 +276,11 @@
                                 this.meetingType = state.meetingType;
                                 // NOTE: this now comes from its own end-point (see below)
                                 // this.myMediaServiceToken = state.myMediaServiceToken;
-                                this.myMediaServiceIdentifier = state.myMediaServiceIdentifier;
+                                this.myMediaServiceIdentifier = +state.myMediaServiceIdentifier;
                                 this.otherParticipants = state.otherParticipants;
 
                                 if(_firstRun) {
+                                    this.mainViewParticipant.uid = +state.myMediaServiceIdentifier;
                                     $.post('/api/meeting/refreshMyMediaServiceToken', (_data) => {  // get new agora token
                                         if(!this.hasError(_data)) {
                                             this.myMediaServiceToken = _data.data;
@@ -294,7 +322,7 @@
                                     let existing = this.otherParticipants.filter(_participant => {
                                         return _participant.uid === eventData.performer;
                                     });
-                                    if(!existing.length) this.otherParticipants.push(eventData);
+                                    if(!existing.length) this.otherParticipants.push(eventData.data);
                                 }
                             }
                         });
@@ -370,6 +398,16 @@
                             if(message && message.body) {
                                 let eventData = JSON.parse(message.body);
                                 if(!_isSelf(eventData) && eventData.data) {
+
+                                    // if the participant who left is in center view, switch center view to self
+                                    for (let i = 0; i < this.otherParticipants.length; i++) {
+                                        if (this.otherParticipants[i].uid === eventData.performer) {
+                                            if(this.mainViewParticipant.uid === (+this.otherParticipants[i].mediaServiceIdentifier)) {
+                                                this.showInCenterView(true, this.myMediaServiceIdentifier, 'You', 'PRO');
+                                            }
+                                        }
+                                    }
+
                                     this.otherParticipants = this.otherParticipants.filter(_participant => {
                                          return _participant.uid !== eventData.performer;
                                     });
@@ -434,7 +472,7 @@
 
                             // Show own feed
                             if(this.myCamera && this.myMedia.isCameraAcquired) {
-                                this.myCamera.play($('#self-view')[0]);
+                                this.myCamera.play($('#self-view')[0], {fit: 'contain'});
                             }
 
                             // init unrenderedParticipantsTimer and unresolvedParticipantsTimer
@@ -484,7 +522,7 @@
                                     user.audioTrack.play();
                                 }
                                 else if(mediaType === 'video' && participant.media.isCameraOn) {
-                                    user.videoTrack.play($('[data-uid="' + user.uid + '"]')[0]);
+                                    user.videoTrack.play($('[data-uid="' + user.uid + '"]')[0], {fit: 'contain'});
                                 }
                                 this.markUserAsRendered(user);
                             }
@@ -621,7 +659,46 @@
                     },
                     // end: actions that notify participants via socket
 
-                    // utils: start
+                    // start: main view / thumb views
+                    showInCenterView: function(_self, _uid, _name, _type) {
+                        this.mainViewParticipant = {
+                            self: _self,
+                            uid: +_uid,
+                            type: _type,
+                            name: _name,
+                        };
+                        Vue.nextTick(() => {
+                            this.refreshVideos();
+                        });
+                    },
+                    refreshVideos: function() {
+                        // play self (only video)
+                        // no need to check camera/mic acquired/on etc. as only published tracks will appear here
+                        for(let track in this.mediaServiceClient.localTracks) {
+                            if(this.mediaServiceClient.localTracks.hasOwnProperty(track)) {
+                                track = this.mediaServiceClient.localTracks[track];
+                                if(track.trackMediaType === 'video') {
+                                    track.play($('[data-uid="' + this.myMediaServiceIdentifier + '"]')[0], {fit: 'contain'});
+                                }
+                            }
+                        }
+
+                        // play others
+                        for(let remoteParticipant in this.mediaServiceClient.remoteUsers) {
+                            if(this.mediaServiceClient.remoteUsers.hasOwnProperty(remoteParticipant)) {
+                                remoteParticipant = this.mediaServiceClient.remoteUsers[remoteParticipant];
+                                if(remoteParticipant.hasAudio && remoteParticipant.audioTrack) {
+                                    remoteParticipant.audioTrack.play();
+                                }
+                                if(remoteParticipant.hasVideo && remoteParticipant.videoTrack) {
+                                    remoteParticipant.videoTrack.play($('[data-uid="' + remoteParticipant.uid + '"]')[0], {fit: 'contain'});
+                                }
+                            }
+                        }
+                    },
+                    // end: main view / thumb views
+
+                    // start: utils
                     hasError: function(_data) {     // check and report error if exists via toastr
                         let msg = 'Unknown error!';
                         if(_data) {
@@ -631,7 +708,7 @@
                         toastr.error(msg);
                         return true;
                     }
-                    // utils: end
+                    // end: utils
                 },
                 mounted: function () {
                     this.enterClientRoomAsPro();