소스 검색

Added support of multiple incoming calls.
Fixed no answer callback.

Kain_Stropov 5 년 전
부모
커밋
c11c9ea3af
2개의 변경된 파일130개의 추가작업 그리고 95개의 파일을 삭제
  1. 40 26
      resources/js/components/vuex/index.js
  2. 90 69
      resources/js/components/widgets/CallBubble.vue

+ 40 - 26
resources/js/components/vuex/index.js

@@ -35,10 +35,13 @@ export default () => new Vuex.Store({
             }
         },
         meetingLoading: false,
-        callWidget: {
-            active: false,
-            callInfo: {}
-        }
+        callToNoAnswer: null,
+        callWidget: []
+        // {
+        //     active: false,
+        //     noAnswer: false,
+        //     callInfo: {}
+        // }
     },
     mutations: {
 
@@ -100,11 +103,12 @@ export default () => new Vuex.Store({
                         state.meeting.active_members = data.active_members
                     }
 
-                    if (state.callWidget.callInfo.meeting_uid == meeting[0].uid) {
+                    call = state.callWidget.find(c => c.callInfo.meeting_uid == meeting[0].uid)
+                    if (call) {
                         if (!meeting[0].active_members.length || meeting[0].pros_online.findIndex((x) => x.uid == state.user.uid) !== -1) {
-                            state.callWidget.active = false
+                            call.active = false
                         } else {
-                            state.callWidget.active = true
+                            call.active = true
                         }
                     }
                 }
@@ -161,22 +165,26 @@ export default () => new Vuex.Store({
         /* Other */
 
         setCall(state, data) {
-            state.callWidget.callInfo = data
+            const call = {
+                active: false,
+                timer: null,
+                callInfo: null
+            }
+            call.callInfo = data
 
-            if (state.callWidget.callInfo.time_limit) {
-                state.callWidget.timer = setInterval(() => {
-                    if (state.callWidget.callInfo.time_limit > 0) {
-                        state.callWidget.callInfo.time_limit--
+            if (call.callInfo.time_limit) {
+                call.timer = setInterval(() => {
+                    if (call.callInfo.time_limit > 0) {
+                        call.callInfo.time_limit--
 
-                        if (state.callWidget.callInfo.time_limit == 0) {
-                            clearInterval(state.callWidget.timer)
-                            state.callWidget.timer = null
+                        if (call.callInfo.time_limit == 0) {
+                            clearInterval(call.timer)
+                            call.timer = null
                             console.log('TIME IS OUT!')
-                            this.$socket.emit("callDecision", {
-                                accepted: false,
-                                ring_uid: state.callWidget.callInfo.ring_uid,
-                                lobby_call_uid: state.callWidget.callInfo.lobby_call_uid
-                            });
+                            const callIndex = state.callWidget.findIndex(c => c.uid === call.uid)
+                            if (callIndex > -1)
+                                state.callWidget.splice(callIndex, 1)
+                            state.callToNoAnswer = call
                             $.ajax({
                                 url: "/post-to-api-ajax",
                                 method: "POST",
@@ -185,7 +193,7 @@ export default () => new Vuex.Store({
                                 },
                                 data: {
                                     _api: "/api/meetingRing/ringNoAnswer",
-                                    uid: state.callWidget.callInfo.ring_uid
+                                    uid: call.callInfo.ring_uid
                                 },
                                 error: (jXhr) => console.log(jXhr)
                             })
@@ -195,13 +203,19 @@ export default () => new Vuex.Store({
             }
 
             if (data.lobby_call_uid)
-                state.callWidget.active = true
+                call.active = true
+            state.callWidget.push(call)
         },
-        rejectCall(state) {
+        rejectCall(state, call) {
             state.callWidget.active = false
-            state.callWidget.callInfo = {}
-            if (state.callWidget.timer)
-                clearInterval(timer)
+            if (call.timer)
+                clearInterval(call.timer)
+            const callIndex = state.callWidget.findIndex(c => c.uid === call.uid)
+            if (callIndex > -1)
+                state.callWidget.splice(callIndex, 1)
+            // state.callWidget.callInfo = {}
+            // if (call.timer)
+            //     clearInterval(timer)
         },
         setSessionConnectivityState(state, data) {
             state.session.sessionConnected = data

+ 90 - 69
resources/js/components/widgets/CallBubble.vue

@@ -1,47 +1,48 @@
 <template>
-    <v-btn
-        color="pink"
-        class="callBtn"
-        :class="{'showingAll': showCalleeDetails, 'active': (callWidget.active && callWidget.callInfo && (callWidget.callInfo.time_limit > 0 || callWidget.callInfo.time_limit == null))}"
-        dark
-        absolute
-        bottom
-        right
-        ripple
-        @click="shiftForm"
-    >
-        <div v-if="callWidget.active">
-            <div class="d-flex flex-row align-items-center btnHeader">
-                <v-icon>mdi-video</v-icon>
-                <div class="ml-2 incomingCallMsg">Incoming Call {{!showCalleeDetails && callWidget.callInfo.time_limit !== null ? `(${callWidget.callInfo.time_limit})` : ''}}</div>
-            </div>
-            <div class="fullDetails mt-3">
-                <div class="d-flex flex-row justify-content-between">
-                    <span>Callee:</span>
-                    <span>{{callWidget.callInfo.user_type}}</span>
+    <div class="ring-container">
+        <v-btn
+            v-for="call of callWidget"
+            :key="call.uid"
+            color="pink"
+            class="callBtn"
+            :class="{'showingAll': showCalleeDetailsUid == call.callInfo.uid, 'active': (call.active && call.callInfo && (call.callInfo.time_limit > 0 || call.callInfo.time_limit == null))}"
+            dark
+            ripple
+            @click="shiftForm(call.callInfo)"
+        >
+            <div v-if="call.active">
+                <div class="d-flex flex-row align-items-center btnHeader">
+                    <v-icon>mdi-video</v-icon>
+                    <div class="ml-2 incomingCallMsg">Incoming Call {{showCalleeDetailsUid != call.callInfo.uid && call.callInfo.time_limit !== null ? `(${call.callInfo.time_limit})` : ''}}</div>
                 </div>
+                <div class="fullDetails mt-3">
+                    <div class="d-flex flex-row justify-content-between">
+                        <span>Callee:</span>
+                        <span>{{call.callInfo.user_type}}</span>
+                    </div>
 
-                <div class="d-flex flex-row justify-content-between">
-                    <span>Lobby:</span>
-                    <span>{{callWidget.callInfo.lobby || 'None'}}</span>
-                </div>
+                    <div class="d-flex flex-row justify-content-between">
+                        <span>Lobby:</span>
+                        <span>{{call.callInfo.lobby || 'None'}}</span>
+                    </div>
 
-                <div class="d-flex flex-row justify-content-center mt-2">
-                    <span>{{callWidget.callInfo.name || 'Unknown'}}</span>
-                </div>
+                    <div class="d-flex flex-row justify-content-center mt-2">
+                        <span>{{call.callInfo.name || 'Unknown'}}</span>
+                    </div>
 
-                <div class="d-flex flex-row justify-content-center mt-5">
-                    <h2 v-if="callWidget.callInfo.time_limit">{{callWidget.callInfo.time_limit}}</h2>
-                </div>
+                    <div class="d-flex flex-row justify-content-center mt-5">
+                        <h2 v-if="call.callInfo.time_limit">{{call.callInfo.time_limit}}</h2>
+                    </div>
 
-                <div class="d-flex flex-row justify-content-between mt-5 ctrlBtns">
-                    <span @click="handleCall(true)">Accept</span>
-                    /
-                    <span @click="handleCall(false)">Reject</span>
+                    <div class="d-flex flex-row justify-content-between mt-5 ctrlBtns">
+                        <span @click="handleCall(call,true)">Accept</span>
+                        /
+                        <span @click="handleCall(call,false)">Reject</span>
+                    </div>
                 </div>
             </div>
-        </div>
-    </v-btn>
+        </v-btn>
+    </div>
 </template>
 
 <script>
@@ -50,35 +51,43 @@ import { mapState } from "vuex";
 export default {
     data() {
         return {
-            showCalleeDetails: false
+            showCalleeDetailsUid: null
         };
     },
     computed: {
-        ...mapState(["lobbies", "settings", "callWidget"])
+        ...mapState(["lobbies", "settings", "callWidget", "callToNoAnswer"])
     },
     watch: {
-        "callWidget.active": {
-            handler(newVal) {
-                if (!newVal) {
-                    let self = this;
-
-                    setTimeout(() => {
-                        self.showCalleeDetails = false;
-                    }, 750);
-                }
-            }
+        // "callWidget.active": {
+        //     handler(newVal) {
+        //         if (!newVal) {
+        //             let self = this;
+        //             setTimeout(() => {
+        //                 self.showCalleeDetails = false;
+        //             }, 750);
+        //         }
+        //     }
+        // }
+        callToNoAnswer(newVal) {
+            this.$socket.emit("callDecision", {
+                uid: newVal.callInfo.uid,
+                accepted: false,
+                ring_uid: newVal.callInfo.ring_uid,
+                lobby_call_uid: newVal.callInfo.lobby_call_uid
+            });
         }
     },
     methods: {
-        handleCall(acceptCall) {
+        handleCall(call, acceptCall) {
             if (acceptCall) {
                 this.$socket.emit("callDecision", {
+                    uid: call.callInfo.uid,
                     accepted: true,
-                    ring_uid: this.callWidget.callInfo.ring_uid,
-                    lobby_call_uid: this.callWidget.callInfo.lobby_call_uid
+                    ring_uid: call.callInfo.ring_uid,
+                    lobby_call_uid: call.callInfo.lobby_call_uid
                 });
 
-                if (this.callWidget.callInfo.ring_uid) {
+                if (call.callInfo.ring_uid) {
                     $.ajax({
                         url: "/post-to-api-ajax",
                         method: "POST",
@@ -87,7 +96,7 @@ export default {
                         },
                         data: {
                             _api: "/api/meetingRing/ringAnswer",
-                            uid: this.callWidget.callInfo.ring_uid
+                            uid: call.callInfo.ring_uid
                         },
                         success: data => {
                             if (!data.success) {
@@ -95,15 +104,14 @@ export default {
                                 console.error(data.message);
                                 return;
                             }
-                            console.log(this.callWidget.callInfo);
                             const joinData = {
                                 uid: null,
                                 name: null,
-                                selected_meeting: this.callWidget.callInfo.meeting
+                                selected_meeting: call.callInfo.meeting
                             };
 
                             this.$eventBus.$emit("joinMeeting", joinData);
-                            this.$store.commit("rejectCall");
+                            this.$store.commit("rejectCall", call);
                         },
                         error: jXhr => console.log(jXhr)
                     });
@@ -113,7 +121,7 @@ export default {
                     let data = {};
 
                     for (let lobby of this.lobbies) {
-                        meeting = lobby.meetings.filter(x => x.uid == this.callWidget.callInfo.meeting_uid);
+                        meeting = lobby.meetings.filter(x => x.uid == call.callInfo.meeting_uid);
 
                         if (meeting.length) {
                             lobby_data = {
@@ -134,16 +142,17 @@ export default {
                         };
                     }
                     this.$eventBus.$emit("joinMeeting", data);
-                    this.$store.commit("rejectCall");
+                    this.$store.commit("rejectCall", call);
                 }
             } else {
                 this.$socket.emit("callDecision", {
+                    uid: call.callInfo.uid,
                     accepted: false,
-                    ring_uid: this.callWidget.callInfo.ring_uid,
-                    lobby_call_uid: this.callWidget.callInfo.lobby_call_uid
+                    ring_uid: call.callInfo.ring_uid,
+                    lobby_call_uid: call.callInfo.lobby_call_uid
                 });
 
-                if (this.callWidget.callInfo.ring_uid) {
+                if (call.callInfo.ring_uid) {
                     $.ajax({
                         url: "/post-to-api-ajax",
                         method: "POST",
@@ -152,26 +161,29 @@ export default {
                         },
                         data: {
                             _api: "/api/meetingRing/ringReject",
-                            uid: this.callWidget.callInfo.ring_uid
+                            uid: call.callInfo.ring_uid
                         },
                         error: jXhr => console.log(jXhr)
                     });
                 }
-                this.$store.commit("rejectCall");
+                this.$store.commit("rejectCall", call);
             }
         },
-        shiftForm() {
+        shiftForm(call) {
+            console.log(call);
             if (!this.settings.newMeetingNotificationExpanded) {
-                this.showCalleeDetails = !this.showCalleeDetails;
+                if (this.showCalleeDetailsUid == call.uid) this.showCalleeDetailsUid = null;
+                else this.showCalleeDetailsUid = call.uid;
+                // this.showCalleeDetails = !this.showCalleeDetails;
             } else {
-                this.showCalleeDetails = true;
+                this.showCalleeDetailsUid = call.uid;
             }
         }
     },
     created() {
-        if (this.settings.newMeetingNotificationExpanded) {
-            this.showCalleeDetails = true;
-        }
+        // if (this.settings.newMeetingNotificationExpanded) {
+        //     this.showCalleeDetails = true;
+        // }
     }
 };
 </script>
@@ -189,6 +201,14 @@ export default {
     }
 }
 
+.ring-container {
+    position: absolute;
+    display: flex;
+    flex-direction: column;
+    right: 16px;
+    bottom: 16px;
+}
+
 .callBtn {
     z-index: 1000;
     border-radius: 28px;
@@ -197,6 +217,7 @@ export default {
     min-width: 56px !important;
     overflow-x: hidden;
     overflow-y: hidden;
+    margin-top: 5px;
 
     transition: all 0.5s;