231 lines
5.4 KiB
Vue
231 lines
5.4 KiB
Vue
<template>
|
|
<view class="chat-row" :class="[
|
|
message.flow === 'out' ? 'chat-row--end' : '',
|
|
{ 'chat-row--elder': elderMode }
|
|
]">
|
|
<image
|
|
src="https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png"
|
|
class="chat-avatar"
|
|
:class="[
|
|
message.flow === 'out' ? 'chat-avatar--right' : '',
|
|
{ 'chat-avatar--elder': elderMode }
|
|
]"
|
|
></image>
|
|
<view class="chat-row-content" :class="{ 'chat-row-content--elder': elderMode }">
|
|
<view
|
|
v-if="message.type === 'TIMTextElem'"
|
|
class="message-container"
|
|
:class="[
|
|
message.flow === 'out' ? 'my-message' : '',
|
|
{ 'message-container--elder': elderMode }
|
|
]"
|
|
>
|
|
{{ message.payload.text }}
|
|
</view> <image
|
|
v-else-if="message.type === 'TIMImageElem'"
|
|
:style="{ width: imageStyles.width, height: imageStyles.height }"
|
|
:src="getImageUrl(props.message)"
|
|
:class="{ 'chat-image--elder': elderMode }"
|
|
@tap="previewImage(message)"
|
|
@load="imageLoad"
|
|
/>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
<script setup>
|
|
import { ref, watchEffect, onMounted, onUnmounted } from "vue";
|
|
|
|
// 长辈模式状态
|
|
const elderMode = ref(false);
|
|
|
|
// 处理长辈模式变化
|
|
const handleElderModeChange = () => {
|
|
try {
|
|
const storedElderMode = uni.getStorageSync('elderMode');
|
|
elderMode.value = storedElderMode === 'true' || storedElderMode === true;
|
|
|
|
// 同步到全局数据
|
|
const app = getApp();
|
|
if (app && app.globalData) {
|
|
app.globalData.elderMode = elderMode.value;
|
|
}
|
|
} catch (error) {
|
|
console.error('获取长辈模式状态失败:', error);
|
|
elderMode.value = false;
|
|
}
|
|
};
|
|
|
|
onMounted(() => {
|
|
handleElderModeChange();
|
|
// 监听长辈模式变化事件
|
|
uni.$on('elderModeChanged', handleElderModeChange);
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
// 移除事件监听
|
|
uni.$off('elderModeChanged', handleElderModeChange);
|
|
});
|
|
|
|
const props = defineProps({
|
|
message: {
|
|
type: Object,
|
|
default: false,
|
|
},
|
|
text: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
});
|
|
const DEFAULT_MAX_SIZE = 155;
|
|
const imageStyles = ref({
|
|
width: "auto",
|
|
height: "auto",
|
|
});
|
|
// 获取图片URL
|
|
const getImageUrl = (message) => {
|
|
if (!message.payload || !message.payload.imageInfoArray) return "";
|
|
|
|
// 优先使用小图
|
|
const smallImage = message.payload.imageInfoArray.find(
|
|
(item) => item.type === 0
|
|
);
|
|
if (smallImage) return smallImage.url;
|
|
|
|
// 如果没有小图,使用原图
|
|
const originalImage = message.payload.imageInfoArray.find(
|
|
(item) => item.type === 1
|
|
);
|
|
if (originalImage) return originalImage.url;
|
|
return "";
|
|
};
|
|
|
|
// 预览图片
|
|
const previewImage = (message) => {
|
|
if (!message.payload || !message.payload.imageInfoArray) return;
|
|
|
|
// 获取原图URL
|
|
const originalImage = message.payload.imageInfoArray.find(
|
|
(item) => item.type === 1
|
|
);
|
|
if (originalImage) {
|
|
uni.previewImage({
|
|
urls: [originalImage.url],
|
|
});
|
|
}
|
|
};
|
|
|
|
function getImageText(item) {
|
|
return {
|
|
imageUrl: item.imageInfoArray[0].imageUrl,
|
|
imageHeight: item.imageInfoArray[0].height,
|
|
imageWidth: item.imageInfoArray[0].width,
|
|
};
|
|
}
|
|
|
|
const genImageStyles = () => {
|
|
const imageInfoArray = props.message?.payload?.imageInfoArray;
|
|
if (
|
|
imageInfoArray &&
|
|
Array.isArray(imageInfoArray) &&
|
|
imageInfoArray.length > 0
|
|
) {
|
|
const { width, height } = imageInfoArray[0];
|
|
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";
|
|
}
|
|
};
|
|
const imageLoad = (event) => {
|
|
genImageStyles(event.detail);
|
|
};
|
|
|
|
watchEffect(() => {
|
|
genImageStyles(props.message);
|
|
});
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
.chat-row {
|
|
display: flex;
|
|
padding-bottom: 20rpx;
|
|
width: 100%;
|
|
|
|
@at-root &.chat-row--end {
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
// 长辈模式样式
|
|
@at-root &.chat-row--elder {
|
|
padding-bottom: 28rpx; // 增加行间距
|
|
}
|
|
}
|
|
|
|
.message-container {
|
|
padding: 24rpx;
|
|
background: #fbfbfb;
|
|
font-size: 28rpx;
|
|
color: #000;
|
|
border-radius: 0rpx 20rpx 20rpx 20rpx;
|
|
|
|
@at-root &.my-message {
|
|
border-radius: 20rpx 0 20rpx 20rpx;
|
|
background: #dceafd;
|
|
}
|
|
|
|
// 长辈模式样式
|
|
@at-root &.message-container--elder {
|
|
padding: 32rpx; // 增加内边距
|
|
font-size: 36rpx; // 字体放大 1.3倍 (28rpx → 36rpx)
|
|
line-height: 1.5; // 增加行高
|
|
border-radius: 0rpx 26rpx 26rpx 26rpx; // 稍微增大圆角
|
|
|
|
&.my-message {
|
|
border-radius: 26rpx 0 26rpx 26rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.chat-row-content {
|
|
max-width: 80%;
|
|
margin: 0 20rpx;
|
|
overflow: hidden;
|
|
order: 2;
|
|
|
|
// 长辈模式样式
|
|
@at-root &.chat-row-content--elder {
|
|
margin: 0 26rpx; // 稍微增加间距
|
|
}
|
|
}
|
|
|
|
.chat-avatar {
|
|
flex-shrink: 0;
|
|
width: 72rpx;
|
|
height: 72rpx;
|
|
order: 1;
|
|
|
|
@at-root &.chat-avatar--right {
|
|
order: 3;
|
|
}
|
|
// 长辈模式样式
|
|
@at-root &.chat-avatar--elder {
|
|
width: 90rpx; // 头像稍微放大 (72rpx → 90rpx)
|
|
height: 90rpx;
|
|
}
|
|
}
|
|
|
|
// 聊天图片长辈模式样式
|
|
.chat-image--elder {
|
|
border-radius: 8rpx; // 添加圆角
|
|
transform: scale(1.1); // 长辈模式下图片稍微放大
|
|
}
|
|
</style> |