消息
This commit is contained in:
172
TUIKit/plugins/extension-server/callkit.ts
Normal file
172
TUIKit/plugins/extension-server/callkit.ts
Normal file
@@ -0,0 +1,172 @@
|
||||
import TUICore, { TUIConstants, TUILogin } from '@tencentcloud/tui-core';
|
||||
import { TUIGlobal } from '@tencentcloud/universal-api';
|
||||
|
||||
export default class CallkitPluginServer {
|
||||
constructor() {
|
||||
// Listen for successful login
|
||||
TUICore.registerEvent(TUIConstants.TUILogin.EVENT.LOGIN_STATE_CHANGED, TUIConstants.TUILogin.EVENT_SUB_KEY.USER_LOGIN_SUCCESS, this);
|
||||
// Native plugin callkit registers call service
|
||||
TUICore.registerService(TUIConstants.TUICalling.SERVICE.NAME, this);
|
||||
// Native plugin callkit registration extension
|
||||
TUICore.registerExtension(TUIConstants.TUIChat.EXTENSION.INPUT_MORE.EXT_ID, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for the successful notification of TUILogin.login and then log in with callkit
|
||||
*/
|
||||
public onNotifyEvent(eventName: string, subKey: string) {
|
||||
if (eventName === TUIConstants.TUILogin.EVENT.LOGIN_STATE_CHANGED) {
|
||||
let SDKAppID, userID, userSig, context;
|
||||
switch (subKey) {
|
||||
case TUIConstants.TUILogin.EVENT_SUB_KEY.USER_LOGIN_SUCCESS:
|
||||
context = TUILogin.getContext();
|
||||
SDKAppID = context.SDKAppID;
|
||||
userID = context.userID;
|
||||
userSig = context.userSig;
|
||||
TUIGlobal.$TUICallKit && TUIGlobal.$TUICallKit.login({
|
||||
SDKAppID,
|
||||
userID,
|
||||
userSig,
|
||||
}, (res: any) => {
|
||||
if (res.code === 0) {
|
||||
console.log('TUICallkit login success!');
|
||||
// Floating window function
|
||||
TUIGlobal.$TUICallKit.enableFloatWindow(true);
|
||||
} else {
|
||||
console.error(`TUICallkit login failed,${res.msg}`);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Native plugin callkit implements onGetExtension method
|
||||
*/
|
||||
public onGetExtension(extensionID: string, params: Record<string, any>) {
|
||||
if (!TUIGlobal.$TUICallKit) {
|
||||
console.warn('请检查原生插件 TencentCloud-TUICallKit 是否已集成');
|
||||
return [];
|
||||
}
|
||||
if (extensionID === TUIConstants.TUIChat.EXTENSION.INPUT_MORE.EXT_ID) {
|
||||
const list = [];
|
||||
const voiceCallExtension = {
|
||||
weight: 1000,
|
||||
text: '语音通话',
|
||||
icon: 'https://web.sdk.qcloud.com/component/TUIKit/assets/call.png',
|
||||
data: {
|
||||
name: 'voiceCall',
|
||||
},
|
||||
listener: {
|
||||
onClicked: (options: any) => {
|
||||
this.setCallExtension(options);
|
||||
},
|
||||
},
|
||||
};
|
||||
const videoCallExtension = {
|
||||
weight: 900,
|
||||
text: '视频通话',
|
||||
icon: 'https://web.sdk.qcloud.com/component/TUIKit/assets/call-video-reverse.svg',
|
||||
data: {
|
||||
name: 'videoCall',
|
||||
},
|
||||
listener: {
|
||||
onClicked: (options: any) => {
|
||||
this.setCallExtension(options);
|
||||
},
|
||||
},
|
||||
};
|
||||
if (!(params as any)?.filterVoice) {
|
||||
list.push(voiceCallExtension);
|
||||
}
|
||||
if (!(params as any)?.filterVideo) {
|
||||
list.push(videoCallExtension);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Native plugin callkit implements onCall method
|
||||
*/
|
||||
public onCall(method: string, params: any) {
|
||||
if (!TUIGlobal.$TUICallKit) {
|
||||
console.warn('请检查原生插件 TencentCloud-TUICallKit 是否已集成');
|
||||
return;
|
||||
}
|
||||
if (method === TUIConstants.TUICalling.SERVICE.METHOD.START_CALL) {
|
||||
const { groupID = undefined, userIDList = [], type, callParams } = params;
|
||||
if (groupID) {
|
||||
TUIGlobal.$TUICallKit.groupCall({
|
||||
groupID,
|
||||
userIDList,
|
||||
callMediaType: type,
|
||||
callParams,
|
||||
}, (res: any) => {
|
||||
if (res.code === 0) {
|
||||
console.log('TUICallkit groupCall success');
|
||||
} else {
|
||||
console.error(`TUICallkit groupCall failed,${res.msg}`);
|
||||
}
|
||||
});
|
||||
} else if (userIDList.length === 1) {
|
||||
TUIGlobal.$TUICallKit.call(
|
||||
{
|
||||
userID: userIDList[0],
|
||||
callMediaType: type,
|
||||
callParams,
|
||||
},
|
||||
(res: any) => {
|
||||
if (res.code === 0) {
|
||||
console.log('TUICallkit call success');
|
||||
} else {
|
||||
console.log(`TUICallkit call failed,${res.msg}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public setCallExtension(options: any) {
|
||||
const { groupID = undefined, userIDList = [], type, callParams } = options;
|
||||
try {
|
||||
if (groupID) {
|
||||
// group call
|
||||
TUIGlobal.$TUICallKit.groupCall({
|
||||
groupID,
|
||||
userIDList,
|
||||
callMediaType: type,
|
||||
callParams,
|
||||
}, (res: any) => {
|
||||
if (res.code === 0) {
|
||||
console.log('TUICallkit groupCall success');
|
||||
} else {
|
||||
console.log(`TUICallkit groupCall failed,${res.msg}`);
|
||||
}
|
||||
});
|
||||
} else if (userIDList.length === 1) {
|
||||
// 1v1 call
|
||||
TUIGlobal.$TUICallKit.call(
|
||||
{
|
||||
userID: userIDList[0],
|
||||
callMediaType: type,
|
||||
callParams,
|
||||
},
|
||||
(res: any) => {
|
||||
if (res.code === 0) {
|
||||
console.log('TUICallkit call success');
|
||||
} else {
|
||||
console.log(`TUICallkit call failed,${res.msg}`);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
TUIGlobal.showToast({
|
||||
title: '拨打失败!',
|
||||
icon: 'error',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
37
TUIKit/plugins/plugin-components/index.ts
Normal file
37
TUIKit/plugins/plugin-components/index.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import TUIChatEngine, { IMessageModel } from '@tencentcloud/chat-uikit-engine';
|
||||
import { isCustomerServicePluginMessage } from './message-customer/index';
|
||||
import { JSONToObject } from '../../utils/type-check';
|
||||
|
||||
export function isCallMessage(message: IMessageModel): boolean {
|
||||
const payloadData = JSONToObject(message?.payload?.data);
|
||||
if (payloadData?.businessID === 1 && payloadData?.data) {
|
||||
const payloadDataData = JSONToObject(payloadData.data);
|
||||
if (payloadDataData.businessID === 'av_call') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isRoomSignalingMessage(message: IMessageModel): boolean {
|
||||
const payloadData = JSONToObject(message?.payload?.data);
|
||||
return (
|
||||
payloadData?.businessID === 'ROOM_INVITE_ACTION'
|
||||
|| payloadData?.businessID === 'tuikit_engine_room'
|
||||
);
|
||||
}
|
||||
|
||||
export function isRoomCardMessage(message: IMessageModel): boolean {
|
||||
const payloadData = JSONToObject(message?.payload?.data);
|
||||
return payloadData?.businessID === 'group_room_message';
|
||||
}
|
||||
|
||||
export function isPluginMessage(message: IMessageModel): boolean {
|
||||
return (
|
||||
message.type === TUIChatEngine.TYPES.MSG_CUSTOM
|
||||
&& (isCallMessage(message)
|
||||
|| isCustomerServicePluginMessage(message as any)
|
||||
|| isRoomCardMessage(message)
|
||||
|| isRoomSignalingMessage(message))
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="isCallMessage && conversationType === TYPES.CONV_C2C"
|
||||
class="call"
|
||||
:class="['call-' + conversationType, message.flow === 'out' && 'call-reverse']"
|
||||
@click="callAgain"
|
||||
>
|
||||
<div :class="['icon', message.flow === 'out' && callInfo.type === 2 && 'icon-reverse']">
|
||||
<Icon :file="callInfo.icon" />
|
||||
</div>
|
||||
<span class="call-content">{{ custom }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TUICore, { TUIConstants } from '@tencentcloud/tui-core';
|
||||
import TUIChatEngine from '@tencentcloud/chat-uikit-engine';
|
||||
import { computed, ref } from '../../../adapter-vue';
|
||||
import { JSONToObject } from '../../../utils/index';
|
||||
import Icon from '../../../components/common/Icon.vue';
|
||||
import callVideoSVG from '../../../assets/icon/call-video.svg';
|
||||
import callVoiceSVG from '../../../assets/icon/call-voice.svg';
|
||||
import OfflinePushInfoManager, { PUSH_SCENE } from '../../../components/TUIChat/offlinePushInfoManager/index';
|
||||
const props = defineProps({
|
||||
message: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
signalingInfo: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
customContent: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const TYPES = ref(TUIChatEngine.TYPES);
|
||||
const isCallMessage = computed(() => props.signalingInfo != null);
|
||||
const callInfo = computed((): { type: number; icon: string } => {
|
||||
const callType = JSONToObject(props.signalingInfo?.data)?.call_type;
|
||||
switch (callType) {
|
||||
case 1:
|
||||
return {
|
||||
type: 1,
|
||||
icon: callVoiceSVG,
|
||||
};
|
||||
case 2:
|
||||
return {
|
||||
type: 2,
|
||||
icon: callVideoSVG,
|
||||
};
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return {
|
||||
type: 0,
|
||||
icon: '',
|
||||
};
|
||||
});
|
||||
const conversationType = computed(() => props.message?.conversationType);
|
||||
const custom = computed(() => props.customContent?.custom);
|
||||
|
||||
const callAgain = () => {
|
||||
if (conversationType.value === TUIChatEngine.TYPES.CONV_C2C) {
|
||||
const userID = props.message?.flow === 'out' ? props.message?.to : props.message?.from;
|
||||
TUICore.callService({
|
||||
serviceName: TUIConstants.TUICalling.SERVICE.NAME,
|
||||
method: TUIConstants.TUICalling.SERVICE.METHOD.START_CALL,
|
||||
params: {
|
||||
userIDList: [userID],
|
||||
type: callInfo?.value?.type,
|
||||
callParams: {
|
||||
offlinePushInfo: OfflinePushInfoManager.getOfflinePushInfo(PUSH_SCENE.CALL),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.call {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
&-C2C {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-GROUP {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&-content {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
&-reverse {
|
||||
flex-direction: row-reverse;
|
||||
|
||||
.icon-reverse {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.call-content {
|
||||
padding-right: 5px;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="isCallMessage && conversationType === TYPES.CONV_GROUP"
|
||||
:class="{ 'blink-text': isBlink }"
|
||||
>
|
||||
{{ custom }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from '../../../adapter-vue';
|
||||
import TUIChatEngine, { IMessageModel } from '@tencentcloud/chat-uikit-engine';
|
||||
|
||||
interface IProps {
|
||||
message: IMessageModel;
|
||||
signalingInfo: any;
|
||||
customContent: any;
|
||||
blinkMessageIDList?: string[];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
message: () => ({}) as IMessageModel,
|
||||
signalingInfo: () => ({}),
|
||||
customContent: () => ({}),
|
||||
blinkMessageIDList: () => [],
|
||||
});
|
||||
|
||||
const TYPES = TUIChatEngine.TYPES;
|
||||
const isCallMessage = computed(() => !!props.signalingInfo);
|
||||
const conversationType = computed(() => props.message?.conversationType);
|
||||
const custom = computed(() => props.customContent?.custom);
|
||||
|
||||
const isBlink = computed(() => {
|
||||
if (props.message?.ID) {
|
||||
return props.blinkMessageIDList?.includes(props.message.ID);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@keyframes blink-text {
|
||||
50% {
|
||||
color: #ff9c19;
|
||||
}
|
||||
}
|
||||
|
||||
.blink-text {
|
||||
animation: blinkText 1s linear 3;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,5 @@
|
||||
import {
|
||||
isCustomerServicePluginMessage,
|
||||
isMessageInvisible as isCustomServiceMessageInvisible,
|
||||
} from '../../../tui-customer-service-plugin';
|
||||
export { isCustomerServicePluginMessage, isCustomServiceMessageInvisible };
|
||||
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<TUICustomerServicePlugin :message="props.message" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { IMessageModel } from '@tencentcloud/chat-uikit-engine';
|
||||
import TUICustomerServicePlugin from '../../../tui-customer-service-plugin/index.vue';
|
||||
interface IProps {
|
||||
message: IMessageModel;
|
||||
}
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
message: () => ({} as IMessageModel),
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
/* stylelint-disable-next-line no-empty-source */
|
||||
</style>
|
||||
123
TUIKit/plugins/plugin-components/message-plugin-layout.vue
Normal file
123
TUIKit/plugins/plugin-components/message-plugin-layout.vue
Normal file
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<div class="message-plugin">
|
||||
<!-- The following is displayed in the form of messageTip -->
|
||||
<div
|
||||
v-if="props.showStyle === 'tip'"
|
||||
class="message-plugin-tip"
|
||||
>
|
||||
<slot name="messageTip" />
|
||||
</div>
|
||||
<!-- The following is displayed in the form of messageBubble -->
|
||||
<div
|
||||
v-else-if="props.showStyle === 'bubble'"
|
||||
class="message-plugin-bubble-content"
|
||||
@longpress="handleToggleMessageItem($event, messageModel, true)"
|
||||
@click.prevent.right="handleToggleMessageItem($event, messageModel)"
|
||||
@touchstart="handleH5LongPress($event, messageModel, 'touchstart')"
|
||||
@touchend="handleH5LongPress($event, messageModel, 'touchend')"
|
||||
@mouseover="handleH5LongPress($event, messageModel, 'touchend')"
|
||||
>
|
||||
<MessageBubble
|
||||
:messageItem="messageModel"
|
||||
:content="messageModel.getMessageContent()"
|
||||
:blinkMessageIDList="props.blinkMessageIDList"
|
||||
:classNameList="props.bubbleClassNameList"
|
||||
@resendMessage="resendMessage(messageModel)"
|
||||
>
|
||||
<!-- web message-bubble is a named slot, content area slotName is messageElement -->
|
||||
<template #messageElement>
|
||||
<slot
|
||||
v-if="!isUniFrameWork"
|
||||
name="messageBubble"
|
||||
/>
|
||||
</template>
|
||||
<!-- uni-app message-bubble is an anonymous slot, no slotName -->
|
||||
<slot
|
||||
v-if="isUniFrameWork"
|
||||
name="messageBubble"
|
||||
/>
|
||||
</MessageBubble>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from '../../adapter-vue';
|
||||
import { TUIStore, IMessageModel } from '@tencentcloud/chat-uikit-engine';
|
||||
import MessageBubble from '../../components/TUIChat/message-list/message-elements/message-bubble.vue';
|
||||
import { isUniFrameWork } from '../../utils/env';
|
||||
|
||||
interface IProps {
|
||||
message: IMessageModel;
|
||||
showStyle: string;
|
||||
bubbleClassNameList?: string[];
|
||||
blinkMessageIDList?: string[];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
message: () => ({} as IMessageModel),
|
||||
showStyle: '',
|
||||
bubbleClassNameList: () => [] as string[],
|
||||
blinkMessageIDList: () => [] as string[],
|
||||
});
|
||||
|
||||
const emits = defineEmits(['resendMessage', 'handleToggleMessageItem', 'handleH5LongPress']);
|
||||
const messageModel = computed(() => TUIStore.getMessageModel(props.message?.ID));
|
||||
|
||||
// The following is for external interaction such as messageTool, no special processing is required, do not change
|
||||
const resendMessage = (message: IMessageModel) => {
|
||||
emits('resendMessage', message);
|
||||
};
|
||||
const handleToggleMessageItem = (e: any, message: IMessageModel, isLongpress = false) => {
|
||||
emits('handleToggleMessageItem', e, message, isLongpress);
|
||||
};
|
||||
const handleH5LongPress = (e: any, message: IMessageModel, type: string) => {
|
||||
emits('handleH5LongPress', e, message, type);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.message-plugin-tip {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
overflow-wrap: anywhere;
|
||||
display: flex;
|
||||
place-content: center center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
margin: 0 10px 10px;
|
||||
}
|
||||
|
||||
.message-tip-highlight {
|
||||
animation: highlight 1000ms infinite;
|
||||
|
||||
@keyframes highlight {
|
||||
50% {
|
||||
color: #ff9c19;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes highlight {
|
||||
50% {
|
||||
color: #ff9c19;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.message-bubble-room) {
|
||||
.message-bubble-main-content {
|
||||
.message-body {
|
||||
.message-body-main {
|
||||
.message-body-content {
|
||||
&.content-in,
|
||||
&.content-out {
|
||||
background-color: transparent;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
106
TUIKit/plugins/plugin-components/message-plugin.vue
Normal file
106
TUIKit/plugins/plugin-components/message-plugin.vue
Normal file
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<MessagePluginLayout
|
||||
:message="props.message"
|
||||
:showStyle="pluginMessageType.showStyle"
|
||||
:bubbleClassNameList="[pluginMessageType.pluginType === 'room' ? 'message-bubble-room':'']"
|
||||
@resendMessage="resendMessage"
|
||||
@handleToggleMessageItem="handleToggleMessageItem"
|
||||
@handleH5LongPress="handleH5LongPress"
|
||||
>
|
||||
<template #messageTip>
|
||||
<MessageCallGroup
|
||||
:message="props.message"
|
||||
:signalingInfo="messageSignalingInfo"
|
||||
:customContent="messageCustomContent"
|
||||
:blinkMessageIDList="props.blinkMessageIDList"
|
||||
/>
|
||||
</template>
|
||||
<template #messageBubble>
|
||||
<MessageCallC2C
|
||||
v-if="pluginMessageType.pluginType === 'call'"
|
||||
:message="props.message"
|
||||
:signalingInfo="messageSignalingInfo"
|
||||
:customContent="messageCustomContent"
|
||||
/>
|
||||
<MessageCustomerService
|
||||
v-if="pluginMessageType.pluginType === 'customer'"
|
||||
:message="props.message"
|
||||
/>
|
||||
<MessageRoom
|
||||
v-if="pluginMessageType.pluginType === 'room'"
|
||||
:message="props.message"
|
||||
/>
|
||||
</template>
|
||||
</MessagePluginLayout>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from '../../adapter-vue';
|
||||
import { TUIStore } from '@tencentcloud/chat-uikit-engine';
|
||||
import TUIChatEngine, { IMessageModel } from '@tencentcloud/chat-uikit-engine';
|
||||
import {
|
||||
isCustomerServicePluginMessage,
|
||||
isCustomServiceMessageInvisible,
|
||||
} from './message-customer/index';
|
||||
import { isCallMessage, isRoomCardMessage } from './index';
|
||||
import MessagePluginLayout from './message-plugin-layout.vue';
|
||||
import MessageCallGroup from './message-call/message-call-group.vue';
|
||||
import MessageCallC2C from './message-call/message-call-c2c.vue';
|
||||
import MessageCustomerService from './message-customer/message-customer-service.vue';
|
||||
// If TUIRoom is not integrated, please introduce the following path
|
||||
import MessageRoom from './message-room/message-room-default.vue';
|
||||
// After integrating TUIRoom, please comment the above path and open the following path to import
|
||||
// import MessageRoom from './message-room/message-room.vue';
|
||||
|
||||
interface IProps {
|
||||
message: IMessageModel;
|
||||
blinkMessageIDList?: string[];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
message: () => ({} as IMessageModel),
|
||||
blinkMessageIDList: () => [] as string[],
|
||||
});
|
||||
|
||||
const emits = defineEmits(['resendMessage', 'handleToggleMessageItem', 'handleH5LongPress']);
|
||||
const messageModel = computed(() => TUIStore.getMessageModel(props.message.ID));
|
||||
const messageSignalingInfo = computed(() => messageModel?.value?.getSignalingInfo());
|
||||
const messageCustomContent = computed(() => messageModel?.value?.getMessageContent());
|
||||
|
||||
const pluginMessageType = computed<{ pluginType: string; showStyle: string }>(() => {
|
||||
let typeObj = { pluginType: '', showStyle: '' };
|
||||
if (isCallMessage(messageModel.value)) {
|
||||
typeObj = {
|
||||
pluginType: 'call',
|
||||
showStyle:
|
||||
messageModel.value?.conversationType === TUIChatEngine.TYPES.CONV_GROUP ? 'tip' : 'bubble',
|
||||
};
|
||||
} else if (isRoomCardMessage(messageModel.value)) {
|
||||
typeObj = {
|
||||
pluginType: 'room',
|
||||
showStyle: 'bubble',
|
||||
};
|
||||
} else if (isCustomerServicePluginMessage(messageModel.value)) {
|
||||
typeObj = {
|
||||
pluginType: 'customer',
|
||||
showStyle: isCustomServiceMessageInvisible(messageModel.value) ? '' : 'bubble',
|
||||
};
|
||||
}
|
||||
return typeObj;
|
||||
});
|
||||
|
||||
// The following are for external interaction such as messageTool, no special processing is required, please do not touch
|
||||
const resendMessage = (message: IMessageModel) => {
|
||||
emits('resendMessage', message);
|
||||
};
|
||||
const handleToggleMessageItem = (e: any, message: IMessageModel, isLongpress = false) => {
|
||||
emits('handleToggleMessageItem', e, message, isLongpress);
|
||||
};
|
||||
const handleH5LongPress = (e: any, message: IMessageModel, type: string) => {
|
||||
emits('handleH5LongPress', e, message, type);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* stylelint-disable-next-line no-empty-source */
|
||||
</style>
|
||||
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div
|
||||
:class="[
|
||||
'room-default',
|
||||
isUniFrameWork && 'room-default-uni',
|
||||
props.message.flow === 'in' ? 'room-default-in' : 'room-default-out',
|
||||
]"
|
||||
>
|
||||
{{ TUITranslateService.t("message.custom.自定义消息") }}
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { TUITranslateService, IMessageModel } from '@tencentcloud/chat-uikit-engine';
|
||||
import { isUniFrameWork } from '../../../utils/env';
|
||||
|
||||
interface IProps {
|
||||
message: IMessageModel;
|
||||
}
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
message: () => ({} as IMessageModel),
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.room-default {
|
||||
padding: 12px;
|
||||
font-size: 14px;
|
||||
|
||||
&-uni{
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&-in {
|
||||
background: #fbfbfb;
|
||||
border-radius: 0 10px;
|
||||
}
|
||||
|
||||
&-out {
|
||||
background: #dceafd;
|
||||
border-radius: 10px 0 10px 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,19 @@
|
||||
<!-- eslint-disable vue/valid-template-root -->
|
||||
<template>
|
||||
<RoomMessageCard :message="props.message" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { IMessageModel } from '@tencentcloud/chat-uikit-engine';
|
||||
import { RoomMessageCard } from '@tencentcloud/roomkit-web-vue3';
|
||||
|
||||
interface IProps {
|
||||
message: IMessageModel;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
message: () => ({} as IMessageModel),
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
/* stylelint-disable-next-line no-empty-source */
|
||||
</style>
|
||||
Reference in New Issue
Block a user