优化滚动效果

This commit is contained in:
Wenjie Zhang 2025-02-27 13:26:08 +08:00
parent 2de7b13e87
commit 458912f635

View File

@ -154,7 +154,7 @@
</template>
<script setup>
import { reactive, ref, onMounted, toRefs, nextTick, computed, watch } from 'vue'
import { reactive, ref, onMounted, toRefs, nextTick, onUnmounted, watch } from 'vue'
import {
SendOutlined,
MenuOutlined,
@ -197,7 +197,11 @@ const configStore = useConfigStore()
const { conv, state } = toRefs(props)
const chatContainer = ref(null)
const isStreaming = ref(false)
const userIsScrolling = ref(false);
const shouldAutoScroll = ref(true);
const panel = ref(null)
const modelCard = ref(null)
const examples = ref([
@ -295,10 +299,23 @@ const renameTitle = () => {
}
}
const handleUserScroll = () => {
// 100
const isNearBottom = chatContainer.value.scrollHeight - chatContainer.value.scrollTop - chatContainer.value.clientHeight < 100;
//
userIsScrolling.value = !isNearBottom;
//
shouldAutoScroll.value = isNearBottom;
};
const scrollToBottom = () => {
setTimeout(() => {
chatContainer.value.scrollTop = chatContainer.value.scrollHeight - chatContainer.value.clientHeight
}, 10)
if (shouldAutoScroll.value) {
setTimeout(() => {
chatContainer.value.scrollTop = chatContainer.value.scrollHeight - chatContainer.value.clientHeight;
}, 10);
}
}
const generateRandomHash = (length) => {
@ -502,22 +519,6 @@ const fetchChatResponse = (user_input, cur_res_id) => {
});
}
const fetchRefs = (cur_res_id) => {
return new Promise((resolve, reject) => {
fetch(`/api/chat/refs?cur_res_id=${cur_res_id}`, {
method: "GET",
headers: {
"Content-Type": "application/json"
},
}).then(response => response.json())
.then(data => {
resolve(data.refs)
})
.catch((error) => {
reject(error)
})
})
}
// sendMessage
const sendMessage = () => {
@ -531,6 +532,8 @@ const sendMessage = () => {
isStreaming.value = true;
appendUserMessage(user_input);
appendAiMessage("", null);
forceScrollToBottom();
const cur_res_id = conv.value.messages[conv.value.messages.length - 1].id;
conv.value.inputText = '';
meta.db_name = dbName;
@ -553,15 +556,15 @@ const retryMessage = (id) => {
sendMessage();
}
const autoSend = (msg) => {
conv.value.inputText = msg
sendMessage()
}
//
onMounted(() => {
scrollToBottom()
loadDatabases()
chatContainer.value.addEventListener('scroll', handleUserScroll);
//
const storedMeta = localStorage.getItem('meta');
if (storedMeta) {
const parsedMeta = JSON.parse(storedMeta);
@ -569,6 +572,20 @@ onMounted(() => {
}
});
onUnmounted(() => {
if (chatContainer.value) {
chatContainer.value.removeEventListener('scroll', handleUserScroll);
}
});
//
const forceScrollToBottom = () => {
shouldAutoScroll.value = true;
setTimeout(() => {
chatContainer.value.scrollTop = chatContainer.value.scrollHeight - chatContainer.value.clientHeight;
}, 10);
};
// meta
watch(
() => meta,
@ -728,7 +745,7 @@ watch(
.chat-box {
width: 100%;
max-width: 900px;
max-width: 800px;
margin: 0 auto;
flex-grow: 1;
padding: 1rem 2rem;
@ -819,7 +836,7 @@ watch(
flex-direction: column;
width: 100%;
height: auto;
max-width: 900px;
max-width: 800px;
margin: 0 auto;
padding: 0.25rem 0.5rem;
border: 2px solid var(--gray-200);
@ -1057,24 +1074,29 @@ watch(
</style>
<style lang="less">
.message-box pre {
border-radius: 8px;
font-size: 14px;
border: 1px solid var(--main-light-3);
padding: 1rem;
&:has(code.hljs) {
padding: 0;
}
}
.message-md {
color: var(--gray-900);
max-width: 100%;
pre {
border-radius: 8px;
font-size: 14px;
border: 1px solid var(--main-light-3);
padding: 1rem;
&:has(code.hljs) {
padding: 0;
}
code.hljs {
background-color: var(--gray-100);
}
}
strong {
color: var(--gray-800);
}
h1, h2, h3, h4, h5, h6 {
font-size: 1rem;
}