Skip to content

Commit

Permalink
Merge pull request #40 from AntonJames-Sistence/master
Browse files Browse the repository at this point in the history
Add Masonry Grid Layout for Uploaded Images with Expandable View
  • Loading branch information
amcdnl authored Aug 28, 2024
2 parents 4a202aa + 0846c1c commit 00d69a9
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .storybook/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind utilities;
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/ChatInput/ChatInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ interface ChatInputProps {
sendIcon?: ReactElement;

/**
* Icon to show for send.
* Icon to show for stop.
*/
stopIcon?: ReactElement;

Expand Down
69 changes: 63 additions & 6 deletions src/SessionMessages/SessionMessage/MessageFiles.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ChatContext } from '@/ChatContext';
import { ConversationFile } from '@/types';
import { cn } from 'reablocks';
import { FC, PropsWithChildren, useContext } from 'react';
import { FC, PropsWithChildren, useContext, useState } from 'react';
import { MessageFile } from './MessageFile';
import { Slot } from '@radix-ui/react-slot';

Expand All @@ -15,20 +15,77 @@ interface MessageFilesProps extends PropsWithChildren {
export const MessageFiles: FC<MessageFilesProps> = ({ files, children }) => {
const { theme } = useContext(ChatContext);
const Comp = children ? Slot : MessageFile;
const [expanded, setExpanded] = useState<boolean>(false);

if (!files || files.length === 0) {
return null;
}

// Group image and other files
const { imageFiles, otherFiles } = files.reduce(
(acc, file) => {
if (file.type.startsWith('image/')) {
acc.imageFiles.push(file);
} else {
acc.otherFiles.push(file);
}

return acc;
},
{
imageFiles: [] as ConversationFile[],
otherFiles: [] as ConversationFile[]
}
);

const maxImageLength = 3;
const truncateImages = !expanded && imageFiles.length > maxImageLength;

// Renders the image files based on the current expansion state
const renderImageFiles = (images: ConversationFile[]) => {
return truncateImages
? images.slice(0, maxImageLength).map((image, index) => (
<figure
key={index}
className={index === 0 ? 'col-span-2 row-span-2' : 'relative'}
>
<img
src={image.url}
alt={image.name}
className="relative w-full h-full object-cover rounded-lg"
/>
{index === maxImageLength - 1 && (
<div
className="absolute top-0 left-0 w-full h-full flex justify-center items-center bg-black bg-opacity-50 rounded-lg cursor-pointer"
onClick={() => setExpanded(true)}
>
+{(imageFiles.length - maxImageLength).toLocaleString()}
</div>
)}
</figure>
))
: images.map((image, index) => (
<Comp key={index} {...image}>
{children}
</Comp>
));
};

return (
files.length > 0 && (
<div className={cn(theme.messages.message.files.base)}>
{files.map((file, index) => (
<div
className={cn(
theme.messages.message.files.base,
truncateImages ? 'grid grid-rows-2 grid-flow-col gap-2 w-1/3' : ''
)}
>
{imageFiles.length > 0 && renderImageFiles(imageFiles)}

{otherFiles.length > 0 &&
otherFiles.map((file, index) => (
<Comp key={index} {...file}>
{children}
</Comp>
))}
</div>
)
</div>
);
};

0 comments on commit 00d69a9

Please sign in to comment.