QAQ
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index.esm'
|
||||
import ToolbarItemContainer from '../toolbar-item-container/index.vue'
|
||||
import custom from '../../../../assets/icon/telephone-icon.svg'
|
||||
import videoIcon from '../../../../assets/icon/video-icon.svg'
|
||||
import { isUniFrameWork } from '../../../../utils/env'
|
||||
import { computed } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { type IConversationModel } from '@tencentcloud/chat-uikit-engine-lite'
|
||||
|
||||
CallLib.init({});
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
/** 通话状态: 0 语音 1 视频 */
|
||||
@@ -26,28 +29,97 @@
|
||||
|
||||
const emits = defineEmits(['onDialogPopupShowOrHide'])
|
||||
|
||||
const container = ref()
|
||||
const closeDialog = () => {
|
||||
container?.value?.toggleDialogDisplay(false)
|
||||
}
|
||||
|
||||
const onDialogShow = () => {
|
||||
console.log('弹出窗口')
|
||||
console.log(props.currentConversation)
|
||||
// emits('onDialogPopupShowOrHide', true)
|
||||
emits('onDialogPopupShowOrHide', true)
|
||||
}
|
||||
|
||||
const onDialogClose = () => {
|
||||
console.log('关闭窗口')
|
||||
// emits('onDialogPopupShowOrHide', false)
|
||||
emits('onDialogPopupShowOrHide', false)
|
||||
}
|
||||
|
||||
CallLib.onCallReceived(res => {
|
||||
console.log(res)
|
||||
console.log(
|
||||
'Engine:OnCallReceived=>' + '监听通话呼入, 目标id=>',
|
||||
res.data.targetId
|
||||
)
|
||||
})
|
||||
|
||||
CallLib.onCallConnected(res => {
|
||||
console.log(res)
|
||||
console.log(
|
||||
'Engine:OnCallConnected=>' +
|
||||
'已建立通话通话接通时,通过回调 onCallConnected 通知当前 call 的详细信息',
|
||||
res
|
||||
)
|
||||
})
|
||||
|
||||
CallLib.onRemoteUserJoined(res => {
|
||||
console.log(
|
||||
'Engine:OnRemoteUserJoined=>' +
|
||||
'主叫端拨出电话,被叫端收到请求后,加入通话,被叫端Id为=>',
|
||||
res.data.userId
|
||||
)
|
||||
})
|
||||
|
||||
CallLib.onCallDisconnected(res => {
|
||||
console.log(
|
||||
'Engine:OnCallDisconnected=>' + '挂断成功, 挂断原因=>',
|
||||
res.data.reason
|
||||
)
|
||||
})
|
||||
|
||||
const onDial = () => {
|
||||
const data = props.currentConversation.userProfile
|
||||
// data.userID
|
||||
CallLib.enableMicrophone(true)
|
||||
CallLib.startSingleCall(data.userID, 0, '邀请您进行语音通话')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ToolbarItemContainer
|
||||
ref="container"
|
||||
needBottomPopup
|
||||
:iconFile="evaluateIcon"
|
||||
:iconWidth="isUniFrameWork ? '34px' : '20px'"
|
||||
:iconHeight="isUniFrameWork ? '34px' : '20px'"
|
||||
:title="isType ? '语音通话' : '视频通话'"
|
||||
@onDialogShow="onDialogShow"
|
||||
@onDialogClose="onDialogClose"
|
||||
></ToolbarItemContainer>
|
||||
>
|
||||
<view class="box-index">
|
||||
<view class="top-icon">
|
||||
<uni-icons
|
||||
type="back"
|
||||
color="#ffffff"
|
||||
size="42rpx"
|
||||
@click.stop="closeDialog"
|
||||
></uni-icons>
|
||||
</view>
|
||||
|
||||
<button @click.stop="onDial">拨打</button>
|
||||
|
||||
<button
|
||||
@click.stop="
|
||||
() => {
|
||||
CallLib.enableMicrophone(true)
|
||||
CallLib.accept()
|
||||
}
|
||||
"
|
||||
>
|
||||
接听
|
||||
</button>
|
||||
</view>
|
||||
</ToolbarItemContainer>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss" src="./style/index.scss"></style>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
.box-index {
|
||||
height: 100vh;
|
||||
background: #161616;
|
||||
|
||||
.top-icon {
|
||||
padding-top: var(--status-bar-height);
|
||||
padding-left: 20rpx;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100rpx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,15 @@ import TUIChatEngine, {
|
||||
StoreName,
|
||||
TUITranslateService,
|
||||
IConversationModel,
|
||||
SendMessageParams,
|
||||
} from '@tencentcloud/chat-uikit-engine-lite';
|
||||
import { Toast, TOAST_TYPE } from '../../common/Toast/index';
|
||||
import { isEnabledMessageReadReceiptGlobal } from '../utils/utils';
|
||||
import { ITipTapEditorContent } from '../../../interface';
|
||||
import { enableSampleTaskStatus } from '../../../utils/enableSampleTaskStatus';
|
||||
import OfflinePushInfoManager, { IOfflinePushInfoCreateParams } from '../offlinePushInfoManager/index';
|
||||
SendMessageParams
|
||||
} from '@tencentcloud/chat-uikit-engine-lite'
|
||||
import { Toast, TOAST_TYPE } from '../../common/Toast/index'
|
||||
import { isEnabledMessageReadReceiptGlobal } from '../utils/utils'
|
||||
import { ITipTapEditorContent } from '../../../interface'
|
||||
import { enableSampleTaskStatus } from '../../../utils/enableSampleTaskStatus'
|
||||
import OfflinePushInfoManager, {
|
||||
IOfflinePushInfoCreateParams
|
||||
} from '../offlinePushInfoManager/index'
|
||||
|
||||
export const sendMessageErrorCodeMap: Map<number, string> = new Map([
|
||||
[3123, '文本包含本地审核拦截词'],
|
||||
@@ -21,26 +23,32 @@ export const sendMessageErrorCodeMap: Map<number, string> = new Map([
|
||||
[8001, '消息长度超出限制,消息长度不要超过12K'],
|
||||
[80001, '消息或者资料中文本存在敏感内容,发送失败'],
|
||||
[80004, '消息中图片存在敏感内容,发送失败'],
|
||||
[10017, '您已被禁止聊天'],
|
||||
]);
|
||||
[10017, '您已被禁止聊天']
|
||||
])
|
||||
|
||||
export const createOfflinePushInfo = (conversation: IConversationModel) => {
|
||||
const androidInfo = {};
|
||||
const apnsInfo = {};
|
||||
const userInfo = TUIStore.getData(StoreName.USER, 'userProfile');
|
||||
export const createOfflinePushInfo = (
|
||||
conversation: IConversationModel
|
||||
) => {
|
||||
const androidInfo = {}
|
||||
const apnsInfo = {}
|
||||
const userInfo = TUIStore.getData(StoreName.USER, 'userProfile')
|
||||
const entity = {
|
||||
sender: conversation.type === TUIChatEngine.TYPES.CONV_GROUP ? conversation.groupProfile?.groupID : userInfo.userID,
|
||||
sender:
|
||||
conversation.type === TUIChatEngine.TYPES.CONV_GROUP
|
||||
? conversation.groupProfile?.groupID
|
||||
: userInfo.userID,
|
||||
nickName: userInfo.nick,
|
||||
chatType: conversation.type === TUIChatEngine.TYPES.CONV_GROUP ? 2 : 1,
|
||||
chatType:
|
||||
conversation.type === TUIChatEngine.TYPES.CONV_GROUP ? 2 : 1,
|
||||
version: 1,
|
||||
action: 1,
|
||||
};
|
||||
action: 1
|
||||
}
|
||||
return {
|
||||
extension: JSON.stringify({ entity }),
|
||||
androidInfo,
|
||||
apnsInfo,
|
||||
};
|
||||
};
|
||||
apnsInfo
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function only processes five message types: Text/TextAt/Image/Video/File
|
||||
@@ -49,112 +57,143 @@ export const createOfflinePushInfo = (conversation: IConversationModel) => {
|
||||
*/
|
||||
export const sendMessages = async (
|
||||
messageList: ITipTapEditorContent[],
|
||||
currentConversation: IConversationModel,
|
||||
currentConversation: IConversationModel
|
||||
) => {
|
||||
// In case of messageJumping, the sent message is automatically cleared and returns to the bottom
|
||||
if (TUIStore.getData(StoreName.CHAT, 'messageSource')) {
|
||||
TUIStore.update(StoreName.CHAT, 'messageSource', undefined);
|
||||
TUIStore.update(StoreName.CHAT, 'messageSource', undefined)
|
||||
}
|
||||
messageList?.forEach(async (content: ITipTapEditorContent) => {
|
||||
try {
|
||||
const options: SendMessageParams = {
|
||||
to: currentConversation?.groupProfile?.groupID || currentConversation?.userProfile?.userID,
|
||||
to:
|
||||
currentConversation?.groupProfile?.groupID ||
|
||||
currentConversation?.userProfile?.userID,
|
||||
conversationType: currentConversation?.type as any,
|
||||
payload: {},
|
||||
needReadReceipt: isEnabledMessageReadReceiptGlobal(),
|
||||
};
|
||||
needReadReceipt: isEnabledMessageReadReceiptGlobal()
|
||||
}
|
||||
// handle message typing
|
||||
let textMessageContent;
|
||||
let textMessageContent
|
||||
const sendMessageOptions = {
|
||||
offlinePushInfo: {},
|
||||
};
|
||||
offlinePushInfo: {}
|
||||
}
|
||||
const offlinePushInfoCreateParams: IOfflinePushInfoCreateParams = {
|
||||
conversation: currentConversation,
|
||||
payload: content.payload,
|
||||
messageType: '',
|
||||
};
|
||||
messageType: ''
|
||||
}
|
||||
switch (content?.type) {
|
||||
case 'text':
|
||||
textMessageContent = JSON.parse(JSON.stringify(content.payload?.text));
|
||||
textMessageContent = JSON.parse(
|
||||
JSON.stringify(content.payload?.text)
|
||||
)
|
||||
// Do not send empty messages
|
||||
if (!textMessageContent) {
|
||||
break;
|
||||
break
|
||||
}
|
||||
options.payload = {
|
||||
text: textMessageContent,
|
||||
};
|
||||
offlinePushInfoCreateParams.messageType = TUIChatEngine.TYPES.MSG_TEXT;
|
||||
sendMessageOptions.offlinePushInfo = OfflinePushInfoManager.create(offlinePushInfoCreateParams);
|
||||
text: textMessageContent
|
||||
}
|
||||
offlinePushInfoCreateParams.messageType =
|
||||
TUIChatEngine.TYPES.MSG_TEXT
|
||||
sendMessageOptions.offlinePushInfo =
|
||||
OfflinePushInfoManager.create(offlinePushInfoCreateParams)
|
||||
if (content.payload?.atUserList) {
|
||||
options.payload.atUserList = content.payload.atUserList;
|
||||
await TUIChatService.sendTextAtMessage(options, sendMessageOptions);
|
||||
options.payload.atUserList = content.payload.atUserList
|
||||
await TUIChatService.sendTextAtMessage(
|
||||
options,
|
||||
sendMessageOptions
|
||||
)
|
||||
} else {
|
||||
try {
|
||||
console.log('发送成功')
|
||||
await TUIChatService.sendTextMessage(options, sendMessageOptions);
|
||||
} catch (err) {
|
||||
console.log('发送失败,对方不是你的好友')
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'image':
|
||||
options.payload = {
|
||||
file: content.payload?.file,
|
||||
};
|
||||
offlinePushInfoCreateParams.messageType = TUIChatEngine.TYPES.MSG_IMAGE;
|
||||
sendMessageOptions.offlinePushInfo = OfflinePushInfoManager.create(offlinePushInfoCreateParams);
|
||||
await TUIChatService.sendImageMessage(options, sendMessageOptions);
|
||||
break;
|
||||
file: content.payload?.file
|
||||
}
|
||||
offlinePushInfoCreateParams.messageType =
|
||||
TUIChatEngine.TYPES.MSG_IMAGE
|
||||
sendMessageOptions.offlinePushInfo =
|
||||
OfflinePushInfoManager.create(offlinePushInfoCreateParams)
|
||||
await TUIChatService.sendImageMessage(
|
||||
options,
|
||||
sendMessageOptions
|
||||
)
|
||||
break
|
||||
case 'video':
|
||||
options.payload = {
|
||||
file: content.payload?.file,
|
||||
};
|
||||
offlinePushInfoCreateParams.messageType = TUIChatEngine.TYPES.MSG_VIDEO;
|
||||
sendMessageOptions.offlinePushInfo = OfflinePushInfoManager.create(offlinePushInfoCreateParams);
|
||||
await TUIChatService.sendVideoMessage(options, sendMessageOptions);
|
||||
break;
|
||||
file: content.payload?.file
|
||||
}
|
||||
offlinePushInfoCreateParams.messageType =
|
||||
TUIChatEngine.TYPES.MSG_VIDEO
|
||||
sendMessageOptions.offlinePushInfo =
|
||||
OfflinePushInfoManager.create(offlinePushInfoCreateParams)
|
||||
await TUIChatService.sendVideoMessage(
|
||||
options,
|
||||
sendMessageOptions
|
||||
)
|
||||
break
|
||||
case 'file':
|
||||
options.payload = {
|
||||
file: content.payload?.file,
|
||||
};
|
||||
offlinePushInfoCreateParams.messageType = TUIChatEngine.TYPES.MSG_FILE;
|
||||
sendMessageOptions.offlinePushInfo = OfflinePushInfoManager.create(offlinePushInfoCreateParams);
|
||||
await TUIChatService.sendFileMessage(options, sendMessageOptions);
|
||||
break;
|
||||
file: content.payload?.file
|
||||
}
|
||||
offlinePushInfoCreateParams.messageType =
|
||||
TUIChatEngine.TYPES.MSG_FILE
|
||||
sendMessageOptions.offlinePushInfo =
|
||||
OfflinePushInfoManager.create(offlinePushInfoCreateParams)
|
||||
await TUIChatService.sendFileMessage(
|
||||
options,
|
||||
sendMessageOptions
|
||||
)
|
||||
break
|
||||
default:
|
||||
break;
|
||||
break
|
||||
}
|
||||
enableSampleTaskStatus('sendMessage');
|
||||
enableSampleTaskStatus('sendMessage')
|
||||
} catch (error: any) {
|
||||
Toast({
|
||||
message: sendMessageErrorCodeMap.get(error?.code)
|
||||
? TUITranslateService.t(`TUIChat.${sendMessageErrorCodeMap.get(error.code) as string}`)
|
||||
? TUITranslateService.t(
|
||||
`TUIChat.${
|
||||
sendMessageErrorCodeMap.get(error.code) as string
|
||||
}`
|
||||
)
|
||||
: error?.message,
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
// If the message fails to be sent and the message is a reference message, clear the reference message information
|
||||
if (TUIStore.getData(StoreName.CHAT, 'quoteMessage')) {
|
||||
TUIStore.update(StoreName.CHAT, 'quoteMessage', {});
|
||||
TUIStore.update(StoreName.CHAT, 'quoteMessage', {})
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
export const handleMessageWithTyping = (cloudCustomData: any) => {
|
||||
if (!cloudCustomData) {
|
||||
cloudCustomData = {};
|
||||
cloudCustomData = {}
|
||||
}
|
||||
cloudCustomData.messageFeature = {
|
||||
needTyping: 1,
|
||||
version: 1,
|
||||
};
|
||||
return cloudCustomData;
|
||||
};
|
||||
|
||||
export const sendTyping = (inputContentEmpty: boolean, inputBlur: boolean) => {
|
||||
if (!inputContentEmpty && !inputBlur) {
|
||||
TUIChatService.enterTypingState();
|
||||
} else {
|
||||
TUIChatService.leaveTypingState();
|
||||
version: 1
|
||||
}
|
||||
};
|
||||
return cloudCustomData
|
||||
}
|
||||
|
||||
export const sendTyping = (
|
||||
inputContentEmpty: boolean,
|
||||
inputBlur: boolean
|
||||
) => {
|
||||
if (!inputContentEmpty && !inputBlur) {
|
||||
TUIChatService.enterTypingState()
|
||||
} else {
|
||||
TUIChatService.leaveTypingState()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user