@droppii-org/chat-sdk 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/tsconfig.tsbuildinfo +1 -0
  2. package/package.json +11 -4
  3. package/dist/components/AutoScrollAnchor.d.ts +0 -2
  4. package/dist/components/AutoScrollAnchor.d.ts.map +0 -1
  5. package/dist/components/AutoScrollAnchor.js +0 -12
  6. package/dist/components/AutoScrollAnchor.jsx +0 -11
  7. package/dist/components/ChatBubble.d.ts +0 -2
  8. package/dist/components/ChatBubble.d.ts.map +0 -1
  9. package/dist/components/ChatBubble.js +0 -18
  10. package/dist/components/ChatBubble.jsx +0 -80
  11. package/dist/components/ChatHeader.d.ts +0 -8
  12. package/dist/components/ChatHeader.d.ts.map +0 -1
  13. package/dist/components/ChatHeader.js +0 -32
  14. package/dist/components/ChatHeader.jsx +0 -72
  15. package/dist/components/ChatInput.d.ts +0 -3
  16. package/dist/components/ChatInput.d.ts.map +0 -1
  17. package/dist/components/ChatInput.js +0 -379
  18. package/dist/components/ChatInput.jsx +0 -444
  19. package/dist/components/ChatInputDemo.d.ts +0 -2
  20. package/dist/components/ChatInputDemo.d.ts.map +0 -1
  21. package/dist/components/ChatInputDemo.js +0 -38
  22. package/dist/components/ChatInputDemo.jsx +0 -53
  23. package/dist/components/ChatInputWithCustomIcon.d.ts +0 -16
  24. package/dist/components/ChatInputWithCustomIcon.d.ts.map +0 -1
  25. package/dist/components/ChatInputWithCustomIcon.js +0 -85
  26. package/dist/components/ChatInputWithCustomIcon.jsx +0 -167
  27. package/dist/components/ChatLayout.d.ts +0 -6
  28. package/dist/components/ChatLayout.d.ts.map +0 -1
  29. package/dist/components/ChatLayout.js +0 -48
  30. package/dist/components/ChatLayout.jsx +0 -122
  31. package/dist/components/ConversationItem.d.ts +0 -9
  32. package/dist/components/ConversationItem.d.ts.map +0 -1
  33. package/dist/components/ConversationItem.js +0 -27
  34. package/dist/components/ConversationItem.jsx +0 -51
  35. package/dist/components/ConversationList.d.ts +0 -8
  36. package/dist/components/ConversationList.d.ts.map +0 -1
  37. package/dist/components/ConversationList.js +0 -11
  38. package/dist/components/ConversationList.jsx +0 -22
  39. package/dist/components/DateDivider.d.ts +0 -7
  40. package/dist/components/DateDivider.d.ts.map +0 -1
  41. package/dist/components/DateDivider.js +0 -27
  42. package/dist/components/DateDivider.jsx +0 -28
  43. package/dist/components/EmojiPicker.d.ts +0 -4
  44. package/dist/components/EmojiPicker.d.ts.map +0 -1
  45. package/dist/components/EmojiPicker.js +0 -191
  46. package/dist/components/EmojiPicker.jsx +0 -229
  47. package/dist/components/ImageLightbox.d.ts +0 -8
  48. package/dist/components/ImageLightbox.d.ts.map +0 -1
  49. package/dist/components/ImageLightbox.js +0 -8
  50. package/dist/components/ImageLightbox.jsx +0 -16
  51. package/dist/components/ImagePreviewModal.d.ts +0 -12
  52. package/dist/components/ImagePreviewModal.d.ts.map +0 -1
  53. package/dist/components/ImagePreviewModal.js +0 -55
  54. package/dist/components/ImagePreviewModal.jsx +0 -84
  55. package/dist/components/MessageItem.d.ts +0 -3
  56. package/dist/components/MessageItem.d.ts.map +0 -1
  57. package/dist/components/MessageItem.js +0 -38
  58. package/dist/components/MessageItem.jsx +0 -99
  59. package/dist/components/MessageItemDemo.d.ts +0 -2
  60. package/dist/components/MessageItemDemo.d.ts.map +0 -1
  61. package/dist/components/MessageItemDemo.js +0 -166
  62. package/dist/components/MessageItemDemo.jsx +0 -179
  63. package/dist/components/MessageList.d.ts +0 -15
  64. package/dist/components/MessageList.d.ts.map +0 -1
  65. package/dist/components/MessageList.js +0 -243
  66. package/dist/components/MessageList.jsx +0 -306
  67. package/dist/components/MessageListDemo.d.ts +0 -2
  68. package/dist/components/MessageListDemo.d.ts.map +0 -1
  69. package/dist/components/MessageListDemo.js +0 -165
  70. package/dist/components/MessageListDemo.jsx +0 -183
  71. package/dist/components/StickerPicker.d.ts +0 -4
  72. package/dist/components/StickerPicker.d.ts.map +0 -1
  73. package/dist/components/StickerPicker.js +0 -68
  74. package/dist/components/StickerPicker.jsx +0 -106
  75. package/dist/components/SwipeIndicator.d.ts +0 -9
  76. package/dist/components/SwipeIndicator.d.ts.map +0 -1
  77. package/dist/components/SwipeIndicator.js +0 -24
  78. package/dist/components/SwipeIndicator.jsx +0 -28
  79. package/dist/components/TextFormattingToolbar.d.ts +0 -4
  80. package/dist/components/TextFormattingToolbar.d.ts.map +0 -1
  81. package/dist/components/TextFormattingToolbar.js +0 -29
  82. package/dist/components/TextFormattingToolbar.jsx +0 -52
  83. package/dist/components/TypingIndicator.d.ts +0 -6
  84. package/dist/components/TypingIndicator.d.ts.map +0 -1
  85. package/dist/components/TypingIndicator.js +0 -21
  86. package/dist/components/TypingIndicator.jsx +0 -27
  87. package/dist/components/VoiceWaveIcon.d.ts +0 -7
  88. package/dist/components/VoiceWaveIcon.d.ts.map +0 -1
  89. package/dist/components/VoiceWaveIcon.js +0 -5
  90. package/dist/components/VoiceWaveIcon.jsx +0 -11
  91. package/dist/context/ChatContext.d.ts +0 -72
  92. package/dist/context/ChatContext.d.ts.map +0 -1
  93. package/dist/context/ChatContext.js +0 -347
  94. package/dist/context/ChatContext.jsx +0 -346
  95. package/dist/hooks/useChat.d.ts +0 -5
  96. package/dist/hooks/useChat.d.ts.map +0 -1
  97. package/dist/hooks/useChat.js +0 -73
  98. package/dist/hooks/useConversationList.d.ts +0 -5
  99. package/dist/hooks/useConversationList.d.ts.map +0 -1
  100. package/dist/hooks/useConversationList.js +0 -9
  101. package/dist/hooks/useMessages.d.ts +0 -5
  102. package/dist/hooks/useMessages.d.ts.map +0 -1
  103. package/dist/hooks/useMessages.js +0 -192
  104. package/dist/hooks/useSocket.d.ts +0 -7
  105. package/dist/hooks/useSocket.d.ts.map +0 -1
  106. package/dist/hooks/useSocket.js +0 -120
  107. package/dist/hooks/useSwipeGesture.d.ts +0 -11
  108. package/dist/hooks/useSwipeGesture.d.ts.map +0 -1
  109. package/dist/hooks/useSwipeGesture.js +0 -54
  110. package/dist/hooks/useTextSelection.d.ts +0 -13
  111. package/dist/hooks/useTextSelection.d.ts.map +0 -1
  112. package/dist/hooks/useTextSelection.js +0 -132
  113. package/dist/hooks/useTyping.d.ts +0 -7
  114. package/dist/hooks/useTyping.d.ts.map +0 -1
  115. package/dist/hooks/useTyping.js +0 -64
  116. package/dist/index.d.ts +0 -28
  117. package/dist/index.d.ts.map +0 -1
  118. package/dist/index.js +0 -29
  119. package/dist/types/chat.d.ts +0 -39
  120. package/dist/types/chat.d.ts.map +0 -1
  121. package/dist/types/chat.js +0 -1
  122. package/dist/types/index.d.ts +0 -86
  123. package/dist/types/index.d.ts.map +0 -1
  124. package/dist/types/index.js +0 -1
@@ -1,38 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useChatContext } from "../context/ChatContext";
4
- import { FileText, Download } from "lucide-react";
5
- import Image from "next/image";
6
- export function MessageItem({ message, isGrouped, onImageClick }) {
7
- const { state } = useChatContext();
8
- const isOwnMessage = message.isMine;
9
- const sender = state.users[message.senderId];
10
- const formatFileSize = (bytes) => {
11
- if (bytes === 0)
12
- return "0 Bytes";
13
- const k = 1024;
14
- const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
15
- const i = Math.floor(Math.log(bytes) / Math.log(k));
16
- return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
17
- };
18
- const renderTextMessage = (msg) => {
19
- const content = msg.text || "";
20
- // Simple regex to detect URLs and make them clickable
21
- const linkRegex = /(https?:\/\/[^\s]+)/g;
22
- const parts = content.split(linkRegex);
23
- return (_jsx("div", { className: `px-3 py-2 sm:px-4 sm:py-2 rounded-2xl max-w-full break-words ${isOwnMessage ? "bg-blue-500 text-white" : "bg-gray-100 text-gray-900"} ${isGrouped ? (isOwnMessage ? "rounded-tr-md" : "rounded-tl-md") : ""}`, children: _jsx("p", { className: "text-sm sm:text-base whitespace-pre-wrap", children: parts.map((part, index) => linkRegex.test(part) ? (_jsx("a", { href: part, target: "_blank", rel: "noopener noreferrer", className: "underline text-blue-200 hover:text-blue-100", children: part }, index)) : (part)) }) }));
24
- };
25
- const renderMediaMessage = (msg) => {
26
- var _a, _b;
27
- const imageAttachments = ((_a = msg.attachments) === null || _a === void 0 ? void 0 : _a.filter((att) => att.type === "image")) || [];
28
- return (_jsxs("div", { className: `flex flex-col gap-2 ${isOwnMessage ? "items-end" : "items-start"}`, children: [msg.text && (_jsx("div", { className: `px-3 py-2 sm:px-4 sm:py-2 rounded-2xl max-w-full break-words ${isOwnMessage ? "bg-blue-500 text-white" : "bg-gray-100 text-gray-900"} ${isGrouped ? (isOwnMessage ? "rounded-tr-md" : "rounded-tl-md") : ""}`, children: _jsx("p", { className: "text-sm sm:text-base whitespace-pre-wrap", children: msg.text }) })), _jsx("div", { className: `grid gap-2 ${imageAttachments.length > 1 ? "grid-cols-2" : "grid-cols-1"}`, children: (_b = msg.attachments) === null || _b === void 0 ? void 0 : _b.map((attachment, idx) => (_jsx("div", { className: `relative rounded-lg overflow-hidden ${isOwnMessage ? "bg-blue-100" : "bg-gray-100"}`, children: attachment.type === "image" ? (_jsxs(_Fragment, { children: [_jsx(Image, { src: attachment.url || "/placeholder.svg", alt: attachment.name || "Attached image", width: 200, height: 150, className: "w-full h-auto object-cover cursor-pointer", onClick: () => onImageClick === null || onImageClick === void 0 ? void 0 : onImageClick(attachment.id, imageAttachments.map((img) => ({ id: img.id, url: img.url, name: img.name }))) }), _jsx("div", { className: "absolute inset-0 bg-black/10 flex items-center justify-center opacity-0 hover:opacity-100 transition-opacity", children: _jsx("span", { className: "text-white text-xs font-medium p-1 rounded bg-black/50", children: "Xem \u1EA3nh" }) })] })) : (_jsxs("a", { href: attachment.url, download: attachment.name, className: "flex items-center p-3 space-x-2 text-gray-800 hover:bg-gray-200 transition-colors", children: [_jsx(FileText, { className: "w-5 h-5 flex-shrink-0" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("span", { className: "block text-sm font-medium truncate", children: attachment.name || "File" }), _jsx("span", { className: "block text-xs text-gray-500", children: attachment.size ? formatFileSize(attachment.size) : "Unknown size" })] }), _jsx(Download, { className: "w-4 h-4 flex-shrink-0 text-gray-600" })] })) }, idx))) })] }));
29
- };
30
- const renderPromoMessage = (msg) => {
31
- if (!msg.promoData)
32
- return null;
33
- const { imageUrl, title, description, buttonText, buttonUrl } = msg.promoData;
34
- return (_jsxs("div", { className: "w-full max-w-xs mx-auto my-2 bg-white shadow-md rounded-lg overflow-hidden border border-gray-200", children: [_jsx("div", { className: "relative w-full h-32 bg-gray-200", children: _jsx(Image, { src: imageUrl || "/placeholder.svg", alt: title, fill: true, style: { objectFit: "cover" }, className: "rounded-t-lg" }) }), _jsxs("div", { className: "p-4", children: [_jsx("h3", { className: "text-base font-semibold text-gray-900 mb-1", children: title }), _jsx("p", { className: "text-sm text-gray-600 mb-3", children: description }), _jsx("a", { href: buttonUrl, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center justify-center w-full px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-md transition-colors", children: buttonText })] })] }));
35
- };
36
- return (_jsx("div", { className: `flex ${isOwnMessage ? "justify-end" : "justify-start"} ${isGrouped ? "mt-0.5 sm:mt-1" : "mt-3 sm:mt-4"}`, children: _jsxs("div", { className: `flex items-end space-x-2 max-w-[85%] sm:max-w-xs lg:max-w-md ${isOwnMessage ? "flex-row-reverse space-x-reverse" : ""}`, style: message.type === "promo" ? { maxWidth: "none" } : {}, children: [message.type !== "promo" && !isOwnMessage && !isGrouped && (_jsx("img", { src: (sender === null || sender === void 0 ? void 0 : sender.avatar) || "/placeholder.svg?height=32&width=32&query=user", alt: (sender === null || sender === void 0 ? void 0 : sender.name) || "User", className: "w-6 h-6 sm:w-8 sm:h-8 rounded-full object-cover flex-shrink-0" })), message.type !== "promo" && !isOwnMessage && isGrouped && (_jsx("div", { className: "w-6 sm:w-8 flex-shrink-0" }) // Spacer for grouped messages
37
- ), _jsxs("div", { className: `flex flex-col ${isOwnMessage ? "items-end" : "items-start"}`, children: [message.type !== "promo" && !isGrouped && !isOwnMessage && (_jsx("span", { className: "text-xs text-gray-500 mb-1 px-3", children: (sender === null || sender === void 0 ? void 0 : sender.name) || "Unknown User" })), message.type === "text" && renderTextMessage(message), message.type === "media" && renderMediaMessage(message), message.type === "promo" && renderPromoMessage(message), message.type !== "promo" && (_jsx("div", { className: `flex items-center space-x-1 mt-1 px-2 ${isOwnMessage ? "flex-row-reverse space-x-reverse" : ""}`, children: isOwnMessage && (_jsx("svg", { className: "w-3 h-3 sm:w-4 sm:h-4 text-blue-500", fill: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z" }) })) }))] })] }) }));
38
- }
@@ -1,99 +0,0 @@
1
- "use client";
2
- import { useChatContext } from "../context/ChatContext";
3
- import { FileText, Download } from "lucide-react";
4
- import Image from "next/image";
5
- export function MessageItem({ message, isGrouped, onImageClick }) {
6
- const { state } = useChatContext();
7
- const isOwnMessage = message.isMine;
8
- const sender = state.users[message.senderId];
9
- const formatFileSize = (bytes) => {
10
- if (bytes === 0)
11
- return "0 Bytes";
12
- const k = 1024;
13
- const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
14
- const i = Math.floor(Math.log(bytes) / Math.log(k));
15
- return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
16
- };
17
- const renderTextMessage = (msg) => {
18
- const content = msg.text || "";
19
- // Simple regex to detect URLs and make them clickable
20
- const linkRegex = /(https?:\/\/[^\s]+)/g;
21
- const parts = content.split(linkRegex);
22
- return (<div className={`px-3 py-2 sm:px-4 sm:py-2 rounded-2xl max-w-full break-words ${isOwnMessage ? "bg-blue-500 text-white" : "bg-gray-100 text-gray-900"} ${isGrouped ? (isOwnMessage ? "rounded-tr-md" : "rounded-tl-md") : ""}`}>
23
- <p className="text-sm sm:text-base whitespace-pre-wrap">
24
- {parts.map((part, index) => linkRegex.test(part) ? (<a key={index} href={part} target="_blank" rel="noopener noreferrer" className="underline text-blue-200 hover:text-blue-100">
25
- {part}
26
- </a>) : (part))}
27
- </p>
28
- </div>);
29
- };
30
- const renderMediaMessage = (msg) => {
31
- var _a, _b;
32
- const imageAttachments = ((_a = msg.attachments) === null || _a === void 0 ? void 0 : _a.filter((att) => att.type === "image")) || [];
33
- return (<div className={`flex flex-col gap-2 ${isOwnMessage ? "items-end" : "items-start"}`}>
34
- {msg.text && (<div className={`px-3 py-2 sm:px-4 sm:py-2 rounded-2xl max-w-full break-words ${isOwnMessage ? "bg-blue-500 text-white" : "bg-gray-100 text-gray-900"} ${isGrouped ? (isOwnMessage ? "rounded-tr-md" : "rounded-tl-md") : ""}`}>
35
- <p className="text-sm sm:text-base whitespace-pre-wrap">{msg.text}</p>
36
- </div>)}
37
- <div className={`grid gap-2 ${imageAttachments.length > 1 ? "grid-cols-2" : "grid-cols-1"}`}>
38
- {(_b = msg.attachments) === null || _b === void 0 ? void 0 : _b.map((attachment, idx) => (<div key={idx} className={`relative rounded-lg overflow-hidden ${isOwnMessage ? "bg-blue-100" : "bg-gray-100"}`}>
39
- {attachment.type === "image" ? (<>
40
- <Image src={attachment.url || "/placeholder.svg"} alt={attachment.name || "Attached image"} width={200} height={150} className="w-full h-auto object-cover cursor-pointer" onClick={() => onImageClick === null || onImageClick === void 0 ? void 0 : onImageClick(attachment.id, imageAttachments.map((img) => ({ id: img.id, url: img.url, name: img.name })))}/>
41
- <div className="absolute inset-0 bg-black/10 flex items-center justify-center opacity-0 hover:opacity-100 transition-opacity">
42
- <span className="text-white text-xs font-medium p-1 rounded bg-black/50">Xem ảnh</span>
43
- </div>
44
- </>) : (<a href={attachment.url} download={attachment.name} className="flex items-center p-3 space-x-2 text-gray-800 hover:bg-gray-200 transition-colors">
45
- <FileText className="w-5 h-5 flex-shrink-0"/>
46
- <div className="flex-1 min-w-0">
47
- <span className="block text-sm font-medium truncate">{attachment.name || "File"}</span>
48
- <span className="block text-xs text-gray-500">
49
- {attachment.size ? formatFileSize(attachment.size) : "Unknown size"}
50
- </span>
51
- </div>
52
- <Download className="w-4 h-4 flex-shrink-0 text-gray-600"/>
53
- </a>)}
54
- </div>))}
55
- </div>
56
- </div>);
57
- };
58
- const renderPromoMessage = (msg) => {
59
- if (!msg.promoData)
60
- return null;
61
- const { imageUrl, title, description, buttonText, buttonUrl } = msg.promoData;
62
- return (<div className="w-full max-w-xs mx-auto my-2 bg-white shadow-md rounded-lg overflow-hidden border border-gray-200">
63
- <div className="relative w-full h-32 bg-gray-200">
64
- <Image src={imageUrl || "/placeholder.svg"} alt={title} fill style={{ objectFit: "cover" }} className="rounded-t-lg"/>
65
- </div>
66
- <div className="p-4">
67
- <h3 className="text-base font-semibold text-gray-900 mb-1">{title}</h3>
68
- <p className="text-sm text-gray-600 mb-3">{description}</p>
69
- <a href={buttonUrl} target="_blank" rel="noopener noreferrer" className="inline-flex items-center justify-center w-full px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-md transition-colors">
70
- {buttonText}
71
- </a>
72
- </div>
73
- </div>);
74
- };
75
- return (<div className={`flex ${isOwnMessage ? "justify-end" : "justify-start"} ${isGrouped ? "mt-0.5 sm:mt-1" : "mt-3 sm:mt-4"}`}>
76
- <div className={`flex items-end space-x-2 max-w-[85%] sm:max-w-xs lg:max-w-md ${isOwnMessage ? "flex-row-reverse space-x-reverse" : ""}`} style={message.type === "promo" ? { maxWidth: "none" } : {}} // Allow promo messages to take full width if needed
77
- >
78
- {message.type !== "promo" && !isOwnMessage && !isGrouped && (<img src={(sender === null || sender === void 0 ? void 0 : sender.avatar) || "/placeholder.svg?height=32&width=32&query=user"} alt={(sender === null || sender === void 0 ? void 0 : sender.name) || "User"} className="w-6 h-6 sm:w-8 sm:h-8 rounded-full object-cover flex-shrink-0"/>)}
79
-
80
- {message.type !== "promo" && !isOwnMessage && isGrouped && (<div className="w-6 sm:w-8 flex-shrink-0"/> // Spacer for grouped messages
81
- )}
82
-
83
- <div className={`flex flex-col ${isOwnMessage ? "items-end" : "items-start"}`}>
84
- {message.type !== "promo" && !isGrouped && !isOwnMessage && (<span className="text-xs text-gray-500 mb-1 px-3">{(sender === null || sender === void 0 ? void 0 : sender.name) || "Unknown User"}</span>)}
85
-
86
- {message.type === "text" && renderTextMessage(message)}
87
- {message.type === "media" && renderMediaMessage(message)}
88
- {message.type === "promo" && renderPromoMessage(message)}
89
-
90
- {message.type !== "promo" && (<div className={`flex items-center space-x-1 mt-1 px-2 ${isOwnMessage ? "flex-row-reverse space-x-reverse" : ""}`}>
91
- {/* Status icon logic (from previous implementation) */}
92
- {isOwnMessage && (<svg className="w-3 h-3 sm:w-4 sm:h-4 text-blue-500" fill="currentColor" viewBox="0 0 24 24">
93
- <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z"/>
94
- </svg>)}
95
- </div>)}
96
- </div>
97
- </div>
98
- </div>);
99
- }
@@ -1,2 +0,0 @@
1
- export declare function MessageItemDemo(): import("react/jsx-runtime").JSX.Element;
2
- //# sourceMappingURL=MessageItemDemo.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MessageItemDemo.d.ts","sourceRoot":"","sources":["../../src/components/MessageItemDemo.tsx"],"names":[],"mappings":"AAMA,wBAAgB,eAAe,4CA2L9B"}
@@ -1,166 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { MessageItem } from "./MessageItem";
4
- import { DateDivider } from "./DateDivider";
5
- export function MessageItemDemo() {
6
- // Demo messages showcasing all message types
7
- const demoMessages = [
8
- // Text message from other user
9
- {
10
- id: "demo-1",
11
- senderId: "user-2",
12
- type: "text",
13
- text: "Hey! How are you doing today? 😊",
14
- createdAt: new Date(Date.now() - 3600000).toISOString(),
15
- isMine: false,
16
- },
17
- // Text message from current user
18
- {
19
- id: "demo-2",
20
- senderId: "current-user",
21
- type: "text",
22
- text: "I'm doing great! Thanks for asking. Check out this link: https://example.com",
23
- createdAt: new Date(Date.now() - 3000000).toISOString(),
24
- isMine: true,
25
- },
26
- // Media message with text and image from other user
27
- {
28
- id: "demo-3",
29
- senderId: "user-2",
30
- type: "media",
31
- text: "Look at this beautiful sunset I captured! 📸",
32
- attachments: [
33
- {
34
- id: "demo-3-1",
35
- type: "image",
36
- url: "/placeholder.svg?height=300&width=400",
37
- name: "sunset.jpg",
38
- size: 245760,
39
- },
40
- ],
41
- createdAt: new Date(Date.now() - 2400000).toISOString(),
42
- isMine: false,
43
- },
44
- // Media message with multiple images from current user
45
- {
46
- id: "demo-4",
47
- senderId: "current-user",
48
- type: "media",
49
- text: "My vacation photos! 🏖️",
50
- attachments: [
51
- {
52
- id: "demo-4-1",
53
- type: "image",
54
- url: "/placeholder.svg?height=200&width=300",
55
- name: "beach1.jpg",
56
- size: 180000,
57
- },
58
- {
59
- id: "demo-4-2",
60
- type: "image",
61
- url: "/placeholder.svg?height=200&width=300",
62
- name: "beach2.jpg",
63
- size: 195000,
64
- },
65
- ],
66
- createdAt: new Date(Date.now() - 1800000).toISOString(),
67
- isMine: true,
68
- },
69
- // Media message with file from other user
70
- {
71
- id: "demo-5",
72
- senderId: "user-2",
73
- type: "media",
74
- text: "Here's the document you requested",
75
- attachments: [
76
- {
77
- id: "demo-5-1",
78
- type: "file",
79
- url: "/placeholder.svg?height=200&width=200",
80
- name: "project-proposal.pdf",
81
- size: 1024000,
82
- },
83
- ],
84
- createdAt: new Date(Date.now() - 1200000).toISOString(),
85
- isMine: false,
86
- },
87
- // Media message with mixed attachments from current user
88
- {
89
- id: "demo-6",
90
- senderId: "current-user",
91
- type: "media",
92
- text: "Screenshot and the related document",
93
- attachments: [
94
- {
95
- id: "demo-6-1",
96
- type: "image",
97
- url: "/placeholder.svg?height=400&width=300",
98
- name: "screenshot.png",
99
- size: 156000,
100
- },
101
- {
102
- id: "demo-6-2",
103
- type: "file",
104
- url: "/placeholder.svg?height=200&width=200",
105
- name: "instructions.docx",
106
- size: 45000,
107
- },
108
- ],
109
- createdAt: new Date(Date.now() - 600000).toISOString(),
110
- isMine: true,
111
- },
112
- // Promotional message (system message)
113
- {
114
- id: "demo-7",
115
- senderId: "system",
116
- type: "promo",
117
- promoData: {
118
- imageUrl: "/placeholder.svg?height=200&width=400",
119
- title: "Giảm 30% đơn hàng hôm nay!",
120
- description: "Khuyến mãi đặc biệt chỉ trong hôm nay. Đừng bỏ lỡ cơ hội tiết kiệm!",
121
- buttonText: "Đặt ngay",
122
- buttonUrl: "https://example.com/sale",
123
- },
124
- createdAt: new Date(Date.now() - 300000).toISOString(),
125
- isMine: false,
126
- },
127
- // Recent text message from other user
128
- {
129
- id: "demo-8",
130
- senderId: "user-2",
131
- type: "text",
132
- text: "Thanks for sharing! Those photos are amazing 🤩",
133
- createdAt: new Date(Date.now() - 60000).toISOString(),
134
- isMine: false,
135
- },
136
- ];
137
- const groupMessagesByDate = () => {
138
- const groups = [];
139
- let currentDate = "";
140
- let currentGroup = [];
141
- demoMessages.forEach((message) => {
142
- const messageDate = new Date(message.createdAt).toDateString();
143
- if (messageDate !== currentDate) {
144
- if (currentGroup.length > 0) {
145
- groups.push({ date: currentDate, messages: currentGroup });
146
- }
147
- currentDate = messageDate;
148
- currentGroup = [message];
149
- }
150
- else {
151
- currentGroup.push(message);
152
- }
153
- });
154
- if (currentGroup.length > 0) {
155
- groups.push({ date: currentDate, messages: currentGroup });
156
- }
157
- return groups;
158
- };
159
- const messageGroups = groupMessagesByDate();
160
- return (_jsxs("div", { className: "max-w-2xl mx-auto bg-white rounded-lg shadow-lg overflow-hidden", children: [_jsxs("div", { className: "bg-gray-50 p-4 border-b", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "MessageItem Demo" }), _jsx("p", { className: "text-sm text-gray-600", children: "Showcasing all message types: text, media, and promotional" })] }), _jsx("div", { className: "h-96 overflow-y-auto p-4 space-y-4", children: messageGroups.map((group, groupIndex) => (_jsxs("div", { children: [_jsx(DateDivider, { date: new Date(group.date) }), _jsx("div", { className: "space-y-2", children: group.messages.map((message, messageIndex) => {
161
- const prevMessage = messageIndex > 0 ? group.messages[messageIndex - 1] : null;
162
- const isGrouped = (prevMessage === null || prevMessage === void 0 ? void 0 : prevMessage.senderId) === message.senderId &&
163
- new Date(message.createdAt).getTime() - new Date(prevMessage.createdAt).getTime() < 300000; // 5 minutes
164
- return _jsx(MessageItem, { message: message, isGrouped: isGrouped }, message.id);
165
- }) })] }, group.date))) })] }));
166
- }
@@ -1,179 +0,0 @@
1
- "use client";
2
- import { MessageItem } from "./MessageItem";
3
- import { DateDivider } from "./DateDivider";
4
- export function MessageItemDemo() {
5
- // Demo messages showcasing all message types
6
- const demoMessages = [
7
- // Text message from other user
8
- {
9
- id: "demo-1",
10
- senderId: "user-2",
11
- type: "text",
12
- text: "Hey! How are you doing today? 😊",
13
- createdAt: new Date(Date.now() - 3600000).toISOString(),
14
- isMine: false,
15
- },
16
- // Text message from current user
17
- {
18
- id: "demo-2",
19
- senderId: "current-user",
20
- type: "text",
21
- text: "I'm doing great! Thanks for asking. Check out this link: https://example.com",
22
- createdAt: new Date(Date.now() - 3000000).toISOString(),
23
- isMine: true,
24
- },
25
- // Media message with text and image from other user
26
- {
27
- id: "demo-3",
28
- senderId: "user-2",
29
- type: "media",
30
- text: "Look at this beautiful sunset I captured! 📸",
31
- attachments: [
32
- {
33
- id: "demo-3-1",
34
- type: "image",
35
- url: "/placeholder.svg?height=300&width=400",
36
- name: "sunset.jpg",
37
- size: 245760,
38
- },
39
- ],
40
- createdAt: new Date(Date.now() - 2400000).toISOString(),
41
- isMine: false,
42
- },
43
- // Media message with multiple images from current user
44
- {
45
- id: "demo-4",
46
- senderId: "current-user",
47
- type: "media",
48
- text: "My vacation photos! 🏖️",
49
- attachments: [
50
- {
51
- id: "demo-4-1",
52
- type: "image",
53
- url: "/placeholder.svg?height=200&width=300",
54
- name: "beach1.jpg",
55
- size: 180000,
56
- },
57
- {
58
- id: "demo-4-2",
59
- type: "image",
60
- url: "/placeholder.svg?height=200&width=300",
61
- name: "beach2.jpg",
62
- size: 195000,
63
- },
64
- ],
65
- createdAt: new Date(Date.now() - 1800000).toISOString(),
66
- isMine: true,
67
- },
68
- // Media message with file from other user
69
- {
70
- id: "demo-5",
71
- senderId: "user-2",
72
- type: "media",
73
- text: "Here's the document you requested",
74
- attachments: [
75
- {
76
- id: "demo-5-1",
77
- type: "file",
78
- url: "/placeholder.svg?height=200&width=200",
79
- name: "project-proposal.pdf",
80
- size: 1024000,
81
- },
82
- ],
83
- createdAt: new Date(Date.now() - 1200000).toISOString(),
84
- isMine: false,
85
- },
86
- // Media message with mixed attachments from current user
87
- {
88
- id: "demo-6",
89
- senderId: "current-user",
90
- type: "media",
91
- text: "Screenshot and the related document",
92
- attachments: [
93
- {
94
- id: "demo-6-1",
95
- type: "image",
96
- url: "/placeholder.svg?height=400&width=300",
97
- name: "screenshot.png",
98
- size: 156000,
99
- },
100
- {
101
- id: "demo-6-2",
102
- type: "file",
103
- url: "/placeholder.svg?height=200&width=200",
104
- name: "instructions.docx",
105
- size: 45000,
106
- },
107
- ],
108
- createdAt: new Date(Date.now() - 600000).toISOString(),
109
- isMine: true,
110
- },
111
- // Promotional message (system message)
112
- {
113
- id: "demo-7",
114
- senderId: "system",
115
- type: "promo",
116
- promoData: {
117
- imageUrl: "/placeholder.svg?height=200&width=400",
118
- title: "Giảm 30% đơn hàng hôm nay!",
119
- description: "Khuyến mãi đặc biệt chỉ trong hôm nay. Đừng bỏ lỡ cơ hội tiết kiệm!",
120
- buttonText: "Đặt ngay",
121
- buttonUrl: "https://example.com/sale",
122
- },
123
- createdAt: new Date(Date.now() - 300000).toISOString(),
124
- isMine: false,
125
- },
126
- // Recent text message from other user
127
- {
128
- id: "demo-8",
129
- senderId: "user-2",
130
- type: "text",
131
- text: "Thanks for sharing! Those photos are amazing 🤩",
132
- createdAt: new Date(Date.now() - 60000).toISOString(),
133
- isMine: false,
134
- },
135
- ];
136
- const groupMessagesByDate = () => {
137
- const groups = [];
138
- let currentDate = "";
139
- let currentGroup = [];
140
- demoMessages.forEach((message) => {
141
- const messageDate = new Date(message.createdAt).toDateString();
142
- if (messageDate !== currentDate) {
143
- if (currentGroup.length > 0) {
144
- groups.push({ date: currentDate, messages: currentGroup });
145
- }
146
- currentDate = messageDate;
147
- currentGroup = [message];
148
- }
149
- else {
150
- currentGroup.push(message);
151
- }
152
- });
153
- if (currentGroup.length > 0) {
154
- groups.push({ date: currentDate, messages: currentGroup });
155
- }
156
- return groups;
157
- };
158
- const messageGroups = groupMessagesByDate();
159
- return (<div className="max-w-2xl mx-auto bg-white rounded-lg shadow-lg overflow-hidden">
160
- <div className="bg-gray-50 p-4 border-b">
161
- <h2 className="text-lg font-semibold text-gray-900">MessageItem Demo</h2>
162
- <p className="text-sm text-gray-600">Showcasing all message types: text, media, and promotional</p>
163
- </div>
164
-
165
- <div className="h-96 overflow-y-auto p-4 space-y-4">
166
- {messageGroups.map((group, groupIndex) => (<div key={group.date}>
167
- <DateDivider date={new Date(group.date)}/>
168
- <div className="space-y-2">
169
- {group.messages.map((message, messageIndex) => {
170
- const prevMessage = messageIndex > 0 ? group.messages[messageIndex - 1] : null;
171
- const isGrouped = (prevMessage === null || prevMessage === void 0 ? void 0 : prevMessage.senderId) === message.senderId &&
172
- new Date(message.createdAt).getTime() - new Date(prevMessage.createdAt).getTime() < 300000; // 5 minutes
173
- return <MessageItem key={message.id} message={message} isGrouped={isGrouped}/>;
174
- })}
175
- </div>
176
- </div>))}
177
- </div>
178
- </div>);
179
- }
@@ -1,15 +0,0 @@
1
- import type { Message } from "../types";
2
- interface MessageListProps {
3
- messages: Message[];
4
- isLoadingMore?: boolean;
5
- onLoadMore?: () => void;
6
- hasMore?: boolean;
7
- currentUserId: string;
8
- conversationId?: string;
9
- className?: string;
10
- onSwipeBack?: () => void;
11
- }
12
- export declare function MessageList({ messages, // Add default empty array
13
- isLoadingMore, onLoadMore, hasMore, currentUserId, conversationId, className, onSwipeBack, }: MessageListProps): import("react/jsx-runtime").JSX.Element;
14
- export {};
15
- //# sourceMappingURL=MessageList.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAkB,OAAO,EAAE,MAAM,UAAU,CAAA;AAGvD,UAAU,gBAAgB;IACxB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;CACzB;AAED,wBAAgB,WAAW,CAAC,EAC1B,QAAa,EAAE,0BAA0B;AACzC,aAAqB,EACrB,UAAU,EACV,OAAe,EACf,aAAa,EACb,cAAc,EACd,SAAc,EACd,WAAW,GACZ,EAAE,gBAAgB,2CA8WlB"}