diff --git a/frontend/src/tools/nachrichten.jsx b/frontend/src/tools/nachrichten.jsx index 04a5f2b..16d7ede 100644 --- a/frontend/src/tools/nachrichten.jsx +++ b/frontend/src/tools/nachrichten.jsx @@ -209,20 +209,35 @@ export default function Nachrichten({ toast, mobile, nav }) { // ── Scroll to bottom ───────────────────────────────────────────────────────── const prevLengthRef = useRef(0); const prevUserRef = useRef(null); + + function scrollToBottom(behavior = 'instant') { + bottomRef.current?.scrollIntoView({ behavior }); + } + useEffect(() => { if (!bottomRef.current) return; - const userChanged = prevUserRef.current !== activeUser?.id; - const isFirstLoad = prevLengthRef.current === 0 && messages.length > 0; + const userChanged = prevUserRef.current !== activeUser?.id; + const isFirstLoad = prevLengthRef.current === 0 && messages.length > 0; prevLengthRef.current = messages.length; prevUserRef.current = activeUser?.id; - // Bei User-Wechsel oder erstem Laden: sofort ans Ende springen if (userChanged || isFirstLoad) { - bottomRef.current.scrollIntoView({ behavior: 'instant' }); + scrollToBottom('instant'); } else if (messages.length > 0) { - bottomRef.current.scrollIntoView({ behavior: 'smooth' }); + scrollToBottom('smooth'); } }, [messages.length, activeUser?.id]); + // Wenn Handy-Tastatur aufklappt (visualViewport schrumpft) → ans Ende scrollen + useEffect(() => { + if (!window.visualViewport) return; + const onResize = () => { + // Kleine Verzögerung damit Layout neu berechnet wird + setTimeout(() => scrollToBottom('instant'), 50); + }; + window.visualViewport.addEventListener('resize', onResize); + return () => window.visualViewport.removeEventListener('resize', onResize); + }, []); + // ── Handlers ───────────────────────────────────────────────────────────────── const loadUsers = async () => { try { const u = await api('/tools/nachrichten/users'); setUsers(u);