diff --git a/packages/assets/assets/alert-circle.svg b/packages/assets/assets/alert-circle.svg new file mode 100644 index 000000000..62f49ae26 --- /dev/null +++ b/packages/assets/assets/alert-circle.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/packages/assets/assets/message-cap.svg b/packages/assets/assets/message-cap.svg new file mode 100644 index 000000000..efc7d3f7f --- /dev/null +++ b/packages/assets/assets/message-cap.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/packages/assets/assets/send-2.svg b/packages/assets/assets/send-2.svg new file mode 100644 index 000000000..a1ccc3769 --- /dev/null +++ b/packages/assets/assets/send-2.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/packages/assets/package.json b/packages/assets/package.json index 8404f2be3..3a72a8c85 100644 --- a/packages/assets/package.json +++ b/packages/assets/package.json @@ -20,6 +20,7 @@ "./Categories": "./dist/Categories.tsx", "./LongLeftArrow": "./dist/LongLeftArrow.tsx", "./LongRightArrow": "./dist/LongRightArrow.tsx", + "./AlertCircle": "./dist/AlertCircle.tsx", "./AllMessages": "./dist/AllMessages.tsx", "./ArrowDown": "./dist/ArrowDown.tsx", "./ArrowLeft": "./dist/ArrowLeft.tsx", @@ -64,13 +65,13 @@ "./Logout": "./dist/Logout.tsx", "./Maximize": "./dist/Maximize.tsx", "./MedalBadge": "./dist/MedalBadge.tsx", + "./MessageCap": "./dist/MessageCap.tsx", "./MessageEdit": "./dist/MessageEdit.tsx", "./MessageQuestion": "./dist/MessageQuestion.tsx", "./Messages": "./dist/Messages.tsx", "./MicrophoneSlashSmall": "./dist/MicrophoneSlashSmall.tsx", "./MicrophoneSlash": "./dist/MicrophoneSlash.tsx", "./Microphone": "./dist/Microphone.tsx", - "./Minimize": "./dist/Minimize.tsx", "./Monitor": "./dist/Monitor.tsx", "./More": "./dist/More.tsx", "./NewTutor": "./dist/NewTutor.tsx", @@ -89,6 +90,7 @@ "./RightArrowHead": "./dist/RightArrowHead.tsx", "./SStar": "./dist/SStar.tsx", "./Search": "./dist/Search.tsx", + "./Send2": "./dist/Send2.tsx", "./Send": "./dist/Send.tsx", "./SettingsScrew": "./dist/SettingsScrew.tsx", "./Settings": "./dist/Settings.tsx", @@ -118,4 +120,4 @@ "./XErroredFill": "./dist/XErroredFill.tsx", "./X": "./dist/X.tsx" } -} +} \ No newline at end of file diff --git a/packages/luna/src/components/Chat/ChatMessage/ChatMessage.stories.tsx b/packages/luna/src/components/Chat/ChatMessage/ChatMessage.stories.tsx index bded2cee8..f6e116443 100644 --- a/packages/luna/src/components/Chat/ChatMessage/ChatMessage.stories.tsx +++ b/packages/luna/src/components/Chat/ChatMessage/ChatMessage.stories.tsx @@ -13,7 +13,7 @@ const meta: Meta = { decorators: [ (Story) => { return ( -
+
); @@ -47,6 +47,34 @@ export const OwnerLongMessage: StoryObj = { }, }; +export const PendingMessage: StoryObj = { + args: { + message: { ...messageTemplate, text: faker.lorem.words(10) }, + owner: true, + pending: true, + retry: () => alert("retry sending"), + }, +}; + +export const ErrorMessage: StoryObj = { + args: { + message: { ...messageTemplate, text: faker.lorem.words(10) }, + owner: true, + error: true, + retry: () => alert("retry sending"), + }, +}; + +export const RetryingMessage: StoryObj = { + args: { + message: { ...messageTemplate, text: faker.lorem.words(10) }, + owner: true, + error: true, + retry: () => alert("retry sending"), + pending: true, + }, +}; + export const ReceiverShortMessage: StoryObj = { args: { message: { ...messageTemplate, text: faker.lorem.words(10) }, diff --git a/packages/luna/src/components/Chat/ChatMessage/ChatMessage.tsx b/packages/luna/src/components/Chat/ChatMessage/ChatMessage.tsx index e540842a9..d6e5c0c4a 100644 --- a/packages/luna/src/components/Chat/ChatMessage/ChatMessage.tsx +++ b/packages/luna/src/components/Chat/ChatMessage/ChatMessage.tsx @@ -1,5 +1,5 @@ import { Void } from "@litespace/types"; -import React, { useState } from "react"; +import React, { useMemo, useState } from "react"; import cn from "classnames"; import More from "@litespace/assets/More"; import { Menu } from "@/components/Menu"; @@ -7,23 +7,72 @@ import { useFormatMessage } from "@/hooks"; import MessageEdit from "@litespace/assets/MessageEdit"; import Trash from "@litespace/assets/Trash"; import { Typography } from "@/components/Typography"; +import MessageCap from "@litespace/assets/MessageCap"; +import AlertCircle from "@litespace/assets/AlertCircle"; +import Send2 from "@litespace/assets/Send2"; +/** + * There are now 4 states of a message: + * - Sent => (no props) + * - Pending => pending: true, error: false + * - Error => pending: false, error: true + * - Retrying => pending: true, error:true + * + * This is beside the 2 types of message: + * - Owner: The messages you send to the user + * - Reciever: The messages You get from the other user + */ export const ChatMessage: React.FC<{ + owner?: boolean; + error?: boolean; viewOnly?: boolean; + pending?: boolean; message: { id: number; text: string }; - owner?: boolean; + retry?: Void; editMessage?: Void; deleteMessage?: Void; -}> = ({ message, owner, editMessage, deleteMessage, viewOnly }) => { +}> = ({ + message, + owner, + editMessage, + deleteMessage, + viewOnly, + pending, + error, + retry, +}) => { const intl = useFormatMessage(); const [showMenu, setShowMenu] = useState(false); const [openMenu, setOpenMenu] = useState(false); + const menuItems = useMemo(() => { + if (error) + return [ + { + label: intl("chat.message.retry"), + onClick: retry, + icon: , + }, + ]; + return [ + { + label: intl("chat.message.edit"), + onClick: editMessage, + icon: , + }, + { + label: intl("chat.message.delete"), + onClick: deleteMessage, + icon: , + }, + ]; + }, [error, deleteMessage, retry, editMessage, intl]); + return (
+ {!pending && owner ? ( +
+ { + if (!open) setShowMenu(false); + setOpenMenu(open); + }} + > +
+ +
+
+
+ ) : null} +
- , - }, - { - label: intl("chat.message.delete"), - onClick: deleteMessage, - icon: , - }, - ]} - open={openMenu} - setOpen={(open: boolean) => { - if (!open) setShowMenu(false); - setOpenMenu(open); - }} - > -
- -
-
-
-
- {!owner ? ( -
- ) : ( + *]:tw-fill-brand-700": owner, + "-tw-right-0 [&>*]:tw-fill-destructive-700": error, + "-tw-left-0 tw-scale-x-[-1] [&>*]:tw-fill-brand-100": !owner, + })} + /> + {error ? (
- )} + > + +
+ ) : null} {message.text} diff --git a/packages/luna/src/components/Chat/ChatMessageGroup/ChatMessageGroup.stories.tsx b/packages/luna/src/components/Chat/ChatMessageGroup/ChatMessageGroup.stories.tsx index 2694b891b..6b34d94b2 100644 --- a/packages/luna/src/components/Chat/ChatMessageGroup/ChatMessageGroup.stories.tsx +++ b/packages/luna/src/components/Chat/ChatMessageGroup/ChatMessageGroup.stories.tsx @@ -64,7 +64,7 @@ export const ReceiverOneMessage: StoryObj = { name: faker.person.fullName(), }, messages: messages(1), - owner: true, + owner: false, sentAt: dayjs().toISOString(), }, }; diff --git a/packages/luna/src/components/Menu/Menu.tsx b/packages/luna/src/components/Menu/Menu.tsx index 8c8a4a09b..0f2ea8dab 100644 --- a/packages/luna/src/components/Menu/Menu.tsx +++ b/packages/luna/src/components/Menu/Menu.tsx @@ -55,7 +55,7 @@ export const Menu: React.FC<{ key={label} disabled={disabled} className={cn( - "tw-flex tw-flex-row tw-gap-2 tw-p-1 tw-pe-4 tw-rounded-lg", + "tw-flex tw-flex-row tw-items-center tw-gap-[10px] tw-p-1 tw-pe-4 tw-rounded-lg", "hover:tw-bg-natural-100 active:tw-bg-brand-700 tw-cursor-pointer", "[&>span]:active:!tw-text-natural-50 [&>svg>*]:active:tw-stroke-natural-50", "focus:tw-outline-none focus:tw-bg-natural-100", diff --git a/packages/luna/src/locales/ar-eg.json b/packages/luna/src/locales/ar-eg.json index ef1041c63..7445836ae 100644 --- a/packages/luna/src/locales/ar-eg.json +++ b/packages/luna/src/locales/ar-eg.json @@ -417,6 +417,7 @@ "chat.message.delete.description": "هل انت متأكد من انك تريد حذف هذة الرسالة ؟ هذا الفعل لا يمكن الرجوع فيه.", "chat.message.delete.confirm": "حذف", "chat.message.delete.cancel": "الرجوع", + "chat.message.retry": "إرسال مجددا", "chat.pin": "تثبيت", "chat.unpin": "إلغاء تثبيت", "chat.mute": "كتم", @@ -692,4 +693,4 @@ "error.password.short": "رقم سري قصير", "error.password.long": "رقم سري طويل", "error.password.invalid": "يجب أن يحتوي علي أرقام، حروف ، رموز" -} \ No newline at end of file +} diff --git a/packages/luna/tailwind.config.js b/packages/luna/tailwind.config.js index d27a4b00a..c1ca45c4d 100644 --- a/packages/luna/tailwind.config.js +++ b/packages/luna/tailwind.config.js @@ -292,6 +292,7 @@ export default { "tutor-profile": "0px 4px 20px 0px rgba(0, 0, 0, 0.08)", "plan-card": "0px 4px 20px 0px rgba(0, 0, 0, 0.2)", "plan-card-label": "0px 4px 20px 0px rgba(0, 0, 0, 0.15)", + "alert-circle": "0px 4px 15px 0px rgba(0, 0, 0, 0.1)", }, }, plugins: [