Is your feature request related to a problem? Please describe.
Currently, every single new message sent causes the chat window to scroll all the way to the bottom. This is not ideal for long conversations as you will always need to jump back to the message being replied to, either by pinning the message or clicking the reply message.
This gets old very quickly, and is rather annoying, so I would like an option to disable this behaviour.
Describe the solution you'd like
Just an option in the settings menu to disable automatic scrolling to the bottom when a new message is sent.
Describe alternatives you've considered
I have developed a userscript to block the client's automatic scrolling, but it doesn't work on longer conversations as the chat window's scrollTop is not stable, and different values can refer to different positions in the chat window.
I have pasted the userscript below:
(function () {
"use strict";
// The maximum delay in milliseconds
// after the message is sent to block the scroll
const MAX_DELAY_MS = 1000;
// The keys that send the message
const KEYS_TO_SEND_MESSAGE = ["Enter"];
// The send buttons
const SEND_BUTTONS = {
webK: ".btn-send",
webA: ".main-button",
};
// The input elements
const INPUT_ELEMENTS = {
webK: ".input-message-input.forwards",
webA: "#editable-message-text",
};
// The chat window
const CHAT_WINDOWS = {
webK: ".bubbles-scrollable",
webA: ".MessageList",
};
// The regular expression to remove the . and # from the selector
const REMOVE_SELECTOR_REGEX = /^[.#]+|[.#]$/g;
// The scrollTop property
const SCROLL_TOP = "scrollTop";
// Initialise the message sent time
let messageSentTime = 0;
// The event listener for the button
function updatePreviousState() {
// Set the message sent time
messageSentTime = performance.now();
}
// Create an observer to watch for changes to the page
const observer = new MutationObserver(() => {
// Try to get the button to send the message
const sendButton = document.querySelector(
Object.values(SEND_BUTTONS).join(", "),
);
// Try to get the input element
const input = document.querySelector(
Object.values(INPUT_ELEMENTS).join(", "),
);
// If the button exists and
// the event listener attribute doesn't exist
if (sendButton && !sendButton.dataset.blockerAdded) {
// Add the click event listener to it
sendButton.addEventListener("click", updatePreviousState);
// Set that the event listener has been added
sendButton.dataset.blockerAdded = true;
}
// If the input element exists and
// the event listener attribute doesn't exist
if (input && !input.dataset.blockerAdded) {
// Add the event listener to update the message sent time
// when the keys used to send a message are pressed
input.addEventListener("keydown", event => {
if (KEYS_TO_SEND_MESSAGE.includes(event.code)) {
updatePreviousState();
}
});
// Set that the event listener has been added
input.dataset.blockerAdded = true;
}
});
// Get the prototype of the html element
const prototype = HTMLElement.prototype;
// Get the descriptor for the element
const descriptor =
Object.getOwnPropertyDescriptor(prototype, SCROLL_TOP) ||
Object.getOwnPropertyDescriptor(Element.prototype, SCROLL_TOP);
// Define the getter and setter of the scrollTop property
Object.defineProperty(prototype, SCROLL_TOP, {
// Define the getter
get() {
return descriptor.get.call(this);
},
// Define the setter
set(value) {
// Initialise whether the element is the chat window
let isChatWindow = false;
// Iterate over all the selectors for the chat window
for (const selector of Object.values(CHAT_WINDOWS)) {
// Get the class name
const className = selector.replace(REMOVE_SELECTOR_REGEX, "");
// If the class list contains the class name,
// set that the element is the chat window
if (this.classList.contains(className)) {
isChatWindow = true;
}
}
// If the element is not the chat window
if (!isChatWindow) {
// Call the original set method
descriptor.set.call(this, value);
// Exit the function
return;
}
// console.log("Current value:", descriptor.get.call(this));
// console.log("Given value:", value);
// Get whether the send button has been pressed recently
const sendButtonPressedRecently =
performance.now() - messageSentTime < MAX_DELAY_MS;
// If all the above conditions are met,
// block the scroll by exiting the function
if (sendButtonPressedRecently) {
// console.warn("Blocked programmatic scroll");
return;
}
// Use the original set call to set the value
descriptor.set.call(this, value);
},
configurable: true,
enumerable: descriptor.enumerable,
});
// Observe the document body
observer.observe(document.body, {
childList: true,
subtree: true,
});
// console.log("Telegram scroll blocker installed");
})();
Additional context
I think this shouldn't be too difficult to implement, so I hope it can be implemented as it would make chatting much easier for me.
Is your feature request related to a problem? Please describe.
Currently, every single new message sent causes the chat window to scroll all the way to the bottom. This is not ideal for long conversations as you will always need to jump back to the message being replied to, either by pinning the message or clicking the reply message.
This gets old very quickly, and is rather annoying, so I would like an option to disable this behaviour.
Describe the solution you'd like
Just an option in the settings menu to disable automatic scrolling to the bottom when a new message is sent.
Describe alternatives you've considered
I have developed a userscript to block the client's automatic scrolling, but it doesn't work on longer conversations as the chat window's
scrollTopis not stable, and different values can refer to different positions in the chat window.I have pasted the userscript below:
Additional context
I think this shouldn't be too difficult to implement, so I hope it can be implemented as it would make chatting much easier for me.