|
@@ -1,4 +1,6 @@
|
|
|
<template>
|
|
|
+ <div v-if="leaderAvatar && showAvatar" class="avatar-box" :style="`background-image:url(${leaderAvatar});`"></div>
|
|
|
+
|
|
|
<div id="PageRtcLive">
|
|
|
<div class="member_number">
|
|
|
<div class="members"></div>
|
|
@@ -6,65 +8,27 @@
|
|
|
</div>
|
|
|
<chat v-show="chatShow" :chatList="chatList" :user_info="user_info"></chat>
|
|
|
|
|
|
- <Trtccom
|
|
|
- :audioMuted="audioMuted"
|
|
|
- :videoMuted="videoMuted"
|
|
|
- v-if="isRunRTC"
|
|
|
- />
|
|
|
+ <Trtccom :audioMuted="audioMuted" :videoMuted="videoMuted" v-if="isRunRTC" />
|
|
|
|
|
|
<div class="contorlBar" v-if="!showInput">
|
|
|
- <div
|
|
|
- v-if="connectStatus == 1"
|
|
|
- :class="{ disabled: !user_info.IsWords }"
|
|
|
- class="saySomething"
|
|
|
- @click="onFocus"
|
|
|
- >
|
|
|
+ <div v-if="connectStatus == 1" :class="{ disabled: !user_info.IsWords }" class="saySomething" @click="onFocus">
|
|
|
<!-- <i class="speakIcon"
|
|
|
:class="{'dis':!user_info.IsWords}"></i> -->
|
|
|
<span v-if="user_info.IsWords">说点什么</span>
|
|
|
<span v-if="!user_info.IsWords">已被禁言</span>
|
|
|
|
|
|
- <div
|
|
|
- class="disSpeakBtn"
|
|
|
- @click.stop="chatShow = !chatShow"
|
|
|
- :class="{ dis: !chatShow }"
|
|
|
- ></div>
|
|
|
- </div>
|
|
|
- <div style="text-align: right; width: 100%" v-if="connectStatus == 0">
|
|
|
- 连接中...
|
|
|
+ <div class="disSpeakBtn" @click.stop="chatShow = !chatShow" :class="{ dis: !chatShow }"></div>
|
|
|
</div>
|
|
|
+ <div style="text-align: right; width: 100%" v-if="connectStatus == 0">连接中...</div>
|
|
|
<div v-if="connectStatus == 1" class="contorl_btn">
|
|
|
- <div
|
|
|
- v-if="isBrushes && user_info.Role == 'leader'"
|
|
|
- @click="onDrawUndo"
|
|
|
- class="brushesBack"
|
|
|
- :class="{ disabled: !canUndo }"
|
|
|
- ></div>
|
|
|
- <div
|
|
|
- v-if="user_info.Role == 'leader'"
|
|
|
- @click="onDraw(!isBrushes)"
|
|
|
- :class="{ brushesed: isBrushes }"
|
|
|
- class="brushes"
|
|
|
- ></div>
|
|
|
-
|
|
|
- <div
|
|
|
- v-if="user_list.length < 50"
|
|
|
- class="invitation"
|
|
|
- @click="onClickShare"
|
|
|
- ></div>
|
|
|
+ <div v-if="isBrushes && user_info.Role == 'leader'" @click="onDrawUndo" class="brushesBack" :class="{ disabled: !canUndo }"></div>
|
|
|
+ <div v-if="user_info.Role == 'leader'" @click="onDraw(!isBrushes)" :class="{ brushesed: isBrushes }" class="brushes"></div>
|
|
|
+
|
|
|
+ <div v-if="user_list.length < 50" class="invitation" @click="onClickShare"></div>
|
|
|
<div v-if="role == 'leader'" class="members" @click="openMember"></div>
|
|
|
<template v-if="role == 'leader'">
|
|
|
- <div
|
|
|
- v-if="!disableMic"
|
|
|
- @click="handleMuteAduio"
|
|
|
- :class="{ mic_off: audioMuted, disabled: !audioDeviceId }"
|
|
|
- class="mic_on"
|
|
|
- ></div>
|
|
|
- <div
|
|
|
- v-if="disableMic"
|
|
|
- class="mic_no"
|
|
|
- :class="{ disabled: !audioDeviceId }"
|
|
|
- ></div>
|
|
|
+ <div v-if="!disableMic" @click="handleMuteAduio" :class="{ mic_off: audioMuted, disabled: !audioDeviceId }" class="mic_on"></div>
|
|
|
+ <div v-if="disableMic" class="mic_no" :class="{ disabled: !audioDeviceId }"></div>
|
|
|
</template>
|
|
|
<!-- <div
|
|
|
v-if="role == 'leader'"
|
|
@@ -80,29 +44,15 @@
|
|
|
<div class="layer" v-if="showInput" @click="closeInput">
|
|
|
<div class="inputBox" @click.stop>
|
|
|
<div class="msgBox">
|
|
|
- <input
|
|
|
- id="input_msg"
|
|
|
- type="text"
|
|
|
- maxlength="200"
|
|
|
- v-model.trim="text"
|
|
|
- :placeholder="`说点什么~`"
|
|
|
- />
|
|
|
- <span
|
|
|
- class="iconsend_icon"
|
|
|
- :class="{ disable: text == '' }"
|
|
|
- @click.stop="sendText"
|
|
|
- >发送</span
|
|
|
- >
|
|
|
+ <input id="input_msg" type="text" maxlength="200" v-model.trim="text" :placeholder="`说点什么~`" />
|
|
|
+ <span class="iconsend_icon" :class="{ disable: text == '' }" @click.stop="sendText">发送</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 成員 -->
|
|
|
<div class="layer" v-if="showMember" @click.self="closeMember">
|
|
|
- <div
|
|
|
- class="memberContent animated"
|
|
|
- :class="animateActive ? 'fadeInUpBig' : 'fadeOutDownBig'"
|
|
|
- >
|
|
|
+ <div class="memberContent animated" :class="animateActive ? 'fadeInUpBig' : 'fadeOutDownBig'">
|
|
|
<div class="blurBox"></div>
|
|
|
<div class="content">
|
|
|
<div class="memberHeader">
|
|
@@ -113,16 +63,9 @@
|
|
|
<div class="memberItem">
|
|
|
<div class="userMsg">
|
|
|
<div class="avatar">
|
|
|
- <img
|
|
|
- :src="
|
|
|
- require('@/assets/images/rtcLive/avatar_small@2x.png')
|
|
|
- "
|
|
|
- alt=""
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="name" v-if="user_info.Role == 'leader'">
|
|
|
- {{ user_info.Nickname }} (主持人,我)
|
|
|
+ <img :src="require('@/assets/images/rtcLive/avatar_small@2x.png')" alt="" />
|
|
|
</div>
|
|
|
+ <div class="name" v-if="user_info.Role == 'leader'">{{ user_info.Nickname }} (主持人,我)</div>
|
|
|
<div class="name" v-else>{{ user_info.Nickname }} (我)</div>
|
|
|
</div>
|
|
|
|
|
@@ -135,30 +78,15 @@
|
|
|
</div> -->
|
|
|
</div>
|
|
|
|
|
|
- <div
|
|
|
- v-show="user_info.UserId != i.UserId && i.Role != 'leader'"
|
|
|
- class="memberItem"
|
|
|
- v-for="(i, idx) in user_list"
|
|
|
- :key="idx"
|
|
|
- >
|
|
|
+ <div v-show="user_info.UserId != i.UserId && i.Role != 'leader'" class="memberItem" v-for="(i, idx) in user_list" :key="idx">
|
|
|
<div class="userMsg">
|
|
|
<div class="avatar">
|
|
|
- <img
|
|
|
- :src="
|
|
|
- require('@/assets/images/rtcLive/avatar_small@2x.png')
|
|
|
- "
|
|
|
- alt=""
|
|
|
- />
|
|
|
+ <img :src="require('@/assets/images/rtcLive/avatar_small@2x.png')" alt="" />
|
|
|
</div>
|
|
|
<div class="name">{{ i.Nickname }}</div>
|
|
|
</div>
|
|
|
<div class="button" v-if="user_info.Role == 'leader'">
|
|
|
- <div
|
|
|
- class="micBtn"
|
|
|
- :class="i.IsWords ? 'ban_speak_on' : 'ban_speak_off'"
|
|
|
- :wo="i.IsWords"
|
|
|
- @click="userCanSpeak(i)"
|
|
|
- ></div>
|
|
|
+ <div class="micBtn" :class="i.IsWords ? 'ban_speak_on' : 'ban_speak_off'" :wo="i.IsWords" @click="userCanSpeak(i)"></div>
|
|
|
<!-- <div
|
|
|
class="micBtn"
|
|
|
:class="i.IsMuted ? 'mute_one_mic_off' : 'mute_one_mic_on'"
|
|
@@ -174,92 +102,74 @@
|
|
|
|
|
|
<teleport :to="`#app`">
|
|
|
<div v-if="showShare" @click="showShare = false" class="sharetip">
|
|
|
- <img
|
|
|
- @click.stop
|
|
|
- :style="`right:${isMP ? '16%' : '6%'}`"
|
|
|
- :src="require('@/assets/images/icon/img_scene_share.png')"
|
|
|
- alt=""
|
|
|
- />
|
|
|
+ <img @click.stop :style="`right:${isMP ? '16%' : '6%'}`" :src="require('@/assets/images/icon/img_scene_share.png')" alt="" />
|
|
|
</div>
|
|
|
</teleport>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import {
|
|
|
- onMounted,
|
|
|
- onUnmounted,
|
|
|
- watch,
|
|
|
- defineEmits,
|
|
|
- ref,
|
|
|
- reactive,
|
|
|
- computed,
|
|
|
- nextTick,
|
|
|
-} from "vue";
|
|
|
-import { useApp, getApp } from "@/app";
|
|
|
-import { useStore } from "vuex";
|
|
|
-import { Dialog } from "@/global_components/";
|
|
|
-import common from "@/utils/common";
|
|
|
-
|
|
|
-import { mapGetters } from "vuex";
|
|
|
-import chat from "./chat/chat.vue";
|
|
|
-import Trtccom from "./Trtccom.vue";
|
|
|
-import browser from "@/utils/browser";
|
|
|
-import wxShare from "@/utils/wxshare";
|
|
|
-
|
|
|
-const emit = defineEmits(["openDialog", "closeSocket"]);
|
|
|
+import { onMounted, onUnmounted, watch, defineEmits, ref, reactive, computed, nextTick } from 'vue';
|
|
|
+import { useApp, getApp } from '@/app';
|
|
|
+import { useStore } from 'vuex';
|
|
|
+import { Dialog } from '@/global_components/';
|
|
|
+import common from '@/utils/common';
|
|
|
+
|
|
|
+import { mapGetters } from 'vuex';
|
|
|
+import chat from './chat/chat.vue';
|
|
|
+import Trtccom from './Trtccom.vue';
|
|
|
+import browser from '@/utils/browser';
|
|
|
+import wxShare from '@/utils/wxshare';
|
|
|
+import defaultAvatar from '@/assets/images/avatar_default.png';
|
|
|
+const emit = defineEmits(['openDialog', 'closeSocket']);
|
|
|
|
|
|
const store = useStore();
|
|
|
+const leaderAvatar = computed(() => {
|
|
|
+ return store.getters['rtc/avatar'] ? store.getters['rtc/avatar'] : localStorage.getItem('leaderAvatar') ? localStorage.getItem('leaderAvatar') : defaultAvatar;
|
|
|
+});
|
|
|
|
|
|
let jumpNewScene = (sceneFirstView) => {
|
|
|
let url = window.location.href;
|
|
|
|
|
|
- if (!browser.hasURLParam("pose")) {
|
|
|
+ if (!browser.hasURLParam('pose')) {
|
|
|
url += `&${sceneFirstView.sceneview}`;
|
|
|
} else {
|
|
|
- url = browser.replaceQueryString(
|
|
|
- url,
|
|
|
- "pose",
|
|
|
- sceneFirstView.sceneview.replace("pose=", "")
|
|
|
- );
|
|
|
+ url = browser.replaceQueryString(url, 'pose', sceneFirstView.sceneview.replace('pose=', ''));
|
|
|
}
|
|
|
|
|
|
- url = browser.replaceQueryString(url, "m", sceneFirstView.num);
|
|
|
+ url = browser.replaceQueryString(url, 'm', sceneFirstView.num);
|
|
|
return url;
|
|
|
};
|
|
|
|
|
|
let chatAutoScroll = () => {
|
|
|
- let el = document.getElementById("chat");
|
|
|
- let client_h = document.getElementById("chat").clientHeight;
|
|
|
- let all = document.getElementById("contents").clientHeight;
|
|
|
+ let el = document.getElementById('chat');
|
|
|
+ let client_h = document.getElementById('chat').clientHeight;
|
|
|
+ let all = document.getElementById('contents').clientHeight;
|
|
|
el.scrollTo(0, client_h + all);
|
|
|
};
|
|
|
|
|
|
let createSocket = (config) => {
|
|
|
var socket = io(process.env.VUE_APP_SOCKET_URL, {
|
|
|
- path: "/ws-sync",
|
|
|
- transports: ["websocket"],
|
|
|
+ path: '/ws-sync',
|
|
|
+ transports: ['websocket'],
|
|
|
});
|
|
|
return socket;
|
|
|
};
|
|
|
|
|
|
-store.commit("rtc/setSocket", createSocket());
|
|
|
+store.commit('rtc/setSocket', createSocket());
|
|
|
|
|
|
let getUrl = (href, queryArr) => {
|
|
|
queryArr.forEach((item) => {
|
|
|
if (!browser.hasURLParam(item.key)) {
|
|
|
- let ttt = href.split("index.html?");
|
|
|
+ let ttt = href.split('index.html?');
|
|
|
href = `${ttt[0]}index.html?${item.key}=${item.val}&${ttt[1]}`;
|
|
|
- console.log(
|
|
|
- href,
|
|
|
- "------index.htmlindex.htmlindex.htmlindex.htmlindex.htmlindex.htmlindex.html----------"
|
|
|
- );
|
|
|
+ console.log(href, '------index.htmlindex.htmlindex.htmlindex.htmlindex.htmlindex.htmlindex.html----------');
|
|
|
} else {
|
|
|
href = browser.replaceQueryString(href, item.key, item.val);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- if (href.indexOf("customer") != -1) {
|
|
|
- return href.replace("&sync=1", "");
|
|
|
+ if (href.indexOf('customer') != -1) {
|
|
|
+ return href.replace('&sync=1', '');
|
|
|
}
|
|
|
|
|
|
return href;
|
|
@@ -282,17 +192,17 @@ const isMP = ref(false);
|
|
|
const audioMuted = ref(false);
|
|
|
const videoMuted = ref(false);
|
|
|
|
|
|
-const socket = computed(() => store.getters["rtc/socket"]);
|
|
|
+const socket = computed(() => store.getters['rtc/socket']);
|
|
|
|
|
|
const myVideoShow = ref(false);
|
|
|
const userVideoShow = ref(false);
|
|
|
const user_info = ref({});
|
|
|
const user_list = ref([]);
|
|
|
-const mode = ref(browser.getURLParam("mode"));
|
|
|
-const role = ref(browser.getURLParam("role"));
|
|
|
+const mode = ref(browser.getURLParam('mode'));
|
|
|
+const role = ref(browser.getURLParam('role'));
|
|
|
|
|
|
-const userId = computed(() => store.getters["rtc/userId"]);
|
|
|
-const roomId = computed(() => store.getters["rtc/roomId"]);
|
|
|
+const userId = computed(() => store.getters['rtc/userId']);
|
|
|
+const roomId = computed(() => store.getters['rtc/roomId']);
|
|
|
|
|
|
const isJoined = ref(false);
|
|
|
|
|
@@ -301,9 +211,9 @@ const isRunRTC = ref(false);
|
|
|
const paint = reactive({});
|
|
|
|
|
|
const chatList = ref([]);
|
|
|
-const text = ref("");
|
|
|
+const text = ref('');
|
|
|
|
|
|
-const shareLink = ref("");
|
|
|
+const shareLink = ref('');
|
|
|
const canUndo = ref(false);
|
|
|
const audioDevices = ref([1]);
|
|
|
const videoDevices = ref([1]);
|
|
@@ -312,17 +222,17 @@ const chatShow = ref(true);
|
|
|
const all_mute_mic = ref(false);
|
|
|
|
|
|
const tags = computed(() => {
|
|
|
- return store.getters["tag/tags"] || [];
|
|
|
+ return store.getters['tag/tags'] || [];
|
|
|
});
|
|
|
|
|
|
const onClickShare = () => {
|
|
|
- openDialog("dialogShare", shareLink.value);
|
|
|
+ openDialog('dialogShare', shareLink.value);
|
|
|
};
|
|
|
|
|
|
const userGetOut = (item, i) => {
|
|
|
socket.value &&
|
|
|
- socket.value.emit("action", {
|
|
|
- type: "getout",
|
|
|
+ socket.value.emit('action', {
|
|
|
+ type: 'getout',
|
|
|
data: {
|
|
|
id: item.UserId,
|
|
|
},
|
|
@@ -335,9 +245,7 @@ const setUserWords = (res) => {
|
|
|
if (res.userId == user_info.value.UserId) {
|
|
|
user_info.value.IsWords = res.words;
|
|
|
Dialog.toast({
|
|
|
- content: !user_info.value.IsWords
|
|
|
- ? `主持人设置了禁言`
|
|
|
- : `主持人已解除禁言`,
|
|
|
+ content: !user_info.value.IsWords ? `主持人设置了禁言` : `主持人已解除禁言`,
|
|
|
});
|
|
|
}
|
|
|
};
|
|
@@ -348,9 +256,9 @@ const handleMuteVideo = () => {
|
|
|
|
|
|
const handleMuteAduio = () => {
|
|
|
audioMuted.value = !audioMuted.value;
|
|
|
- if (role.value == "leader") {
|
|
|
- socket.value.emit("action", {
|
|
|
- type: "users-muted",
|
|
|
+ if (role.value == 'leader') {
|
|
|
+ socket.value.emit('action', {
|
|
|
+ type: 'users-muted',
|
|
|
muted: audioMuted.value,
|
|
|
userId: user_info.value.UserId,
|
|
|
});
|
|
@@ -359,12 +267,10 @@ const handleMuteAduio = () => {
|
|
|
|
|
|
const setUserMuted = (res) => {
|
|
|
if (res.userId) {
|
|
|
- if (res.userId == user_info.value.UserId && role.value == "customer") {
|
|
|
+ if (res.userId == user_info.value.UserId && role.value == 'customer') {
|
|
|
user_info.value.IsMuted = res.muted;
|
|
|
Dialog.toast({
|
|
|
- content: !user_info.value.IsMuted
|
|
|
- ? `主持人设置了开麦`
|
|
|
- : `主持人设置了静音`,
|
|
|
+ content: !user_info.value.IsMuted ? `主持人设置了开麦` : `主持人设置了静音`,
|
|
|
});
|
|
|
disableMic.value = res.muted;
|
|
|
audioMuted.value = res.muted;
|
|
@@ -375,8 +281,8 @@ const setUserMuted = (res) => {
|
|
|
};
|
|
|
|
|
|
const setAllMuted = (data) => {
|
|
|
- console.log(data, "IsMuted");
|
|
|
- socket.value.emit("action", { type: "users-muted", muted: data });
|
|
|
+ console.log(data, 'IsMuted');
|
|
|
+ socket.value.emit('action', { type: 'users-muted', muted: data });
|
|
|
};
|
|
|
|
|
|
const onAllMuted = (res) => {
|
|
@@ -387,18 +293,16 @@ const onAllMuted = (res) => {
|
|
|
return tempArr;
|
|
|
}, []);
|
|
|
|
|
|
- if (role.value == "leader") {
|
|
|
+ if (role.value == 'leader') {
|
|
|
all_mute_mic.value = res.muted;
|
|
|
}
|
|
|
|
|
|
user_list.value.forEach((item) => {
|
|
|
user_info.value.IsMuted = res.muted;
|
|
|
item.IsMuted = res.muted;
|
|
|
- if (role.value == "customer") {
|
|
|
+ if (role.value == 'customer') {
|
|
|
Dialog.toast({
|
|
|
- content: !user_info.value.IsMuted
|
|
|
- ? `主持人设置了开麦`
|
|
|
- : `主持人设置了静音`,
|
|
|
+ content: !user_info.value.IsMuted ? `主持人设置了开麦` : `主持人设置了静音`,
|
|
|
});
|
|
|
disableMic.value = res.muted;
|
|
|
audioMuted.value = res.muted;
|
|
@@ -408,7 +312,7 @@ const onAllMuted = (res) => {
|
|
|
|
|
|
//用戶加入
|
|
|
const setUserJoin = async (res) => {
|
|
|
- console.log("有人进来了", res);
|
|
|
+ console.log('有人进来了', res);
|
|
|
// self.user_info = res.user;
|
|
|
user_list.value = res.members.reduce(function (tempArr, item) {
|
|
|
if (tempArr.findIndex((ele) => ele.UserId === item.UserId) === -1) {
|
|
@@ -418,17 +322,18 @@ const setUserJoin = async (res) => {
|
|
|
}, []);
|
|
|
// self.chekcLeaderInfo();
|
|
|
let name = res.user.Nickname;
|
|
|
- if (res.user.Role == "leader") {
|
|
|
- name = "主持人";
|
|
|
+ if (res.user.Role == 'leader') {
|
|
|
+ name = '主持人';
|
|
|
Dialog.toast({ content: `主持人进入房间` });
|
|
|
- socket.value.emit("action", { type: "user-init" });
|
|
|
+ socket.value.emit('action', { type: 'user-init' });
|
|
|
+ store.commit('rtc/setAvatar',res.user.Avatar)
|
|
|
}
|
|
|
let data = {
|
|
|
role: res.user.Role,
|
|
|
mode: mode.value,
|
|
|
Nickname: name,
|
|
|
UserId: res.user.UserId,
|
|
|
- text: "进入房间",
|
|
|
+ text: '进入房间',
|
|
|
};
|
|
|
if (role.value == "leader") {
|
|
|
chatList.value.push(data);
|
|
@@ -445,7 +350,7 @@ const onDrawUndo = async () => {
|
|
|
app.Connect.paint.undo();
|
|
|
canUndo.value = app.Connect.paint.records.length > 0;
|
|
|
|
|
|
- console.log(app.Connect.paint.records, "app.Connect.paint.records");
|
|
|
+ console.log(app.Connect.paint.records, 'app.Connect.paint.records');
|
|
|
};
|
|
|
|
|
|
// 畫筆開啟
|
|
@@ -454,15 +359,15 @@ const onDraw = async (status) => {
|
|
|
if (isBrushes.value) {
|
|
|
await getApp().Connect.paint.show({
|
|
|
role: role.value,
|
|
|
- paint: role.value == "leader" ? true : false,
|
|
|
+ paint: role.value == 'leader' ? true : false,
|
|
|
});
|
|
|
- if (role.value == "leader") {
|
|
|
- socket.value.emit("action", { type: "user-paint", open: true });
|
|
|
+ if (role.value == 'leader') {
|
|
|
+ socket.value.emit('action', { type: 'user-paint', open: true });
|
|
|
}
|
|
|
} else {
|
|
|
await getApp().Connect.paint.hide();
|
|
|
- if (role.value == "leader") {
|
|
|
- socket.value.emit("action", { type: "user-paint", open: false });
|
|
|
+ if (role.value == 'leader') {
|
|
|
+ socket.value.emit('action', { type: 'user-paint', open: false });
|
|
|
}
|
|
|
}
|
|
|
};
|
|
@@ -471,14 +376,14 @@ const onDraw = async (status) => {
|
|
|
const onFocus = () => {
|
|
|
showInput.value = true;
|
|
|
nextTick(() => {
|
|
|
- let input_msg = document.getElementById("input_msg");
|
|
|
+ let input_msg = document.getElementById('input_msg');
|
|
|
input_msg.focus();
|
|
|
});
|
|
|
};
|
|
|
|
|
|
//發彈幕
|
|
|
const sendText = async () => {
|
|
|
- if (text.value == "") {
|
|
|
+ if (text.value == '') {
|
|
|
return;
|
|
|
}
|
|
|
let data = {
|
|
@@ -489,8 +394,8 @@ const sendText = async () => {
|
|
|
text: text.value,
|
|
|
};
|
|
|
socket.value &&
|
|
|
- socket.value.emit("action", {
|
|
|
- type: "danmumsg",
|
|
|
+ socket.value.emit('action', {
|
|
|
+ type: 'danmumsg',
|
|
|
data,
|
|
|
});
|
|
|
|
|
@@ -498,7 +403,7 @@ const sendText = async () => {
|
|
|
await nextTick();
|
|
|
try {
|
|
|
chatAutoScroll();
|
|
|
- let input_msg = document.getElementById("input_msg");
|
|
|
+ let input_msg = document.getElementById('input_msg');
|
|
|
input_msg.blur();
|
|
|
} catch (error) {}
|
|
|
closeInput();
|
|
@@ -507,8 +412,8 @@ const sendText = async () => {
|
|
|
//接收消息
|
|
|
const setReceiveMsg = async (res) => {
|
|
|
console.log(res);
|
|
|
- if (res.role == "leader") {
|
|
|
- res.Nickname = "主持人";
|
|
|
+ if (res.role == 'leader') {
|
|
|
+ res.Nickname = '主持人';
|
|
|
}
|
|
|
chatList.value.push(res);
|
|
|
await nextTick();
|
|
@@ -520,7 +425,7 @@ const setReceiveMsg = async (res) => {
|
|
|
// 關閉輸入框
|
|
|
const closeInput = () => {
|
|
|
showInput.value = false;
|
|
|
- text.value = "";
|
|
|
+ text.value = '';
|
|
|
};
|
|
|
|
|
|
// 開啟成員
|
|
@@ -538,20 +443,20 @@ const closeMember = () => {
|
|
|
};
|
|
|
|
|
|
const openDialog = (str, link) => {
|
|
|
- emit("openDialog", str, link);
|
|
|
+ emit('openDialog', str, link);
|
|
|
};
|
|
|
|
|
|
const onMemberMuted = (item) => {
|
|
|
item.IsMuted = !item.IsMuted;
|
|
|
- socket.value.emit("action", {
|
|
|
- type: "users-muted",
|
|
|
+ socket.value.emit('action', {
|
|
|
+ type: 'users-muted',
|
|
|
muted: item.IsMuted,
|
|
|
userId: item.UserId,
|
|
|
});
|
|
|
};
|
|
|
|
|
|
const onMemberLeave = async (res) => {
|
|
|
- console.log("有人离开了", res);
|
|
|
+ console.log('有人离开了', res);
|
|
|
user_list.value = res.members.reduce(function (tempArr, item) {
|
|
|
if (tempArr.findIndex((ele) => ele.UserId === item.UserId) === -1) {
|
|
|
tempArr.push(item);
|
|
@@ -559,8 +464,8 @@ const onMemberLeave = async (res) => {
|
|
|
return tempArr;
|
|
|
}, []);
|
|
|
let name = res.user.Nickname;
|
|
|
- if (res.user.Role == "leader") {
|
|
|
- name = "主持人";
|
|
|
+ if (res.user.Role == 'leader') {
|
|
|
+ name = '主持人';
|
|
|
Dialog.toast({ content: `主持人离开了房间` });
|
|
|
}
|
|
|
let data = {
|
|
@@ -568,7 +473,7 @@ const onMemberLeave = async (res) => {
|
|
|
mode: mode.value,
|
|
|
Nickname: name,
|
|
|
UserId: res.user.UserId,
|
|
|
- text: "离开房间",
|
|
|
+ text: '离开房间',
|
|
|
};
|
|
|
if (role.value == "leader") {
|
|
|
chatList.value.push(data);
|
|
@@ -582,8 +487,8 @@ const onMemberLeave = async (res) => {
|
|
|
|
|
|
const userCanSpeak = (item) => {
|
|
|
item.IsWords = !item.IsWords;
|
|
|
- socket.value.emit("action", {
|
|
|
- type: "users-words",
|
|
|
+ socket.value.emit('action', {
|
|
|
+ type: 'users-words',
|
|
|
words: item.IsWords,
|
|
|
userId: item.UserId,
|
|
|
});
|
|
@@ -591,7 +496,7 @@ const userCanSpeak = (item) => {
|
|
|
|
|
|
const onGetOuT = (data) => {
|
|
|
if (data.id == user_info.value.UserId) {
|
|
|
- emit("closeSocket");
|
|
|
+ emit('closeSocket');
|
|
|
Dialog.toast({ content: `您已被移除` });
|
|
|
}
|
|
|
};
|
|
@@ -599,42 +504,54 @@ const onGetOuT = (data) => {
|
|
|
watch(
|
|
|
user_list,
|
|
|
() => {
|
|
|
- if (role.value == "leader") {
|
|
|
- all_mute_mic.value = !user_list.value.some(
|
|
|
- (item) => !item.IsMuted && item.Role == "customer"
|
|
|
- );
|
|
|
+ if (role.value == 'leader') {
|
|
|
+ all_mute_mic.value = !user_list.value.some((item) => !item.IsMuted && item.Role == 'customer');
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
deep: true,
|
|
|
}
|
|
|
);
|
|
|
+const showAvatar = ref(false);
|
|
|
|
|
|
const startFollow = (app) => {
|
|
|
- app.Connect.follow.start({ follow: role.value == "customer" });
|
|
|
-
|
|
|
- store.commit(
|
|
|
- "rtc/setUserId",
|
|
|
- browser.getURLParam("vruserId") ||
|
|
|
- `user_${role.value}${Math.floor(Math.random() * 100000000)}`
|
|
|
- );
|
|
|
- store.commit(
|
|
|
- "rtc/setRoomId",
|
|
|
- browser.getURLParam("roomId") ||
|
|
|
- `room_${Math.floor(Math.random() * 100000000)}`
|
|
|
- );
|
|
|
-
|
|
|
- socket.value.on("connect", (e) => {
|
|
|
- socket.value.emit("join", {
|
|
|
+ app.Connect.follow.start({ follow: role.value == 'customer' });
|
|
|
+
|
|
|
+ store.commit('rtc/setUserId', browser.getURLParam('vruserId') || `user_${role.value}${Math.floor(Math.random() * 100000000)}`);
|
|
|
+ store.commit('rtc/setRoomId', browser.getURLParam('roomId') || `room_${Math.floor(Math.random() * 100000000)}`);
|
|
|
+
|
|
|
+ socket.value.on('connect', (e) => {
|
|
|
+ let params = {
|
|
|
userId: userId.value,
|
|
|
roomId: roomId.value,
|
|
|
- role: role.value || "leader",
|
|
|
- nickname: browser.getURLParam("name"),
|
|
|
- });
|
|
|
+ role: role.value || 'leader',
|
|
|
+ nickname: browser.getURLParam('name'),
|
|
|
+ // avatar: leaderAvatar.value,
|
|
|
+ };
|
|
|
+ if (role.value == 'leader') {
|
|
|
+ params.avatar = leaderAvatar.value;
|
|
|
+ }
|
|
|
+ socket.value.emit('join', params);
|
|
|
});
|
|
|
|
|
|
+ const leaderInfo = ref({});
|
|
|
// 加入房間成功
|
|
|
- socket.value.on("join", (data) => {
|
|
|
+ socket.value.on('join', (data) => {
|
|
|
+ // leaderInfo.value = data.members.filter((item) => item.Role == 'leader');
|
|
|
+
|
|
|
+ if (role.value == 'customer') {
|
|
|
+ data.members.forEach((item) => {
|
|
|
+ if (item.Role == 'leader') {
|
|
|
+ leaderInfo.value = item;
|
|
|
+ showAvatar.value = true;
|
|
|
+ store.commit('rtc/setAvatar', leaderInfo.value.Avatar);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ showAvatar.value = true;
|
|
|
+ console.error(showAvatar.value);
|
|
|
+ }
|
|
|
+
|
|
|
let meblist = data.members.reduce(function (tempArr, item) {
|
|
|
if (tempArr.findIndex((ele) => ele.UserId === item.UserId) === -1) {
|
|
|
tempArr.push(item);
|
|
@@ -642,17 +559,17 @@ const startFollow = (app) => {
|
|
|
return tempArr;
|
|
|
}, []);
|
|
|
|
|
|
- if (meblist.length > 50 && role.value == "customer") {
|
|
|
+ if (meblist.length > 50 && role.value == 'customer') {
|
|
|
Dialog.toast({ content: `房间已满员` });
|
|
|
- emit("closeSocket");
|
|
|
+ emit('closeSocket');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
connectStatus.value = 1;
|
|
|
- if (role.value == "customer") {
|
|
|
- socket.value.emit("action", { type: "ask-currentscene" });
|
|
|
+ if (role.value == 'customer') {
|
|
|
+ socket.value.emit('action', { type: 'ask-currentscene' });
|
|
|
setTimeout(() => {
|
|
|
- socket.value.emit("action", { type: "user-init" });
|
|
|
+ socket.value.emit('action', { type: 'user-init' });
|
|
|
}, 1500);
|
|
|
|
|
|
if (data.user.IsMuted) {
|
|
@@ -677,63 +594,63 @@ const startFollow = (app) => {
|
|
|
//更新分享鏈接
|
|
|
shareLink.value = getUrl(window.location.href, [
|
|
|
{
|
|
|
- key: "mode",
|
|
|
+ key: 'mode',
|
|
|
val: mode.value,
|
|
|
},
|
|
|
{
|
|
|
- key: "name",
|
|
|
- val: "",
|
|
|
+ key: 'name',
|
|
|
+ val: '',
|
|
|
},
|
|
|
{
|
|
|
- key: "vruserId",
|
|
|
- val: "",
|
|
|
+ key: 'vruserId',
|
|
|
+ val: '',
|
|
|
},
|
|
|
{
|
|
|
- key: "role",
|
|
|
- val: "customer",
|
|
|
+ key: 'role',
|
|
|
+ val: 'customer',
|
|
|
},
|
|
|
{
|
|
|
- key: "roomId",
|
|
|
+ key: 'roomId',
|
|
|
val: user_info.value.RoomId,
|
|
|
},
|
|
|
]);
|
|
|
|
|
|
- let tmp = "";
|
|
|
+ let tmp = '';
|
|
|
|
|
|
- if (user_info.value.Role == "leader") {
|
|
|
+ if (user_info.value.Role == 'leader') {
|
|
|
tmp = getUrl(window.location.href, [
|
|
|
{
|
|
|
- key: "roomId",
|
|
|
+ key: 'roomId',
|
|
|
val: user_info.value.RoomId,
|
|
|
},
|
|
|
{
|
|
|
- key: "vruserId",
|
|
|
+ key: 'vruserId',
|
|
|
val: user_info.value.UserId,
|
|
|
},
|
|
|
]);
|
|
|
} else {
|
|
|
tmp = getUrl(window.location.href, [
|
|
|
{
|
|
|
- key: "vruserId",
|
|
|
+ key: 'vruserId',
|
|
|
val: user_info.value.UserId,
|
|
|
},
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
- store.commit("rtc/setRole", user_info.value.Role);
|
|
|
+ store.commit('rtc/setRole', user_info.value.Role);
|
|
|
history.replaceState(null, null, tmp);
|
|
|
});
|
|
|
|
|
|
- socket.value.on("action", (data) => {
|
|
|
- console.log(data, "=============");
|
|
|
- if (data.type == "error") {
|
|
|
- Dialog.toast({ content: `房间未找到`, type: "error" });
|
|
|
- emit("closeSocket");
|
|
|
- } else if (data.type == "danmumsg") {
|
|
|
+ socket.value.on('action', (data) => {
|
|
|
+ console.log(data, '=============');
|
|
|
+ if (data.type == 'error') {
|
|
|
+ Dialog.toast({ content: `房间未找到`, type: 'error' });
|
|
|
+ emit('closeSocket');
|
|
|
+ } else if (data.type == 'danmumsg') {
|
|
|
setReceiveMsg(data.data);
|
|
|
- } else if (data.type == "getout") {
|
|
|
+ } else if (data.type == 'getout') {
|
|
|
onGetOuT(data.data);
|
|
|
- } else if (data.type == "user-init") {
|
|
|
+ } else if (data.type == 'user-init') {
|
|
|
app.Connect.follow.sync();
|
|
|
if (role.value == "leader") {
|
|
|
setTimeout(() => {
|
|
@@ -759,39 +676,39 @@ const startFollow = (app) => {
|
|
|
}
|
|
|
} else if (data.type == "user-paint") {
|
|
|
onDraw(data.open);
|
|
|
- if (role.value == "customer") {
|
|
|
+ if (role.value == 'customer') {
|
|
|
if (data.open) {
|
|
|
Dialog.toast({ content: `主持人开启画笔` });
|
|
|
} else {
|
|
|
Dialog.toast({ content: `主持人关闭画笔` });
|
|
|
}
|
|
|
}
|
|
|
- } else if (data.type == "user-join") {
|
|
|
+ } else if (data.type == 'user-join') {
|
|
|
setUserJoin(data);
|
|
|
- } else if (data.type == "users-muted") {
|
|
|
+ } else if (data.type == 'users-muted') {
|
|
|
setUserMuted(data);
|
|
|
//閉麥
|
|
|
- } else if (data.type == "users-words") {
|
|
|
+ } else if (data.type == 'users-words') {
|
|
|
setUserWords(data);
|
|
|
//禁言
|
|
|
- } else if (data.type == "user-leave") {
|
|
|
+ } else if (data.type == 'user-leave') {
|
|
|
// 房間解散
|
|
|
onMemberLeave(data);
|
|
|
- } else if (data.type == "leader-dismiss") {
|
|
|
- emit("closeSocket");
|
|
|
+ } else if (data.type == 'leader-dismiss') {
|
|
|
+ emit('closeSocket');
|
|
|
Dialog.toast({ content: `主持人已解散房间` });
|
|
|
- } else if (data.type == "tagclick") {
|
|
|
- if (role.value == "customer") {
|
|
|
+ } else if (data.type == 'tagclick') {
|
|
|
+ if (role.value == 'customer') {
|
|
|
let item = tags.value.find((item) => item.sid == data.data.sid);
|
|
|
store.commit("tag/setTagClickType", {
|
|
|
type: "goodlist",
|
|
|
data: item,
|
|
|
});
|
|
|
}
|
|
|
- } else if (data.type == "tagclose") {
|
|
|
- if (role.value == "customer") {
|
|
|
- store.commit("tag/setTagClickType", {
|
|
|
- type: "",
|
|
|
+ } else if (data.type == 'tagclose') {
|
|
|
+ if (role.value == 'customer') {
|
|
|
+ store.commit('tag/setTagClickType', {
|
|
|
+ type: '',
|
|
|
data: {},
|
|
|
});
|
|
|
}
|
|
@@ -804,20 +721,16 @@ const startFollow = (app) => {
|
|
|
socket.value.emit("action", {
|
|
|
type: "answer-currentscene",
|
|
|
data: {
|
|
|
- scene: browser.getURLParam("m"),
|
|
|
- pose: browser.getURLParam("pose"),
|
|
|
+ scene: browser.getURLParam('m'),
|
|
|
+ pose: browser.getURLParam('pose'),
|
|
|
},
|
|
|
});
|
|
|
}
|
|
|
- } else if (data.type == "answer-currentscene") {
|
|
|
- if (role.value == "customer") {
|
|
|
- if (data.data.scene != browser.getURLParam("m")) {
|
|
|
- let url1 = browser.replaceQueryString(
|
|
|
- window.location.href,
|
|
|
- "m",
|
|
|
- data.data.scene
|
|
|
- );
|
|
|
- let url = browser.replaceQueryString(url1, "pose", data.data.pose);
|
|
|
+ } else if (data.type == 'answer-currentscene') {
|
|
|
+ if (role.value == 'customer') {
|
|
|
+ if (data.data.scene != browser.getURLParam('m')) {
|
|
|
+ let url1 = browser.replaceQueryString(window.location.href, 'm', data.data.scene);
|
|
|
+ let url = browser.replaceQueryString(url1, 'pose', data.data.pose);
|
|
|
location.replace(url);
|
|
|
}
|
|
|
}
|
|
@@ -825,45 +738,59 @@ const startFollow = (app) => {
|
|
|
});
|
|
|
|
|
|
// 同屏帶看
|
|
|
- socket.value.on("sync", (data) => {
|
|
|
- if (role.value == "customer") {
|
|
|
+ socket.value.on('sync', (data) => {
|
|
|
+ if (role.value == 'customer') {
|
|
|
app.Connect.follow.receive(data);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 畫筆
|
|
|
- socket.value.on("paint", (data) => {
|
|
|
- if (role.value == "customer") {
|
|
|
+ socket.value.on('paint', (data) => {
|
|
|
+ if (role.value == 'customer') {
|
|
|
app.Connect.paint.receive(data);
|
|
|
}
|
|
|
});
|
|
|
};
|
|
|
let onfollowData = (data) => {
|
|
|
if (isJoined.value) {
|
|
|
- socket.value.emit("sync", data);
|
|
|
+ socket.value.emit('sync', data);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
let onfollowPaint = async (data) => {
|
|
|
canUndo.value = (await getApp().Connect.paint.records.length) > 0;
|
|
|
- socket.value.emit("paint", data);
|
|
|
+ socket.value.emit('paint', data);
|
|
|
};
|
|
|
|
|
|
onMounted(async () => {
|
|
|
let app = await getApp();
|
|
|
startFollow(app);
|
|
|
- app.Connect.follow.on("data", onfollowData);
|
|
|
- app.Connect.paint.on("data", onfollowPaint);
|
|
|
+ app.Connect.follow.on('data', onfollowData);
|
|
|
+ app.Connect.paint.on('data', onfollowPaint);
|
|
|
});
|
|
|
|
|
|
onUnmounted(async () => {
|
|
|
let app = await getApp();
|
|
|
- app.Connect.follow.off("data", onfollowData);
|
|
|
- app.Connect.follow.off("data", onfollowData);
|
|
|
+ app.Connect.follow.off('data', onfollowData);
|
|
|
+ app.Connect.follow.off('data', onfollowData);
|
|
|
});
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
+.avatar-box {
|
|
|
+ width: 1.7067rem;
|
|
|
+ height: 1.7067rem;
|
|
|
+ margin: 0.56rem auto 0;
|
|
|
+ border: 1px #ed5d18 solid;
|
|
|
+ border-radius: 50%;
|
|
|
+ // background-image: url('@/assets/images/avatar_default.jpg');
|
|
|
+ background-size: 100%;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ position: fixed;
|
|
|
+ top: 0.2667rem;
|
|
|
+ left: 0.2667rem;
|
|
|
+ z-index: 1000;
|
|
|
+}
|
|
|
#PageRtcLive {
|
|
|
position: absolute;
|
|
|
left: 0;
|
|
@@ -935,13 +862,11 @@ onUnmounted(async () => {
|
|
|
.disSpeakBtn {
|
|
|
width: 0.533333rem;
|
|
|
height: 0.533333rem;
|
|
|
- background: url(~@/assets/images/rtcLive/pop-up_screen_on@2x.png)
|
|
|
- no-repeat;
|
|
|
+ background: url(~@/assets/images/rtcLive/pop-up_screen_on@2x.png) no-repeat;
|
|
|
background-size: 100% 100%;
|
|
|
cursor: pointer;
|
|
|
&.dis {
|
|
|
- background: url(~@/assets/images/rtcLive/pop-up_screen_off@2x.png)
|
|
|
- no-repeat;
|
|
|
+ background: url(~@/assets/images/rtcLive/pop-up_screen_off@2x.png) no-repeat;
|
|
|
background-size: 100% 100%;
|
|
|
}
|
|
|
}
|