This commit is contained in:
2026-05-18 18:32:19 +02:00
parent 3ac1489d1f
commit 0074355df8
2 changed files with 26 additions and 10 deletions

View File

@@ -10463,7 +10463,7 @@ body.layout-modern>.pagewrapper:not(:has(.index-layout-wrapper)):not(:has(.item-
max-width: none !important; max-width: none !important;
max-height: none !important; max-height: none !important;
width: auto !important; width: auto !important;
height: 100% !important; height: auto !important;
border-radius: 2px; border-radius: 2px;
animation: modalZoomIn 0.3s cubic-bezier(0.165, 0.84, 0.44, 1); animation: modalZoomIn 0.3s cubic-bezier(0.165, 0.84, 0.44, 1);
cursor: move !important; cursor: move !important;
@@ -10888,8 +10888,15 @@ body.layout-modern .tag-controls {
} }
@keyframes dm-presence-pulse { @keyframes dm-presence-pulse {
0%, 100% { box-shadow: 0 0 0 2px rgba(61, 220, 132, 0.25); }
50% { box-shadow: 0 0 0 4px rgba(61, 220, 132, 0.1); } 0%,
100% {
box-shadow: 0 0 0 2px rgba(61, 220, 132, 0.25);
}
50% {
box-shadow: 0 0 0 4px rgba(61, 220, 132, 0.1);
}
} }
/* ── Key notice banner ───────────────────────────────────── */ /* ── Key notice banner ───────────────────────────────────── */

View File

@@ -497,14 +497,17 @@
// Embedded images: register with lazy observer; scroll on load only for new messages (not history) // Embedded images: register with lazy observer; scroll on load only for new messages (not history)
node.querySelectorAll('.gchat-embed-img img[data-lazy-src]').forEach(img => { node.querySelectorAll('.gchat-embed-img img[data-lazy-src]').forEach(img => {
img.addEventListener('load', () => scrollToBottom(scrollForce)); // Only snap to bottom on image load for NEW incoming messages, not history.
// History already scrolls once at the end of loadHistory; an extra scroll
// here is what causes the double jump.
if (scrollForce) img.addEventListener('load', () => scrollToBottom(true));
img.addEventListener('click', () => openImgModal(img.src)); img.addEventListener('click', () => openImgModal(img.src));
img.style.cursor = 'zoom-in'; img.style.cursor = 'zoom-in';
lazyImgObserver.observe(img); lazyImgObserver.observe(img);
}); });
// Also handle already-src'd images (avatars etc.) // Already-src'd images (avatars etc.) — same rule
node.querySelectorAll('.gchat-embed-img img:not([data-lazy-src])').forEach(img => { node.querySelectorAll('.gchat-embed-img img:not([data-lazy-src])').forEach(img => {
img.addEventListener('load', () => scrollToBottom(scrollForce)); if (scrollForce) img.addEventListener('load', () => scrollToBottom(true));
img.addEventListener('click', () => openImgModal(img.src)); img.addEventListener('click', () => openImgModal(img.src));
img.style.cursor = 'zoom-in'; img.style.cursor = 'zoom-in';
}); });
@@ -529,10 +532,14 @@
const data = await res.json(); const data = await res.json();
if (!data.success) return; if (!data.success) return;
const container = document.getElementById('gchat-messages'); const container = document.getElementById('gchat-messages');
if (container) container.innerHTML = ''; if (!container) return;
container.innerHTML = '';
(data.messages || []).forEach(m => appendMsg(m, false)); (data.messages || []).forEach(m => appendMsg(m, false));
// One instant snap — images above viewport won't load (lazy) so no layout shift // Double rAF: wait for the browser to commit the layout (panel just became
// visible from display:none) before reading scrollHeight.
requestAnimationFrame(() => requestAnimationFrame(() => {
container.scrollTop = container.scrollHeight; container.scrollTop = container.scrollHeight;
}));
} catch (e) { } catch (e) {
console.error('[Chat] Failed to load history:', e); console.error('[Chat] Failed to load history:', e);
} }
@@ -636,7 +643,9 @@
if (icon) icon.className = `fa-solid ${isMinimized ? 'fa-chevron-up' : 'fa-chevron-down'}`; if (icon) icon.className = `fa-solid ${isMinimized ? 'fa-chevron-up' : 'fa-chevron-down'}`;
if (!isMinimized) { if (!isMinimized) {
clearUnread(); clearUnread();
loadHistory(); // Wait one rAF so the panel transitions from display:none to its full
// height before loadHistory measures scrollHeight.
requestAnimationFrame(() => loadHistory());
if (!window.matchMedia('(pointer: coarse)').matches) if (!window.matchMedia('(pointer: coarse)').matches)
setTimeout(() => document.getElementById('gchat-input')?.focus(), 150); setTimeout(() => document.getElementById('gchat-input')?.focus(), 150);
} }