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

400 lines
10 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;" :style="{'height':msgKeyHeight}">
<view class="g_clear_scroll" style="overflow-y: auto;overflow-x: hidden;">
<!-- :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">
<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('')
onMounted(() => {
// 键盘高度{{keyHeight}} 输入框距离底部距离{{writeStyle}}屏幕高度{{screenHeight}}顶部聊天区域高度{{msgKeyHeight}}
uni.$on('msgKeyHeight', (res) => {
mlwHeight.value = res;
screenHeight1.value = res;
if (res != '100%') {
msgKeyHeight.value = res + 'px'
} else {
msgKeyHeight.value = res
setTimeout(() => {
scrollToBottom();
}, 1)
}
})
// // 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
query.select(".msg-list-wrapper")
.boundingClientRect((res) => {
uni.$emit('screenHeight', res.height);
})
.exec();
// #endif
// #ifdef APP-PLUS
uni.$emit('screenHeight', uni.getSystemInfoSync().windowHeight);
// #endif
uni.$on('KeyboardHeight',(e) =>{
rell.value = "新键盘高度" + e
if (e > 0) {
paddingBottom.value = `padding-bottom:${e}px`
} else {
// e == 0 时,直接设为 0
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>