fix browser scrollable bug

This commit is contained in:
Zhang Minghan 2023-11-12 08:09:19 +08:00
parent cfd4fe782c
commit 3250e34cad
3 changed files with 63 additions and 2 deletions

View File

@ -5,6 +5,7 @@ import { selectCurrent, selectMessages } from "@/store/chat.ts";
import MessageSegment from "@/components/Message.tsx"; import MessageSegment from "@/components/Message.tsx";
import { connectionEvent } from "@/events/connection.ts"; import { connectionEvent } from "@/events/connection.ts";
import { chatEvent } from "@/events/chat.ts"; import { chatEvent } from "@/events/chat.ts";
import {addEventListeners} from "@/utils/dom.ts";
type ChatInterfaceProps = { type ChatInterfaceProps = {
setTarget: (target: HTMLDivElement | null) => void; setTarget: (target: HTMLDivElement | null) => void;
@ -14,10 +15,11 @@ function ChatInterface({ setTarget }: ChatInterfaceProps) {
const ref = React.useRef(null); const ref = React.useRef(null);
const messages: Message[] = useSelector(selectMessages); const messages: Message[] = useSelector(selectMessages);
const current: number = useSelector(selectCurrent); const current: number = useSelector(selectCurrent);
const [scrollable, setScrollable] = React.useState(true);
useEffect( useEffect(
function () { function () {
if (!ref.current) return; if (!ref.current || !scrollable) return;
const el = ref.current as HTMLDivElement; const el = ref.current as HTMLDivElement;
el.scrollTop = el.scrollHeight; el.scrollTop = el.scrollHeight;
chatEvent.emit(); chatEvent.emit();
@ -25,6 +27,22 @@ function ChatInterface({ setTarget }: ChatInterfaceProps) {
[messages], [messages],
); );
useEffect(() => {
if (!ref.current) return;
const el = ref.current as HTMLDivElement;
const event = () => {
setScrollable(
el.scrollTop + el.clientHeight + 100 >= el.scrollHeight,
);
}
return addEventListeners(el, [
"scroll", "resize", "touchmove",
"touchend", "touchcancel",
], event);
}, [ref]);
useEffect(() => { useEffect(() => {
setTarget(ref.current); setTarget(ref.current);
}, [ref]); }, [ref]);

View File

@ -8,7 +8,7 @@ import {
} from "@/utils/env.ts"; } from "@/utils/env.ts";
import { getMemory } from "@/utils/memory.ts"; import { getMemory } from "@/utils/memory.ts";
export const version = "3.6.18"; export const version = "3.6.19";
export const dev: boolean = getDev(); export const dev: boolean = getDev();
export const deploy: boolean = true; export const deploy: boolean = true;
export let rest_api: string = getRestApi(deploy); export let rest_api: string = getRestApi(deploy);

View File

@ -157,3 +157,46 @@ export function useInputValue(id: string, value: string) {
const input = document.getElementById(id) as HTMLInputElement | undefined; const input = document.getElementById(id) as HTMLInputElement | undefined;
return input && replaceInputValue(input, value) && input.focus(); return input && replaceInputValue(input, value) && input.focus();
} }
export function addEventListener(
el: HTMLElement,
event: string,
handler: EventListenerOrEventListenerObject,
): () => void {
/**
* Add event listener to element
* @param el Element
* @param event Event name
* @param handler Event handler
* @example
* const el = document.getElementById("el");
* const handler = () => console.log("Hello world!");
* const remove = addEventListener(el, "click", handler);
* remove();
*/
el.addEventListener(event, handler);
return () => el.removeEventListener(event, handler);
}
export function addEventListeners(
el: HTMLElement,
events: string[],
handler: EventListenerOrEventListenerObject,
): () => void {
/**
* Add event listeners to element
* @param el Element
* @param events Event names
* @param handler Event handler
* @example
* const el = document.getElementById("el");
* const handler = () => console.log("Hello world!");
* const remove = addEventListeners(el, ["click", "touchstart"], handler);
* remove();
*/
events.forEach((event) => el.addEventListener(event, handler));
return () => events.forEach((event) => el.removeEventListener(event, handler));
}