From aac4ef24a46fe59d0e9ce468f4521e954a206367 Mon Sep 17 00:00:00 2001 From: Massimo Melina Date: Tue, 17 Mar 2026 15:44:00 +0100 Subject: [PATCH 1/2] added gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7552f6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +dist/storage \ No newline at end of file From aa2136d3821f98cb56bcbca84811f4fab375cdf0 Mon Sep 17 00:00:00 2001 From: Massimo Melina Date: Tue, 17 Mar 2026 15:40:50 +0100 Subject: [PATCH 2/2] fix: don't overlap with pagination-bar on phone --- dist/plugin.js | 5 ++++- dist/public/main.js | 49 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/dist/plugin.js b/dist/plugin.js index b372973..dd63548 100644 --- a/dist/plugin.js +++ b/dist/plugin.js @@ -1,4 +1,4 @@ -exports.version = 1.3 +exports.version = 1.31 exports.description = "Simple chat integrated in HFS" exports.apiRequired = 8.87 exports.repo = "damienzonly/hfs-chat" @@ -56,6 +56,9 @@ exports.config = { frontend: true } } +exports.changelog = [ + { "version": 1.21, "message": "fix: don't overlap with pagination-bar on phone" } +] exports.init = async api => { const chatDb = await api.openDb('chat', { rewriteLater: true }) diff --git a/dist/public/main.js b/dist/public/main.js index 9178db4..1ee85d4 100644 --- a/dist/public/main.js +++ b/dist/public/main.js @@ -29,6 +29,7 @@ msg && HFS.toast(msg, 'error') } + const CONTAINER_CLASS = 'chat-container' function ChatContainer() { const {username} = HFS.useSnapState() const [m, sm] = useState(''); @@ -70,8 +71,8 @@ if (goBottom) el?.scrollTo(0, el.scrollHeight) }, [goBottom, msgs, collapsed]) - - return h('div', { className: 'chat-container' }, + useStickyHelper() + return h('div', { className: CONTAINER_CLASS }, h('div', { className: 'chat-header' }, h('span', {}, `Chat`, @@ -134,6 +135,50 @@ }) return isBanned || (!anonCanRead && !anonCanWrite)? null : h(ChatContainer); } + + // don't overlap with pagination-bar when we are in sticky mode + function useStickyHelper() { + useEffect(() => { + let frame = 0 + let resizeObserver + const mutationObserver = new MutationObserver(update) + const stopResize = HFS.domOn('resize', update, { target: window }) + mutationObserver.observe(document.body, { childList: true, subtree: true }) + update() + return () => { + cancelAnimationFrame(frame) + stopResize?.() + mutationObserver.disconnect() + resizeObserver?.disconnect() + const paging = document.getElementById('paging') + if (paging) paging.style.bottom = '' + } + + function update() { + frame ||= requestAnimationFrame(() => { + frame = 0 + const chat = document.querySelector('.'+CONTAINER_CLASS) + const paging = document.getElementById('paging') + if (!paging) return + if (!chat) { + paging.style.bottom = '' + return + } + const { position } = getComputedStyle(chat) + // use the applied css position as source of truth, so js doesn't duplicate media-query rules + const shouldOffsetPaging = position === 'sticky' + paging.style.bottom = shouldOffsetPaging ? Math.ceil(chat.getBoundingClientRect().height) + 'px' : '' + resizeObserver?.disconnect() + if (window.ResizeObserver) { + resizeObserver = new ResizeObserver(update) + resizeObserver.observe(chat) + resizeObserver.observe(paging) + } + }) + } + + }, []) + } }