Teamlinker/code/client/src/business/controller/app/meeting/meetingOperation.vue
sx1989827 bc9a907ab1 dev
2023-09-10 08:09:03 +08:00

198 lines
6.3 KiB
Vue

<template>
<a-row style="width: 100%;height: 100%;display: flex;align-items: center;justify-content: space-between;padding:0 5px;box-sizing: border-box">
<a-space>
<a-button size="large" type="text" v-if="me" @click="onToggleAudio">
<template #icon>
<sicon size="20" color="" name="Ant" type="audio" v-if="me.audio"></sicon>
<sicon size="20" color="gray" name="Ant" type="audio static" v-else></sicon>
</template>
</a-button>
<a-button size="large" type="text" v-if="me" @click="onToggleVideo">
<template #icon>
<sicon size="20" color="" name="Ant" type="video" v-if="me.video"></sicon>
<sicon size="20" color="gray" name="Ant" type="video-mute" v-else></sicon>
</template>
</a-button>
</a-space>
<a-space>
<a-popover>
<a-button size="large" type="text">
<template #icon>
<sicon size="20" color="" name="Ant" type="add user"></sicon>
</template>
</a-button>
<template #content>
<a-descriptions :title="$t('controller.app.meeting.meetingOperation.meetingInfo')" :data="[
{
label:'Meeting Id',
value:currentMeeting.id
},
{
label:'Password',
value:currentMeeting.password
}
]" v-if="currentMeeting"></a-descriptions>
<a-divider :margin="10"></a-divider>
<a-form :model="form" auto-label-width>
<a-form-item field="memberIds" :label="$t('util.users')" required>
<a-select style="width: 100%" :placeholder="$t('placeholder.typeUserOrTeam')" multiple allow-search allow-clear v-model="form.memberIds" @search="onSearch">
<a-optgroup :label="$t('util.team')" v-if="selectList && selectList.teams && selectList.teams.length>0">
<a-option v-for="item in selectList.teams" :value="item.id">
<a-row style="align-items: center">
<a-avatar :image-url="item.photo" :size="24"></a-avatar>&nbsp;
{{item.name}}
</a-row>
</a-option>
</a-optgroup>
<a-optgroup :label="$t('util.user')" v-if="selectList && selectList.users && selectList.users.length>0">
<a-option v-for="item in selectList.users" :value="item.id">
<a-row style="align-items: center">
<a-avatar :image-url="item.photo" :size="24"></a-avatar>&nbsp;
{{item.name}}
</a-row>
</a-option>
</a-optgroup>
</a-select>
</a-form-item>
<a-form-item>
<a-button html-type="button" type="primary" @click="onInvite">{{$t("util.invite")}}</a-button>
</a-form-item>
</a-form>
</template>
</a-popover>
<a-button size="large" type="text" @click="onToggleScreen">
<template #icon>
<sicon size="20" color="" name="Ant" type="desktop" v-if="!isScreen"></sicon>
<sicon size="20" color="red" name="Ant" type="desktop" v-else></sicon>
</template>
</a-button>
</a-space>
<a-space>
<a-button size="mini" type="primary" @click="onLeave">
{{$t("util.leave")}}
</a-button>
<a-button size="mini" type="primary" status="danger" v-if="me?.permission===ECommon_Meeting_Room_Permission.PRESENTER" @click="onEnd">
{{$t("util.end")}}
</a-button>
</a-space>
</a-row>
</template>
<script setup lang="ts">
import {ECommon_Meeting_Room_Permission, ICommon_Model_Meeting_Room} from "../../../../../../common/model/meeting_room";
import {OrganizationUserItem} from "./type";
import {apiOrganization, DCSType} from "../../../common/request/request";
import {Dialog} from "../../../common/component/dialog/dialog";
import {Message} from "@arco-design/web-vue";
import {getCurrentNavigator, getRootNavigatorRef} from "../../../../teamOS/common/component/navigator/navigator";
import {MeetingClient} from "../../../common/component/meeting/client";
import {getCurrentInstance, reactive, ref} from "vue";
import {SocketIOClient} from "../../../common/socket/socket";
import {ECommon_Socket_Type} from "../../../../../../common/socket/types";
import {ICommon_Route_Res_Organization_FilterUserAndTeam} from "../../../../../../common/routes/response";
import {ECommon_Model_Organization_Member_Type} from "../../../../../../common/model/organization";
import {useI18n} from "vue-i18n";
const props=defineProps<{
me:OrganizationUserItem,
currentMeeting:DCSType<ICommon_Model_Meeting_Room>,
meetingClient:MeetingClient
}>()
const form=reactive({
memberIds:[]
})
const selectList=ref<ICommon_Route_Res_Organization_FilterUserAndTeam>()
const navigator=getCurrentNavigator()
const root=getRootNavigatorRef()
const appContext=getCurrentInstance().appContext
const socket=SocketIOClient.getSocket(ECommon_Socket_Type.MEETING).getSocket()
let isScreen=ref(false)
const {t}=useI18n()
props.meetingClient.onScreenStopped=() => {
isScreen.value=false
}
const onToggleAudio=()=>{
if(props.me.audio) {
props.meetingClient.pause("audio")
props.me.audio=false
} else {
props.meetingClient.resume("audio")
props.me.audio=true
}
}
const onToggleVideo=()=>{
if(props.me.video) {
props.meetingClient.pause("video")
props.me.video=false
} else {
props.meetingClient.resume("video")
props.me.video=true
}
}
const onLeave=async ()=>{
let ret=await Dialog.confirm(root.value,appContext,t("tip.leaveMeeting"))
if(ret) {
await props.meetingClient.leave()
navigator.pop()
}
}
const onEnd=async ()=>{
let ret=await Dialog.confirm(root.value,appContext,t("tip.endMeeting"))
if(ret) {
let res=await props.meetingClient.end()
if(res) {
navigator.pop()
} else {
Message.error(t("tip.operationFailed"))
}
}
}
const onSearch=async (keyword:string)=>{
if(!keyword) {
return
}
let ret=await apiOrganization.filterAvailableUserAndTeam({
keyword:keyword,
exceptMe:1
})
if(ret?.code==0) {
selectList.value=ret.data
}
}
const onInvite=async()=>{
if(form.memberIds.length>0) {
socket.emit("meeting_invite",form.memberIds.map(item=>{
return {
id:item,
type:selectList.value.users.map(item=>item.id).includes(item)?ECommon_Model_Organization_Member_Type.USER:ECommon_Model_Organization_Member_Type.TEAM
}
}))
form.memberIds=[]
}
}
const onToggleScreen=async ()=>{
if(!isScreen.value) {
let ret=await props.meetingClient.startShare()
if(ret===false) {
Message.error(t("tip.cannotShare"))
} else if(ret===true) {
isScreen.value=true
}
} else {
props.meetingClient.stopShare()
isScreen.value=false
}
}
</script>
<style scoped>
</style>