Added auto-scrolling to private message panel. Fixed auto-scrolling w/ laggy assets in chat and PM.

This commit is contained in:
rainbow napkin 2025-10-07 03:17:16 -04:00
parent 3d2b40b3c8
commit 4698ba4122
2 changed files with 122 additions and 6 deletions

View file

@ -145,6 +145,12 @@ class chatBox{
*/
this.showChatIcon = document.querySelector("#media-panel-show-chat-icon");
/**
* re-occuring auto-scroll call
* cope for the fact that postprocessedMessage objects in renderMessage aren't throwing load events
*/
this.scrollInterval = setInterval(this.handleAutoScroll.bind(this), 200);
//Setup functions
this.setupInput();
this.defineListeners();
@ -567,11 +573,15 @@ class chatBox{
const bufferHeight = Math.round(bufferRect.height);
const bufferWidth = Math.round(bufferRect.width);
//If last height was unset
if(this.lastHeight == 0){
//Set it based on buffer Height
this.lastHeight = bufferHeight;
}
//if last width is unset
if(this.lastWidth == 0){
//Set it based on buffer width
this.lastWidth = bufferWidth;
}

View file

@ -42,6 +42,32 @@ class pmPanel extends panelObj{
*/
this.txSound = '/nonfree/imsend.ogg';
/**
* Message Buffer Scroll Top on last scroll
*/
this.lastPos = 0;
/**
* Height of Message Buffer on last scroll
*/
this.lastHeight = 0;
/**
* Width of Message Buffer on last scroll
*/
this.lastWidth = 0;
/**
* Whether or not auto-scroll is enabled
*/
this.autoScroll = true;
/**
* re-occuring auto-scroll call
* cope for the fact that postprocessedMessage objects in renderMessage aren't throwing load events
*/
this.scrollInterval = setInterval(this.handleAutoScroll.bind(this), 200);
//Tell PMHandler to start tracking this panel
this.client.pmHandler.panelList.set(this.uuid, null);
@ -49,20 +75,29 @@ class pmPanel extends panelObj{
}
closer(){
//Tell PMHandler to start tracking this panel
//Tell PMHandler to stop tracking this panel
this.client.pmHandler.panelList.delete(this.uuid);
//Clear the scroll interval
clearInterval(this.scrollInterval);
//Run derived closer
super.closer();
}
docSwitch(){
async docSwitch(){
//Call derived method
super.docSwitch();
this.startSeshButton = this.panelDocument.querySelector('#pm-panel-start-sesh');
this.seshList = this.panelDocument.querySelector('#pm-panel-sesh-list');
this.seshBuffer = this.panelDocument.querySelector('#pm-panel-sesh-buffer');
this.seshPrompt = this.panelDocument.querySelector('#pm-panel-message-prompt');
this.seshSendButton = this.panelDocument.querySelector('#pm-panel-send-button');
//reset auto-scroll
this.autoScroll = true;
this.setupInput();
this.renderSeshList();
@ -72,9 +107,6 @@ class pmPanel extends panelObj{
//Render messages
this.renderMessages();
}
//Call derived method
super.docSwitch();
}
/**
@ -92,6 +124,9 @@ class pmPanel extends panelObj{
this.startSeshButton.addEventListener('click', this.startSesh.bind(this));
this.seshPrompt.addEventListener("keydown", this.send.bind(this));
this.seshSendButton.addEventListener("click", this.send.bind(this));
this.seshBuffer.addEventListener('scroll', this.scrollHandler.bind(this));
this.ownerDoc.defaultView.addEventListener('resize', this.handleAutoScroll.bind(this));
}
startSesh(event){
@ -227,6 +262,9 @@ class pmPanel extends panelObj{
//Tell PMHandler what sesh we have open for notification reasons
this.client.pmHandler.readSesh(this.uuid, this.activeSesh);
//Reset auto scroll to scroll newly selected sesh down to the bottom
this.autoScroll = true;
//Re-render message buffer
this.renderMessages();
@ -255,7 +293,7 @@ class pmPanel extends panelObj{
* Renders message out to PM Panel Message Buffer
* @param {Object} message - Message to render
*/
renderMessage(message){
async renderMessage(message){
//If we have an empty message
if(message.msg == null || message.msg == ''){
//BAIL!!
@ -267,6 +305,74 @@ class pmPanel extends panelObj{
//Append message to buffer
this.seshBuffer.appendChild(postprocessedMessage);
//Auto-scroll buffer on content load
this.handleAutoScroll();
}
/**
* Handles scrolling within the message buffer
* @param {Event} event - Event passed down from Event Handler
*/
scrollHandler(event){
//If we're just starting out
if(this.lastPos == 0){
//Set last pos for the first time
this.lastPos = this.seshBuffer.scrollTop;
}
//Calculate scroll delta
const deltaY = this.seshBuffer.scrollTop - this.lastPos;
//Grab visible bounding rect so we don't have to do it again (can't use offset because someone might zoom in :P)
const bufferRect = this.seshBuffer.getBoundingClientRect();
const bufferHeight = Math.round(bufferRect.height);
const bufferWidth = Math.round(bufferRect.width);
//If last height was unset
if(this.lastHeight == 0){
//Set it based on buffer Height
this.lastHeight = bufferHeight;
}
//if last width is unset
if(this.lastWidth == 0){
//Set it based on buffer width
this.lastWidth = bufferWidth;
}
//If we're scrolling up
if(deltaY < 0){
//If we have room to scroll, and we didn't resize
if(this.seshBuffer.scrollHeight > bufferHeight && (this.lastWidth == bufferWidth && this.lastHeight == bufferHeight)){
//Disable auto scrolling
this.autoScroll = false;
//We probably resized
}else{
this.handleAutoScroll();
}
//Otherwise if the difference between the message buffers scroll height and offset height is equal to the scroll top
//(Because it is scrolled all the way down)
}else if((this.seshBuffer.scrollHeight - bufferHeight) == this.seshBuffer.scrollTop){
this.autoScroll = true;
}
//Set last post/size for next the run
this.lastPos = this.seshBuffer.scrollTop;
this.lastHeight = bufferHeight;
this.lastWidth = bufferWidth;
}
/**
// * Auto-scrolls sesh chat buffer when new chats are entered.
*/
handleAutoScroll(){
//If autoscroll is enabled
if(this.autoScroll){
console.log("SCROLLME");
//Set seshBuffer scrollTop to the difference between scrollHeight and buffer height (scroll to the bottom)
this.seshBuffer.scrollTop = this.seshBuffer.scrollHeight - Math.round(this.seshBuffer.getBoundingClientRect().height);
}
}
}