From effdbc4d956ae029238b327757f74ec8ad5f4618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 18 Feb 2026 13:36:54 -0500 Subject: [PATCH] use visualViewport if it exists to detecth mobile keyboard open and scroll to bottom of chat list if we are near, this keeps the message list at the bottom when you open the keyboard on mobile --- public/src/client/chats.js | 34 ++++++++++++++++++++++++++-------- public/src/modules/chat.js | 2 +- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/public/src/client/chats.js b/public/src/client/chats.js index 0f2ef05082..9c0c7c0ddf 100644 --- a/public/src/client/chats.js +++ b/public/src/client/chats.js @@ -32,6 +32,8 @@ define('forum/chats', [ let chatNavWrapper = null; + let isAtBottom = true; + $(window).on('action:ajaxify.start', function () { Chats.destroyAutoComplete(ajaxify.data.roomId); if (ajaxify.data.template.chats) { @@ -90,7 +92,10 @@ define('forum/chats', [ const mainWrapper = $('[component="chat/main-wrapper"]'); const chatMessageContent = $('[component="chat/message/content"]'); const chatControls = components.get('chat/controls'); - Chats.addSendHandlers(roomId, $('.chat-input'), $('.expanded-chat button[data-action="send"]')); + const chatInput = $('[component="chat/input"]'); + + Chats.addSendHandlers(roomId, chatInput, $('.expanded-chat button[data-action="send"]')); + Chats.addMobileResizeHandler(chatMessageContent); Chats.addPopoutHandler(); Chats.addActionHandlers(components.get('chat/message/window'), roomId); Chats.addManageHandler(roomId, chatControls.find('[data-action="manage"]')); @@ -105,18 +110,16 @@ define('forum/chats', [ Chats.addTypingHandler(mainWrapper, roomId); Chats.addIPHandler(mainWrapper); Chats.addCopyTextLinkHandler(mainWrapper); - Chats.createAutoComplete(roomId, $('[component="chat/input"]')); + Chats.createAutoComplete(roomId, chatInput); Chats.addUploadHandler({ dragDropAreaEl: $('.chats-full'), - pasteEl: $('[component="chat/input"]'), + pasteEl: chatInput, uploadFormEl: $('[component="chat/upload"]'), uploadBtnEl: $('[component="chat/upload/button"]'), - inputEl: $('[component="chat/input"]'), + inputEl: chatInput, }); - $('[data-action="close"]').on('click', function () { - Chats.switchChat(); - }); + $('[data-action="close"]').on('click', () => Chats.switchChat()); userList.init(roomId, mainWrapper); Chats.addNotificationSettingHandler(roomId, mainWrapper); messageSearch.init(roomId, mainWrapper); @@ -295,7 +298,12 @@ define('forum/chats', [ let loading = false; let previousScrollTop = el.scrollTop(); let currentScrollTop = previousScrollTop; - el.off('scroll').on('scroll', utils.debounce(async function () { + + el.off('scroll'); + el.on('scroll', function () { + isAtBottom = messages.isAtBottom(el); + }); + el.on('scroll', utils.debounce(async function () { if (parseInt(el.attr('data-ignore-next-scroll'), 10) === 1) { el.removeAttr('data-ignore-next-scroll'); previousScrollTop = el.scrollTop(); @@ -546,6 +554,16 @@ define('forum/chats', [ }); }; + Chats.addMobileResizeHandler = function (chatMessageContent) { + if (utils.isMobile() && window.visualViewport) { + window.visualViewport.addEventListener('resize', function () { + if (isAtBottom) { + messages.scrollToBottom(chatMessageContent); + } + }); + } + }; + Chats.createAutoComplete = function (roomId, element, options = {}) { if (!element.length) { return; diff --git a/public/src/modules/chat.js b/public/src/modules/chat.js index 81b9ce9d9c..be70ba0937 100644 --- a/public/src/modules/chat.js +++ b/public/src/modules/chat.js @@ -20,7 +20,7 @@ define('chat', [ roomId: roomId, uid: uid, }).then((hookData) => { - if (!hookData.modal) { + if (!hookData.modal || utils.isMobile()) { return ajaxify.go(`/chats/${roomId}`); } if (Chat.modalExists(roomId)) {