@linktr.ee/messaging-react 1.21.0 → 1.21.2-rc-1771385662
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.
- package/dist/index.js +554 -551
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ChannelList/CustomChannelPreview.stories.tsx +2 -1
- package/src/components/ChannelList/CustomChannelPreview.tsx +14 -3
- package/src/components/CustomMessage/CustomMessage.stories.tsx +36 -0
- package/src/components/CustomMessage/MessageTag.stories.tsx +57 -5
- package/src/components/CustomMessage/MessageTag.tsx +7 -5
package/package.json
CHANGED
|
@@ -262,7 +262,8 @@ export const WithCustomMessagePreview: StoryFn = () => {
|
|
|
262
262
|
participantName: 'Alice Urgent',
|
|
263
263
|
participantId: 'participant-urgent',
|
|
264
264
|
participantImage: 'https://i.pravatar.cc/150?img=36',
|
|
265
|
-
lastMessageText:
|
|
265
|
+
lastMessageText:
|
|
266
|
+
'Critical issue needs immediate attention! Please review the server logs for more details and escalate to the on-call engineer. This system outage is affecting multiple users, and we need to resolve it as soon as possible. Impacted services include messaging, notifications, and real-time updates. All hands are required to investigate and remediate the situation. If you have any questions or need additional resources, contact the incident commander immediately!',
|
|
266
267
|
lastMessageTime: new Date(Date.now() - 1000 * 60), // 1 minute ago
|
|
267
268
|
lastMessageMetadata: { custom_type: 'MESSAGE_URGENT' },
|
|
268
269
|
unreadCount: 3,
|
|
@@ -36,6 +36,15 @@ const CustomChannelPreview = React.memo<CustomChannelPreviewProps>(
|
|
|
36
36
|
onChannelSelect(channel)
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
+
const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
|
|
40
|
+
const isActivationKey = event.key === 'Enter' || event.key === ' '
|
|
41
|
+
const isRepeatedKeydown = event.repeat
|
|
42
|
+
|
|
43
|
+
if (!isActivationKey || isRepeatedKeydown) return
|
|
44
|
+
|
|
45
|
+
event.preventDefault()
|
|
46
|
+
handleClick()
|
|
47
|
+
}
|
|
39
48
|
|
|
40
49
|
// Get participant info
|
|
41
50
|
const members = Object.values(channel?.state?.members || {})
|
|
@@ -96,9 +105,11 @@ const CustomChannelPreview = React.memo<CustomChannelPreviewProps>(
|
|
|
96
105
|
}
|
|
97
106
|
|
|
98
107
|
return (
|
|
99
|
-
<
|
|
100
|
-
|
|
108
|
+
<div
|
|
109
|
+
role="button"
|
|
110
|
+
tabIndex={0}
|
|
101
111
|
onClick={handleClick}
|
|
112
|
+
onKeyDown={handleKeyDown}
|
|
102
113
|
className={classNames(
|
|
103
114
|
'group w-full px-4 py-3 transition-colors text-left max-w-full overflow-hidden focus-ring',
|
|
104
115
|
{
|
|
@@ -149,7 +160,7 @@ const CustomChannelPreview = React.memo<CustomChannelPreviewProps>(
|
|
|
149
160
|
</div>
|
|
150
161
|
</div>
|
|
151
162
|
</div>
|
|
152
|
-
</
|
|
163
|
+
</div>
|
|
153
164
|
)
|
|
154
165
|
}
|
|
155
166
|
)
|
|
@@ -154,6 +154,21 @@ WithTipTag.args = {
|
|
|
154
154
|
],
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
/** Tip message without amount_text (backend may not set it). Tag shows "Delivered with tip". */
|
|
158
|
+
export const WithTipTagNoAmount: StoryFn<TemplateProps> = Template.bind({})
|
|
159
|
+
WithTipTagNoAmount.args = {
|
|
160
|
+
messages: [
|
|
161
|
+
{ id: 'msg-1', text: 'Love your content!', user: participant },
|
|
162
|
+
{
|
|
163
|
+
id: 'msg-2',
|
|
164
|
+
text: "Here's a tip for you!",
|
|
165
|
+
user: participant,
|
|
166
|
+
metadata: { custom_type: 'MESSAGE_TIP' },
|
|
167
|
+
},
|
|
168
|
+
{ id: 'msg-3', text: 'Thank you! 🙏', user: mockUser },
|
|
169
|
+
],
|
|
170
|
+
}
|
|
171
|
+
|
|
157
172
|
export const TipOnly: StoryFn<TemplateProps> = Template.bind({})
|
|
158
173
|
TipOnly.args = {
|
|
159
174
|
messages: [
|
|
@@ -168,6 +183,21 @@ TipOnly.args = {
|
|
|
168
183
|
],
|
|
169
184
|
}
|
|
170
185
|
|
|
186
|
+
/** Tip-only bubble without amount_text. Tag shows "Tip". */
|
|
187
|
+
export const TipOnlyNoAmount: StoryFn<TemplateProps> = Template.bind({})
|
|
188
|
+
TipOnlyNoAmount.args = {
|
|
189
|
+
messages: [
|
|
190
|
+
{ id: 'msg-1', text: 'Hello!', user: participant },
|
|
191
|
+
{
|
|
192
|
+
id: 'msg-2',
|
|
193
|
+
text: '',
|
|
194
|
+
user: participant,
|
|
195
|
+
metadata: { custom_type: 'MESSAGE_TIP' },
|
|
196
|
+
},
|
|
197
|
+
{ id: 'msg-3', text: 'Thank you for the tip!', user: mockUser },
|
|
198
|
+
],
|
|
199
|
+
}
|
|
200
|
+
|
|
171
201
|
export const MixedTags: StoryFn<TemplateProps> = Template.bind({})
|
|
172
202
|
MixedTags.args = {
|
|
173
203
|
messages: [
|
|
@@ -196,6 +226,12 @@ MixedTags.args = {
|
|
|
196
226
|
user: participant,
|
|
197
227
|
metadata: { custom_type: 'MESSAGE_PAID', amount_text: '$10.00' },
|
|
198
228
|
},
|
|
229
|
+
{
|
|
230
|
+
id: 'msg-6b',
|
|
231
|
+
text: 'Another paid message (no amount_text).',
|
|
232
|
+
user: participant,
|
|
233
|
+
metadata: { custom_type: 'MESSAGE_PAID' },
|
|
234
|
+
},
|
|
199
235
|
{ id: 'msg-7', text: 'Got it, thanks!', user: mockUser },
|
|
200
236
|
{
|
|
201
237
|
id: 'msg-8',
|
|
@@ -48,6 +48,14 @@ Tip.args = {
|
|
|
48
48
|
}),
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
/** Tip with only custom_type (no amount_text). Matches backend when we don't set amount_text. */
|
|
52
|
+
export const TipWithoutAmount: StoryFn<ComponentProps> = Template.bind({})
|
|
53
|
+
TipWithoutAmount.args = {
|
|
54
|
+
message: createMockMessage({
|
|
55
|
+
metadata: { custom_type: 'MESSAGE_TIP' },
|
|
56
|
+
}),
|
|
57
|
+
}
|
|
58
|
+
|
|
51
59
|
export const TipStandalone: StoryFn<ComponentProps> = Template.bind({})
|
|
52
60
|
TipStandalone.args = {
|
|
53
61
|
message: createMockMessage({
|
|
@@ -57,6 +65,16 @@ TipStandalone.args = {
|
|
|
57
65
|
standalone: true,
|
|
58
66
|
}
|
|
59
67
|
|
|
68
|
+
/** Tip-only bubble with no amount_text (fallback label "Tip"). */
|
|
69
|
+
export const TipStandaloneWithoutAmount: StoryFn<ComponentProps> = Template.bind({})
|
|
70
|
+
TipStandaloneWithoutAmount.args = {
|
|
71
|
+
message: createMockMessage({
|
|
72
|
+
text: '',
|
|
73
|
+
metadata: { custom_type: 'MESSAGE_TIP' },
|
|
74
|
+
}),
|
|
75
|
+
standalone: true,
|
|
76
|
+
}
|
|
77
|
+
|
|
60
78
|
export const Paid: StoryFn<ComponentProps> = Template.bind({})
|
|
61
79
|
Paid.args = {
|
|
62
80
|
message: createMockMessage({
|
|
@@ -64,6 +82,14 @@ Paid.args = {
|
|
|
64
82
|
}),
|
|
65
83
|
}
|
|
66
84
|
|
|
85
|
+
/** Paid with only custom_type (no amount_text). Fallback label "Delivered with tip". */
|
|
86
|
+
export const PaidWithoutAmount: StoryFn<ComponentProps> = Template.bind({})
|
|
87
|
+
PaidWithoutAmount.args = {
|
|
88
|
+
message: createMockMessage({
|
|
89
|
+
metadata: { custom_type: 'MESSAGE_PAID' },
|
|
90
|
+
}),
|
|
91
|
+
}
|
|
92
|
+
|
|
67
93
|
export const Chatbot: StoryFn<ComponentProps> = Template.bind({})
|
|
68
94
|
Chatbot.args = {
|
|
69
95
|
message: createMockMessage({ metadata: { custom_type: 'MESSAGE_CHATBOT' } }),
|
|
@@ -78,7 +104,7 @@ export const AllVariants: StoryFn = () => {
|
|
|
78
104
|
return (
|
|
79
105
|
<div className="p-12 flex flex-col gap-4">
|
|
80
106
|
<div className="flex items-center gap-4">
|
|
81
|
-
<span className="text-sm w-
|
|
107
|
+
<span className="text-sm w-40">Tip (with amount):</span>
|
|
82
108
|
<MessageTag
|
|
83
109
|
message={createMockMessage({
|
|
84
110
|
metadata: { custom_type: 'MESSAGE_TIP', amount_text: '$10.50' },
|
|
@@ -86,7 +112,15 @@ export const AllVariants: StoryFn = () => {
|
|
|
86
112
|
/>
|
|
87
113
|
</div>
|
|
88
114
|
<div className="flex items-center gap-4">
|
|
89
|
-
<span className="text-sm w-
|
|
115
|
+
<span className="text-sm w-40">Tip (no amount_text):</span>
|
|
116
|
+
<MessageTag
|
|
117
|
+
message={createMockMessage({
|
|
118
|
+
metadata: { custom_type: 'MESSAGE_TIP' },
|
|
119
|
+
})}
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
<div className="flex items-center gap-4">
|
|
123
|
+
<span className="text-sm w-40">Paid (with amount):</span>
|
|
90
124
|
<MessageTag
|
|
91
125
|
message={createMockMessage({
|
|
92
126
|
metadata: { custom_type: 'MESSAGE_PAID', amount_text: '$25.00' },
|
|
@@ -94,7 +128,15 @@ export const AllVariants: StoryFn = () => {
|
|
|
94
128
|
/>
|
|
95
129
|
</div>
|
|
96
130
|
<div className="flex items-center gap-4">
|
|
97
|
-
<span className="text-sm w-
|
|
131
|
+
<span className="text-sm w-40">Paid (no amount_text):</span>
|
|
132
|
+
<MessageTag
|
|
133
|
+
message={createMockMessage({
|
|
134
|
+
metadata: { custom_type: 'MESSAGE_PAID' },
|
|
135
|
+
})}
|
|
136
|
+
/>
|
|
137
|
+
</div>
|
|
138
|
+
<div className="flex items-center gap-4">
|
|
139
|
+
<span className="text-sm w-40">Tip standalone (with amount):</span>
|
|
98
140
|
<MessageTag
|
|
99
141
|
message={createMockMessage({
|
|
100
142
|
text: '',
|
|
@@ -104,13 +146,23 @@ export const AllVariants: StoryFn = () => {
|
|
|
104
146
|
/>
|
|
105
147
|
</div>
|
|
106
148
|
<div className="flex items-center gap-4">
|
|
107
|
-
<span className="text-sm w-
|
|
149
|
+
<span className="text-sm w-40">Tip standalone (no amount_text):</span>
|
|
150
|
+
<MessageTag
|
|
151
|
+
message={createMockMessage({
|
|
152
|
+
text: '',
|
|
153
|
+
metadata: { custom_type: 'MESSAGE_TIP' },
|
|
154
|
+
})}
|
|
155
|
+
standalone
|
|
156
|
+
/>
|
|
157
|
+
</div>
|
|
158
|
+
<div className="flex items-center gap-4">
|
|
159
|
+
<span className="text-sm w-40">Chatbot:</span>
|
|
108
160
|
<MessageTag
|
|
109
161
|
message={createMockMessage({ metadata: { custom_type: 'MESSAGE_CHATBOT' } })}
|
|
110
162
|
/>
|
|
111
163
|
</div>
|
|
112
164
|
<div className="flex items-center gap-4">
|
|
113
|
-
<span className="text-sm w-
|
|
165
|
+
<span className="text-sm w-40">No tag:</span>
|
|
114
166
|
<MessageTag message={createMockMessage()} />
|
|
115
167
|
<span className="text-xs text-stone">(renders nothing)</span>
|
|
116
168
|
</div>
|
|
@@ -54,15 +54,17 @@ export const MessageTag = ({
|
|
|
54
54
|
|
|
55
55
|
if (isTipOrPaid) {
|
|
56
56
|
const amountText = message.metadata?.amount_text
|
|
57
|
-
if (!amountText) return null
|
|
58
|
-
|
|
59
57
|
const className = standalone
|
|
60
58
|
? 'message-tip-standalone'
|
|
61
59
|
: 'message-tag message-tag--tip'
|
|
62
60
|
|
|
63
|
-
const label =
|
|
64
|
-
?
|
|
65
|
-
|
|
61
|
+
const label = amountText
|
|
62
|
+
? standalone
|
|
63
|
+
? `${amountText} tip`
|
|
64
|
+
: `Delivered with ${amountText} tip`
|
|
65
|
+
: standalone
|
|
66
|
+
? 'Tip'
|
|
67
|
+
: 'Delivered with tip'
|
|
66
68
|
|
|
67
69
|
return (
|
|
68
70
|
<div className={className}>
|