mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(desktop): restore sticky date divider handoff (#1135)
This commit is contained in:
@@ -2,7 +2,7 @@ export function DayDivider({ label }: { label: string }) {
|
||||
return (
|
||||
<section
|
||||
aria-label={label}
|
||||
className="sticky top-[92px] z-[5] flex justify-center py-1 before:absolute before:inset-x-0 before:top-1/2 before:h-px before:-translate-y-1/2 before:bg-border/35 before:content-['']"
|
||||
className="sticky top-(--buzz-channel-content-top-padding,5.75rem) z-[5] flex justify-center"
|
||||
data-testid="message-timeline-day-divider"
|
||||
data-day-label={label}
|
||||
>
|
||||
|
||||
@@ -92,6 +92,14 @@ type TimelineRenderRow =
|
||||
| TimelineUnreadRow
|
||||
| TimelineMessageRowModel;
|
||||
|
||||
type TimelineNonDayRow = TimelineUnreadRow | TimelineMessageRowModel;
|
||||
|
||||
type TimelineDayGroup = {
|
||||
key: string;
|
||||
label: string;
|
||||
rows: TimelineNonDayRow[];
|
||||
};
|
||||
|
||||
function buildTimelineRenderRows({
|
||||
firstUnreadMessageId,
|
||||
messages,
|
||||
@@ -139,6 +147,36 @@ function buildTimelineRenderRows({
|
||||
return rows;
|
||||
}
|
||||
|
||||
function buildTimelineDayGroups(rows: TimelineRenderRow[]): TimelineDayGroup[] {
|
||||
const groups: TimelineDayGroup[] = [];
|
||||
let currentGroup: TimelineDayGroup | null = null;
|
||||
|
||||
for (const row of rows) {
|
||||
if (row.type === "day") {
|
||||
currentGroup = {
|
||||
key: row.key,
|
||||
label: row.label,
|
||||
rows: [],
|
||||
};
|
||||
groups.push(currentGroup);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!currentGroup) {
|
||||
currentGroup = {
|
||||
key: "day-undated",
|
||||
label: "",
|
||||
rows: [],
|
||||
};
|
||||
groups.push(currentGroup);
|
||||
}
|
||||
|
||||
currentGroup.rows.push(row);
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
export const TimelineMessageList = React.memo(function TimelineMessageList({
|
||||
agentPubkeys,
|
||||
channelId,
|
||||
@@ -169,39 +207,55 @@ export const TimelineMessageList = React.memo(function TimelineMessageList({
|
||||
() => buildTimelineRenderRows({ firstUnreadMessageId, messages }),
|
||||
[firstUnreadMessageId, messages],
|
||||
);
|
||||
return rows.map((row) => (
|
||||
<TimelineRenderRowView
|
||||
agentPubkeys={agentPubkeys}
|
||||
allMessages={
|
||||
row.type === "message" && hasVideoAttachment(row.message)
|
||||
? messages
|
||||
: undefined
|
||||
}
|
||||
channelId={channelId}
|
||||
channelName={channelName}
|
||||
channelType={channelType}
|
||||
currentPubkey={currentPubkey}
|
||||
followThreadById={followThreadById}
|
||||
highlightedMessageId={highlightedMessageId}
|
||||
isFollowingThreadById={isFollowingThreadById}
|
||||
isSendingVideoReviewComment={isSendingVideoReviewComment}
|
||||
key={row.key}
|
||||
messageFooters={messageFooters}
|
||||
onDelete={onDelete}
|
||||
onEdit={onEdit}
|
||||
onMarkUnread={onMarkUnread}
|
||||
onReply={onReply}
|
||||
onSendVideoReviewComment={onSendVideoReviewComment}
|
||||
onToggleReaction={onToggleReaction}
|
||||
profiles={profiles}
|
||||
row={row}
|
||||
searchActiveMessageId={searchActiveMessageId}
|
||||
searchMatchingMessageIds={searchMatchingMessageIds}
|
||||
searchQuery={searchQuery}
|
||||
threadUnreadCounts={threadUnreadCounts}
|
||||
unfollowThreadById={unfollowThreadById}
|
||||
/>
|
||||
));
|
||||
const dayGroups = React.useMemo(() => buildTimelineDayGroups(rows), [rows]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-0">
|
||||
{dayGroups.map((group) => (
|
||||
<section
|
||||
className="relative flex flex-col gap-2 before:absolute before:inset-x-0 before:top-4 before:h-px before:bg-border/35 before:content-['']"
|
||||
data-day-label={group.label}
|
||||
data-testid="message-timeline-day-group"
|
||||
key={group.key}
|
||||
>
|
||||
{group.label ? <DayDivider label={group.label} /> : null}
|
||||
{group.rows.map((row) => (
|
||||
<TimelineRenderRowView
|
||||
agentPubkeys={agentPubkeys}
|
||||
allMessages={
|
||||
row.type === "message" && hasVideoAttachment(row.message)
|
||||
? messages
|
||||
: undefined
|
||||
}
|
||||
channelId={channelId}
|
||||
channelName={channelName}
|
||||
channelType={channelType}
|
||||
currentPubkey={currentPubkey}
|
||||
followThreadById={followThreadById}
|
||||
highlightedMessageId={highlightedMessageId}
|
||||
isFollowingThreadById={isFollowingThreadById}
|
||||
isSendingVideoReviewComment={isSendingVideoReviewComment}
|
||||
key={row.key}
|
||||
messageFooters={messageFooters}
|
||||
onDelete={onDelete}
|
||||
onEdit={onEdit}
|
||||
onMarkUnread={onMarkUnread}
|
||||
onReply={onReply}
|
||||
onSendVideoReviewComment={onSendVideoReviewComment}
|
||||
onToggleReaction={onToggleReaction}
|
||||
profiles={profiles}
|
||||
row={row}
|
||||
searchActiveMessageId={searchActiveMessageId}
|
||||
searchMatchingMessageIds={searchMatchingMessageIds}
|
||||
searchQuery={searchQuery}
|
||||
threadUnreadCounts={threadUnreadCounts}
|
||||
unfollowThreadById={unfollowThreadById}
|
||||
/>
|
||||
))}
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
type TimelineRenderRowViewProps = Omit<
|
||||
|
||||
Reference in New Issue
Block a user