@linktr.ee/messaging-react 1.21.2-rc-1771385662 → 1.21.2
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.d.ts +15 -1
- package/dist/index.js +882 -871
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ActionButton/index.tsx +1 -1
- package/src/components/ChannelView.tsx +8 -0
- package/src/components/CustomMessage/CustomMessage.stories.tsx +0 -36
- package/src/components/CustomMessage/MessageTag.stories.tsx +5 -57
- package/src/components/CustomMessage/MessageTag.tsx +5 -7
- package/src/components/MessagingShell/index.tsx +2 -0
- package/src/index.ts +2 -0
- package/src/types.ts +9 -0
package/package.json
CHANGED
|
@@ -244,6 +244,7 @@ const ChannelInfoDialog: React.FC<{
|
|
|
244
244
|
onDeleteConversationClick?: () => void
|
|
245
245
|
onBlockParticipantClick?: () => void
|
|
246
246
|
onReportParticipantClick?: () => void
|
|
247
|
+
customChannelActions?: React.ReactNode
|
|
247
248
|
}> = ({
|
|
248
249
|
dialogRef,
|
|
249
250
|
onClose,
|
|
@@ -256,6 +257,7 @@ const ChannelInfoDialog: React.FC<{
|
|
|
256
257
|
onDeleteConversationClick,
|
|
257
258
|
onBlockParticipantClick,
|
|
258
259
|
onReportParticipantClick,
|
|
260
|
+
customChannelActions,
|
|
259
261
|
}) => {
|
|
260
262
|
const { service, debug } = useMessagingContext()
|
|
261
263
|
const [isParticipantBlocked, setIsParticipantBlocked] = useState(false)
|
|
@@ -505,6 +507,7 @@ const ChannelInfoDialog: React.FC<{
|
|
|
505
507
|
<span>Report</span>
|
|
506
508
|
</ActionButton>
|
|
507
509
|
</li>
|
|
510
|
+
{customChannelActions}
|
|
508
511
|
</ul>
|
|
509
512
|
</div>
|
|
510
513
|
</div>
|
|
@@ -529,6 +532,7 @@ const ChannelViewInner: React.FC<{
|
|
|
529
532
|
showStarButton?: boolean
|
|
530
533
|
chatbotVotingEnabled?: boolean
|
|
531
534
|
renderChannelBanner?: () => React.ReactNode
|
|
535
|
+
customChannelActions?: React.ReactNode
|
|
532
536
|
}> = ({
|
|
533
537
|
onBack,
|
|
534
538
|
showBackButton,
|
|
@@ -542,6 +546,7 @@ const ChannelViewInner: React.FC<{
|
|
|
542
546
|
showStarButton = false,
|
|
543
547
|
chatbotVotingEnabled = false,
|
|
544
548
|
renderChannelBanner,
|
|
549
|
+
customChannelActions,
|
|
545
550
|
}) => {
|
|
546
551
|
const { channel } = useChannelStateContext()
|
|
547
552
|
const infoDialogRef = useRef<HTMLDialogElement>(null)
|
|
@@ -636,6 +641,7 @@ const ChannelViewInner: React.FC<{
|
|
|
636
641
|
onDeleteConversationClick={onDeleteConversationClick}
|
|
637
642
|
onBlockParticipantClick={onBlockParticipantClick}
|
|
638
643
|
onReportParticipantClick={onReportParticipantClick}
|
|
644
|
+
customChannelActions={customChannelActions}
|
|
639
645
|
/>
|
|
640
646
|
</>
|
|
641
647
|
)
|
|
@@ -664,6 +670,7 @@ export const ChannelView = React.memo<ChannelViewProps>(
|
|
|
664
670
|
showStarButton = false,
|
|
665
671
|
chatbotVotingEnabled = false,
|
|
666
672
|
renderChannelBanner,
|
|
673
|
+
customChannelActions,
|
|
667
674
|
}) => {
|
|
668
675
|
// Custom send message handler that:
|
|
669
676
|
// 1. Applies messageMetadata if provided
|
|
@@ -738,6 +745,7 @@ export const ChannelView = React.memo<ChannelViewProps>(
|
|
|
738
745
|
showStarButton={showStarButton}
|
|
739
746
|
chatbotVotingEnabled={chatbotVotingEnabled}
|
|
740
747
|
renderChannelBanner={renderChannelBanner}
|
|
748
|
+
customChannelActions={customChannelActions}
|
|
741
749
|
/>
|
|
742
750
|
</Channel>
|
|
743
751
|
</div>
|
|
@@ -154,21 +154,6 @@ 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
|
-
|
|
172
157
|
export const TipOnly: StoryFn<TemplateProps> = Template.bind({})
|
|
173
158
|
TipOnly.args = {
|
|
174
159
|
messages: [
|
|
@@ -183,21 +168,6 @@ TipOnly.args = {
|
|
|
183
168
|
],
|
|
184
169
|
}
|
|
185
170
|
|
|
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
|
-
|
|
201
171
|
export const MixedTags: StoryFn<TemplateProps> = Template.bind({})
|
|
202
172
|
MixedTags.args = {
|
|
203
173
|
messages: [
|
|
@@ -226,12 +196,6 @@ MixedTags.args = {
|
|
|
226
196
|
user: participant,
|
|
227
197
|
metadata: { custom_type: 'MESSAGE_PAID', amount_text: '$10.00' },
|
|
228
198
|
},
|
|
229
|
-
{
|
|
230
|
-
id: 'msg-6b',
|
|
231
|
-
text: 'Another paid message (no amount_text).',
|
|
232
|
-
user: participant,
|
|
233
|
-
metadata: { custom_type: 'MESSAGE_PAID' },
|
|
234
|
-
},
|
|
235
199
|
{ id: 'msg-7', text: 'Got it, thanks!', user: mockUser },
|
|
236
200
|
{
|
|
237
201
|
id: 'msg-8',
|
|
@@ -48,14 +48,6 @@ 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
|
-
|
|
59
51
|
export const TipStandalone: StoryFn<ComponentProps> = Template.bind({})
|
|
60
52
|
TipStandalone.args = {
|
|
61
53
|
message: createMockMessage({
|
|
@@ -65,16 +57,6 @@ TipStandalone.args = {
|
|
|
65
57
|
standalone: true,
|
|
66
58
|
}
|
|
67
59
|
|
|
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
|
-
|
|
78
60
|
export const Paid: StoryFn<ComponentProps> = Template.bind({})
|
|
79
61
|
Paid.args = {
|
|
80
62
|
message: createMockMessage({
|
|
@@ -82,14 +64,6 @@ Paid.args = {
|
|
|
82
64
|
}),
|
|
83
65
|
}
|
|
84
66
|
|
|
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
|
-
|
|
93
67
|
export const Chatbot: StoryFn<ComponentProps> = Template.bind({})
|
|
94
68
|
Chatbot.args = {
|
|
95
69
|
message: createMockMessage({ metadata: { custom_type: 'MESSAGE_CHATBOT' } }),
|
|
@@ -104,7 +78,7 @@ export const AllVariants: StoryFn = () => {
|
|
|
104
78
|
return (
|
|
105
79
|
<div className="p-12 flex flex-col gap-4">
|
|
106
80
|
<div className="flex items-center gap-4">
|
|
107
|
-
<span className="text-sm w-
|
|
81
|
+
<span className="text-sm w-32">Tip:</span>
|
|
108
82
|
<MessageTag
|
|
109
83
|
message={createMockMessage({
|
|
110
84
|
metadata: { custom_type: 'MESSAGE_TIP', amount_text: '$10.50' },
|
|
@@ -112,15 +86,7 @@ export const AllVariants: StoryFn = () => {
|
|
|
112
86
|
/>
|
|
113
87
|
</div>
|
|
114
88
|
<div className="flex items-center gap-4">
|
|
115
|
-
<span className="text-sm w-
|
|
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>
|
|
89
|
+
<span className="text-sm w-32">Paid:</span>
|
|
124
90
|
<MessageTag
|
|
125
91
|
message={createMockMessage({
|
|
126
92
|
metadata: { custom_type: 'MESSAGE_PAID', amount_text: '$25.00' },
|
|
@@ -128,15 +94,7 @@ export const AllVariants: StoryFn = () => {
|
|
|
128
94
|
/>
|
|
129
95
|
</div>
|
|
130
96
|
<div className="flex items-center gap-4">
|
|
131
|
-
<span className="text-sm w-
|
|
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>
|
|
97
|
+
<span className="text-sm w-32">Tip (standalone):</span>
|
|
140
98
|
<MessageTag
|
|
141
99
|
message={createMockMessage({
|
|
142
100
|
text: '',
|
|
@@ -146,23 +104,13 @@ export const AllVariants: StoryFn = () => {
|
|
|
146
104
|
/>
|
|
147
105
|
</div>
|
|
148
106
|
<div className="flex items-center gap-4">
|
|
149
|
-
<span className="text-sm w-
|
|
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>
|
|
107
|
+
<span className="text-sm w-32">Chatbot:</span>
|
|
160
108
|
<MessageTag
|
|
161
109
|
message={createMockMessage({ metadata: { custom_type: 'MESSAGE_CHATBOT' } })}
|
|
162
110
|
/>
|
|
163
111
|
</div>
|
|
164
112
|
<div className="flex items-center gap-4">
|
|
165
|
-
<span className="text-sm w-
|
|
113
|
+
<span className="text-sm w-32">No tag:</span>
|
|
166
114
|
<MessageTag message={createMockMessage()} />
|
|
167
115
|
<span className="text-xs text-stone">(renders nothing)</span>
|
|
168
116
|
</div>
|
|
@@ -54,17 +54,15 @@ export const MessageTag = ({
|
|
|
54
54
|
|
|
55
55
|
if (isTipOrPaid) {
|
|
56
56
|
const amountText = message.metadata?.amount_text
|
|
57
|
+
if (!amountText) return null
|
|
58
|
+
|
|
57
59
|
const className = standalone
|
|
58
60
|
? 'message-tip-standalone'
|
|
59
61
|
: 'message-tag message-tag--tip'
|
|
60
62
|
|
|
61
|
-
const label =
|
|
62
|
-
?
|
|
63
|
-
|
|
64
|
-
: `Delivered with ${amountText} tip`
|
|
65
|
-
: standalone
|
|
66
|
-
? 'Tip'
|
|
67
|
-
: 'Delivered with tip'
|
|
63
|
+
const label = standalone
|
|
64
|
+
? `${amountText} tip`
|
|
65
|
+
: `Delivered with ${amountText} tip`
|
|
68
66
|
|
|
69
67
|
return (
|
|
70
68
|
<div className={className}>
|
|
@@ -37,6 +37,7 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
|
|
|
37
37
|
chatbotVotingEnabled = false,
|
|
38
38
|
renderMessagePreview,
|
|
39
39
|
renderChannelBanner,
|
|
40
|
+
customChannelActions,
|
|
40
41
|
}) => {
|
|
41
42
|
const {
|
|
42
43
|
service,
|
|
@@ -495,6 +496,7 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
|
|
|
495
496
|
onMessageSent={onMessageSent}
|
|
496
497
|
showStarButton={showStarButton}
|
|
497
498
|
chatbotVotingEnabled={chatbotVotingEnabled}
|
|
499
|
+
customChannelActions={customChannelActions}
|
|
498
500
|
/>
|
|
499
501
|
</div>
|
|
500
502
|
) : initialParticipantFilter ? (
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import './styles.css'
|
|
|
5
5
|
export { MessagingShell } from './components/MessagingShell'
|
|
6
6
|
export { ChannelList } from './components/ChannelList'
|
|
7
7
|
export { ChannelView } from './components/ChannelView'
|
|
8
|
+
export { default as ActionButton } from './components/ActionButton'
|
|
8
9
|
export { ParticipantPicker } from './components/ParticipantPicker'
|
|
9
10
|
export { Avatar } from './components/Avatar'
|
|
10
11
|
export { FaqList } from './components/FaqList'
|
|
@@ -36,6 +37,7 @@ export type {
|
|
|
36
37
|
} from './types'
|
|
37
38
|
export type { MessageMetadata } from './stream-custom-data'
|
|
38
39
|
export type { AvatarProps } from './components/Avatar'
|
|
40
|
+
export type { ActionButtonProps } from './components/ActionButton'
|
|
39
41
|
export type { Faq, FaqListProps } from './components/FaqList'
|
|
40
42
|
export type { FaqListItemProps } from './components/FaqList/FaqListItem'
|
|
41
43
|
export type { VoteSelection } from './hooks/useMessageVote'
|
package/src/types.ts
CHANGED
|
@@ -154,6 +154,14 @@ export interface ChannelViewProps {
|
|
|
154
154
|
* Useful for showing summaries, alerts, or contextual information.
|
|
155
155
|
*/
|
|
156
156
|
renderChannelBanner?: () => React.ReactNode
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Custom actions rendered at the bottom of the channel info dialog
|
|
160
|
+
* (below Delete Conversation, Block/Unblock, Report).
|
|
161
|
+
* Pass one or more <li> elements so they match the list styling.
|
|
162
|
+
* Use the exported ActionButton for consistent styling.
|
|
163
|
+
*/
|
|
164
|
+
customChannelActions?: React.ReactNode
|
|
157
165
|
}
|
|
158
166
|
|
|
159
167
|
/**
|
|
@@ -173,6 +181,7 @@ export type ChannelViewPassthroughProps = Pick<
|
|
|
173
181
|
| 'showStarButton'
|
|
174
182
|
| 'chatbotVotingEnabled'
|
|
175
183
|
| 'renderChannelBanner'
|
|
184
|
+
| 'customChannelActions'
|
|
176
185
|
>
|
|
177
186
|
|
|
178
187
|
/**
|