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

238 lines
6.2 KiB
Vue

5 months ago
<template>
<div class="msg-list-wrapper" @click="handleTapMessageList">
<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;">
<view class="g_clear_scroll"
style="overflow-y: auto; min-height: 100%;height: auto !important;overflow-x: hidden;"
:style="paddingBottom">
<!-- <div v-show="!noMore" @click.stop="onLoadMore" class="view-more-text">
{{ t("viewMoreText") }}
</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>
</div>
</view>
</scroll-view>
</div>
</template>
<script lang="ts" setup>
import { ref, computed, onBeforeMount, onMounted, onUnmounted, defineProps, withDefaults } 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;
};
}>(),
{}
);
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);
}
});
});
const handleScroll = (event) => {
const scrollTop = event.detail.scrollTop;
if (scrollTop <= 100) {
onLoadMore();
// setTimeout(() => {
// scrollTop.value = scrollTop; // 恢复滚动位置
// }, 0);
}
};
const paddingBottom = ref('');
onMounted(() => {
// console.log(finalMsgs.value.length)
// // #ifdef MP-WEIXIN
// if(uni.getSystemInfoSync().osName == "ios"){
uni.$on(events.KeyboardEvent, (e) => {
if (e > 0) {
const count = finalMsgs.value.length;
if (count >= 10) {
paddingBottom.value = `padding-bottom:${e}px`;
} else if (count >= 5 && count < 10) {
paddingBottom.value = `padding-bottom:${count * count * 4}px`;
scrollToBottom();
} else {
paddingBottom.value = `padding-bottom:0px`;
}
} 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 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 onLoadMore = () => {
// // console.log("loadMore")
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>