Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 1x 6x 6x 6x 12x 6x | import React, { RefObject } from "react";
import { FlashList, FlashListRef } from "@shopify/flash-list";
import { makeStyles } from "@repo/ui/themes/makeStyles";
import { ThinkingIndicator } from "@/components/Indicators/ThinkingIndicator";
import { ChatMessage } from "@/types/chat";
import { MessageItem } from "./MessageItem";
interface MessageListProps {
listRef: RefObject<FlashListRef<ChatMessage> | null>;
messages: ChatMessage[];
processingActionIds: string[];
isThinking: boolean;
onReset: () => void;
handleAction: (msgId: string, actionId: string, type: "confirm" | "cancel") => void;
}
export const MessageList = ({
listRef,
messages,
processingActionIds,
isThinking,
onReset,
handleAction,
}: MessageListProps) => {
const styles = useStyles();
return (
<FlashList
ref={listRef}
data={messages}
// Without this the list inherits "never", and with the keyboard up the
// first tap anywhere in it is spent dismissing the keyboard instead of
// reaching the button under the finger — See More, and Confirm/Cancel on
// a pending action, both needed pressing twice.
keyboardShouldPersistTaps="handled"
maintainVisibleContentPosition={{
autoscrollToTopThreshold: 10,
startRenderingFromBottom: false,
}}
renderItem={({ item }) => (
<MessageItem
message={item}
processingActionIds={processingActionIds}
onReset={onReset}
handleAction={handleAction}
/>
)}
keyExtractor={(item) => String(item._id)}
contentContainerStyle={styles.messagesContainer}
ListFooterComponent={isThinking ? <ThinkingIndicator /> : null}
/>
);
};
const useStyles = makeStyles(() => ({
messagesContainer: { paddingTop: 16, paddingBottom: 8 },
}));
|