You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
apply-assistant-v3/root/NEUIKit/pages/Chat/message/message-list.vue

404 lines
11 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="msg-list-wrapper" @click="handleTapMessageList" :style="{'height':msgKeyHeight}">
<scroll-view id="message-scroll-list" scroll-y="true" @scroll="handleScroll" @click.stop="nothing"
:scroll-top="scrollTop" class="message-scroll-list g_flex_column_end" style="overflow-x: hidden;height: 100%" :style="{'height':msgKeyHeight}">
<view class="g_clear_scroll" style="overflow-y: auto;overflow-x: hidden;" :style="isWeapp ? '' :paddingBottom">
<!-- :style="paddingBottom" -->
<!-- <div v-show="!noMore" @click.stop="onLoadMore" class="view-more-text">
{{ t("viewMoreText") }}
底部往上推paddingBottom + {{paddingBottom}}
// 底部往上推paddingBottom + {{paddingBottom}}
// 聊天内容高度msgKeyHeight + {{msgKeyHeight}}
{{rell}}
</div> -->
<view class="msg-tip" v-show="noMore"></view>
<div v-for="(item, index) in finalMsgs" :key="item.renderKey">
聊天区域高度{{msgKeyHeight}}
<MessageItem :msg="item" :index="index" :key="item.renderKey" :reply-msgs-map="replyMsgsMap"
:broadcastNewAudioSrc="broadcastNewAudioSrc"> </MessageItem>
<!-- {{screenHeight1}}
{{msgKeyHeight}} {{screenHeight1}} {{rell}}-->
</div>
<!-- 滚动条位置scrollTop + {{scrollTop}}
底部往上推paddingBottom + {{paddingBottom}}
聊天内容高度msgKeyHeight + {{msgKeyHeight}}
-->
</view>
</scroll-view>
</div>
</template>
<script lang="ts" setup>
import { ref, computed, onBeforeMount, onMounted, onUnmounted, defineProps, withDefaults, getCurrentInstance, nextTick } from "../../../utils/transformVue";
import MessageItem from "./message-item.vue";
import { events } from "../../../utils/constants";
import { caculateTimeago } from "../../../utils/date";
import { t } from "../../../utils/i18n";
import { V2NIMMessageForUI } from "@xkit-yx/im-store-v2/dist/types/types";
import { V2NIMConst } from "nim-web-sdk-ng/dist/v2/NIM_UNIAPP_SDK";
import { V2NIMTeam } from "nim-web-sdk-ng/dist/v2/NIM_UNIAPP_SDK/V2NIMTeamService";
import { autorun } from "mobx";
import { deepClone } from "../../../utils";
const props = withDefaults(
defineProps<{
msgs : V2NIMMessageForUI[];
conversationType : V2NIMConst.V2NIMConversationType;
to : string;
// loadingMore?: boolean;
noMore ?: boolean;
replyMsgsMap ?: {
[key : string] : V2NIMMessageForUI;
};
}>(),
{}
);
let scroll_old = 0
let scroll_new = 0
onBeforeMount(() => {
let team : V2NIMTeam | undefined = undefined;
autorun(() => {
team = deepClone(uni.$UIKitStore.teamStore.teams.get(props.to));
});
if (props.conversationType === V2NIMConst.V2NIMConversationType.V2NIM_CONVERSATION_TYPE_TEAM) {
uni.$UIKitStore.teamMemberStore.getTeamMemberActive({
teamId: props.to,
queryOption: {
limit: Math.max((team as unknown as V2NIMTeam)?.memberLimit || 0, 200),
roleQueryType: 0,
},
});
}
uni.$on(events.AUDIO_URL_CHANGE, (url) => {
broadcastNewAudioSrc.value = url;
});
uni.$on(events.ON_SCROLL_BOTTOM, () => {
scrollToBottom();
});
uni.$on(events.ON_LOAD_MORE, () => {
const msg = finalMsgs.value.filter((item) => !(item.messageType === V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_CUSTOM && ["beReCallMsg", "reCallMsg"].includes(item.recallType || "")))[0];
if (msg) {
uni.$emit(events.GET_HISTORY_MSG, msg);
}
});
uni.$on('newScroll', () => {
// // console.log('AAAA')
const query = uni.createSelectorQuery().in(instance.proxy);
query.select(".message-scroll-list")
// .selectViewport()
.scrollOffset((res) => {
scroll_new = res.scrollHeight;
// scrollTop.value = scroll_new - scroll_old;
// // console.log("竖直滚动位置", scroll_new);
})
.exec();
})
});
// 防抖函数实现
// const debounce = (func, delay) => {
// let timer = null;
// return (...args) => {
// clearTimeout(timer);
// timer = setTimeout(() => {
// func(...args);
// }, delay);
// };
// };
let timer = null;
const handleScroll = (event) => {
// console.log(event)
// console.log(event.detail.scrollTop);
const scrollTop = event.detail.scrollTop;
if (scrollTop <= 150) {
clearTimeout(timer);
timer = setTimeout(() => {
onLoadMore();
}, 300);
// debouncedOnLoadMore();
}
};
const paddingBottom = ref('');
const mlwHeight = ref("");
const msgKeyHeight = ref('100%')
const screenHeight1 = ref('')
const screenHeight2 = ref('')
const isWeapp = ref(true)
onMounted(() => {
// 键盘高度{{keyHeight}} 输入框距离底部距离{{writeStyle}}屏幕高度{{screenHeight}}顶部聊天区域高度{{msgKeyHeight}}
uni.$on('msgKeyHeight', (res) => {
mlwHeight.value = res;
screenHeight1.value = res;
// 无论是否为小程序都直接应用高度移除100%的特殊处理)
if (typeof res === 'number') {
msgKeyHeight.value = `${res - 34}px`;
} else {
msgKeyHeight.value = res; // 处理'100%'的情况
}
// 强制刷新滚动位置
setTimeout(() => {
scrollToBottom();
}, 50);
});
// // console.log(finalMsgs.value.length +"========================")
const query = uni.createSelectorQuery().in(instance.proxy);
query.select(".g_clear_scroll")
// .selectViewport()
.boundingClientRect((res) => {
mlwHeight.value = res.height;
uni.$emit('msgHeight', mlwHeight.value);
// // console.log('message-scroll-list的高度',res)
})
.exec();
// query.select(".msg-list-wrapper")
// // .selectViewport()
// .boundingClientRect((res) => {
// // mlwHeight.value = res.height;
// console.log('screen的高度',res.scrollHeight)
// console.log('screen的高度',res.height)
// screenHeight1.value = res.height
// screenHeight2.value = res.scrollHeight
// uni.$emit('screenHeight', res.height);
// // // console.log('screen的高度',res.height)
// })
// .exec();
// #ifdef MP-WEIXIN
isWeapp.value = true; // 判断是否是微信小程序
query.select(".msg-list-wrapper")
.boundingClientRect((res) => {
uni.$emit('screenHeight', res.height);
})
.exec();
// #endif
// #ifdef APP-PLUS
isWeapp.value = false; // 判断是否是微信小程序
uni.$emit('screenHeight', uni.getSystemInfoSync().windowHeight);
// #endif
// 在message-list.vue的KeyboardHeight监听中修改
uni.$on('KeyboardHeight',(e) =>{
rell.value = "新键盘高度" + e;
if (e > 0) {
// APP端不需要额外padding通过高度控制小程序保留padding
paddingBottom.value = isWeapp.value ? `padding-bottom:${e}px` : '';
} else {
paddingBottom.value = `padding-bottom:0px`;
}
});
// // #ifdef MP-WEIXIN
// if(uni.getSystemInfoSync().osName == "ios"){
uni.$on(events.KeyboardEvent, (e) => {
rell.value = "键盘高度" + e
if (e > 0) {
paddingBottom.value = `padding-bottom:${e}px`
} else {
// e == 0 时,直接设为 0
paddingBottom.value = `padding-bottom:0px`;
}
setTimeout(() => {
scrollToBottom();
}, 1)
});
// }
// // #endif
})
onUnmounted(() => {
uni.$off(events.ON_SCROLL_BOTTOM);
uni.$off(events.ON_LOAD_MORE);
uni.$off(events.AUDIO_URL_CHANGE);
});
const rell = ref('');
const scrollTop = ref(99999);
const finalMsgs = computed(() => {
const res : V2NIMMessageForUI[] = [];
props.msgs.forEach((item, index) => {
// 如果两条消息间隔超过5分钟插入一条自定义时间消息
if (index > 0 && item.createTime - props.msgs[index - 1].createTime > 5 * 60 * 1000) {
res.push({
...item,
messageClientId: "time-" + item.createTime,
messageType: V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_CUSTOM,
sendingState: V2NIMConst.V2NIMMessageSendingState.V2NIM_MESSAGE_SENDING_STATE_SUCCEEDED,
// @ts-ignore
timeValue: caculateTimeago(item.createTime),
renderKey: `${item.createTime + 1}`,
});
}
res.push({
...item,
// @ts-ignore
renderKey: `${item.createTime}`,
});
});
return res;
});
const broadcastNewAudioSrc = ref<string>("");
// 消息滑动到底部,建议搭配 nextTick 使用
const scrollToBottom = () => {
scrollTop.value += 9999999;
const timer = setTimeout(() => {
scrollTop.value += 1;
clearTimeout(timer);
}, 1);
};
const instance = getCurrentInstance();
const onLoadMore = () => {
if (!uni.$events || !uni.$events[events.KeyboardEvent]) {
// 如果事件未注册,直接执行 else 逻辑
console.log("KeyboardEvent not registered, executing else logic");
const query = uni.createSelectorQuery().in(instance.proxy);
query
.select(".message-scroll-list")
.scrollOffset((res) => {
scroll_old = res.scrollHeight;
})
.exec();
console.log(finalMsgs)
const msg = finalMsgs.value.filter(
(item) =>
!(
item.messageType ===
V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_CUSTOM &&
['beReCallMsg', 'reCallMsg'].includes(item.recallType || '')
)
)[0];
if (msg) {
uni.$emit(events.GET_HISTORY_MSG, msg);
}
return;
}
// uni.$on(events.KeyboardEvent, (e) => {
// if (e > 0) {
// console.log("e>0")
// return
// }else{
// console.log("e=0")
// const query = uni.createSelectorQuery().in(instance.proxy);
// query
// .select(".message-scroll-list")
// // .selectViewport()
// .scrollOffset((res) => {
// scroll_old = res.scrollHeight;
// // // console.log("竖直滚动位置", res.scrollHeight);
// })
// .exec();
// const msg = finalMsgs.value.filter(
// (item) =>
// !(
// item.messageType ===
// V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_CUSTOM &&
// ['beReCallMsg', 'reCallMsg'].includes(item.recallType || '')
// )
// )[0]
// if (msg) {
// uni.$emit(events.GET_HISTORY_MSG, msg)
// }
// }
// })
};
const nothing = () => {
// // console.log("nothing")
uni.$emit(events.KeyboardEvent, 0)
setTimeout(() => {
uni.$emit(events.CLOSE_PANEL);
}, 100);
};
const handleTapMessageList = () => {
uni.$emit(events.KeyboardEvent, 0)
setTimeout(() => {
uni.$emit(events.CLOSE_PANEL);
}, 100);
};
</script>
<style scoped lang="scss">
.msg-list-wrapper {
flex: 1;
overflow: hidden;
display: flex;
height: 100%;
box-sizing: border-box;
padding: 0;
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
background-color: #ededed;
}
.msg-tip {
text-align: center;
color: #b3b7bc;
font-size: 12px;
margin-top: 10px;
}
.block {
width: 100%;
height: 40px;
}
.message-scroll-list {
// height: 100%;
box-sizing: border-box;
padding-bottom: 1px;
}
.view-more-text {
text-align: center;
color: #b3b7bc;
font-size: 12px;
margin-top: 20px;
}
page>view>message>view>message-list {
height: 100%;
}
.first-msg {
margin-top: 16px;
}
</style>