From d44938ebfe9b3bdc3d220c6c992f7125f20df92b Mon Sep 17 00:00:00 2001 From: AntonJames-Sistence Date: Sun, 25 Aug 2024 11:51:06 -0400 Subject: [PATCH 1/7] Add basic masonary images implementation with native css --- .storybook/index.css | 23 +++++++ package-lock.json | 4 +- src/ChatInput/ChatInput.tsx | 2 +- .../SessionMessage/MessageFiles.tsx | 65 ++++++++++++++++--- stories/Console.stories.tsx | 6 ++ 5 files changed, 87 insertions(+), 13 deletions(-) diff --git a/.storybook/index.css b/.storybook/index.css index b5c61c9..8ae60db 100644 --- a/.storybook/index.css +++ b/.storybook/index.css @@ -1,3 +1,26 @@ @tailwind base; @tailwind components; @tailwind utilities; + +.masonry-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(5rem, 1fr)); + gap: 10px; + grid-template-rows: masonry; +} + +.masonry-item { + width: 100%; + object-fit: cover; + border-radius: 10px; +} + +.masonry-button-overlay { + display: flex; + justify-content: center; + align-items: center; + background-color: rgba(0, 0, 0, 0.5); + color: white; + border-radius: 10px; + cursor: pointer; +} diff --git a/package-lock.json b/package-lock.json index 72ae5bc..97bf6fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "reachat", - "version": "1.4.0", + "version": "1.4.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "reachat", - "version": "1.4.0", + "version": "1.4.2", "license": "Apache-2.0", "dependencies": { "@radix-ui/react-slot": "^1.1.0", diff --git a/src/ChatInput/ChatInput.tsx b/src/ChatInput/ChatInput.tsx index 9477f45..2f17b97 100644 --- a/src/ChatInput/ChatInput.tsx +++ b/src/ChatInput/ChatInput.tsx @@ -37,7 +37,7 @@ interface ChatInputProps { sendIcon?: ReactElement; /** - * Icon to show for send. + * Icon to show for stop. */ stopIcon?: ReactElement; diff --git a/src/SessionMessages/SessionMessage/MessageFiles.tsx b/src/SessionMessages/SessionMessage/MessageFiles.tsx index 62632f8..3044643 100644 --- a/src/SessionMessages/SessionMessage/MessageFiles.tsx +++ b/src/SessionMessages/SessionMessage/MessageFiles.tsx @@ -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'; @@ -15,20 +15,65 @@ interface MessageFilesProps extends PropsWithChildren { export const MessageFiles: FC = ({ files, children }) => { const { theme } = useContext(ChatContext); const Comp = children ? Slot : MessageFile; + const [expanded, setExpanded] = useState(false); if (!files || files.length === 0) { return null; } + // Filter image files + const imageFiles = files.filter(file => file.type.startsWith('image/')); + const otherFiles = files.filter(file => !file.type.startsWith('image/')); + + // return ( + // files.length > 0 && ( + //
+ // {files.map((file, index) => ( + // + // {children} + // + // ))} + //
+ // ) + // ); return ( - files.length > 0 && ( -
- {files.map((file, index) => ( - - {children} - - ))} -
- ) + <> + {imageFiles.length > 3 ? ( +
+ {imageFiles.slice(0, expanded ? imageFiles.length : 3).map((file, index) => ( + expanded ? ( + + {children} + + ) : ( + {file.name} + ) + ))} + {imageFiles.length > 3 && !expanded && ( +
setExpanded(true)}> + +{imageFiles.length - 3} +
+ )} +
+ ) : ( +
+ {files.map((file, index) => ( + + {children} + + ))} +
+ )} + + {otherFiles.length > 0 && ( +
+ {otherFiles.map((file, index) => ( + + {children} + + ))} +
+ )} + ); }; diff --git a/stories/Console.stories.tsx b/stories/Console.stories.tsx index 785ed95..2ec7a92 100644 --- a/stories/Console.stories.tsx +++ b/stories/Console.stories.tsx @@ -1030,6 +1030,12 @@ export const ImageFiles = () => { name: 'nature.jpg', type: 'image/jpeg', url: 'https://www.goodcode.us/static/steph-1ffd4f0dd3c0100ad9019cae8d7954eb.jpg' + }, + { + id: '5', + name: 'nature2.jpg', + type: 'image/jpeg', + url: 'https://www.goodcode.us/static/steph-1ffd4f0dd3c0100ad9019cae8d7954eb.jpg' } ]; From 41336c7a67ee59f676583bb84a69e02b91fbf32f Mon Sep 17 00:00:00 2001 From: AntonJames-Sistence Date: Sun, 25 Aug 2024 13:26:14 -0400 Subject: [PATCH 2/7] Improve UI to match provided design example --- .storybook/index.css | 22 ++++++++++--- .../SessionMessage/MessageFiles.tsx | 31 ++++++++----------- stories/Console.stories.tsx | 6 ---- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/.storybook/index.css b/.storybook/index.css index 8ae60db..b1502b7 100644 --- a/.storybook/index.css +++ b/.storybook/index.css @@ -4,23 +4,37 @@ .masonry-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(5rem, 1fr)); - gap: 10px; - grid-template-rows: masonry; + grid-template-columns: repeat(3, 5rem); + grid-template-rows: 5rem 5rem; +} + +.grid-item-large { + grid-column: span 2; + grid-row: span 2; } .masonry-item { + position: relative; width: 100%; + height: 100%; object-fit: cover; border-radius: 10px; } +.grid-item-small:nth-child(3) { + position: relative; +} + .masonry-button-overlay { + position: absolute; + top: 0; + left: 0; + width: 5rem; + height: 5rem; display: flex; justify-content: center; align-items: center; background-color: rgba(0, 0, 0, 0.5); - color: white; border-radius: 10px; cursor: pointer; } diff --git a/src/SessionMessages/SessionMessage/MessageFiles.tsx b/src/SessionMessages/SessionMessage/MessageFiles.tsx index 3044643..54f0598 100644 --- a/src/SessionMessages/SessionMessage/MessageFiles.tsx +++ b/src/SessionMessages/SessionMessage/MessageFiles.tsx @@ -12,10 +12,11 @@ interface MessageFilesProps extends PropsWithChildren { files: ConversationFile[]; } + export const MessageFiles: FC = ({ files, children }) => { const { theme } = useContext(ChatContext); const Comp = children ? Slot : MessageFile; - const [expanded, setExpanded] = useState(false); + const [expanded, setExpanded] = useState(false); if (!files || files.length === 0) { return null; @@ -25,17 +26,6 @@ export const MessageFiles: FC = ({ files, children }) => { const imageFiles = files.filter(file => file.type.startsWith('image/')); const otherFiles = files.filter(file => !file.type.startsWith('image/')); - // return ( - // files.length > 0 && ( - //
- // {files.map((file, index) => ( - // - // {children} - // - // ))} - //
- // ) - // ); return ( <> {imageFiles.length > 3 ? ( @@ -46,14 +36,19 @@ export const MessageFiles: FC = ({ files, children }) => { {children} ) : ( - {file.name} +
+ {file.name} + {index === 2 && imageFiles.length > 3 && !expanded && ( +
setExpanded(true)}> + +{imageFiles.length - 3} +
+ )} +
) ))} - {imageFiles.length > 3 && !expanded && ( -
setExpanded(true)}> - +{imageFiles.length - 3} -
- )} ) : (
diff --git a/stories/Console.stories.tsx b/stories/Console.stories.tsx index 2ec7a92..785ed95 100644 --- a/stories/Console.stories.tsx +++ b/stories/Console.stories.tsx @@ -1030,12 +1030,6 @@ export const ImageFiles = () => { name: 'nature.jpg', type: 'image/jpeg', url: 'https://www.goodcode.us/static/steph-1ffd4f0dd3c0100ad9019cae8d7954eb.jpg' - }, - { - id: '5', - name: 'nature2.jpg', - type: 'image/jpeg', - url: 'https://www.goodcode.us/static/steph-1ffd4f0dd3c0100ad9019cae8d7954eb.jpg' } ]; From deb6f8d9b6a26b760ba5c009691b6f5ab34c1589 Mon Sep 17 00:00:00 2001 From: AntonJames-Sistence Date: Sun, 25 Aug 2024 15:32:49 -0400 Subject: [PATCH 3/7] Minor improvements --- src/SessionMessages/SessionMessage/MessageFiles.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SessionMessages/SessionMessage/MessageFiles.tsx b/src/SessionMessages/SessionMessage/MessageFiles.tsx index 54f0598..5aeeb81 100644 --- a/src/SessionMessages/SessionMessage/MessageFiles.tsx +++ b/src/SessionMessages/SessionMessage/MessageFiles.tsx @@ -36,7 +36,7 @@ export const MessageFiles: FC = ({ files, children }) => { {children} ) : ( -
@@ -46,13 +46,13 @@ export const MessageFiles: FC = ({ files, children }) => { +{imageFiles.length - 3}
)} -
+ ) ))} ) : (
- {files.map((file, index) => ( + {imageFiles.map((file, index) => ( {children} From 131dadc5f4fd1d32d8d4bc37e1869389233358ca Mon Sep 17 00:00:00 2001 From: AntonJames-Sistence Date: Mon, 26 Aug 2024 11:34:04 -0400 Subject: [PATCH 4/7] Optimize file grouping by combining image and other file filtering --- src/SessionMessages/SessionMessage/MessageFiles.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/SessionMessages/SessionMessage/MessageFiles.tsx b/src/SessionMessages/SessionMessage/MessageFiles.tsx index 5aeeb81..688e524 100644 --- a/src/SessionMessages/SessionMessage/MessageFiles.tsx +++ b/src/SessionMessages/SessionMessage/MessageFiles.tsx @@ -22,9 +22,16 @@ export const MessageFiles: FC = ({ files, children }) => { return null; } - // Filter image files - const imageFiles = files.filter(file => file.type.startsWith('image/')); - const otherFiles = files.filter(file => !file.type.startsWith('image/')); + // 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[] }) return ( <> From b20d773fef03c6549925a16dca29a0282a116030 Mon Sep 17 00:00:00 2001 From: AntonJames-Sistence Date: Mon, 26 Aug 2024 12:12:01 -0400 Subject: [PATCH 5/7] Convert custom CSS to Tailwind CSS --- .storybook/index.css | 39 +------------------ .../SessionMessage/MessageFiles.tsx | 10 ++--- 2 files changed, 6 insertions(+), 43 deletions(-) diff --git a/.storybook/index.css b/.storybook/index.css index b1502b7..bd6213e 100644 --- a/.storybook/index.css +++ b/.storybook/index.css @@ -1,40 +1,3 @@ @tailwind base; @tailwind components; -@tailwind utilities; - -.masonry-grid { - display: grid; - grid-template-columns: repeat(3, 5rem); - grid-template-rows: 5rem 5rem; -} - -.grid-item-large { - grid-column: span 2; - grid-row: span 2; -} - -.masonry-item { - position: relative; - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 10px; -} - -.grid-item-small:nth-child(3) { - position: relative; -} - -.masonry-button-overlay { - position: absolute; - top: 0; - left: 0; - width: 5rem; - height: 5rem; - display: flex; - justify-content: center; - align-items: center; - background-color: rgba(0, 0, 0, 0.5); - border-radius: 10px; - cursor: pointer; -} +@tailwind utilities; \ No newline at end of file diff --git a/src/SessionMessages/SessionMessage/MessageFiles.tsx b/src/SessionMessages/SessionMessage/MessageFiles.tsx index 688e524..806e587 100644 --- a/src/SessionMessages/SessionMessage/MessageFiles.tsx +++ b/src/SessionMessages/SessionMessage/MessageFiles.tsx @@ -36,7 +36,7 @@ export const MessageFiles: FC = ({ files, children }) => { return ( <> {imageFiles.length > 3 ? ( -
+
{imageFiles.slice(0, expanded ? imageFiles.length : 3).map((file, index) => ( expanded ? ( @@ -45,12 +45,12 @@ export const MessageFiles: FC = ({ files, children }) => { ) : (
- {file.name} + {file.name} {index === 2 && imageFiles.length > 3 && !expanded && ( -
setExpanded(true)}> - +{imageFiles.length - 3} +
setExpanded(true)}> + +{(imageFiles.length - 3).toLocaleString()}
)}
From 78b633b9aad305c2b8ff207a714d755f69cec9d1 Mon Sep 17 00:00:00 2001 From: AntonJames-Sistence Date: Mon, 26 Aug 2024 16:10:19 -0400 Subject: [PATCH 6/7] Improve logic of Masonry grid layout --- .../SessionMessage/MessageFiles.tsx | 105 ++++++++++-------- 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/src/SessionMessages/SessionMessage/MessageFiles.tsx b/src/SessionMessages/SessionMessage/MessageFiles.tsx index 806e587..5d281a5 100644 --- a/src/SessionMessages/SessionMessage/MessageFiles.tsx +++ b/src/SessionMessages/SessionMessage/MessageFiles.tsx @@ -12,7 +12,6 @@ interface MessageFilesProps extends PropsWithChildren { files: ConversationFile[]; } - export const MessageFiles: FC = ({ files, children }) => { const { theme } = useContext(ChatContext); const Comp = children ? Slot : MessageFile; @@ -23,59 +22,67 @@ export const MessageFiles: FC = ({ files, children }) => { } // 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); + 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[] } + ); - return acc; - }, { imageFiles: [] as ConversationFile[], otherFiles: [] as ConversationFile[] }) + // Renders the image files based on the current expansion state + const renderImageFiles = (images: ConversationFile[]) => { + return !expanded && imageFiles.length > 3 + ? images.slice(0, 3).map((image, index) => ( +
+ {image.name} + {index === 2 && ( +
setExpanded(true)} + > + +{(imageFiles.length - 3).toLocaleString()} +
+ )} +
+ )) + : images.map((image, index) => ( + + {children} + + )); + }; return ( - <> - {imageFiles.length > 3 ? ( -
- {imageFiles.slice(0, expanded ? imageFiles.length : 3).map((file, index) => ( - expanded ? ( - - {children} - - ) : ( -
- {file.name} - {index === 2 && imageFiles.length > 3 && !expanded && ( -
setExpanded(true)}> - +{(imageFiles.length - 3).toLocaleString()} -
- )} -
- ) - ))} -
- ) : ( -
- {imageFiles.map((file, index) => ( - - {children} - - ))} -
+
+ {imageFiles.length > 0 && renderImageFiles(imageFiles)} - {otherFiles.length > 0 && ( -
- {otherFiles.map((file, index) => ( - - {children} - - ))} -
- )} - + {otherFiles.length > 0 && + otherFiles.map((file, index) => ( + + {children} + + ))} +
); }; From 0846c1c710115f8324b1147fd570e99f43492581 Mon Sep 17 00:00:00 2001 From: AntonJames-Sistence Date: Wed, 28 Aug 2024 12:06:06 -0400 Subject: [PATCH 7/7] Add maxImageLength variable to enhance reusability and enable different breakpoints for masonry grid; apply minor style improvements for handling more than 3 images in the Masonry layout --- src/SessionMessages/SessionMessage/MessageFiles.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/SessionMessages/SessionMessage/MessageFiles.tsx b/src/SessionMessages/SessionMessage/MessageFiles.tsx index 5d281a5..863b3e8 100644 --- a/src/SessionMessages/SessionMessage/MessageFiles.tsx +++ b/src/SessionMessages/SessionMessage/MessageFiles.tsx @@ -38,10 +38,13 @@ export const MessageFiles: FC = ({ files, children }) => { } ); + const maxImageLength = 3; + const truncateImages = !expanded && imageFiles.length > maxImageLength; + // Renders the image files based on the current expansion state const renderImageFiles = (images: ConversationFile[]) => { - return !expanded && imageFiles.length > 3 - ? images.slice(0, 3).map((image, index) => ( + return truncateImages + ? images.slice(0, maxImageLength).map((image, index) => (
= ({ files, children }) => { alt={image.name} className="relative w-full h-full object-cover rounded-lg" /> - {index === 2 && ( + {index === maxImageLength - 1 && (
setExpanded(true)} > - +{(imageFiles.length - 3).toLocaleString()} + +{(imageFiles.length - maxImageLength).toLocaleString()}
)}
@@ -72,7 +75,7 @@ export const MessageFiles: FC = ({ files, children }) => {
{imageFiles.length > 0 && renderImageFiles(imageFiles)}