Skip to content

Commit

Permalink
🔧 refactor: include createdAt in conversation selection and update re…
Browse files Browse the repository at this point in the history
…lated types
  • Loading branch information
berry-13 committed Feb 10, 2025
1 parent c8b04a5 commit d356f2d
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 27 deletions.
2 changes: 1 addition & 1 deletion api/models/Conversation.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ module.exports = {

try {
const convos = await Conversation.find(query)
.select('conversationId endpoint title updatedAt user')
.select('conversationId endpoint title createdAt updatedAt user')
.sort({ updatedAt: order === 'asc' ? 1 : -1 })
.limit(limit + 1)
.lean();
Expand Down
68 changes: 44 additions & 24 deletions client/src/components/Conversations/Conversations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@ interface ConversationsProps {
conversations: Array<TConversation | null>;
moveToTop: () => void;
toggleNav: () => void;
containerRef: React.RefObject<HTMLDivElement | List>;
containerRef: React.RefObject<HTMLDivElement>;
loadMoreConversations: () => void;
isFetchingNextPage: boolean;
}

const LoadingSpinner = memo(() => (
<Spinner className="m-1 mx-auto mb-4 h-4 w-4 text-text-primary" />
<div className="flex justify-center py-2">
<Spinner className="m-1 h-4 w-4 text-text-primary" />
</div>
));
LoadingSpinner.displayName = 'LoadingSpinner';

const DateLabel: FC<{ groupName: string }> = memo(({ groupName }) => {
const localize = useLocalize();
Expand All @@ -33,7 +36,8 @@ DateLabel.displayName = 'DateLabel';

type FlattenedItem =
| { type: 'header'; groupName: string }
| { type: 'convo'; convo: TConversation };
| { type: 'convo'; convo: TConversation }
| { type: 'spinner' };

const Conversations: FC<ConversationsProps> = ({
conversations: rawConversations,
Expand Down Expand Up @@ -66,8 +70,11 @@ const Conversations: FC<ConversationsProps> = ({
items.push({ type: 'header', groupName });
items.push(...convos.map((convo) => ({ type: 'convo' as const, convo })));
});
if (isFetchingNextPage) {
items.push({ type: 'spinner' });
}
return items;
}, [groupedConversations]);
}, [groupedConversations, isFetchingNextPage]);

const cache = useMemo(
() =>
Expand All @@ -76,7 +83,13 @@ const Conversations: FC<ConversationsProps> = ({
defaultHeight: 34,
keyMapper: (index) => {
const item = flattenedItems[index];
return item.type === 'header' ? `header-${index}` : `convo-${item.convo.conversationId}`;
if (item.type === 'header') {
return `header-${index}`;
}
if (item.type === 'spinner') {
return 'spinner';
}
return `convo-${item.convo.conversationId}`;
},
}),
[flattenedItems],
Expand All @@ -85,20 +98,32 @@ const Conversations: FC<ConversationsProps> = ({
const rowRenderer = useCallback(
({ index, key, parent, style }) => {
const item = flattenedItems[index];

const renderContent = () => {
switch (item.type) {
case 'header':
return <DateLabel groupName={item.groupName} />;
case 'spinner':
return <LoadingSpinner />;
case 'convo':
return (
<Convo
conversation={item.convo}
retainView={moveToTop}
toggleNav={toggleNav}
isLatestConvo={item.convo.conversationId === firstTodayConvoId}
/>
);
default:
return null;
}
};

return (
<CellMeasurer cache={cache} columnIndex={0} key={key} parent={parent} rowIndex={index}>
{({ registerChild }) => (
<div ref={registerChild} style={style}>
{item.type === 'header' ? (
<DateLabel groupName={item.groupName} />
) : (
<Convo
conversation={item.convo}
retainView={moveToTop}
toggleNav={toggleNav}
isLatestConvo={item.convo.conversationId === firstTodayConvoId}
/>
)}
{renderContent()}
</div>
)}
</CellMeasurer>
Expand All @@ -112,15 +137,13 @@ const Conversations: FC<ConversationsProps> = ({
[cache],
);

// Throttle the loadMoreConversations call so it's not triggered too frequently.
const throttledLoadMore = useMemo(
() => throttle(loadMoreConversations, 300),
[loadMoreConversations],
);

const handleRowsRendered = useCallback(
({ stopIndex }: { stopIndex: number }) => {
// Trigger early when user scrolls within 2 items of the end.
if (stopIndex >= flattenedItems.length - 2) {
throttledLoadMore();
}
Expand All @@ -129,12 +152,14 @@ const Conversations: FC<ConversationsProps> = ({
);

return (
<div className="relative flex h-full flex-col pb-2 text-sm text-text-primary">
<div
ref={containerRef}
className="relative flex h-full flex-col pb-2 text-sm text-text-primary"
>
<div className="flex-1">
<AutoSizer>
{({ width, height }) => (
<List
ref={containerRef as React.RefObject<List>}
width={width}
height={height}
deferredMeasurementCache={cache}
Expand All @@ -151,11 +176,6 @@ const Conversations: FC<ConversationsProps> = ({
)}
</AutoSizer>
</div>
{isFetchingNextPage && (
<div className="mt-2">
<LoadingSpinner />
</div>
)}
</div>
);
};
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Nav/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ const Nav = memo(
toggleNav={itemToggleNav}
containerRef={containerRef}
loadMoreConversations={loadMoreConversations}
isFetchingNextPage={isFetchingNextPage}
isFetchingNextPage={isFetchingNextPage || showLoading}
/>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion packages/data-provider/src/types/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export type ConversationListParams = {

export type MinimalConversation = Pick<
s.TConversation,
'conversationId' | 'endpoint' | 'title' | 'updatedAt' | 'user'
'conversationId' | 'endpoint' | 'title' | 'createdAt' | 'updatedAt' | 'user'
>;

export type ConversationListResponse = {
Expand Down

0 comments on commit d356f2d

Please sign in to comment.