发送红包接口有问题,添加群恢复
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -72,6 +72,22 @@
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
<template
|
||||
v-else-if="
|
||||
customData.businessID === CHAT_MSG_CUSTOM_TYPE.RED_ENVELOPE
|
||||
"
|
||||
>
|
||||
<!-- 红包 -->
|
||||
<view class="red-envelope">
|
||||
<view class="top-title">
|
||||
<Icon :file="unopenedEnvelope" width="78rpx" height="80rpx" />
|
||||
<text class="title">
|
||||
{{ customData.title }}
|
||||
</text>
|
||||
</view>
|
||||
<text class="bottom-text">积分红包</text>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span v-html="content.custom" />
|
||||
</template>
|
||||
@@ -89,6 +105,8 @@
|
||||
import { ICustomMessagePayload } from '../../../../interface'
|
||||
import Icon from '../../../common/Icon.vue'
|
||||
import star from '../../../../assets/icon/star-light.png'
|
||||
import unopenedEnvelope from '../../../../assets/icon/unopened-envelope.svg'
|
||||
|
||||
interface Props {
|
||||
messageItem: IMessageModel
|
||||
content: any
|
||||
@@ -187,4 +205,32 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.red-envelope {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #f3901f;
|
||||
border-radius: 16rpx;
|
||||
padding: 20rpx;
|
||||
.top-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: 10rpx;
|
||||
margin-bottom: 10rpx;
|
||||
border-bottom: 2rpx solid #ffffff;
|
||||
.title {
|
||||
width: 40vw;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
.bottom-text {
|
||||
font-size: 24rpx;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div
|
||||
class="image-container"
|
||||
@click="handleImagePreview"
|
||||
>
|
||||
<div class="image-container" @click="handleImagePreview">
|
||||
<image
|
||||
class="message-image"
|
||||
mode="aspectFit"
|
||||
@@ -14,72 +11,72 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { watchEffect, ref } from '../../../../adapter-vue';
|
||||
import type { IMessageModel } from '@tencentcloud/chat-uikit-engine-lite';
|
||||
import type { IImageMessageContent } from '../../../../interface';
|
||||
import { watchEffect, ref } from '../../../../adapter-vue'
|
||||
import type { IMessageModel } from '@tencentcloud/chat-uikit-engine-lite'
|
||||
import type { IImageMessageContent } from '../../../../interface'
|
||||
|
||||
interface IProps {
|
||||
content: IImageMessageContent;
|
||||
messageItem: IMessageModel;
|
||||
}
|
||||
interface IEmit {
|
||||
(key: 'previewImage'): void;
|
||||
}
|
||||
interface IProps {
|
||||
content: IImageMessageContent
|
||||
messageItem: IMessageModel
|
||||
}
|
||||
interface IEmit {
|
||||
(key: 'previewImage'): void
|
||||
}
|
||||
|
||||
const emits = defineEmits<IEmit>();
|
||||
const props = withDefaults(
|
||||
defineProps<IProps>(),
|
||||
{
|
||||
const emits = defineEmits<IEmit>()
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
content: () => ({}),
|
||||
messageItem: () => ({} as IMessageModel),
|
||||
},
|
||||
);
|
||||
messageItem: () => ({} as IMessageModel)
|
||||
})
|
||||
|
||||
const DEFAULT_MAX_SIZE = 155;
|
||||
const imageStyles = ref({ width: 'auto', height: 'auto' });
|
||||
const DEFAULT_MAX_SIZE = 155
|
||||
const imageStyles = ref({ width: 'auto', height: 'auto' })
|
||||
|
||||
const genImageStyles = (value: { width?: any; height?: any }) => {
|
||||
const { width, height } = value;
|
||||
if (width === 0 || height === 0) {
|
||||
return;
|
||||
const genImageStyles = (value: { width?: any; height?: any }) => {
|
||||
const { width, height } = value
|
||||
if (width === 0 || height === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
let imageWidth = 0
|
||||
let imageHeight = 0
|
||||
if (width >= height) {
|
||||
imageWidth = DEFAULT_MAX_SIZE
|
||||
imageHeight = (DEFAULT_MAX_SIZE * height) / width
|
||||
} else {
|
||||
imageWidth = (DEFAULT_MAX_SIZE * width) / height
|
||||
imageHeight = DEFAULT_MAX_SIZE
|
||||
}
|
||||
imageStyles.value.width = imageWidth + 'px'
|
||||
imageStyles.value.height = imageHeight + 'px'
|
||||
}
|
||||
|
||||
let imageWidth = 0;
|
||||
let imageHeight = 0;
|
||||
if (width >= height) {
|
||||
imageWidth = DEFAULT_MAX_SIZE;
|
||||
imageHeight = (DEFAULT_MAX_SIZE * height) / width;
|
||||
} else {
|
||||
imageWidth = (DEFAULT_MAX_SIZE * width) / height;
|
||||
imageHeight = DEFAULT_MAX_SIZE;
|
||||
watchEffect(() => {
|
||||
genImageStyles(props.content)
|
||||
})
|
||||
|
||||
const imageLoad = (event: Event) => {
|
||||
genImageStyles(event.detail)
|
||||
}
|
||||
imageStyles.value.width = imageWidth + 'px';
|
||||
imageStyles.value.height = imageHeight + 'px';
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
genImageStyles(props.content);
|
||||
});
|
||||
|
||||
const imageLoad = (event: Event) => {
|
||||
genImageStyles(event.detail);
|
||||
};
|
||||
|
||||
const handleImagePreview = () => {
|
||||
if (props.messageItem?.status === 'success' || props.messageItem.progress === 1) {
|
||||
emits('previewImage');
|
||||
const handleImagePreview = () => {
|
||||
if (
|
||||
props.messageItem?.status === 'success' ||
|
||||
props.messageItem.progress === 1
|
||||
) {
|
||||
emits('previewImage')
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.image-container {
|
||||
position: relative;
|
||||
background-color: #f4f4f4;
|
||||
font-size: 0;
|
||||
.image-container {
|
||||
position: relative;
|
||||
background-color: #f4f4f4;
|
||||
font-size: 0;
|
||||
|
||||
.message-image {
|
||||
max-width: 150px;
|
||||
.message-image {
|
||||
max-width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="message-record-container"
|
||||
@click="openMergeDetail"
|
||||
>
|
||||
<div
|
||||
class="record-title"
|
||||
>
|
||||
<div class="message-record-container" @click="openMergeDetail">
|
||||
<div class="record-title">
|
||||
{{ props.renderData.title }}
|
||||
</div>
|
||||
<div class="record-abstract-container">
|
||||
<div
|
||||
v-for="(item, index) in props.renderData.abstractList.slice(0, 7)"
|
||||
v-for="(item, index) in props.renderData.abstractList.slice(
|
||||
0,
|
||||
7
|
||||
)"
|
||||
:key="index"
|
||||
class="record-abstract-item"
|
||||
>
|
||||
{{ transformTextWithKeysToEmojiNames(item) }}
|
||||
<!-- {{ transformTextWithKeysToEmojiNames(item) }} -->
|
||||
{{ topName(item) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="record-footer">
|
||||
@@ -52,86 +51,98 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, withDefaults } from '../../../../../adapter-vue';
|
||||
import { TUITranslateService, IMessageModel } from '@tencentcloud/chat-uikit-engine-lite';
|
||||
import Overlay from '../../../../common/Overlay/index.vue';
|
||||
import Drawer from '../../../../common/Drawer/index.vue';
|
||||
import SimpleMessageList from '../simple-message-list/index.vue';
|
||||
import { isH5, isPC, isUniFrameWork } from '../../../../../utils/env';
|
||||
import { transformTextWithKeysToEmojiNames } from '../../../emoji-config/index';
|
||||
import { IMergeMessageContent } from '../../../../../interface';
|
||||
import { ref, computed, withDefaults } from '../../../../../adapter-vue'
|
||||
import {
|
||||
TUITranslateService,
|
||||
IMessageModel
|
||||
} from '@tencentcloud/chat-uikit-engine-lite'
|
||||
import Overlay from '../../../../common/Overlay/index.vue'
|
||||
import Drawer from '../../../../common/Drawer/index.vue'
|
||||
import SimpleMessageList from '../simple-message-list/index.vue'
|
||||
import { isH5, isPC, isUniFrameWork } from '../../../../../utils/env'
|
||||
import { transformTextWithKeysToEmojiNames } from '../../../emoji-config/index'
|
||||
import { IMergeMessageContent } from '../../../../../interface'
|
||||
import { CHAT_MSG_CUSTOM_TYPE } from '../../../../../constant'
|
||||
|
||||
interface IEmits {
|
||||
(e: 'assignMessageIDInUniapp', messageID: string): void;
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
// Core data for rendering message record card and message list
|
||||
renderData: IMergeMessageContent;
|
||||
/**
|
||||
* The MessageRecord component has two main functions:
|
||||
* 1. display message record cards primarily.
|
||||
* 2. clicking on it and show the simple message list.
|
||||
* When used as a nested component with the disabled prop
|
||||
* it is only need renderData to render message record cards.
|
||||
* Therefore, 'messageItem' and 'disabled' is not a required prop.
|
||||
*/
|
||||
disabled?: boolean;
|
||||
messageItem?: IMessageModel;
|
||||
}
|
||||
|
||||
const emits = defineEmits<IEmits>();
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
messageItem: () => ({}) as IMessageModel,
|
||||
disabled: false,
|
||||
});
|
||||
|
||||
const isMessageListVisible = ref(false);
|
||||
|
||||
function openMergeDetail() {
|
||||
if (props.disabled) {
|
||||
return;
|
||||
interface IEmits {
|
||||
(e: 'assignMessageIDInUniapp', messageID: string): void
|
||||
}
|
||||
if (!isUniFrameWork) {
|
||||
isMessageListVisible.value = true;
|
||||
} else {
|
||||
emits('assignMessageIDInUniapp', props.messageItem.ID);
|
||||
}
|
||||
}
|
||||
|
||||
function closeMergeDetail() {
|
||||
isMessageListVisible.value = false;
|
||||
}
|
||||
interface IProps {
|
||||
// Core data for rendering message record card and message list
|
||||
renderData: IMergeMessageContent
|
||||
/**
|
||||
* The MessageRecord component has two main functions:
|
||||
* 1. display message record cards primarily.
|
||||
* 2. clicking on it and show the simple message list.
|
||||
* When used as a nested component with the disabled prop
|
||||
* it is only need renderData to render message record cards.
|
||||
* Therefore, 'messageItem' and 'disabled' is not a required prop.
|
||||
*/
|
||||
disabled?: boolean
|
||||
messageItem?: IMessageModel
|
||||
}
|
||||
|
||||
const emits = defineEmits<IEmits>()
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
messageItem: () => ({} as IMessageModel),
|
||||
disabled: false
|
||||
})
|
||||
|
||||
const isMessageListVisible = ref(false)
|
||||
|
||||
// 把替[自定义消息]替换为积分红包
|
||||
const topName = (str: string) => {
|
||||
if (str.includes('[自定义消息]')) {
|
||||
return str.replace('[自定义消息]', '[积分红包]')
|
||||
} else {
|
||||
return transformTextWithKeysToEmojiNames(str)
|
||||
}
|
||||
}
|
||||
|
||||
function openMergeDetail() {
|
||||
if (props.disabled) {
|
||||
return
|
||||
}
|
||||
if (!isUniFrameWork) {
|
||||
isMessageListVisible.value = true
|
||||
} else {
|
||||
emits('assignMessageIDInUniapp', props.messageItem.ID)
|
||||
}
|
||||
}
|
||||
function closeMergeDetail() {
|
||||
isMessageListVisible.value = false
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
:not(not) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.message-record-container {
|
||||
padding: 10px 15px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
background-color: #fff;
|
||||
max-width: 400px;
|
||||
min-width: 180px;
|
||||
overflow: hidden;
|
||||
|
||||
.record-abstract-container {
|
||||
color: #bbb;
|
||||
font-size: 12px;
|
||||
margin: 8px 0;
|
||||
:not(not) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.record-footer {
|
||||
color: #888;
|
||||
font-size: 11px;
|
||||
padding-top: 5px;
|
||||
border-top: 1px solid #eee;
|
||||
.message-record-container {
|
||||
padding: 10px 15px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
background-color: #fff;
|
||||
max-width: 400px;
|
||||
min-width: 180px;
|
||||
overflow: hidden;
|
||||
|
||||
.record-abstract-container {
|
||||
color: #bbb;
|
||||
font-size: 12px;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.record-footer {
|
||||
color: #888;
|
||||
font-size: 11px;
|
||||
padding-top: 5px;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,20 +2,15 @@
|
||||
<div
|
||||
:class="{
|
||||
'simple-message-list-container': true,
|
||||
'simple-message-list-container-mobile': isMobile,
|
||||
'simple-message-list-container-mobile': isMobile
|
||||
}"
|
||||
>
|
||||
<div class="header-container">
|
||||
<span
|
||||
class="back"
|
||||
@click="backPreviousLevel"
|
||||
>
|
||||
<Icon
|
||||
class="close-icon"
|
||||
:file="addIcon"
|
||||
:size="'18px'"
|
||||
/>
|
||||
<span v-if="isReturn">{{ TUITranslateService.t('TUIChat.返回') }}</span>
|
||||
<span class="back" @click="backPreviousLevel">
|
||||
<Icon class="close-icon" :file="addIcon" :size="'18px'" />
|
||||
<span v-if="isReturn">
|
||||
{{ TUITranslateService.t('TUIChat.返回') }}
|
||||
</span>
|
||||
<span v-else>{{ TUITranslateService.t('TUIChat.关闭') }}</span>
|
||||
</span>
|
||||
|
||||
@@ -23,9 +18,7 @@
|
||||
{{ currentMergeMessageInfo.title }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="isDownloadOccurError">
|
||||
Load Merge Message Error
|
||||
</div>
|
||||
<div v-if="isDownloadOccurError">Load Merge Message Error</div>
|
||||
<div
|
||||
v-else-if="isMergeMessageInfoLoaded"
|
||||
ref="simpleMessageListRef"
|
||||
@@ -35,7 +28,7 @@
|
||||
v-for="item in currentMergeMessageInfo.messageList"
|
||||
:key="item.ID"
|
||||
:class="{
|
||||
'message-item': true,
|
||||
'message-item': true
|
||||
}"
|
||||
>
|
||||
<MessageContainer
|
||||
@@ -50,20 +43,21 @@
|
||||
class="message-text"
|
||||
>
|
||||
<span
|
||||
v-for="(textInfo, index) in parseTextToRenderArray(item.messageBody[0].payload['text'])"
|
||||
v-for="(textInfo, index) in parseTextToRenderArray(
|
||||
item.messageBody[0].payload['text']
|
||||
)"
|
||||
:key="index"
|
||||
class="message-text-container"
|
||||
>
|
||||
<span
|
||||
v-if="textInfo.type === 'text'"
|
||||
class="text"
|
||||
>{{ textInfo.content }}</span>
|
||||
<span v-if="textInfo.type === 'text'" class="text">
|
||||
{{ textInfo.content }}
|
||||
</span>
|
||||
<img
|
||||
v-else
|
||||
class="simple-emoji"
|
||||
:src="textInfo.content"
|
||||
alt="small-face"
|
||||
>
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<!-- image -->
|
||||
@@ -73,10 +67,12 @@
|
||||
>
|
||||
<img
|
||||
class="image"
|
||||
:src="(item.messageBody[0].payload)['imageInfoArray'][2]['url']"
|
||||
:src="
|
||||
item.messageBody[0].payload['imageInfoArray'][2]['url']
|
||||
"
|
||||
mode="widthFix"
|
||||
alt="image"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<!-- video -->
|
||||
<div
|
||||
@@ -85,29 +81,30 @@
|
||||
>
|
||||
<div
|
||||
v-if="isUniFrameWork"
|
||||
@click="previewVideoInUniapp((item.messageBody[0].payload)['remoteVideoUrl'])"
|
||||
@click="
|
||||
previewVideoInUniapp(
|
||||
item.messageBody[0].payload['remoteVideoUrl']
|
||||
)
|
||||
"
|
||||
>
|
||||
<image
|
||||
class="image"
|
||||
:src="(item.messageBody[0].payload)['thumbUrl']"
|
||||
:src="item.messageBody[0].payload['thumbUrl']"
|
||||
mode="widthFix"
|
||||
alt="image"
|
||||
/>
|
||||
<Icon
|
||||
class="video-play-icon"
|
||||
:file="playIcon"
|
||||
/>
|
||||
<Icon class="video-play-icon" :file="playIcon" />
|
||||
</div>
|
||||
<video
|
||||
v-else
|
||||
class="video"
|
||||
controls
|
||||
:poster="(item.messageBody[0].payload)['thumbUrl']"
|
||||
:poster="item.messageBody[0].payload['thumbUrl']"
|
||||
>
|
||||
<source
|
||||
:src="(item.messageBody[0].payload)['remoteVideoUrl']"
|
||||
:src="item.messageBody[0].payload['remoteVideoUrl']"
|
||||
type="video/mp4"
|
||||
>
|
||||
/>
|
||||
</video>
|
||||
</div>
|
||||
<!-- audio -->
|
||||
@@ -115,7 +112,7 @@
|
||||
v-else-if="item.messageBody[0].type === TYPES.MSG_AUDIO"
|
||||
class="message-audio"
|
||||
>
|
||||
<span>{{ TUITranslateService.t("TUIChat.语音") }} </span>
|
||||
<span>{{ TUITranslateService.t('TUIChat.语音') }} </span>
|
||||
<span>{{ item.messageBody[0].payload.second }}s</span>
|
||||
</div>
|
||||
<!-- big face -->
|
||||
@@ -127,7 +124,7 @@
|
||||
class="image"
|
||||
:src="resolveBigFaceUrl(item.messageBody[0].payload.data)"
|
||||
alt="face"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<!-- file -->
|
||||
<div
|
||||
@@ -153,6 +150,10 @@
|
||||
:renderData="item.messageBody[0].payload"
|
||||
/>
|
||||
</div>
|
||||
<!-- 红包 -->
|
||||
<div v-else-if="isRedEnvelope(item)">
|
||||
{{ redEnvelopeText(item) }}
|
||||
</div>
|
||||
<!-- custom -->
|
||||
<div v-else-if="item.messageBody[0].type === TYPES.MSG_CUSTOM">
|
||||
{{ TUITranslateService.t('TUIChat.[自定义消息]') }}
|
||||
@@ -164,270 +165,309 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from '../../../../../adapter-vue';
|
||||
import TUIChatEngine, {
|
||||
TUIStore,
|
||||
TUIChatService,
|
||||
TUITranslateService,
|
||||
} from '@tencentcloud/chat-uikit-engine-lite';
|
||||
import addIcon from '../../../../../assets/icon/back.svg';
|
||||
import playIcon from '../../../../../assets/icon/video-play.png';
|
||||
import Icon from '../../../../common/Icon.vue';
|
||||
import MessageContainer from './message-container.vue';
|
||||
import MessageRecord from '../message-record/index.vue';
|
||||
import { parseTextToRenderArray, DEFAULT_BIG_EMOJI_URL, CUSTOM_BIG_EMOJI_URL } from '../../../emoji-config/index';
|
||||
import { isMobile, isUniFrameWork } from '../../../../../utils/env';
|
||||
import { IMergeMessageContent } from '../../../../../interface';
|
||||
import { computed, ref, watch } from '../../../../../adapter-vue'
|
||||
import TUIChatEngine, {
|
||||
TUIStore,
|
||||
TUIChatService,
|
||||
TUITranslateService
|
||||
} from '@tencentcloud/chat-uikit-engine-lite'
|
||||
import addIcon from '../../../../../assets/icon/back.svg'
|
||||
import playIcon from '../../../../../assets/icon/video-play.png'
|
||||
import Icon from '../../../../common/Icon.vue'
|
||||
import MessageContainer from './message-container.vue'
|
||||
import MessageRecord from '../message-record/index.vue'
|
||||
import {
|
||||
parseTextToRenderArray,
|
||||
DEFAULT_BIG_EMOJI_URL,
|
||||
CUSTOM_BIG_EMOJI_URL
|
||||
} from '../../../emoji-config/index'
|
||||
import { isMobile, isUniFrameWork } from '../../../../../utils/env'
|
||||
import { IMergeMessageContent } from '../../../../../interface'
|
||||
import { CHAT_MSG_CUSTOM_TYPE } from '../../../../../constant'
|
||||
|
||||
interface IProps {
|
||||
/**
|
||||
* only use messageID when first render of simple-message-list
|
||||
* because the nested simple-message-list do not have corresponding message object
|
||||
* need to download message from sdk by constructed message
|
||||
* and use downloaded message object to render nested simple-message-list
|
||||
*/
|
||||
messageID?: string;
|
||||
isMounted?: boolean;
|
||||
}
|
||||
|
||||
interface IEmits {
|
||||
(e: 'closeOverlay'): void;
|
||||
}
|
||||
|
||||
const emits = defineEmits<IEmits>();
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
messageID: '',
|
||||
isMounted: false,
|
||||
});
|
||||
|
||||
const TYPES = TUIChatEngine.TYPES;
|
||||
const isDownloadOccurError = ref(false);
|
||||
const messageListStack = ref<IMergeMessageContent[]>([]);
|
||||
const currentMergeMessageInfo = ref<Partial<IMergeMessageContent>>({
|
||||
title: '',
|
||||
messageList: [],
|
||||
});
|
||||
const simpleMessageListRef = ref<HTMLElement>();
|
||||
|
||||
watch(() => messageListStack.value.length, async (newValue) => {
|
||||
isDownloadOccurError.value = false;
|
||||
if (newValue < 1) {
|
||||
return;
|
||||
interface IProps {
|
||||
/**
|
||||
* only use messageID when first render of simple-message-list
|
||||
* because the nested simple-message-list do not have corresponding message object
|
||||
* need to download message from sdk by constructed message
|
||||
* and use downloaded message object to render nested simple-message-list
|
||||
*/
|
||||
messageID?: string
|
||||
isMounted?: boolean
|
||||
}
|
||||
const stackTopMessageInfo = messageListStack.value[messageListStack.value.length - 1];
|
||||
if (stackTopMessageInfo.downloadKey && stackTopMessageInfo.messageList.length === 0) {
|
||||
try {
|
||||
const res = await TUIChatService.downloadMergedMessages({
|
||||
payload: stackTopMessageInfo,
|
||||
type: TUIChatEngine.TYPES.MSG_MERGER,
|
||||
} as any);
|
||||
// if download complete message, cover the original message in stack top
|
||||
messageListStack.value[messageListStack.value.length - 1] = res.payload;
|
||||
} catch (error) {
|
||||
isDownloadOccurError.value = true;
|
||||
|
||||
interface IEmits {
|
||||
(e: 'closeOverlay'): void
|
||||
}
|
||||
|
||||
const emits = defineEmits<IEmits>()
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
messageID: '',
|
||||
isMounted: false
|
||||
})
|
||||
|
||||
const TYPES = TUIChatEngine.TYPES
|
||||
const isDownloadOccurError = ref(false)
|
||||
const messageListStack = ref<IMergeMessageContent[]>([])
|
||||
const currentMergeMessageInfo = ref<Partial<IMergeMessageContent>>({
|
||||
title: '',
|
||||
messageList: []
|
||||
})
|
||||
const simpleMessageListRef = ref<HTMLElement>()
|
||||
|
||||
watch(
|
||||
() => messageListStack.value.length,
|
||||
async newValue => {
|
||||
isDownloadOccurError.value = false
|
||||
if (newValue < 1) {
|
||||
return
|
||||
}
|
||||
const stackTopMessageInfo =
|
||||
messageListStack.value[messageListStack.value.length - 1]
|
||||
if (
|
||||
stackTopMessageInfo.downloadKey &&
|
||||
stackTopMessageInfo.messageList.length === 0
|
||||
) {
|
||||
try {
|
||||
const res = await TUIChatService.downloadMergedMessages({
|
||||
payload: stackTopMessageInfo,
|
||||
type: TUIChatEngine.TYPES.MSG_MERGER
|
||||
} as any)
|
||||
// if download complete message, cover the original message in stack top
|
||||
messageListStack.value[messageListStack.value.length - 1] =
|
||||
res.payload
|
||||
} catch (error) {
|
||||
isDownloadOccurError.value = true
|
||||
}
|
||||
}
|
||||
currentMergeMessageInfo.value =
|
||||
messageListStack.value[messageListStack.value.length - 1]
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.isMounted,
|
||||
newValue => {
|
||||
// For compatibility with uniapp, use watch to implement onMounted
|
||||
if (newValue) {
|
||||
if (!props.messageID) {
|
||||
throw new Error(
|
||||
'messageID is required when first render of simple-message-list.'
|
||||
)
|
||||
}
|
||||
const sdkMessagePayload = TUIStore.getMessageModel(
|
||||
props.messageID
|
||||
).getMessage().payload
|
||||
messageListStack.value = [sdkMessagePayload]
|
||||
} else {
|
||||
messageListStack.value = []
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
|
||||
const isReturn = computed(() => {
|
||||
return messageListStack.value.length > 1
|
||||
})
|
||||
|
||||
const isMergeMessageInfoLoaded = computed(() => {
|
||||
return currentMergeMessageInfo.value?.messageList
|
||||
? currentMergeMessageInfo.value.messageList.length > 0
|
||||
: false
|
||||
})
|
||||
|
||||
function entryNextLevel(e, sdkMessage: any) {
|
||||
messageListStack.value.push(sdkMessage.messageBody[0].payload)
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
||||
function backPreviousLevel() {
|
||||
messageListStack.value.pop()
|
||||
if (messageListStack.value.length < 1) {
|
||||
emits('closeOverlay')
|
||||
}
|
||||
}
|
||||
currentMergeMessageInfo.value = messageListStack.value[messageListStack.value.length - 1];
|
||||
});
|
||||
|
||||
watch(() => props.isMounted, (newValue) => {
|
||||
// For compatibility with uniapp, use watch to implement onMounted
|
||||
if (newValue) {
|
||||
if (!props.messageID) {
|
||||
throw new Error('messageID is required when first render of simple-message-list.');
|
||||
function previewVideoInUniapp(url: string) {
|
||||
if (isUniFrameWork) {
|
||||
const encodedUrl = encodeURIComponent(url)
|
||||
uni.navigateTo({
|
||||
url: `/TUIKit/components/TUIChat/video-play?videoUrl=${encodedUrl}`
|
||||
})
|
||||
}
|
||||
const sdkMessagePayload = TUIStore.getMessageModel(props.messageID).getMessage().payload;
|
||||
messageListStack.value = [sdkMessagePayload];
|
||||
} else {
|
||||
messageListStack.value = [];
|
||||
}
|
||||
}, {
|
||||
immediate: true,
|
||||
});
|
||||
|
||||
const isReturn = computed(() => {
|
||||
return messageListStack.value.length > 1;
|
||||
});
|
||||
|
||||
const isMergeMessageInfoLoaded = computed(() => {
|
||||
return currentMergeMessageInfo.value?.messageList ? currentMergeMessageInfo.value.messageList.length > 0 : false;
|
||||
});
|
||||
|
||||
function entryNextLevel(e, sdkMessage: any) {
|
||||
messageListStack.value.push(sdkMessage.messageBody[0].payload);
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
function backPreviousLevel() {
|
||||
messageListStack.value.pop();
|
||||
if (messageListStack.value.length < 1) {
|
||||
emits('closeOverlay');
|
||||
}
|
||||
}
|
||||
|
||||
function previewVideoInUniapp(url: string) {
|
||||
if (isUniFrameWork) {
|
||||
const encodedUrl = encodeURIComponent(url);
|
||||
uni.navigateTo({
|
||||
url: `/TUIKit/components/TUIChat/video-play?videoUrl=${encodedUrl}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function resolveBigFaceUrl(bigFaceKey: string): string {
|
||||
let url = '';
|
||||
if (bigFaceKey.indexOf('@custom') > -1) {
|
||||
url = CUSTOM_BIG_EMOJI_URL + bigFaceKey;
|
||||
} else {
|
||||
url = DEFAULT_BIG_EMOJI_URL + bigFaceKey;
|
||||
if (url.indexOf('@2x') === -1) {
|
||||
url += '@2x.png';
|
||||
function resolveBigFaceUrl(bigFaceKey: string): string {
|
||||
let url = ''
|
||||
if (bigFaceKey.indexOf('@custom') > -1) {
|
||||
url = CUSTOM_BIG_EMOJI_URL + bigFaceKey
|
||||
} else {
|
||||
url += '.png';
|
||||
url = DEFAULT_BIG_EMOJI_URL + bigFaceKey
|
||||
if (url.indexOf('@2x') === -1) {
|
||||
url += '@2x.png'
|
||||
} else {
|
||||
url += '.png'
|
||||
}
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
/** 是否红包 */
|
||||
const isRedEnvelope = (item: any) => {
|
||||
if (item.messageBody[0]?.payload?.data) {
|
||||
const businessID = JSON?.parse(
|
||||
item.messageBody[0]?.payload?.data
|
||||
)?.businessID
|
||||
return businessID === CHAT_MSG_CUSTOM_TYPE.RED_ENVELOPE
|
||||
}
|
||||
return false
|
||||
}
|
||||
/** 红包文案 */
|
||||
const redEnvelopeText = (item: any) => {
|
||||
const payload = JSON.parse(item.messageBody[0]?.payload?.data)
|
||||
return `[积分红包] ${payload.title}`
|
||||
}
|
||||
return url;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:not(not){
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.simple-message-list-container {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: calc(40vw);
|
||||
min-width: 550px;
|
||||
height: calc(100vh - 200px);
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
border-radius: 8px;
|
||||
|
||||
&-mobile {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
min-width: auto;
|
||||
border-radius: 0;
|
||||
:not(not) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.header-container {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
height: 60px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0 70px;
|
||||
.simple-message-list-container {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: calc(40vw);
|
||||
min-width: 550px;
|
||||
height: calc(100vh - 200px);
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
border-radius: 8px;
|
||||
|
||||
.back {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
cursor: pointer;
|
||||
&-mobile {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
min-width: auto;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
.header-container {
|
||||
width: 100%;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
height: 60px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0 70px;
|
||||
background-color: #fff;
|
||||
|
||||
.back {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.message-list {
|
||||
padding: 60px 20px 20px;
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden auto;
|
||||
}
|
||||
}
|
||||
|
||||
.message-list {
|
||||
padding: 60px 20px 20px;
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden auto;
|
||||
}
|
||||
}
|
||||
|
||||
.message-item {
|
||||
flex-direction: row;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.message-text {
|
||||
flex-flow: row wrap;
|
||||
display: inline;
|
||||
|
||||
&-container {
|
||||
display: inline;
|
||||
flex: 0 0 auto;
|
||||
.message-item {
|
||||
flex-direction: row;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.text {
|
||||
vertical-align: bottom;
|
||||
.message-text {
|
||||
flex-flow: row wrap;
|
||||
display: inline;
|
||||
|
||||
&-container {
|
||||
display: inline;
|
||||
word-break: break-all;
|
||||
}
|
||||
flex: 0 0 auto;
|
||||
flex-direction: row;
|
||||
|
||||
.simple-emoji {
|
||||
display: inline-flex;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
.text {
|
||||
vertical-align: bottom;
|
||||
display: inline;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.simple-emoji {
|
||||
display: inline-flex;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message-image {
|
||||
max-width: 180px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
.image {
|
||||
.message-image {
|
||||
max-width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
.message-face {
|
||||
max-width: 100px;
|
||||
|
||||
.image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
.message-audio {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.message-video {
|
||||
position: relative;
|
||||
|
||||
.image {
|
||||
max-width: 180px;
|
||||
}
|
||||
|
||||
.video-play-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.video {
|
||||
max-width: 150px;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
overflow: hidden;
|
||||
|
||||
.message-combine {
|
||||
max-width: 300px;
|
||||
}
|
||||
.image {
|
||||
max-width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
.message-face {
|
||||
max-width: 100px;
|
||||
|
||||
.image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
.message-audio {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.message-video {
|
||||
position: relative;
|
||||
|
||||
.image {
|
||||
max-width: 180px;
|
||||
}
|
||||
|
||||
.video-play-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.video {
|
||||
max-width: 150px;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.message-combine {
|
||||
max-width: 300px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user