Initial public release
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import React from 'react';
|
||||
import type { Message, Part } from '@opencode-ai/sdk';
|
||||
|
||||
import ChatMessage from './ChatMessage';
|
||||
import { PermissionCard } from './PermissionCard';
|
||||
import type { Permission } from '@/types/permission';
|
||||
import type { AnimationHandlers, ContentChangeReason } from '@/hooks/useChatScrollManager';
|
||||
import { isFullySyntheticMessage } from '@/lib/messages/synthetic';
|
||||
import { useTurnGrouping } from './hooks/useTurnGrouping';
|
||||
|
||||
interface MessageListProps {
|
||||
messages: { info: Message; parts: Part[] }[];
|
||||
permissions: Permission[];
|
||||
onMessageContentChange: (reason?: ContentChangeReason) => void;
|
||||
getAnimationHandlers: (messageId: string) => AnimationHandlers;
|
||||
hasMoreAbove: boolean;
|
||||
isLoadingOlder: boolean;
|
||||
onLoadOlder: () => void;
|
||||
scrollToBottom?: (options?: { instant?: boolean }) => void;
|
||||
pendingAnchorId?: string | null;
|
||||
}
|
||||
|
||||
const MessageList: React.FC<MessageListProps> = ({
|
||||
messages,
|
||||
permissions,
|
||||
onMessageContentChange,
|
||||
getAnimationHandlers,
|
||||
hasMoreAbove,
|
||||
isLoadingOlder,
|
||||
onLoadOlder,
|
||||
scrollToBottom,
|
||||
pendingAnchorId,
|
||||
}) => {
|
||||
React.useEffect(() => {
|
||||
if (permissions.length === 0) {
|
||||
return;
|
||||
}
|
||||
onMessageContentChange('permission');
|
||||
}, [permissions, onMessageContentChange]);
|
||||
|
||||
const displayMessages = React.useMemo(() => {
|
||||
return messages.filter((message) => !isFullySyntheticMessage(message.parts));
|
||||
}, [messages]);
|
||||
|
||||
const { getContextForMessage } = useTurnGrouping(displayMessages);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{hasMoreAbove && (
|
||||
<div className="flex justify-center py-3">
|
||||
{isLoadingOlder ? (
|
||||
<span className="text-xs uppercase tracking-wide text-muted-foreground/80">
|
||||
Loading…
|
||||
</span>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onLoadOlder}
|
||||
className="text-xs uppercase tracking-wide text-muted-foreground/80 hover:text-foreground"
|
||||
>
|
||||
Load older messages
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-col">
|
||||
{displayMessages.map((message, index) => (
|
||||
<ChatMessage
|
||||
key={message.info.id}
|
||||
message={message}
|
||||
previousMessage={index > 0 ? displayMessages[index - 1] : undefined}
|
||||
nextMessage={index < displayMessages.length - 1 ? displayMessages[index + 1] : undefined}
|
||||
onContentChange={onMessageContentChange}
|
||||
animationHandlers={getAnimationHandlers(message.info.id)}
|
||||
scrollToBottom={scrollToBottom}
|
||||
isPendingAnchor={pendingAnchorId === message.info.id}
|
||||
turnGroupingContext={getContextForMessage(message.info.id)}
|
||||
/>
|
||||
))}
|
||||
|
||||
</div>
|
||||
|
||||
{permissions.length > 0 && (
|
||||
<div>
|
||||
{permissions.map((permission) => (
|
||||
<PermissionCard key={permission.id} permission={permission} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(MessageList);
|
||||
Reference in New Issue
Block a user