429 lines
13 KiB
Vue
429 lines
13 KiB
Vue
<template>
|
|
<ChatHeader class="ChatHeadercss"/>
|
|
<div class="dingweizhibox"></div>
|
|
<div class="chat">
|
|
<div :class="['tui-chat', !isPC && 'tui-chat-h5']">
|
|
<div
|
|
v-if="!currentConversationID"
|
|
:class="['tui-chat-default', !isPC && 'tui-chat-h5-default']"
|
|
>
|
|
<slot />
|
|
</div>
|
|
<div v-if="currentConversationID" :class="['tui-chat', !isPC && 'tui-chat-h5']">
|
|
<Forward @toggleMultipleSelectMode="toggleMultipleSelectMode" />
|
|
<MessageList
|
|
ref="messageListRef"
|
|
:class="['tui-chat-message-list',!isPC && 'tui-chat-h5-message-list']"
|
|
:isGroup="isGroup"
|
|
:groupID="groupID"
|
|
:isNotInGroup="isNotInGroup"
|
|
:isMultipleSelectMode="isMultipleSelectMode"
|
|
@handleEditor="handleEditor"
|
|
@closeInputToolBar="() => changeToolbarDisplayType('none')"
|
|
@toggleMultipleSelectMode="toggleMultipleSelectMode"
|
|
/>
|
|
<div
|
|
v-if="isNotInGroup"
|
|
:class="{
|
|
'tui-chat-leave-group': true,
|
|
'tui-chat-leave-group-mobile': isMobile,
|
|
}"
|
|
>
|
|
{{ leaveGroupReasonText }}
|
|
</div>
|
|
<MultipleSelectPanel
|
|
v-else-if="isMultipleSelectMode"
|
|
@oneByOneForwardMessage="oneByOneForwardMessage"
|
|
@mergeForwardMessage="mergeForwardMessage"
|
|
@toggleMultipleSelectMode="toggleMultipleSelectMode"
|
|
/>
|
|
<template v-else>
|
|
<MessageInputToolbar
|
|
v-if="isInputToolbarShow"
|
|
:class="[
|
|
'tui-chat-message-input-toolbar',
|
|
!isPC && 'tui-chat-h5-message-input-toolbar',
|
|
isUniFrameWork && 'tui-chat-uni-message-input-toolbar',
|
|
]"
|
|
:displayType="inputToolbarDisplayType"
|
|
@insertEmoji="insertEmoji"
|
|
@changeToolbarDisplayType="changeToolbarDisplayType"
|
|
@scrollToLatestMessage="scrollToLatestMessage"
|
|
/>
|
|
<MessageInput
|
|
ref="messageInputRef"
|
|
:class="[
|
|
'tui-chat-message-input',
|
|
!isPC && 'tui-chat-h5-message-input',
|
|
isUniFrameWork && 'tui-chat-uni-message-input',
|
|
isWeChat && 'tui-chat-wx-message-input',
|
|
]"
|
|
:enableAt="featureConfig.InputMention"
|
|
:isMuted="false"
|
|
:muteText="TUITranslateService.t('TUIChat.您已被管理员禁言')"
|
|
:placeholder="TUITranslateService.t('TUIChat.请输入消息')"
|
|
:inputToolbarDisplayType="inputToolbarDisplayType"
|
|
@changeToolbarDisplayType="changeToolbarDisplayType"
|
|
/>
|
|
</template>
|
|
</div>
|
|
<!-- Group Management -->
|
|
<div
|
|
v-if="
|
|
!isNotInGroup &&
|
|
!isApp &&
|
|
isUniFrameWork &&
|
|
isGroup &&
|
|
headerExtensionList.length > 0
|
|
"
|
|
class="group-profile"
|
|
@click="handleGroup"
|
|
>
|
|
{{ headerExtensionList[0].text }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script lang="ts" setup>
|
|
import { ref, onMounted, onUnmounted, computed } from "../../adapter-vue";
|
|
import TUIChatEngine, {
|
|
TUITranslateService,
|
|
TUIConversationService,
|
|
TUIStore,
|
|
StoreName,
|
|
IMessageModel,
|
|
IConversationModel,
|
|
} from "@tencentcloud/chat-uikit-engine";
|
|
import TUICore, { TUIConstants, ExtensionInfo } from "@tencentcloud/tui-core";
|
|
import ChatHeader from "./chat-header/index.vue";
|
|
import MessageList from "./message-list/index.vue";
|
|
import MessageInput from "./message-input/index.vue";
|
|
import MultipleSelectPanel from "./mulitple-select-panel/index.vue";
|
|
import Forward from "./forward/index.vue";
|
|
import MessageInputToolbar from "./message-input-toolbar/index.vue";
|
|
import { isPC, isWeChat, isUniFrameWork, isMobile, isApp } from "../../utils/env";
|
|
import { ToolbarDisplayType } from "../../interface";
|
|
import TUIChatConfig from "./config";
|
|
// @Start uniapp use Chat only
|
|
import { onLoad, onUnload } from "@dcloudio/uni-app";
|
|
import { initChat, logout } from "./entry-chat-only.ts";
|
|
import { isEnabledMessageReadReceiptGlobal } from "./utils/utils";
|
|
import OfflinePushInfoManager from "./offlinePushInfoManager/index";
|
|
import { TUIChatService } from "@tencentcloud/chat-uikit-engine";
|
|
import { useCounterStore } from "@/stores/counter";
|
|
import request from "@/components/request";
|
|
import generateMsgId from "../../../components/generateMsgId.js";
|
|
const counter = useCounterStore();
|
|
|
|
let myitem = ref();
|
|
let youritem = ref();
|
|
onLoad((options) => {
|
|
initChat(options);
|
|
try{
|
|
myitem.value = JSON.parse(options.myitem);
|
|
youritem.value = JSON.parse(options.youritem);
|
|
counter.$patch({ youritem: youritem.value });
|
|
setTimeout(() => {
|
|
sendCustomMessage(myitem.value, youritem.value);
|
|
}, 1000);
|
|
}catch(e){}
|
|
});
|
|
|
|
onUnload(() => {
|
|
// Whether logout is decided by yourself when the page is unloaded. The default is false.
|
|
logout(false)
|
|
.then(() => {
|
|
// Handle success result from promise.then when you set true.
|
|
})
|
|
.catch(() => {
|
|
// handle error
|
|
});
|
|
});
|
|
// @End uniapp use Chat only
|
|
|
|
const emits = defineEmits(["closeChat"]);
|
|
|
|
const groupID = ref(undefined);
|
|
const isGroup = ref(false);
|
|
const isNotInGroup = ref(false);
|
|
const notInGroupReason = ref<number>();
|
|
const currentConversationID = ref();
|
|
const isMultipleSelectMode = ref(false);
|
|
const inputToolbarDisplayType = ref<ToolbarDisplayType>("none");
|
|
const messageInputRef = ref();
|
|
const messageListRef = ref<InstanceType<typeof MessageList>>();
|
|
const headerExtensionList = ref<ExtensionInfo[]>([]);
|
|
const featureConfig = TUIChatConfig.getFeatureConfig();
|
|
let marginTopcss = ref("0px");
|
|
onMounted(() => {
|
|
TUIStore.watch(StoreName.CONV, {
|
|
currentConversation: onCurrentConversationUpdate,
|
|
});
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
TUIStore.unwatch(StoreName.CONV, {
|
|
currentConversation: onCurrentConversationUpdate,
|
|
});
|
|
reset();
|
|
});
|
|
//发送自定义消息
|
|
//············································标记3············································
|
|
let currentConversation = ref();
|
|
|
|
TUIStore.watch(StoreName.CONV, {
|
|
currentConversation: (conversation) => {
|
|
currentConversation.value = conversation;
|
|
},
|
|
});
|
|
|
|
function sendCustomMessage(myitem, youritem) {
|
|
request({
|
|
url: "pk/createPkRecord",
|
|
method: "POST",
|
|
data: {
|
|
pkIdA: youritem.id,
|
|
pkIdB: myitem.id,
|
|
userIdA: youritem.senderId,
|
|
userIdB: myitem.senderId,
|
|
pkTime: youritem.pkTime,
|
|
pkNumber: youritem.pkNumber,
|
|
anchorIdA: youritem.anchorId,
|
|
anchorIdB: myitem.anchorId,
|
|
anchorIconA: youritem.anchorIcon,
|
|
anchorIconB: myitem.anchorIcon,
|
|
piIdA: youritem.id,
|
|
piIdB: myitem.id,
|
|
},
|
|
userInfo: true,
|
|
}).then((res) => {
|
|
if (res.code === 200) {
|
|
const keyid = generateMsgId();
|
|
const payload = {
|
|
data: JSON.stringify({
|
|
businessID: "pk",
|
|
keyid: keyid,
|
|
myitem: counter.myitem.id,
|
|
pkIdA: youritem.id,
|
|
pkIdB: myitem.id,
|
|
userIdA: youritem.senderId,
|
|
userIdB: myitem.senderId,
|
|
pkTime: youritem.pkTime,
|
|
pkNumber: youritem.pkNumber,
|
|
id:res.data.id,
|
|
link: "https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/pk.png",
|
|
btnDisplay: true,
|
|
}),
|
|
description: "邀请参加PK",
|
|
extension: "邀请参加PK",
|
|
};
|
|
const options = {
|
|
to:
|
|
currentConversation?.value?.groupProfile?.groupID ||
|
|
currentConversation?.value?.userProfile?.userID,
|
|
conversationType: currentConversation?.value?.type,
|
|
payload,
|
|
needReadReceipt: isEnabledMessageReadReceiptGlobal(),
|
|
};
|
|
const offlinePushInfoCreateParams = {
|
|
conversation: currentConversation.value,
|
|
payload: options.payload,
|
|
messageType: TUIChatEngine.TYPES.MSG_CUSTOM,
|
|
};
|
|
const sendMessageOptions = {
|
|
offlinePushInfo: OfflinePushInfoManager.create(offlinePushInfoCreateParams),
|
|
};
|
|
TUIChatService.sendCustomMessage(options, sendMessageOptions).then((res) => {
|
|
const messagein = request({
|
|
url: "chat/add",
|
|
method: "POST",
|
|
data: {
|
|
messageInfo: JSON.stringify(res.data.message),
|
|
keyId: keyid,
|
|
},
|
|
userInfo: true,
|
|
});
|
|
});
|
|
myitem.value = null;
|
|
youritem.value = null;
|
|
currentConversation.value = null;
|
|
} else {
|
|
uni.showToast({
|
|
title: res.msg,
|
|
icon: "none",
|
|
duration: 3000,
|
|
});
|
|
}
|
|
});
|
|
}
|
|
//`````````````````````````````````````````````````````````````````````标记
|
|
const isInputToolbarShow = computed<boolean>(() => {
|
|
return isUniFrameWork ? inputToolbarDisplayType.value !== "none" : true;
|
|
});
|
|
|
|
const leaveGroupReasonText = computed<string>(() => {
|
|
let text = "";
|
|
switch (notInGroupReason.value) {
|
|
case 4:
|
|
text = TUITranslateService.t("TUIChat.您已被管理员移出群聊");
|
|
break;
|
|
case 5:
|
|
text = TUITranslateService.t("TUIChat.该群聊已被解散");
|
|
break;
|
|
case 8:
|
|
text = TUITranslateService.t("TUIChat.您已退出该群聊");
|
|
break;
|
|
default:
|
|
text = TUITranslateService.t("TUIChat.您已退出该群聊");
|
|
break;
|
|
}
|
|
return text;
|
|
});
|
|
|
|
const reset = () => {
|
|
TUIConversationService.switchConversation("");
|
|
};
|
|
|
|
const closeChat = (conversationID: string) => {
|
|
emits("closeChat", conversationID);
|
|
reset();
|
|
};
|
|
|
|
const insertEmoji = (emojiObj: object) => {
|
|
messageInputRef.value?.insertEmoji(emojiObj);
|
|
};
|
|
|
|
const handleEditor = (message: IMessageModel, type: string) => {
|
|
if (!message || !type) return;
|
|
switch (type) {
|
|
case "reference":
|
|
// todo
|
|
break;
|
|
case "reply":
|
|
// todo
|
|
break;
|
|
case "reedit":
|
|
if (message?.payload?.text) {
|
|
messageInputRef?.value?.reEdit(message?.payload?.text);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
};
|
|
|
|
const handleGroup = () => {
|
|
headerExtensionList.value[0].listener.onClicked({ groupID: groupID.value });
|
|
};
|
|
|
|
function changeToolbarDisplayType(type: ToolbarDisplayType) {
|
|
inputToolbarDisplayType.value = inputToolbarDisplayType.value === type ? "none" : type;
|
|
if (inputToolbarDisplayType.value !== "none" && isUniFrameWork) {
|
|
uni.$emit("scroll-to-bottom");
|
|
}
|
|
}
|
|
function scrollToLatestMessage() {
|
|
messageListRef.value?.scrollToLatestMessage();
|
|
}
|
|
|
|
function toggleMultipleSelectMode(visible?: boolean) {
|
|
isMultipleSelectMode.value =
|
|
visible === undefined ? !isMultipleSelectMode.value : visible;
|
|
}
|
|
|
|
function mergeForwardMessage() {
|
|
messageListRef.value?.mergeForwardMessage();
|
|
}
|
|
|
|
function oneByOneForwardMessage() {
|
|
messageListRef.value?.oneByOneForwardMessage();
|
|
}
|
|
|
|
function updateUIUserNotInGroup(conversation: IConversationModel) {
|
|
if (conversation?.operationType > 0) {
|
|
headerExtensionList.value = [];
|
|
isNotInGroup.value = true;
|
|
/**
|
|
* 4 - be removed from the group
|
|
* 5 - group is dismissed
|
|
* 8 - quit group
|
|
*/
|
|
notInGroupReason.value = conversation?.operationType;
|
|
} else {
|
|
isNotInGroup.value = false;
|
|
notInGroupReason.value = undefined;
|
|
}
|
|
}
|
|
|
|
function onCurrentConversationUpdate(conversation: IConversationModel) {
|
|
updateUIUserNotInGroup(conversation);
|
|
// return when currentConversation is null
|
|
if (!conversation) {
|
|
return;
|
|
}
|
|
// return when currentConversationID.value is the same as conversation.conversationID.
|
|
if (currentConversationID.value === conversation?.conversationID) {
|
|
return;
|
|
}
|
|
|
|
isGroup.value = false;
|
|
let conversationType = TUIChatEngine.TYPES.CONV_C2C;
|
|
const conversationID = conversation.conversationID;
|
|
if (conversationID.startsWith(TUIChatEngine.TYPES.CONV_GROUP)) {
|
|
conversationType = TUIChatEngine.TYPES.CONV_GROUP;
|
|
isGroup.value = true;
|
|
groupID.value = conversationID.replace(TUIChatEngine.TYPES.CONV_GROUP, "");
|
|
}
|
|
|
|
headerExtensionList.value = [];
|
|
isMultipleSelectMode.value = false;
|
|
// Initialize chatType
|
|
TUIChatConfig.setChatType(conversationType);
|
|
// While converstaion change success, notify callkit and roomkit、or other components.
|
|
TUICore.notifyEvent(
|
|
TUIConstants.TUIChat.EVENT.CHAT_STATE_CHANGED,
|
|
TUIConstants.TUIChat.EVENT_SUB_KEY.CHAT_OPENED,
|
|
{ groupID: groupID.value }
|
|
);
|
|
// The TUICustomerServicePlugin plugin determines if the current conversation is a customer service conversation, then sets chatType and activates the conversation.
|
|
TUICore.callService({
|
|
serviceName: TUIConstants.TUICustomerServicePlugin.SERVICE.NAME,
|
|
method: TUIConstants.TUICustomerServicePlugin.SERVICE.METHOD.ACTIVE_CONVERSATION,
|
|
params: { conversationID: conversationID },
|
|
});
|
|
// When open chat in room, close main chat ui and reset theme.
|
|
if (TUIChatConfig.getChatType() === TUIConstants.TUIChat.TYPE.ROOM) {
|
|
if (
|
|
TUIChatConfig.getFeatureConfig(TUIConstants.TUIChat.FEATURE.InputVoice) === true
|
|
) {
|
|
TUIChatConfig.setTheme("light");
|
|
currentConversationID.value = "";
|
|
return;
|
|
}
|
|
}
|
|
// Get chat header extensions
|
|
if (TUIChatConfig.getChatType() === TUIConstants.TUIChat.TYPE.GROUP) {
|
|
headerExtensionList.value = TUICore.getExtensionList(
|
|
TUIConstants.TUIChat.EXTENSION.CHAT_HEADER.EXT_ID
|
|
);
|
|
}
|
|
TUIStore.update(StoreName.CUSTOM, "activeConversation", conversationID);
|
|
currentConversationID.value = conversationID;
|
|
}
|
|
</script>
|
|
<style scoped lang="scss" src="./style/index.scss"></style>
|
|
<style>
|
|
.dingweizhibox{
|
|
width: 100%;
|
|
height: 15%;
|
|
}
|
|
.ChatHeadercss{
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
z-index: 999;
|
|
width: 100%;
|
|
height: 15%;
|
|
}
|
|
</style>
|