openvibers/openvibe.live Commits

Mobile chat sheet: tapping inside the offline channel chat (input, emote button) no longer closes it — the outside-tap closer now knows both sheets and chat-owned pickers/modals

OP OpenVibers committed 16 Sept 2026 · f512b8e84c · 2 files, +13 −10

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CMxJm1dB8rdsaMSgNjVa82

Changes

ddiff --git a/public/index.html b/public/index.html
iindex be7b15e9..835219d2 100644
---- a/public/index.html
++++ b/public/index.html
@@@ -5089,7 +5089,7 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig
<script src="/js/chat-shared.js?v=3" defer></script>
<script src="/js/emotes.js?v=8" defer></script>
<script src="/js/gif-picker.js?v=1" defer></script>
--<script src="/js/chat.js?v=80" defer></script>
++<script src="/js/chat.js?v=81" defer></script>
<script src="/js/chat-autocomplete.js?v=1" defer></script>
<script src="/js/channel-uploads.js?v=12" defer></script>
<script src="/js/controls.js?v=8" defer></script>
ddiff --git a/public/js/chat.js b/public/js/chat.js
iindex 75723762..2ac97834 100644
---- a/public/js/chat.js
++++ b/public/js/chat.js
@@@ -6499,15 +6499,19 @@ const _origAddChatMessage = typeof addChatMessage === 'function' ? addChatMessag
if (_mobileChatOpen) toggleMobileChat();
});
-- // Close mobile chat when tapping the backdrop scrim
++ // Close mobile chat when tapping the backdrop scrim. The open sheet is #chat-sidebar on a
++ // LIVE channel but #offline-global-chat on an offline one — checking only the live one made
++ // every tap inside the offline chat (the input, the emote button…) count as "outside" and
++ // slam the sheet shut. Anything chat-owned that renders outside the sheet (pickers, modals,
++ // toasts) is inside too.
++ const INSIDE = ['#chat-sidebar', '#offline-global-chat', '#mobile-chat-toggle', '.emote-picker', '.emote-picker-panel', '.gif-picker', '.soundboard-panel', '.chat-picker', '.modal', '.modal-overlay', '.toast', '.tts-voice-picker', '.chat-context-menu'];
document.addEventListener('click', (e) => {
if (!_mobileChatOpen || !isMobileChatLayout()) return;
-- // Check if click is on the scrim (the ::after pseudo-element area above chat)
-- const sidebar = document.getElementById('chat-sidebar');
-- const fab = document.getElementById('mobile-chat-toggle');
-- if (sidebar && !sidebar.contains(e.target) && fab && !fab.contains(e.target)) {
-- toggleMobileChat();
-- }
++ const t = e.target;
++ if (!t || !(t instanceof Element)) return;
++ if (INSIDE.some(sel => t.closest(sel))) return;
++ // Only the scrim (the page behind the sheet) closes it.
++ toggleMobileChat();
});
// Reset state on resize crossing the breakpoint
@@@ -6517,8 +6521,7 @@ const _origAddChatMessage = typeof addChatMessage === 'function' ? addChatMessag
if (_wasMobile && !nowMobile && _mobileChatOpen) {
// Went from mobile → desktop while chat was open: reset
_mobileChatOpen = false;
-- const sidebar = document.getElementById('chat-sidebar');
-- if (sidebar) sidebar.classList.remove('mobile-chat-open');
++ for (const id of ['chat-sidebar', 'offline-global-chat']) { const sb = document.getElementById(id); if (sb) sb.classList.remove('mobile-chat-open'); }
document.body.classList.remove('mobile-chat-visible');
const fab = document.getElementById('mobile-chat-toggle');
if (fab) {