123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- <template>
- <div
- :class="[
- 'message-input-toolbar',
- 'message-input-toolbar-h5',
- 'message-input-toolbar-uni',
- ]"
- >
- <div v-if="props.displayType === 'emojiPicker'">
- <EmojiPickerDialog />
- </div>
- <div v-else>
- <swiper
- :class="['message-input-toolbar-swiper']"
- :indicator-dots="isSwiperIndicatorDotsEnable"
- :autoplay="false"
- :circular="false"
- >
- <swiper-item
- :class="[
- 'message-input-toolbar-list',
- 'message-input-toolbar-h5-list',
- 'message-input-toolbar-uni-list',
- ]"
- >
- <ImageUpload v-if="featureConfig.InputImage" imageSourceType="camera" />
- <ImageUpload v-if="featureConfig.InputImage" imageSourceType="album" />
- <VideoUpload v-if="featureConfig.InputVideo" videoSourceType="album" />
- <VideoUpload v-if="featureConfig.InputVideo" videoSourceType="camera" />
- <template v-if="currentExtensionList.length > 0">
- <div
- v-for="(extension, index) in currentExtensionList.slice(0, slicePos)"
- :key="index"
- >
- <ToolbarItemContainer
- v-if="extension"
- :iconFile="genExtensionIcon(extension)"
- :title="genExtensionText(extension)"
- iconWidth="25px"
- iconHeight="25px"
- :needDialog="false"
- @onIconClick="onExtensionClick(extension)"
- />
- </div>
- </template>
- <!-- <template v-if="neededCountFirstPage === 1">
- <Evaluate
- v-if="featureConfig.InputEvaluation"
- @onDialogPopupShowOrHide="handleSwiperDotShow"
- />
- <Words
- v-else-if="featureConfig.InputQuickReplies"
- @onDialogPopupShowOrHide="handleSwiperDotShow"
- />
- </template>
- <template v-if="neededCountFirstPage > 1">
- <Evaluate
- v-if="featureConfig.InputEvaluation"
- @onDialogPopupShowOrHide="handleSwiperDotShow"
- />
- <Words
- v-if="featureConfig.InputQuickReplies"
- @onDialogPopupShowOrHide="handleSwiperDotShow"
- />
- </template> -->
- </swiper-item>
- <swiper-item
- v-if="neededCountFirstPage <= 1"
- :class="[
- 'message-input-toolbar-list',
- 'message-input-toolbar-h5-list',
- 'message-input-toolbar-uni-list',
- ]"
- >
- <div
- v-for="(extension, index) in currentExtensionList.slice(slicePos)"
- :key="index"
- >
- <ToolbarItemContainer
- v-if="extension"
- :iconFile="genExtensionIcon(extension)"
- :title="genExtensionText(extension)"
- iconWidth="25px"
- iconHeight="25px"
- :needDialog="false"
- @onIconClick="onExtensionClick(extension)"
- />
- </div>
- <template v-if="neededCountFirstPage === 1">
- <Words
- v-if="featureConfig.InputQuickReplies"
- @onDialogPopupShowOrHide="handleSwiperDotShow"
- />
- </template>
- <template v-else>
- <Evaluate
- v-if="featureConfig.InputEvaluation"
- @onDialogPopupShowOrHide="handleSwiperDotShow"
- />
- <Words
- v-if="featureConfig.InputQuickReplies"
- @onDialogPopupShowOrHide="handleSwiperDotShow"
- />
- </template>
- </swiper-item>
- </swiper>
- </div>
- <UserSelector
- ref="userSelectorRef"
- :type="selectorShowType"
- :currentConversation="currentConversation"
- :isGroup="isGroup"
- @submit="onUserSelectorSubmit"
- @cancel="onUserSelectorCancel"
- />
- </div>
- </template>
- <script setup lang="ts">
- import { ref, onUnmounted, onMounted } from "../../../adapter-vue";
- import TUIChatEngine, {
- IConversationModel,
- TUIStore,
- StoreName,
- } from "@tencentcloud/chat-uikit-engine";
- import TUICore, { ExtensionInfo, TUIConstants } from "@tencentcloud/tui-core";
- import ImageUpload from "./image-upload/index.vue";
- import VideoUpload from "./video-upload/index.vue";
- import Evaluate from "./evaluate/index.vue";
- import Words from "./words/index.vue";
- import ToolbarItemContainer from "./toolbar-item-container/index.vue";
- import EmojiPickerDialog from "./emoji-picker/emoji-picker-dialog.vue";
- import UserSelector from "./user-selector/index.vue";
- import TUIChatConfig from "../config";
- import { enableSampleTaskStatus } from "../../../utils/enableSampleTaskStatus";
- import { ToolbarDisplayType } from "../../../interface";
- import OfflinePushInfoManager, { PUSH_SCENE } from "../offlinePushInfoManager/index";
- interface IProps {
- displayType: ToolbarDisplayType;
- }
- const props = withDefaults(defineProps<IProps>(), {});
- const currentConversation = ref<IConversationModel>();
- const isGroup = ref<boolean>(false);
- const selectorShowType = ref<string>("");
- const userSelectorRef = ref();
- const currentUserSelectorExtension = ref<ExtensionInfo | null>();
- const currentExtensionList = ref<ExtensionInfo[]>([]);
- const isSwiperIndicatorDotsEnable = ref<boolean>(false);
- const featureConfig = TUIChatConfig.getFeatureConfig();
- const neededCountFirstPage = ref<number>(8);
- const slicePos = ref<number>(0);
- const computeToolbarPaging = () => {
- if (featureConfig.InputImage && featureConfig.InputVideo) {
- neededCountFirstPage.value -= 4;
- } else if (featureConfig.InputImage || featureConfig.InputVideo) {
- neededCountFirstPage.value -= 2;
- }
- slicePos.value = neededCountFirstPage.value;
- neededCountFirstPage.value -= currentExtensionList.value.length;
- if (neededCountFirstPage.value === 1) {
- isSwiperIndicatorDotsEnable.value =
- featureConfig.InputEvaluation && featureConfig.InputQuickReplies;
- } else if (neededCountFirstPage.value < 1) {
- isSwiperIndicatorDotsEnable.value =
- featureConfig.InputEvaluation || featureConfig.InputQuickReplies;
- }
- };
- const getExtensionList = (conversationID: string) => {
- if (!conversationID) {
- return;
- }
- const chatType = TUIChatConfig.getChatType();
- const params: Record<string, boolean | string> = { chatType };
- // Backward compatibility: When callkit does not have chatType judgment, use filterVoice and filterVideo to filter
- if (chatType === TUIConstants.TUIChat.TYPE.CUSTOMER_SERVICE) {
- params.filterVoice = true;
- params.filterVideo = true;
- enableSampleTaskStatus("customerService");
- }
- // uni-app build ios app has null in last index need to filter
- currentExtensionList.value = [
- ...TUICore.getExtensionList(TUIConstants.TUIChat.EXTENSION.INPUT_MORE.EXT_ID, params),
- ].filter((extension: ExtensionInfo) => {
- if (extension?.data?.name === "search") {
- return featureConfig.MessageSearch;
- }
- return true;
- });
- };
- const onCurrentConversationUpdate = (conversation: IConversationModel) => {
- if (
- conversation?.conversationID &&
- conversation.conversationID !== currentConversation.value?.conversationID
- ) {
- getExtensionList(conversation.conversationID);
- computeToolbarPaging();
- }
- currentConversation.value = conversation;
- isGroup.value = currentConversation?.value?.type === TUIChatEngine.TYPES.CONV_GROUP;
- };
- onMounted(() => {
- TUIStore.watch(StoreName.CONV, {
- currentConversation: onCurrentConversationUpdate,
- });
- });
- onUnmounted(() => {
- TUIStore.unwatch(StoreName.CONV, {
- currentConversation: onCurrentConversationUpdate,
- });
- });
- // handle extensions onclick
- const onExtensionClick = (extension: ExtensionInfo) => {
- // uniapp vue2 build wx lose listener proto
- const extensionModel = currentExtensionList.value.find(
- (targetExtension) => targetExtension?.data?.name === extension?.data?.name
- );
- switch (extensionModel?.data?.name) {
- case "voiceCall":
- onCallExtensionClicked(extensionModel, 1);
- break;
- case "videoCall":
- onCallExtensionClicked(extensionModel, 2);
- break;
- case "search":
- extensionModel?.listener?.onClicked?.();
- break;
- default:
- break;
- }
- };
- const onCallExtensionClicked = (extension: ExtensionInfo, callType: number) => {
- selectorShowType.value = extension?.data?.name;
- if (currentConversation?.value?.type === TUIChatEngine.TYPES.CONV_C2C) {
- extension?.listener?.onClicked?.({
- userIDList: [currentConversation?.value?.conversationID?.slice(3)],
- type: callType,
- callParams: {
- offlinePushInfo: OfflinePushInfoManager.getOfflinePushInfo(PUSH_SCENE.CALL),
- },
- });
- } else if (isGroup.value) {
- currentUserSelectorExtension.value = extension;
- userSelectorRef?.value?.toggleShow && userSelectorRef.value.toggleShow(true);
- }
- };
- const genExtensionIcon = (extension: any) => {
- return extension?.icon;
- };
- const genExtensionText = (extension: any) => {
- return extension?.text;
- };
- const onUserSelectorSubmit = (selectedInfo: any) => {
- currentUserSelectorExtension.value?.listener?.onClicked?.({
- ...selectedInfo,
- callParams: {
- offlinePushInfo: OfflinePushInfoManager.getOfflinePushInfo(PUSH_SCENE.CALL),
- },
- });
- currentUserSelectorExtension.value = null;
- };
- const onUserSelectorCancel = () => {
- currentUserSelectorExtension.value = null;
- };
- const handleSwiperDotShow = (showStatus: boolean) => {
- isSwiperIndicatorDotsEnable.value = neededCountFirstPage.value <= 1 && !showStatus;
- };
- </script>
- <script lang="ts">
- export default {
- options: {
- styleIsolation: "shared",
- },
- };
- </script>
- <style lang="scss">
- @import "../../../assets/styles/common";
- @import "./style/uni";
- </style>
|