Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 修复消息滚动相关bug #58

Merged
merged 1 commit into from
Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/components/VirtualList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,15 @@ export default defineComponent({
/**
* 滚动到指定索引
* @param index 索引值
* @param smooth 是否平滑滚动
* @param topDistance 顶部间隔距离
* @description 如果索引值大于等于数据长度说明到底了则滚动到底部
*/
const scrollToIndex = (index: number, smooth?: boolean) => {
const scrollToIndex = (index: number, smooth?: boolean, topDistance = 0) => {
if (index >= props.data.length - 1) {
scrollToBottom()
} else {
const offset = virtual.getOffset(index)
const offset = virtual.getOffset(index) - topDistance
scrollToOffset(offset, smooth)
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/stores/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ export const useChatStore = defineStore('chat', () => {
params: { pageSize: size, cursor: cursor.value, roomId: 1 },
})
.send()
.catch(() => {
isLoading.value = false
})
if (!data) return
const computedList = computedTimeBlock(data.list)
computedList.forEach((msg) => {
Expand Down
4 changes: 2 additions & 2 deletions src/views/Home/components/ChatList/MsgItem/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const scrollToMsg = async (msg: MsgType) => {
// 如果消息已经加载过了,就直接跳转
const index = chatStore.getMsgIndex(reply.id)
if (index > -1) {
virtualListRef?.value?.scrollToIndex(index, true)
virtualListRef?.value?.scrollToIndex(index, true, 12)
} else {
// 如果没有加载过,就先加载,然后跳转
const curMsgIndex = chatStore.getMsgIndex(id)
Expand All @@ -85,7 +85,7 @@ const scrollToMsg = async (msg: MsgType) => {
await chatStore.loadMore(needLoadPageSize)
// 跳转
// FIXME 这时候新加载消息了,所以会有滚动冲突,故不加动画效果,否则会很怪异。
setTimeout(virtualListRef?.value?.scrollToIndex(chatStore.getMsgIndex(reply.id), false), 0)
setTimeout(virtualListRef?.value?.scrollToIndex(chatStore.getMsgIndex(reply.id), false, 12), 0)
// TODO 跳转到的消息 高亮一下
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/views/Home/components/ChatList/MsgItem/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
width: fit-content;
min-height: 1em;
padding: 8px 12px;
font-size: 15px;
line-height: 22px;
color: #fff;
word-break: break-word;
white-space: pre-line;
Expand Down
22 changes: 13 additions & 9 deletions src/views/Home/components/ChatList/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ const goToBottom = () => {
}
}

// 回到最新消息
const goToNewMessage = () => {
// 未读消息数 = 总数 - 新消息数
virtualListRef.value.scrollToIndex(chatStore.chatMessageList.length - chatStore.newMsgCount)
}

// 提供虚拟列表 ref 给子组件使用
provide('virtualListRef', virtualListRef)

Expand All @@ -29,14 +35,12 @@ onMounted(() => {
})

// 到顶部时触发函数 记录旧的滚动高度,加载更多消息后滚动回加载时那条消息的位置
const onTotop = throttle(async () => {
const oldScrollTop = virtualListRef.value.getScrollSize()
const onTotop = async () => {
if (chatStore.isLoading) return
const oldIndex = virtualListRef.value.getSizes()
await chatStore.loadMore()
nextTick(() => {
const newScrollTop = virtualListRef.value.getScrollSize() - oldScrollTop
virtualListRef.value.scrollToOffset(newScrollTop)
})
}, 1600)
virtualListRef.value.scrollToIndex(virtualListRef.value.getSizes() - oldIndex)
}

// 滚动时触发函数,主要处理新消息提示
const onScroll = throttle((eventData) => {
Expand Down Expand Up @@ -78,8 +82,8 @@ const getKey = (item: MessageType) => item.message.id
<template v-if="!chatStore.isLoading && chatStore.chatMessageList?.length === 0">
<div class="empty">暂无消息,快来发送第一条消息吧~</div>
</template>
<span class="new-msgs-tips" v-show="chatStore.newMsgCount > 0" @click="goToBottom">
{{ chatStore.newMsgCount }}条新消息
<span class="new-msgs-tips" v-show="chatStore.newMsgCount > 0" @click="goToNewMessage">
{{ chatStore.newMsgCount }} 条新消息
<el-icon :size="10"><IEpArrowDownBold /></el-icon>
</span>
</div>
Expand Down
18 changes: 9 additions & 9 deletions src/views/Home/components/ChatList/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
perspective: 1000;

.loading {
display: flex;
position: absolute;
z-index: 20;
gap: 4px;
align-items: center;
justify-content: center;
width: 100%;
margin-bottom: 4px;
padding: 16px 0;
font-size: 14px;
color: #999;
color: #eee;
background: linear-gradient(180deg, rgb(50 54 68 / 100%) 0%, rgb(50 54 68 / 0%) 85%);

svg {
@keyframes rotate {
Expand Down Expand Up @@ -61,14 +61,14 @@
align-items: center;
padding: 2px 12px;
font-size: 14px;
line-height: 1;
color: var(--el-color-primary-light-3);
cursor: pointer;
background-color: var(--color-gray-bg);
border: 1px solid #fff;
background-color: var(--color-dark-bg);
border-radius: 12px;
box-shadow: 0 0 1px 1px var(--el-box-shadow-dark);

&:hover {
background-color: var(--color-primary);
background-color: #1a1c22;
}
}

Expand Down