| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- <template>
- <div
- class="dialog-emoji"
- :class="env?.isH5 ? 'dialog-emoji-h5' : ''"
- v-if="type === 'dropdown'"
- >
- <div class="face-list collapse">
- <ul class="face-list-collapse">
- <li
- class="face-list-item"
- v-for="(childrenItem, childrenIndex) in emojiCollapseList"
- :key="childrenIndex"
- @click.stop="select(childrenItem)"
- >
- <img :src="emojiUrl + emojiMap[childrenItem]" />
- </li>
- </ul>
- <div class="face-list-button" @click.stop="isCollapse = !isCollapse">
- <i
- class="icon"
- :class="[isCollapse ? 'icon-expand' : 'icon-collapse']"
- ></i>
- </div>
- </div>
- <ul class="face-list face-list-expand" v-show="!isCollapse">
- <li
- class="face-list-item"
- v-for="(childrenItem, childrenIndex) in emojiExpandList"
- :key="childrenIndex"
- @click.stop="select(childrenItem)"
- >
- <img :src="emojiUrl + emojiMap[childrenItem]" />
- </li>
- </ul>
- </div>
- <div v-if="type === 'content'" class="emoji-content">
- <ul class="emoji-react" ref="container">
- <li
- class="emoji-react-item"
- v-for="(val, key) in handleEmojiReact(message)"
- :key="key"
- v-show="val && val?.length"
- @click.stop="select(key)"
- >
- <img :src="emojiUrl + emojiMap[key]" />
- <div class="emoji-react-item-content">
- <span>{{ handleEmojiReactItem(val) }}</span>
- </div>
- </li>
- </ul>
- </div>
- </template>
- <script lang="ts">
- import {
- defineComponent,
- watch,
- reactive,
- toRefs,
- computed,
- ref,
- onMounted,
- nextTick
- } from 'vue';
- import TIM from '../../../../TUICore/tim';
- import { emojiUrl, emojiMap, emojiName } from '../utils/emojiMap';
- import { JSONToObject } from '../utils/utils';
- import TUIChat from '../index.vue';
- import { Message } from '@tencentcloud/chat';
- export default defineComponent({
- props: {
- message: {
- type: Object,
- default: () => ({})
- },
- emojiList: {
- type: Array,
- default: () => []
- },
- type: {
- type: String,
- default: ''
- }
- },
- emits: ['handleCollapse'],
- setup(props: any, ctx: any) {
- const { TUIServer } = TUIChat;
- const data = reactive({
- message: {} as Message,
- emojiUrl,
- emojiMap,
- emojiName,
- isCollapse: true,
- types: TIM.TYPES,
- env: TUIServer.TUICore.TUIEnv,
- type: props.type,
- emojiReacts: {},
- allMemberList: []
- });
- const container = ref({} as HTMLElement);
- const emojiCollapseList = computed(() => {
- return data.emojiName.slice(0, 6);
- });
- const emojiExpandList = computed(() => {
- return data.emojiName.slice(6);
- });
- const select = (item: any) => {
- TUIServer.emojiReact(data.message, item);
- };
- const handleEmojiReact = (message: any) => {
- try {
- if (!message?.cloudCustomData) return;
- const reactList = JSONToObject(message?.cloudCustomData)?.messageReact
- ?.reacts;
- if (!reactList) return;
- data.emojiReacts = reactList;
- return reactList;
- } catch (err) {
- console.warn(err);
- }
- };
- const handleEmojiReactItem = (userIDList: any) => {
- let res = '';
- userIDList?.forEach((item: any, index: any) => {
- const memberInfo = data.allMemberList?.find(
- (member: any) => member.userID === item
- );
- res = res + (memberInfo ? (memberInfo as any)?.nick : item) + ', ';
- });
- if (res.length) res = res.substring(0, res.lastIndexOf(','));
- return res;
- };
- const handleAllMemberList = (message: any) => {
- const TUIChatStore = TUIServer?.currentStore;
- switch (message?.conversationType) {
- case TIM.TYPES.CONV_C2C:
- data.allMemberList = [
- {
- userID: TUIChatStore?.conversation?.userProfile?.userID,
- nick: TUIChatStore?.conversation?.userProfile?.nick
- },
- {
- userID: TUIChatStore?.selfInfo?.userID,
- nick: TUIChatStore?.selfInfo?.nick
- }
- ] as any;
- break;
- case TIM.TYPES.CONV_GROUP:
- data.allMemberList = TUIChatStore?.allMemberList?.memberList;
- break;
- default:
- break;
- }
- };
- watch(
- () => props.message,
- (newVal: any, oldVal: any) => {
- data.message = props.message;
- if (newVal?.conversationID !== oldVal?.conversationID) {
- handleAllMemberList(newVal);
- }
- },
- { deep: true, immediate: true }
- );
- watch(
- () => data.isCollapse,
- (newVal, oldVal) => {
- if (newVal === oldVal) return;
- if (!data?.env?.isH5) return;
- ctx.emit('handleCollapse', newVal);
- }
- );
- return {
- ...toRefs(data),
- emojiCollapseList,
- emojiExpandList,
- select,
- handleEmojiReact,
- handleEmojiReactItem,
- container
- };
- }
- });
- </script>
- <style lang="scss" scoped>
- @import url('../../../styles/common.scss');
- @import url('../../../styles/icon.scss');
- .dialog-emoji {
- margin-left: 2Px;
- background: #ffffff;
- border: 1Px solid #e0e0e0;
- box-shadow: 0 4Px 12Px 0 rgba(0, 0, 0, 0.06);
- width: 242Px;
- min-height: 28Px;
- height: fit-content;
- padding: 2Px 6Px;
- word-break: keep-all;
- top: 30Px;
- border-radius: 8Px;
- &-h5 {
- margin: 0 5Px;
- border: none;
- border-bottom: 1Px solid #e0e0e0;
- box-shadow: none;
- border-radius: 10Px 10Px 0 0;
- }
- .collapse {
- padding: 2Px 0Px;
- }
- .face-list {
- display: flex;
- overflow: hidden;
- flex-wrap: nowrap;
- flex-direction: row;
- &-collapse {
- display: flex;
- overflow: hidden;
- flex-wrap: nowrap;
- justify-content: space-between;
- align-items: center;
- flex: 1;
- }
- &-expand {
- border-top: 1Px solid #e0e0e0;
- display: flex;
- overflow-x: hidden;
- flex-wrap: wrap;
- max-height: 90Px;
- overflow-y: auto;
- }
- &-button {
- padding: 5Px 7Px;
- height: 20Px;
- line-height: 20Px;
- text-align: center;
- align-items: center;
- i {
- text-align: center;
- }
- }
- li {
- margin: 4Px;
- display: flex;
- flex-direction: row;
- align-items: center;
- flex-direction: row;
- img {
- width: 22Px;
- height: 22Px;
- }
- }
- }
- }
- .emoji-content {
- .emoji-react {
- margin-top: 3Px;
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- align-items: center;
- &-item {
- width: fit-content;
- height: 20Px;
- background: rgba(0, 0, 0, 0.05);
- border-radius: 12Px;
- padding: 2Px 6Px;
- margin: 2Px;
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: 200Px;
- display: flex;
- img {
- width: 16Px;
- height: 16Px;
- padding: 2Px;
- }
- &-content {
- overflow: hidden;
- text-overflow: ellipsis;
- font-size: 10Px;
- color: #999999;
- align-self: center;
- span {
- margin: 2Px;
- font-size: 10Px;
- color: #999999;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- }
- }
- }
- }
- </style>
|