148 lines
3.8 KiB
Vue
Raw Normal View History

2025-05-30 18:05:17 +08:00
<template>
<div :class="['chat-header', !isPC && 'chat-header-h5']">
<div
v-if="!isPC && isNotRoomChat"
:class="['chat-header-back', !isPC && 'chat-header-h5-back']"
@click="closeChat(currentConversation.conversationID)"
>
<Icon :file="backSVG" />
</div>
<div class="chat-header-container">
2025-06-27 09:53:36 +08:00
<div v-if="isNotRoomChat" :class="['chat-header-content', !isPC && 'chat-header-h5-content']">
2025-05-30 18:05:17 +08:00
{{ currentConversationName }}
</div>
<div>
<!-- <JoinGroupCard v-if="isPC" /> -->
</div>
</div>
<div :class="['chat-header-setting', !isPC && 'chat-header-h5-setting']">
2025-06-27 09:53:36 +08:00
<div v-for="(item, index) in props.headerExtensionList" :key="index" @click.stop="handleExtensions(item)">
2025-05-30 18:05:17 +08:00
<Icon :file="item.icon" />
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onUnmounted, withDefaults } from '../../../adapter-vue';
2025-06-27 09:53:36 +08:00
import { TUIStore, StoreName, TUITranslateService, IConversationModel } from '@tencentcloud/chat-uikit-engine';
2025-05-30 18:05:17 +08:00
import { TUIConstants, ExtensionInfo } from '@tencentcloud/tui-core';
// import { JoinGroupCard } from '@tencentcloud/call-uikit-vue';
import Icon from '../../common/Icon.vue';
import backSVG from '../../../assets/icon/back.svg';
import { isPC } from '../../../utils/env';
import TUIChatConfig from '../config';
const props = withDefaults(
defineProps<{
headerExtensionList: ExtensionInfo[];
}>(),
{
2025-06-27 09:53:36 +08:00
headerExtensionList: () => []
}
2025-05-30 18:05:17 +08:00
);
const emits = defineEmits(['closeChat']);
const currentConversation = ref<IConversationModel>();
const currentConversationName = ref('');
const typingStatus = ref(false);
const groupID = ref('');
const isNotRoomChat = ref<boolean>(TUIChatConfig.getChatType() !== TUIConstants.TUIChat.TYPE.ROOM);
onMounted(() => {
TUIStore.watch(StoreName.CONV, {
2025-06-27 09:53:36 +08:00
currentConversation: onCurrentConversationUpdated
2025-05-30 18:05:17 +08:00
});
TUIStore.watch(StoreName.CHAT, {
2025-06-27 09:53:36 +08:00
typingStatus: onTypingStatusUpdated
2025-05-30 18:05:17 +08:00
});
});
onUnmounted(() => {
TUIStore.unwatch(StoreName.CONV, {
2025-06-27 09:53:36 +08:00
currentConversation: onCurrentConversationUpdated
2025-05-30 18:05:17 +08:00
});
TUIStore.unwatch(StoreName.CHAT, {
2025-06-27 09:53:36 +08:00
typingStatus: onTypingStatusUpdated
2025-05-30 18:05:17 +08:00
});
});
const closeChat = (conversationID: string | undefined) => {
emits('closeChat', conversationID);
};
const handleExtensions = (item: ExtensionInfo) => {
item.listener.onClicked?.({ groupID: groupID.value });
};
function onCurrentConversationUpdated(conversation: IConversationModel) {
currentConversation.value = conversation;
groupID.value = currentConversation.value?.groupProfile?.groupID;
currentConversationName.value = currentConversation?.value?.getShowName();
}
function onTypingStatusUpdated(status: boolean) {
typingStatus.value = status;
if (typingStatus.value) {
currentConversationName.value = TUITranslateService.t('TUIChat.对方正在输入');
} else {
currentConversationName.value = currentConversation.value?.getShowName() || '';
}
}
</script>
<style lang="scss" scoped>
.chat-header {
display: flex;
min-width: 0;
flex-direction: row;
align-items: center;
justify-content: space-between;
&-container {
display: flex;
min-width: 0;
flex-direction: column;
justify-content: flex-start;
}
&-content {
margin-right: 20px;
flex: 1;
font-size: 16px;
line-height: 30px;
font-family: PingFangSC-Medium;
font-weight: 500;
color: #000;
letter-spacing: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
&-back,
&-setting {
width: 27px;
height: 27px;
.icon {
width: 100%;
height: 100%;
}
}
}
.chat-header-h5 {
&-back {
display: flex;
justify-content: center;
align-items: center;
}
2025-06-27 09:53:36 +08:00
&-content {
2025-05-30 18:05:17 +08:00
margin: 0 20px;
text-align: center;
}
}
</style>