[webchat] Web chat does not scroll to latest comment in Chrome. [I've fixed it!]

Make all T-Engine/ToME 4 bug reports here

Moderator: Moderator

Post Reply
Message
Author
Cook66
Posts: 4
Joined: Wed May 11, 2022 7:29 pm

[webchat] Web chat does not scroll to latest comment in Chrome. [I've fixed it!]

#1 Post by Cook66 »

Sorry if this is the wrong place for this, but I can't find anywhere else to post it.

Problem
The chrome webchat does not scroll to the bottom when a new comment is added.

What happens
The chat has a function which checks if a user has scrolled up the log manually before it scrolls to the bottom when a new comment is added.

This is done to let people scroll up to read old comments, without new ones forcing them to the bottom.

Code responsible: line 299 of https://te4.org/ingame-chat/connected
Inside function: chatlogAdd(text)

Code: Select all

if ((parent.prop('scrollHeight') - parent.prop('clientHeight')) == parent.prop('scrollTop')) doscroll = true;
What this does: IF "Amount user has scrolled down" EQUALS "Bottom of page" THEN "scroll down"
This is represented as a number, but the problem is that chrome for some reason isn't exact here. It sometimes thinks the bottom of the page is a bit lower or higher than it actually is.
The reason it NEVER works is because chrome returns the user position as for example: 1000.50 (when user is at bottom)
But the actual bottom of the page is 1000, so the comparison fails and it doesn't scroll.

But even if we fixed this, it will still fail because sometimes chrome thinks the user is at 999, not 1000, after it has moved the user to the bottom.

To solve this we need to give some wiggle room, not use a perfect comparison. In my testing I found giving it a 5 pixel wiggle room was enough to always work, but not so much that the user can't scroll up.

The solution
Change line 299 of https://te4.org/ingame-chat/connected

Code: Select all

if ((parent.prop('scrollHeight') - parent.prop('clientHeight')) == parent.prop('scrollTop')) doscroll = true;
To:

Code: Select all

if ((parent.prop('scrollHeight') - parent.prop('clientHeight') - 5) <= parent.prop('scrollTop')) doscroll = true;
== changed to <=
This means if the user/chrome has scrolled lower than what should be the lowest, we keep scrolling, since chrome adds a random point value to what should be the bottom sometimes.

(parent.prop('scrollHeight') - parent.prop('clientHeight')) to (parent.prop('scrollHeight') - parent.prop('clientHeight') - 5)
5 pixels of "playroom" where the auto scroll keeps scrolling.
Subtracting 5 pixels is so little that almost any manual user scrolling stops auto scrolling, but accounts for the times chrome doesn't scroll all the way down, for what ever reason.

5 is arbitrary, and I never saw it be that much out of sync, so it can be set lower, but if you only scroll up that little I think you intended to be at the bottom anyway. Increasing this to 10-20 might be a good UX decision since it would account for users failing to scroll ALL the way down, when that is probably what they tried to do.

Other browsers
I have tested my fix in Firefox, and it works fine. It should work anywhere where auto scrolling already works since the fix doesn't change much, it just adds a more flexible way to make sure the chat is scrolled all the way to the bottom.

If it turns out to break something in another browser I can easily fix that as well though.

Cook66
Posts: 4
Joined: Wed May 11, 2022 7:29 pm

Re: [webchat] Web chat does not scroll to latest comment in Chrome. [I've fixed it!]

#2 Post by Cook66 »

If you want to test my fix before implementing it simply do this:
  1. Open chat, make sure you're connected:
  2. Press F12
  3. Open the "Console" tab
  4. Paste the code below into the input box at the bottom, after the >
  5. Press enter
Warning!
Doing this means you'll be running the code below in your browser, only do this with code you trust, it can be dangerous!
If you don't trust my code, do not run it!

Code: Select all

function chatlogAdd(text) {
	if (timestamp_enabled) {
		var d = new Date();
		text = "<span class='date'>&lt;" + d.toLocaleTimeString() + "&gt;</span> " + text;
	}
	var parent = $("#chatlog").parent();
	var doscroll = false;
	if ((parent.prop('scrollHeight') - parent.prop('clientHeight') - 5) <= parent.prop('scrollTop')) doscroll = true;
	$('#chatlog').append("<div class='log'>"+text+"</div>");
	if (doscroll) parent.prop({ scrollTop: parent.prop("scrollHeight") });
}

Post Reply