Parcourir la source

add sender icon and name if sender is described in users dict (#1686)

resolves #1670

Co-authored-by: Fred Lefévère-Laoide <Fred.Lefevere-Laoide@Taipy.io>
Fred Lefévère-Laoide il y a 9 mois
Parent
commit
213703a702

+ 1 - 1
frontend/taipy-gui/src/components/Taipy/Chat.spec.tsx

@@ -48,7 +48,7 @@ describe("Chat Component", () => {
     it("uses the class", async () => {
         const { getByText } = render(<Chat messages={messages} className="taipy-chat" defaultKey={valueKey} />);
         const elt = getByText(searchMsg);
-        expect(elt.parentElement?.parentElement?.parentElement?.parentElement).toHaveClass("taipy-chat");
+        expect(elt.parentElement?.parentElement?.parentElement?.parentElement?.parentElement?.parentElement).toHaveClass("taipy-chat");
     });
     it("can display an avatar", async () => {
         const { getByAltText } = render(<Chat messages={messages} users={users} defaultKey={valueKey} />);

+ 37 - 29
frontend/taipy-gui/src/components/Taipy/Chat.tsx

@@ -37,6 +37,7 @@ import { LoVElt, useLovListMemo } from "./lovUtils";
 import { IconAvatar, avatarSx } from "../../utils/icon";
 import { emptyArray, getInitials } from "../../utils";
 import { RowType, TableValueType } from "./tableUtils";
+import { Stack } from "@mui/material";
 
 interface ChatProps extends TaipyActiveProps {
     messages?: TableValueType;
@@ -56,7 +57,11 @@ const indicWidth = 0.7;
 const avatarWidth = 24;
 const chatAvatarSx = { ...avatarSx, width: avatarWidth, height: avatarWidth };
 const avatarColSx = { width: 1.5 * avatarWidth };
-const senderMsgSx = { width: "fit-content", maxWidth: "80%", marginLeft: "auto" };
+const senderMsgSx = {
+    width: "fit-content",
+    maxWidth: "80%",
+    color: (theme: Theme) => theme.palette.text.disabled,
+} as SxProps<Theme>;
 const gridSx = { pb: "1em", mt: "unset", flex: 1, overflow: "auto" };
 const loadMoreSx = { width: "fit-content", marginLeft: "auto", marginRight: "auto" };
 const inputSx = { maxWidth: "unset" };
@@ -79,6 +84,7 @@ const senderPaperSx = {
         top: "0",
         right: `-${indicWidth}em`,
     },
+    color: (theme: Theme) => theme.palette.text.disabled,
 } as SxProps<Theme>;
 const otherPaperSx = {
     position: "relative",
@@ -118,41 +124,42 @@ interface ChatRowProps {
     message: string;
     name: string;
     className?: string;
-    getAvatar: (id: string) => ReactNode;
+    getAvatar: (id: string, sender: boolean) => ReactNode;
     index: number;
 }
 
 const ChatRow = (props: ChatRowProps) => {
     const { senderId, message, name, className, getAvatar, index } = props;
-    return senderId == name ? (
-        <Grid item className={getSuffixedClassNames(className, "-sent")} xs={12} sx={noAnchorSx}>
-            <Box sx={senderMsgSx}>
-                <Paper sx={senderPaperSx} data-idx={index}>
-                    {message}
-                </Paper>
-            </Box>
-        </Grid>
-    ) : (
+    const sender = senderId == name;
+    const avatar = getAvatar(name, sender);
+    return (
         <Grid
             item
             container
-            className={getSuffixedClassNames(className, "-received")}
-            rowSpacing={0.2}
-            columnSpacing={1}
+            className={getSuffixedClassNames(className, sender ? "-sent" : "-received")}
+            xs={12}
             sx={noAnchorSx}
+            justifyContent={sender ? "flex-end" : undefined}
         >
-            <Grid item sx={avatarColSx}></Grid>
-            <Grid item sx={nameSx}>
-                {name}
-            </Grid>
-            <Box width="100%" />
-            <Grid item sx={avatarColSx}>
-                {getAvatar(name)}
-            </Grid>
-            <Grid item>
-                <Paper sx={otherPaperSx} data-idx={index}>
-                    {message}
-                </Paper>
+            <Grid item sx={sender ? senderMsgSx : undefined}>
+                {avatar ? (
+                    <Stack>
+                        <Stack direction="row" gap={1}>
+                            <Box sx={avatarColSx}></Box>
+                            <Box sx={nameSx}>{name}</Box>
+                        </Stack>
+                        <Stack direction="row" gap={1}>
+                            <Box sx={avatarColSx}>{avatar}</Box>
+                            <Paper sx={sender ? senderPaperSx : otherPaperSx} data-idx={index}>
+                                {message}
+                            </Paper>
+                        </Stack>
+                    </Stack>
+                ) : (
+                    <Paper sx={sender ? senderPaperSx : otherPaperSx} data-idx={index}>
+                        {message}
+                    </Paper>
+                )}
             </Grid>
         </Grid>
     );
@@ -238,12 +245,13 @@ const Chat = (props: ChatProps) => {
     }, [users]);
 
     const getAvatar = useCallback(
-        (id: string) =>
-            avatars[id] || (
+        (id: string, sender: boolean) =>
+            avatars[id] ||
+            (sender ? null : (
                 <Tooltip title={id}>
                     <Avatar sx={chatAvatarSx}>{getInitials(id)}</Avatar>
                 </Tooltip>
-            ),
+            )),
         [avatars]
     );