330 lines
9.8 KiB
Vue
330 lines
9.8 KiB
Vue
<template>
|
|
<div v-if="callInfoContextValue.callStatus !== CallStatus.IDLE" :style="[{ visibility: floatWindowContextValue.isFloatWindow ? 'hidden' : '' }]" id="tuicallkit-id" :class="[bodyStyle, miniMizedDeskStyle, mobileVideoStyle, mobileAudioStyle]">
|
|
<SingleCall v-if="!callInfoContextValue.isGroupCall" class="singCall"></SingleCall>
|
|
<GroupCall v-else class="singCall"></GroupCall>
|
|
<AISubtitle />
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref, onMounted, reactive, onUnmounted, toRefs, watchEffect, provide } from '../adapter-vue';
|
|
import SingleCall from './components/SingleCall/SingleCall.vue';
|
|
import GroupCall from './components/GroupCall/GroupCall.vue';
|
|
import { TUIGlobal, TUIStore, StoreName, TUICallKitAPI, NAME, CallStatus, CallMediaType, VideoDisplayMode, VideoResolution } from '../TUICallService/index';
|
|
import {
|
|
CallInfoContextKey,
|
|
CallerUserInfoContextKey,
|
|
UserInfoExcludeVolumeContextKey,
|
|
FloatWindowContextKey,
|
|
TCallerUserInfoValue,
|
|
TFloatWindowContextValue,
|
|
CustomUIConfigContextKey,
|
|
translateContextKey,
|
|
} from './context';
|
|
import { isEmpty } from './util/isEmpty';
|
|
const isMobile = !TUIGlobal.isPC;
|
|
const bodyStyle = isMobile ? 'TUICallKit-mobile transition-animation' : 'TUICallKit-desktop';
|
|
const miniMizedDeskStyle = ref('');
|
|
const mobileAudioStyle = ref('');
|
|
const mobileVideoStyle = ref('');
|
|
const isShowFloatWindow = ref(false);
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
beforeCalling?: (...args: any[]) => void;
|
|
afterCalling?: (...args: any[]) => void;
|
|
onMinimized?: (...args: any[]) => void;
|
|
onMessageSentByMe?: (...args: any[]) => void;
|
|
kickedOut?: (...args: any[]) => void;
|
|
statusChanged?: (...args: any[]) => void;
|
|
allowedMinimized?: boolean;
|
|
allowedFullScreen?: boolean;
|
|
videoDisplayMode?: string;
|
|
videoResolution?: string;
|
|
}>(),
|
|
{
|
|
allowedMinimized: false,
|
|
allowedFullScreen: true,
|
|
videoDisplayMode: VideoDisplayMode.COVER,
|
|
videoResolution: VideoResolution.RESOLUTION_720P,
|
|
},
|
|
);
|
|
|
|
const callStatus = ref(TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS));
|
|
const callRole = ref(TUIStore.getData(StoreName.CALL, NAME.CALL_ROLE));
|
|
const callType = ref(TUIStore.getData(StoreName.CALL, NAME.CALL_MEDIA_TYPE));
|
|
const isGroupCall = ref(TUIStore.getData(StoreName.CALL, NAME.IS_GROUP));
|
|
const isEarPhone = ref(TUIStore.getData(StoreName.CALL, NAME.IS_EAR_PHONE));
|
|
const focusElement = ref(null);
|
|
const localUserInfoExcludeVolume = ref(TUIStore.getData(StoreName.CALL, NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN));
|
|
const remoteUserListExcludeVolume = ref(TUIStore.getData(StoreName.CALL, NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST));
|
|
const callerUserInfo = ref(TUIStore.getData(StoreName.CALL, NAME.CALLER_USER_INFO));
|
|
const isFloatWindow = ref(TUIStore.getData(StoreName.CALL, NAME.IS_MINIMIZED));
|
|
const enableVirtualBackground = ref(TUIStore.getData(StoreName.CALL, NAME.ENABLE_VIRTUAL_BACKGROUND));
|
|
const isShowEnableVirtualBackground = ref(TUIStore.getData(StoreName.CALL, NAME.IS_SHOW_ENABLE_VIRTUAL_BACKGROUND));
|
|
const customUIConfigContextValue = ref(TUIStore.getData(StoreName.CALL, NAME.CUSTOM_UI_CONFIG));
|
|
const isMuteSpeaker = ref(TUIStore.getData(StoreName.CALL, NAME.IS_MUTE_SPEAKER));
|
|
const translate = ref(TUIStore.getData(StoreName.CALL, NAME.TRANSLATE));
|
|
const callInfoContextValue = reactive({
|
|
callStatus,
|
|
callRole,
|
|
callType,
|
|
isGroupCall,
|
|
isEarPhone,
|
|
focusElement,
|
|
allowedFullScreen: props.allowedFullScreen,
|
|
enableVirtualBackground,
|
|
isShowEnableVirtualBackground,
|
|
isMuteSpeaker,
|
|
});
|
|
const callerUserInfoValue: TCallerUserInfoValue = reactive({ callerUserInfo });
|
|
const userInfoExcludeVolumeContextValue = reactive({
|
|
localUserInfoExcludeVolume,
|
|
remoteUserListExcludeVolume,
|
|
});
|
|
const floatWindowContextValue: TFloatWindowContextValue = reactive({ isFloatWindow });
|
|
const translateContextValue = ref(translate);
|
|
|
|
const {
|
|
beforeCalling,
|
|
afterCalling,
|
|
onMinimized,
|
|
onMessageSentByMe,
|
|
videoDisplayMode,
|
|
videoResolution,
|
|
kickedOut,
|
|
statusChanged,
|
|
allowedMinimized,
|
|
} = toRefs(props);
|
|
|
|
const handleCallStatusChange = (value) => {
|
|
callInfoContextValue.callStatus = value;
|
|
};
|
|
const handleIsGroupChange = (value) => {
|
|
callInfoContextValue.isGroupCall = value;
|
|
};
|
|
const handleToastInfoChange = (value) => {
|
|
if (typeof value === 'object') {
|
|
const { content, type = 'info' } = value;
|
|
!isEmpty(content) && showToast(translate.value(content), type);
|
|
}
|
|
};
|
|
|
|
const handleCallMediaTypeChange = (value) => {
|
|
callInfoContextValue.callType = value;
|
|
if (isMobile && isShowFloatWindow.value) {
|
|
mobileVideoStyle.value = 'miniMized-mobile-audio';
|
|
mobileAudioStyle.value = '';
|
|
}
|
|
|
|
if (isMobile && !isShowFloatWindow.value) {
|
|
mobileAudioStyle.value = 'mobile-audio';
|
|
}
|
|
};
|
|
|
|
const handleIsMinimizedChange = (value) => {
|
|
floatWindowContextValue.isFloatWindow = value;
|
|
// 开启悬浮窗
|
|
if (value) {
|
|
if (!isMobile) {
|
|
miniMizedDeskStyle.value = 'miniMized';
|
|
} else {
|
|
if (callInfoContextValue.callType === CallMediaType.AUDIO) {
|
|
mobileAudioStyle.value = 'miniMized-mobile-audio';
|
|
} else {
|
|
mobileVideoStyle.value = 'miniMized-mobile-video';
|
|
}
|
|
}
|
|
} else {
|
|
// 关闭悬浮窗
|
|
mobileAudioStyle.value = 'mobile-audio';
|
|
miniMizedDeskStyle.value = '';
|
|
mobileVideoStyle.value = '';
|
|
}
|
|
};
|
|
|
|
const handlePermissionErrorTipChange = (data) => {
|
|
};
|
|
const handleCallRoleChange = (value) => {
|
|
callInfoContextValue.callRole = value;
|
|
};
|
|
const handleLocalUserInfoChange = (value) => {
|
|
userInfoExcludeVolumeContextValue.localUserInfoExcludeVolume = value;
|
|
};
|
|
const handleRemoteUserInfoListChange = (value) => {
|
|
userInfoExcludeVolumeContextValue.remoteUserListExcludeVolume = [...value];
|
|
};
|
|
const handleCallerUserInfoChange = (value) => {
|
|
callerUserInfoValue.callerUserInfo = value;
|
|
};
|
|
const handEarPhoneChange = (value) => {
|
|
callInfoContextValue.isEarPhone = value;
|
|
};
|
|
const handleEnableVirtualBackgroundChange = (value) => {
|
|
callInfoContextValue.enableVirtualBackground = value;
|
|
};
|
|
const handleIsShowEnableVirtualBackgroundChange = (value) => {
|
|
callInfoContextValue.isShowEnableVirtualBackground = value;
|
|
};
|
|
const handleCustomUIConfigChange = (value) => {
|
|
customUIConfigContextValue.value = value;
|
|
};
|
|
const handleMuteSpeakerChange = (value) => {
|
|
callInfoContextValue.isMuteSpeaker = value;
|
|
};
|
|
const handleTranslateChange = (value) => {
|
|
translate.value = value;
|
|
};
|
|
|
|
watchEffect(() => {
|
|
TUICallKitAPI.setCallback({
|
|
beforeCalling: beforeCalling && beforeCalling.value,
|
|
afterCalling: afterCalling && afterCalling.value,
|
|
onMinimized: onMinimized && onMinimized.value,
|
|
onMessageSentByMe: onMessageSentByMe && onMessageSentByMe.value,
|
|
kickedOut: kickedOut && kickedOut.value,
|
|
statusChanged: statusChanged && statusChanged.value,
|
|
});
|
|
});
|
|
|
|
const watchOptions = {
|
|
[NAME.CALL_STATUS]: handleCallStatusChange,
|
|
[NAME.IS_GROUP]: handleIsGroupChange,
|
|
[NAME.TOAST_INFO]: handleToastInfoChange,
|
|
[NAME.CALL_MEDIA_TYPE]: handleCallMediaTypeChange,
|
|
[NAME.SHOW_PERMISSION_TIP]: handlePermissionErrorTipChange,
|
|
[NAME.CALL_ROLE]: handleCallRoleChange,
|
|
[NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN]: handleLocalUserInfoChange,
|
|
[NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST]: handleRemoteUserInfoListChange,
|
|
[NAME.CALLER_USER_INFO]: handleCallerUserInfoChange,
|
|
[NAME.IS_EAR_PHONE]: handEarPhoneChange,
|
|
[NAME.ENABLE_VIRTUAL_BACKGROUND]: handleEnableVirtualBackgroundChange,
|
|
[NAME.IS_SHOW_ENABLE_VIRTUAL_BACKGROUND]: handleIsShowEnableVirtualBackgroundChange,
|
|
[NAME.CUSTOM_UI_CONFIG]: handleCustomUIConfigChange,
|
|
[NAME.IS_MUTE_SPEAKER]: handleMuteSpeakerChange,
|
|
[NAME.TRANSLATE]: handleTranslateChange,
|
|
};
|
|
|
|
onMounted(() => {
|
|
if(allowedMinimized.value){
|
|
TUICallKitAPI.enableFloatWindow(allowedMinimized.value)
|
|
}
|
|
TUICallKitAPI.setVideoDisplayMode(videoDisplayMode.value as any);
|
|
TUICallKitAPI.setVideoResolution(videoResolution.value as any);
|
|
TUIStore.watch(
|
|
StoreName.CALL,
|
|
watchOptions,
|
|
{
|
|
notifyRangeWhenWatch: NAME.MYSELF,
|
|
},
|
|
);
|
|
TUIStore.watch(StoreName.CALL, {
|
|
[NAME.IS_MINIMIZED]: handleIsMinimizedChange,
|
|
});
|
|
});
|
|
|
|
function showToast(value: string, type: string) {
|
|
switch (type) {
|
|
case 'info':
|
|
uni.showToast({
|
|
title: value,
|
|
icon: 'none',
|
|
});
|
|
break;
|
|
case 'error':
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
onUnmounted(async () => {
|
|
TUIStore.unwatch(StoreName.CALL, {
|
|
...watchOptions,
|
|
[NAME.IS_MINIMIZED]: handleIsMinimizedChange,
|
|
});
|
|
await TUICallKitAPI.handleExceptionExit();
|
|
});
|
|
|
|
provide(CallInfoContextKey, callInfoContextValue);
|
|
provide(CallerUserInfoContextKey, callerUserInfoValue);
|
|
provide(UserInfoExcludeVolumeContextKey, userInfoExcludeVolumeContextValue);
|
|
provide(FloatWindowContextKey, floatWindowContextValue);
|
|
provide(CustomUIConfigContextKey, customUIConfigContextValue);
|
|
provide(translateContextKey, translateContextValue);
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.TUICallKit-mobile {
|
|
|
|
width: 100vw;
|
|
height: 100vh;
|
|
|
|
.singCall {
|
|
|
|
width: 100vw;
|
|
height: 100vh;
|
|
}
|
|
}
|
|
|
|
.transition-animation {
|
|
transform: translateY(-100%);
|
|
animation: slideInDown 0.5s ease forwards;
|
|
}
|
|
|
|
@keyframes slideInDown {
|
|
from {
|
|
transform: translateY(-100%);
|
|
}
|
|
to {
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.TUICallKit-desktop {
|
|
margin: 0 auto;
|
|
position: relative;
|
|
position: relative;
|
|
border-radius: inherit;
|
|
width: 100%;
|
|
height: 100%;
|
|
color: white;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
overflow: hidden;
|
|
z-index: 12;
|
|
border-radius: 16px;
|
|
|
|
.singCall {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
|
|
.mobile-audio {
|
|
background-color: white;
|
|
}
|
|
|
|
.miniMized {
|
|
width: 168px !important;
|
|
height: 56px !important;
|
|
overflow: visible !important;
|
|
}
|
|
|
|
.miniMized-mobile-audio {
|
|
width: 72px;
|
|
height: 72px;
|
|
position: fixed;
|
|
top: 40px;
|
|
right: 40px;
|
|
}
|
|
|
|
.miniMized-mobile-video {
|
|
width: 40%;
|
|
height: 30%;
|
|
position: fixed;
|
|
top: 40px;
|
|
right: 40px;
|
|
}
|
|
</style>
|