소스 검색

boilerplate open tok added to client page

Flavionel 5 년 전
부모
커밋
3647fa460e
1개의 변경된 파일396개의 추가작업 그리고 24개의 파일을 삭제
  1. 396 24
      resources/js/components/pages/ClientEntrance.vue

+ 396 - 24
resources/js/components/pages/ClientEntrance.vue

@@ -24,30 +24,30 @@
                         color="grey lighten-1"
                         height="200px"
                         >
-                        <div class="checkin-form d-flex justify-content-center align-items-center">
-                            <form action="/post-to-api"
-                                method="post"
-                                enctype="multipart/form-data">
-
-                                <input type="hidden" name="lobbyUid" value=""/>
-                                <input type="hidden" name="_api" value="/api/session/proRequestSmsTokenToLogIn">
-                                <input type="hidden" name="_success" value="/pro/login">
-                                <input type="hidden" name="_return" value="/">
-
-                                <div class="row mb-3">
-                                    <div class="col">
-                                        <input type="text" name="strangerFirstName" class="form-control" placeholder="First Name" required>
-                                    </div>
-                                    <div class="col">
-                                        <input type="text" name="strangerLastName" class="form-control" placeholder="Last Name" required>
+                            <div class="checkin-form d-flex justify-content-center align-items-center">
+                                <form action="/post-to-api"
+                                    method="post"
+                                    enctype="multipart/form-data">
+
+                                    <input type="hidden" name="lobbyUid" value=""/>
+                                    <input type="hidden" name="_api" value="/api/session/proRequestSmsTokenToLogIn">
+                                    <input type="hidden" name="_success" value="/pro/login">
+                                    <input type="hidden" name="_return" value="/">
+
+                                    <div class="row mb-3">
+                                        <div class="col">
+                                            <input type="text" name="strangerFirstName" class="form-control" placeholder="First Name" required>
+                                        </div>
+                                        <div class="col">
+                                            <input type="text" name="strangerLastName" class="form-control" placeholder="Last Name" required>
+                                        </div>
                                     </div>
-                                </div>
 
-                                <div class="input-group mb-3">
-                                    <input type="date" name="strangerDob" class="form-control" placeholder="Date of Birth" required>
-                                </div>
-                            </form>
-                        </div>
+                                    <div class="input-group mb-3">
+                                        <input type="date" name="strangerDob" class="form-control" placeholder="Date of Birth" required>
+                                    </div>
+                                </form>
+                            </div>
                         </v-card>
 
                         <v-btn
@@ -71,7 +71,9 @@
                         class="mb-12"
                         color="grey lighten-1"
                         height="200px"
-                        ></v-card>
+                        >
+                        
+                        </v-card>
 
                         <v-btn
                         color="primary"
@@ -121,7 +123,24 @@ export default {
         return {
             stepper: 1,
             cameraWorkingConfirmed: false,
-            loading: false
+            loading: false,
+            /* Copied */
+            readyForUse: false,
+            uniqueId: Math.floor(Math.random() * Math.floor(10000)),
+            counter: 1,
+            openTokSession: null,
+            publisher: null,
+            screenPublisher: null,
+            subscribers: [],
+            publisherReady: false,
+            accessDialogShown: false,
+            videos: [],
+            videoGrid: [],
+            maxCols: 12,
+            maxRows: 4,
+            rowHeight: 240,
+            gridPadding: 8,
+            loadingInProgress: false
         }
     },
     methods: {
@@ -129,7 +148,360 @@ export default {
             //ajax logic
 
             this.stepper = 2
+        },
+        /* Copied */
+        disconnect() {
+            if (!this.openTokSession) return;
+            this.openTokSession.disconnect();
+            this.openTokSession.off();
+            this.videos = [];
+            this.publisher.destroy();
+            this.publisher = null;
+            this.subscribers = [];
+            this.publisherReady = false;
+            this.$store.commit("setSessionConnectivityState", false);
+            this.openTokSession = null;
+            if (this.screenPublisher) {
+                this.screenPublisher.destroy();
+                this.screenPublisher = null;
+                this.$store.commit("setScreenShareState", null);
+            }
+        },
+        getToken(data, isAssociate) {
+            if (this.meeting.scheduledDate && !this.meeting.startedAt && this.meeting.scheduledDate > new Date() && (this.user.type === "guest" || !confirm("Meeting not started. Start it now?")))
+                return;
+            data.meetingId = this.meeting.id;
+            data.userUid = this.user.UID;
+            $.ajax({
+                url: isAssociate ? "/associate/token" : "/token",
+                method: "POST",
+                headers: {
+                    "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
+                },
+                data,
+                success: data => {
+                    this.$refs.initialModal.hide();
+                    if (!isAssociate) {
+                        const user = Object.assign({}, this.user);
+                        user.id = data.participantId;
+                        user.name = data.participantName;
+                        user.pin = data.participantPin;
+                        this.$store.commit("setUser", user);
+                    }
+                    this.initializeOpenTok(data.apiKey, data.sessionId, data.token);
+                },
+                error: jXhr => {
+                    if (jXhr.responseJSON && jXhr.responseJSON.errorCode) {
+                        switch (jXhr.responseJSON.errorCode) {
+                            case "LM-1":
+                                alert("Meeting not started yet.");
+                                break;
+                            case "LM-2":
+                                alert("You was kicked from this meeting.");
+                                window.location = "/";
+                                break;
+                            case "LM-3":
+                                alert("Wrong password");
+                                this.$refs.initialModal.disableWaiting();
+                                break;
+                        }
+                    } else {
+                        this.$refs.initialModal.disableWaiting();
+                        alert(getSingleError(jXhr));
+                    }
+                }
+            });
+        },
+        createVideoContainer() {
+            let videoCont = {};
+            videoCont.id = `${this.uniqueId}_video_${this.counter++}`;
+
+            this.videos.push(videoCont);
+            this.adjustVideoContainers();
+
+            return videoCont;
+        },
+        adjustVideoContainers() {
+            this.videoGrid = [];
+
+            let windowHeight = window.innerHeight;
+            this.rowHeight = (windowHeight - this.gridPadding * (this.maxRows + 1)) / this.maxRows;
+
+            let cols = Math.ceil(Math.sqrt(this.videos.length));
+            let rows = Math.ceil(this.videos.length / cols);
+
+            let elementsLastRow = this.videos.length % cols;
+            let lastNormalIndex = this.videos.length - elementsLastRow;
+
+            if (elementsLastRow) {
+                this.maxCols = cols * elementsLastRow;
+            } else {
+                this.maxCols = cols;
+            }
+
+            let colsPerElement = this.maxCols / cols;
+            let rowsPerElement = this.maxRows / rows;
+
+            let colsLastRow = Math.ceil(this.maxCols / elementsLastRow);
+
+            let cntX = 0;
+            let cntY = 0;
+
+            for (let [index, video] of this.videos.entries()) {
+                video.i = index;
+                video.x = cntX;
+                video.y = cntY;
+                video.h = rowsPerElement;
+                video.w = colsPerElement;
+                cntX += colsPerElement;
+
+                if (cntX >= this.maxCols) {
+                    cntX = 0;
+                    cntY += rowsPerElement;
+                }
+
+                let videoTemp = Object.assign({}, video);
+                videoTemp.video = video;
+                this.videoGrid.push(videoTemp);
+            }
+
+            /* OLD IMPLEMENTATION */
+
+            /* for (let [index, video] of this.videos.entries()) {
+                video.i = index;
+                if (index < lastNormalIndex) {
+                    video.x = cntX;
+                    video.y = cntY;
+                    video.h = rowsPerElement;
+                    video.w = colsPerElement;
+                    cntX += colsPerElement;
+
+                    if (cntX >= this.maxCols) {
+                        cntX = 0;
+                        cntY += rowsPerElement;
+                    }
+                } else {
+                    video.x = cntX;
+                    video.y = cntY;
+                    video.h = rowsPerElement;
+                    video.w = colsLastRow;
+                    cntX += colsLastRow;
+                }
+
+                let videoTemp = Object.assign({}, video);
+                this.videoGrid.push(videoTemp);
+            } */
+
+            /* let gridColumn, gridRows = ''
+
+            if(rows && cols){
+                gridColumn = `grid-template-columns: repeat(${cols}, minmax(320px, 1fr));`
+                gridRows = `grid-template-rows: repeat(${rows}, minmax(240px, 1fr));`
+            } */
+        },
+        initializeOpenTok(apiKey, sessionId, token) {
+            this.openTokSession = OT.initSession(apiKey, sessionId);
+
+            this.openTokSession.on({
+                sessionDisconnected: event => {
+                    if (event.reason === "forceDisconnected") {
+                        alert("You were kicked.");
+                        if (this.user.type === "associate") {
+                            this.disconnect();
+                            this.$store.dispatch("leaveMeeting");
+                        } else {
+                            window.location = "/";
+                        }
+                    }
+                }
+            });
+
+            // Create a publisher
+            this.publisher = OT.initPublisher(
+                this.$refs.otContainer,
+                {
+                    insertMode: "append",
+                    width: "100%",
+                    height: "100%",
+                    resolution: "1280x720",
+                    frameRate: 30,
+                    name: this.user.name,
+                    style: {
+                        nameDisplayMode: "on",
+                        archiveStatusDisplayMode: "off"
+                    }
+                },
+                error => {
+                    if (error) {
+                        alert(error.message);
+                    } else {
+                        this.publisherReady = true;
+                        const cont = this.createVideoContainer();
+                        this.$nextTick(() => {
+                            cont.el = $(`#${cont.id}`)[0];
+                            cont.el.appendChild(this.publisher.element);
+                            cont.obj = this.publisher;
+                            this.$set(cont, "self", true);
+                            //cont.self = true;
+                        });
+                    }
+                }
+            );
+
+            this.publisher.on({
+                accessDialogOpened: e => {
+                    this.accessDialogShown = true;
+                },
+                accessDialogClosed: e => {
+                    this.accessDialogShown = false;
+                }
+            });
+
+            this.openTokSession.on("streamCreated", event => {
+                //console.log("stream Created event");
+                let container;
+                if (event.stream.videoType === "screen") {
+                //TODO: This is
+                }
+                const subscriber = this.openTokSession.subscribe(
+                event.stream,
+                this.$refs.otContainer,
+                {
+                    insertMode: "append",
+                    width: "100%",
+                    height: "100%",
+                    style: { nameDisplayMode: "on" }
+                },
+                error => {
+                    if (error) {
+                        alert(error.message);
+                    } else {
+                        const cont = this.createVideoContainer();
+                        this.$nextTick(() => {
+                            cont.el = $(`#${cont.id}`)[0];
+                            cont.el.appendChild(subscriber.element);
+                            cont.obj = subscriber;
+                            container = cont;
+                        });
+                    }
+                }
+                );
+                subscriber.on({
+                destroyed: e => {
+                    container.el.remove();
+                    const index = this.videos.findIndex(v => v.id == container.id);
+                    if (index >= 0) this.videos.splice(index, 1);
+                    this.adjustVideoContainers();
+                }
+                });
+                this.subscribers.push(subscriber);
+            });
+
+            this.openTokSession.connect(token, error => {
+                // If the connection is successful, publish to the session
+                if (error) {
+                    alert(error.message);
+                } else {
+                    this.$store.commit("setSessionConnectivityState", true);
+                }
+            });
+            this.loadingInProgress = false;
+        },
+        publishToSession() {
+            this.openTokSession.publish(this.publisher, error => {
+            if (error) {
+                alert(error.message);
+            }
+            });
+        },
+        ready() {
+            this.$nextTick(function() {
+            this.readyForUse = true;
+            if (this.user.type === "associate") {
+                if (!this.meeting.id || this.active_menu_item.template !== "room") return;
+                this.getToken({}, true);
+                return;
+            }
+
+            if (this.meeting.scheduledDate && !this.meeting.startedAt && this.meeting.scheduledDate > new Date()) {
+                alert("Meeting not started.");
+                return;
+            }
+            let participantId = this.user.id;
+            if (!participantId) {
+                this.$refs.initialModal.show(this.meeting.passwordRequired);
+                return;
+            }
+            this.getToken({
+                participantId
+            });
+            });
         }
+    },
+    watch: {
+        publisherReady(val) {
+        if (val && this.session.sessionConnected) this.publishToSession();
+        },
+        "session.sessionConnected"(val) {
+        if (val && this.publisherReady) this.publishToSession();
+        },
+        "user.is_active_and_visible"(val) {
+        if (!this.publisher || !this.publisher.publishVideo) return;
+        this.publisher.publishVideo(val);
+        this.publisher.publishAudio(val);
+        },
+        "meeting.id"(val) {
+        if (this.loadingInProgress) return;
+        this.loadingInProgress = true;
+        this.disconnect();
+
+        if (val) {
+            this.getToken({}, true);
+        } else {
+            this.loadingInProgress = false;
+        }
+        },
+        "active_menu_item.template"(val) {
+        if (this.loadingInProgress || val !== "room" || !this.meeting.id || this.openTokSession) return;
+        this.loadingInProgress = true;
+        this.getToken({}, true);
+        }
+    },
+    mounted() {
+        let self = this;
+
+        this.$eventBus.$on("meetingRejoin", () => {
+            this.loadingInProgress = true;
+            this.disconnect();
+            this.getToken({}, true);
+        });
+
+        let width = $(window).width();
+        let height = $(window).height();
+
+        window.addEventListener("resize", function() {
+        let new_width = $(window).width();
+        let new_height = $(window).height();
+
+        if (width !== new_width || height !== new_height) {
+            self.adjustVideoContainers();
+        }
+        });
+
+        this.$eventBus.$on("leaveMeeting", () => {
+            $.ajax({
+                url: "/associate/meeting/leave",
+                method: "POST",
+                headers: {
+                "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
+                },
+                error: jXhr => {
+                console.error(getSingleError(jXhr));
+                }
+            });
+            this.$store.dispatch("leaveMeeting");
+            this.disconnect();
+        });
     }
 }
 </script>