Smooth deferred channel loading

Keep timeline intro and empty affordances hidden while live messages are waiting
for the deferred list commit, so channel entry shows the message skeleton until
rows are ready instead of briefly flashing the channel intro.

Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
This commit is contained in:
Wes
2026-06-17 13:52:09 -07:00
co-authored by Pinky
parent e4d8ab270e
commit e668f3d899
@@ -1,6 +1,7 @@
import * as React from "react";
import { ArrowDown, ArrowUp, Hash } from "lucide-react";
import { selectDeferredListRenderState } from "@/features/messages/lib/timelineSnapshot";
import { getDmParticipantPreview } from "@/features/channels/lib/dmParticipantDisplay";
import type { TimelineMessage } from "@/features/messages/types";
import type { UserProfileLookup } from "@/features/profile/lib/identity";
@@ -252,16 +253,27 @@ export const MessageTimeline = React.memo(function MessageTimeline({
sentinelRef: topSentinelRef,
});
const showDirectMessageIntro = !isLoading && directMessageIntro !== null;
const timelineRenderState = selectDeferredListRenderState(
deferredMessages.length,
messages.length,
);
const isDeferredListPending = !isLoading && timelineRenderState === "pending";
const showDirectMessageIntro =
!isLoading &&
timelineRenderState !== "pending" &&
directMessageIntro !== null;
const showChannelIntro =
!isLoading && channelIntro !== null && directMessageIntro === null;
!isLoading &&
timelineRenderState !== "pending" &&
channelIntro !== null &&
directMessageIntro === null;
const showIntro = showDirectMessageIntro || showChannelIntro;
const showGenericEmpty =
!isLoading &&
deferredMessages.length === 0 &&
timelineRenderState === "empty" &&
directMessageIntro === null &&
channelIntro === null;
const showMessageList = !isLoading && deferredMessages.length > 0;
const showMessageList = !isLoading && timelineRenderState === "list";
const timelineSkeletonRows = useTimelineSkeletonRows({
channelId,
isLoading,
@@ -327,7 +339,7 @@ export const MessageTimeline = React.memo(function MessageTimeline({
"flex flex-col gap-2",
(showIntro || showGenericEmpty) && "min-h-full",
)}
loading={isLoading}
loading={isLoading || isDeferredListPending}
skeleton={<TimelineSkeleton rows={timelineSkeletonRows} />}
>
{showDirectMessageIntro ? (