mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
feat(core): remove auto-scroll when chatting and display down-arrow instead (#13066)
close AI-311 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Simplified chat scroll behavior by removing wheel event tracking and conditional scroll-to-end logic. * Improved scroll position tracking by only updating on scroll end events. * Streamlined scroll-down indicator logic for chat messages, making it more responsive during message transmission. * **Bug Fixes** * Ensured scroll state updates correctly when new messages are being sent. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -17,7 +17,6 @@ import { property, state } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { createRef, type Ref, ref } from 'lit/directives/ref.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
import { throttle } from 'lodash-es';
|
||||
|
||||
import { HISTORY_IMAGE_ACTIONS } from '../../chat-panel/const';
|
||||
import { type AIChatParams, AIProvider } from '../../provider/ai-provider';
|
||||
@@ -185,8 +184,6 @@ export class AIChatContent extends SignalWatcher(
|
||||
// request counter to track the latest request
|
||||
private updateHistoryCounter = 0;
|
||||
|
||||
private wheelTriggered = false;
|
||||
|
||||
private lastScrollTop: number | undefined;
|
||||
|
||||
get messages() {
|
||||
@@ -237,9 +234,6 @@ export class AIChatContent extends SignalWatcher(
|
||||
new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
|
||||
),
|
||||
});
|
||||
|
||||
this.wheelTriggered = false;
|
||||
this.scrollToEnd();
|
||||
};
|
||||
|
||||
private readonly updateActions = async () => {
|
||||
@@ -263,9 +257,6 @@ export class AIChatContent extends SignalWatcher(
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
this.wheelTriggered = false;
|
||||
this.scrollToEnd();
|
||||
};
|
||||
|
||||
private readonly updateContext = (context: Partial<ChatContextValue>) => {
|
||||
@@ -273,59 +264,31 @@ export class AIChatContent extends SignalWatcher(
|
||||
this.onContextChange?.(context);
|
||||
};
|
||||
|
||||
private readonly scrollToEnd = () => {
|
||||
if (!this.wheelTriggered) {
|
||||
this.chatMessagesRef.value?.scrollToEnd();
|
||||
}
|
||||
};
|
||||
|
||||
private readonly _throttledScrollToEnd = throttle(this.scrollToEnd, 600);
|
||||
|
||||
private readonly initChatContent = async () => {
|
||||
this.isHistoryLoading = true;
|
||||
await this.updateHistory();
|
||||
this.isHistoryLoading = false;
|
||||
};
|
||||
|
||||
protected override firstUpdated(): void {
|
||||
protected override firstUpdated(): void {}
|
||||
|
||||
private _scrollListenersInitialized = false;
|
||||
private _initializeScrollListeners() {
|
||||
const chatMessages = this.chatMessagesRef.value;
|
||||
if (chatMessages) {
|
||||
chatMessages.updateComplete
|
||||
.then(() => {
|
||||
const scrollContainer = chatMessages.getScrollContainer();
|
||||
scrollContainer?.addEventListener('wheel', () => {
|
||||
this.wheelTriggered = true;
|
||||
});
|
||||
scrollContainer?.addEventListener('scrollend', () => {
|
||||
this.lastScrollTop = scrollContainer.scrollTop;
|
||||
});
|
||||
this._scrollListenersInitialized = true;
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
}
|
||||
|
||||
protected override updated(changedProperties: PropertyValues) {
|
||||
if (this.chatContextValue.status === 'loading') {
|
||||
// reset the wheel triggered flag when the status is loading
|
||||
this.wheelTriggered = false;
|
||||
}
|
||||
|
||||
if (
|
||||
changedProperties.has('chatContextValue') &&
|
||||
(this.chatContextValue.status === 'loading' ||
|
||||
this.chatContextValue.status === 'error' ||
|
||||
this.chatContextValue.status === 'success')
|
||||
) {
|
||||
setTimeout(this.scrollToEnd, 500);
|
||||
}
|
||||
|
||||
if (
|
||||
changedProperties.has('chatContextValue') &&
|
||||
this.chatContextValue.status === 'transmitting'
|
||||
) {
|
||||
this._throttledScrollToEnd();
|
||||
}
|
||||
|
||||
// restore pinned chat scroll position
|
||||
if (
|
||||
changedProperties.has('host') &&
|
||||
@@ -334,6 +297,10 @@ export class AIChatContent extends SignalWatcher(
|
||||
) {
|
||||
this.chatMessagesRef.value?.scrollToPos(this.lastScrollTop);
|
||||
}
|
||||
|
||||
if (!this._scrollListenersInitialized) {
|
||||
this._initializeScrollListeners();
|
||||
}
|
||||
}
|
||||
|
||||
public reset() {
|
||||
|
||||
@@ -262,10 +262,7 @@ export class AIChatMessages extends WithDisposable(ShadowlessElement) {
|
||||
const { isHistoryLoading } = this;
|
||||
const filteredItems = this.messages;
|
||||
|
||||
const showDownIndicator =
|
||||
this.canScrollDown &&
|
||||
filteredItems.length > 0 &&
|
||||
this.chatContextValue.status !== 'transmitting';
|
||||
const showDownIndicator = this.canScrollDown && filteredItems.length > 0;
|
||||
|
||||
return html`
|
||||
<div
|
||||
@@ -393,6 +390,13 @@ export class AIChatMessages extends WithDisposable(ShadowlessElement) {
|
||||
if (_changedProperties.has('isHistoryLoading')) {
|
||||
this.canScrollDown = false;
|
||||
}
|
||||
|
||||
if (
|
||||
_changedProperties.has('chatContextValue') &&
|
||||
this.chatContextValue.status === 'transmitting'
|
||||
) {
|
||||
this._onScroll();
|
||||
}
|
||||
}
|
||||
|
||||
scrollToEnd() {
|
||||
|
||||
Reference in New Issue
Block a user