Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion desktop/src/features/messages/ui/MessageTimeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -863,8 +863,12 @@ const MessageTimelineBase = React.forwardRef<
<div
className={cn(
"pointer-events-none absolute inset-x-0 bottom-4 z-50 flex justify-center px-4",
// Position the pill with layout rather than a transform. WebKit
// can keep an inherited custom property stale on a promoted
// transform layer when the composer grows, leaving the pill
// stranded inside the dock.
hasComposerOverlay &&
"translate-y-[calc(-1*var(--composer-overlay-height,8rem))] transform-gpu transition-transform duration-200 ease-[cubic-bezier(0.23,1,0.32,1)] motion-reduce:transition-none",
"bottom-[calc(1rem+var(--composer-overlay-height,8rem))] transition-[bottom] duration-200 ease-[cubic-bezier(0.23,1,0.32,1)] motion-reduce:transition-none",
)}
>
<UnreadPill
Expand Down
52 changes: 52 additions & 0 deletions desktop/tests/e2e/smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -892,3 +892,55 @@ test("does not shift the timeline when the composer grows", async ({
expect(Math.abs(after.scrollTop - before.scrollTop)).toBeLessThanOrEqual(2);
expect(after.distanceFromBottom).toBeGreaterThan(160);
});

test("lifts Jump to latest when the composer grows", async ({ page }) => {
const input = page.getByTestId("message-input");

await page.goto("/");
await page.getByTestId("channel-general").click();
await expect(page.getByTestId("chat-title")).toHaveText("general");

await ensureTimelineScrollable(page, `Jump pill growth ${Date.now()}`);
await page.waitForTimeout(400);
const timeline = page.getByTestId("message-timeline");
await timeline.evaluate((element) => {
element.dispatchEvent(new WheelEvent("wheel", { deltaY: -100 }));
element.scrollTop = 0;
element.dispatchEvent(new Event("scroll", { bubbles: true }));
});

const jumpToLatest = page.getByTestId("message-scroll-to-latest");
const composer = page.getByTestId("message-composer");
await expect(jumpToLatest).toBeVisible();
const initialPillBox = await jumpToLatest.boundingBox();
const initialComposerBox = await composer.boundingBox();

await input.fill(
[
"Composer growth line one",
"Composer growth line two",
"Composer growth line three",
"Composer growth line four",
].join("\n"),
);

await expect
.poll(async () => (await composer.boundingBox())?.height ?? 0)
.toBeGreaterThan((initialComposerBox?.height ?? 0) + 40);
await page.waitForTimeout(250);

const expandedPillBox = await jumpToLatest.boundingBox();
const expandedComposerBox = await composer.boundingBox();
expect(initialPillBox).not.toBeNull();
expect(initialComposerBox).not.toBeNull();
expect(expandedPillBox).not.toBeNull();
expect(expandedComposerBox).not.toBeNull();

const composerGrowth =
(expandedComposerBox?.height ?? 0) - (initialComposerBox?.height ?? 0);
const pillLift = (initialPillBox?.y ?? 0) - (expandedPillBox?.y ?? 0);
expect(pillLift).toBeGreaterThanOrEqual(composerGrowth - 2);
expect(
(expandedPillBox?.y ?? 0) + (expandedPillBox?.height ?? 0),
).toBeLessThanOrEqual(expandedComposerBox?.y ?? 0);
});
Loading