fix(dm): prevent repeated peek animation on re-renders

Use module-level variables to track if the peek animation has played for ConversationList and MessageThread, ensuring it only runs once per page session to avoid annoying scrolling behavior.

Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
google-labs-jules[bot]andPR0M3TH3AN committed 2026-02-02 14:02:35 +00:00
1 parent d018e21ad4
commit ffa6b7076d
2 files changed
+19 -8

No files matched your search

+5 -1
View File
@@ -1,5 +1,7 @@
import { ContactRow } from "./ContactRow.js";
let hasPeekAnimationPlayed = false;
function createElement(doc, tag, className, text) {
const element = doc.createElement(tag);
if (className) {
@@ -93,12 +95,13 @@ export function ConversationList({
});
// Peek animation
if (conversations.length > 0) {
if (conversations.length > 0 && !hasPeekAnimationPlayed) {
if (typeof IntersectionObserver !== "undefined") {
const observer = new IntersectionObserver((entries) => {
const entry = entries[0];
if (entry.isIntersecting) {
observer.disconnect();
hasPeekAnimationPlayed = true;
setTimeout(() => {
if (list.scrollHeight > list.clientHeight) {
list.scrollTo({ top: 40, behavior: "smooth" });
@@ -112,6 +115,7 @@ export function ConversationList({
observer.observe(list);
} else {
// Fallback for no IntersectionObserver (e.g. some tests or very old browsers)
hasPeekAnimationPlayed = true;
setTimeout(() => {
if (list.scrollHeight > list.clientHeight) {
list.scrollTo({ top: 40, behavior: "smooth" });
+14 -7
View File
@@ -1,6 +1,8 @@
import { DayDivider } from "./DayDivider.js";
import { MessageBubble } from "./MessageBubble.js";
let hasPeekAnimationPlayed = false;
function createElement(doc, tag, className, text) {
const element = doc.createElement(tag);
if (className) {
@@ -142,10 +144,13 @@ export function MessageThread({
// Scroll to bottom and peek
if (messages.length > 0) {
const animate = () => {
timeline.scrollTop = timeline.scrollHeight;
const performPeek = () => {
if (hasPeekAnimationPlayed) {
return;
}
if (timeline.scrollHeight > timeline.clientHeight) {
hasPeekAnimationPlayed = true;
setTimeout(() => {
const targetScroll = Math.max(0, timeline.scrollTop - 40);
timeline.scrollTo({ top: targetScroll, behavior: "smooth" });
@@ -160,6 +165,11 @@ export function MessageThread({
}
};
const initializeScroll = () => {
timeline.scrollTop = timeline.scrollHeight;
performPeek();
};
if (typeof IntersectionObserver !== "undefined") {
const observer = new IntersectionObserver((entries) => {
const entry = entries[0];
@@ -167,15 +177,12 @@ export function MessageThread({
observer.disconnect();
// First ensure we are at bottom
timeline.scrollTop = timeline.scrollHeight;
setTimeout(animate, 300);
setTimeout(initializeScroll, 300);
}
}, { threshold: 0.1 });
observer.observe(timeline);
} else {
setTimeout(() => {
timeline.scrollTop = timeline.scrollHeight;
animate();
}, 0);
setTimeout(initializeScroll, 0);
}
}