feat: auto-pause chat on scroll, resume at bottom
This commit is contained in:
@@ -64,7 +64,6 @@ export interface AppConfig {
|
|||||||
matchmaker: Keybind;
|
matchmaker: Keybind;
|
||||||
matchmakerAccept: Keybind;
|
matchmakerAccept: Keybind;
|
||||||
matchmakerCancel: Keybind;
|
matchmakerCancel: Keybind;
|
||||||
pauseChat: Keybind;
|
|
||||||
fullscreenToggle: Keybind;
|
fullscreenToggle: Keybind;
|
||||||
};
|
};
|
||||||
userscripts: {
|
userscripts: {
|
||||||
@@ -120,7 +119,6 @@ export const DEFAULT_KEYBINDS: AppConfig['keybinds'] = {
|
|||||||
matchmaker: { key: 'F6', ctrl: false, shift: false, alt: false },
|
matchmaker: { key: 'F6', ctrl: false, shift: false, alt: false },
|
||||||
matchmakerAccept: { key: 'Enter', ctrl: false, shift: false, alt: false },
|
matchmakerAccept: { key: 'Enter', ctrl: false, shift: false, alt: false },
|
||||||
matchmakerCancel: { key: 'Escape', ctrl: false, shift: false, alt: false },
|
matchmakerCancel: { key: 'Escape', ctrl: false, shift: false, alt: false },
|
||||||
pauseChat: { key: 'F10', ctrl: false, shift: false, alt: false },
|
|
||||||
fullscreenToggle: { key: 'F11', ctrl: false, shift: false, alt: false },
|
fullscreenToggle: { key: 'F11', ctrl: false, shift: false, alt: false },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+24
-2
@@ -16,8 +16,11 @@ let observer: MutationObserver | null = null;
|
|||||||
let historyMax = 0;
|
let historyMax = 0;
|
||||||
let betterChatEnabled = false;
|
let betterChatEnabled = false;
|
||||||
let reInsertGuard = false;
|
let reInsertGuard = false;
|
||||||
|
let scrollPaused = false;
|
||||||
let _con: SavedConsole | null = null;
|
let _con: SavedConsole | null = null;
|
||||||
|
|
||||||
|
const SCROLL_BOTTOM_THRESHOLD = 30; // px from bottom to consider "at bottom"
|
||||||
|
|
||||||
function isChatMessage(node: Node): node is HTMLElement {
|
function isChatMessage(node: Node): node is HTMLElement {
|
||||||
return node.nodeType === 1 && (node as HTMLElement).id?.startsWith('chatMsg_');
|
return node.nodeType === 1 && (node as HTMLElement).id?.startsWith('chatMsg_');
|
||||||
}
|
}
|
||||||
@@ -83,18 +86,37 @@ function handleMutations(mutations: MutationRecord[]): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-scroll unless paused
|
// Auto-scroll to bottom unless the user has scrolled up
|
||||||
if (chatList && !chatList.classList.contains('kpc-chat-paused')) {
|
if (chatList && !scrollPaused) {
|
||||||
chatList.scrollTop = chatList.scrollHeight;
|
chatList.scrollTop = chatList.scrollHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isNearBottom(el: HTMLElement): boolean {
|
||||||
|
return el.scrollHeight - el.scrollTop - el.clientHeight <= SCROLL_BOTTOM_THRESHOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePauseState(): void {
|
||||||
|
if (!chatList) return;
|
||||||
|
const atBottom = isNearBottom(chatList);
|
||||||
|
if (scrollPaused && atBottom) {
|
||||||
|
scrollPaused = false;
|
||||||
|
chatList.classList.remove('kpc-chat-paused');
|
||||||
|
} else if (!scrollPaused && !atBottom) {
|
||||||
|
scrollPaused = true;
|
||||||
|
chatList.classList.add('kpc-chat-paused');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function tryAttach(): boolean {
|
function tryAttach(): boolean {
|
||||||
chatList = document.getElementById('chatList');
|
chatList = document.getElementById('chatList');
|
||||||
if (!chatList) return false;
|
if (!chatList) return false;
|
||||||
|
|
||||||
observer = new MutationObserver(handleMutations);
|
observer = new MutationObserver(handleMutations);
|
||||||
observer.observe(chatList, { childList: true });
|
observer.observe(chatList, { childList: true });
|
||||||
|
|
||||||
|
chatList.addEventListener('scroll', updatePauseState, { passive: true });
|
||||||
|
|
||||||
_con?.log('[KCC-Chat] Observer attached to #chatList');
|
_con?.log('[KCC-Chat] Observer attached to #chatList');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user