@linktr.ee/messaging-react 1.22.3 → 1.23.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linktr.ee/messaging-react",
3
- "version": "1.22.3",
3
+ "version": "1.23.0",
4
4
  "description": "React messaging components built on messaging-core for web applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,12 @@
1
1
  import type { Meta, StoryFn } from '@storybook/react'
2
2
  import React, { useEffect } from 'react'
3
- import { Channel as ChannelType, QueryChannelAPIResponse, StreamChat } from 'stream-chat'
3
+ import {
4
+ Channel as ChannelType,
5
+ ChannelMemberResponse,
6
+ Event,
7
+ QueryChannelAPIResponse,
8
+ StreamChat,
9
+ } from 'stream-chat'
4
10
  import { Chat } from 'stream-chat-react'
5
11
 
6
12
  import { mockParticipants } from '../stories/mocks'
@@ -248,6 +254,52 @@ WithMessageActions.parameters = {
248
254
  },
249
255
  }
250
256
 
257
+ export const WithMessageDecoration: StoryFn<TemplateProps> = Template.bind({})
258
+ WithMessageDecoration.args = {
259
+ showBackButton: false,
260
+ renderMessage: (messageNode, message) => {
261
+ const isPriorityMessage = message.id === 'msg-3'
262
+
263
+ if (!isPriorityMessage) {
264
+ return messageNode
265
+ }
266
+
267
+ return (
268
+ <section className="bg-[#F6F2FF] px-4 py-3 my-4 [&_.str-chat\_\_message-bubble]:bg-white">
269
+ <header className="mb-3 flex items-center justify-between gap-3">
270
+ <span className="text-sm font-semibold text-[#6D28D9]">
271
+ ✧ Marked as a priority by AI
272
+ </span>
273
+ <span className="flex items-center gap-3">
274
+ <button
275
+ className="text-sm text-[#5B5662] underline underline-offset-2 hover:text-[#2E2A34]"
276
+ type="button"
277
+ >
278
+ Not a priority
279
+ </button>
280
+ <button
281
+ aria-label="Dismiss priority banner"
282
+ className="text-base text-[#5B5662] hover:text-[#2E2A34]"
283
+ type="button"
284
+ >
285
+ ×
286
+ </button>
287
+ </span>
288
+ </header>
289
+ {messageNode}
290
+ </section>
291
+ )
292
+ },
293
+ }
294
+ WithMessageDecoration.parameters = {
295
+ docs: {
296
+ description: {
297
+ story:
298
+ 'Decorates one message with a priority treatment using ChannelView renderMessage(messageNode, message).',
299
+ },
300
+ },
301
+ }
302
+
251
303
  const WithStarButtonTemplate: StoryFn<ComponentProps> = (args) => {
252
304
  const [client] = React.useState(() => {
253
305
  const client = new StreamChat('mock-api-key', {
@@ -18,6 +18,7 @@ import {
18
18
  Channel,
19
19
  Window,
20
20
  MessageList,
21
+ useMessageContext,
21
22
  useChannelStateContext,
22
23
  WithComponents,
23
24
  MessageUIComponentProps,
@@ -534,6 +535,10 @@ const ChannelViewInner: React.FC<{
534
535
  chatbotVotingEnabled?: boolean
535
536
  renderChannelBanner?: () => React.ReactNode
536
537
  customChannelActions?: React.ReactNode
538
+ renderMessage?: (
539
+ messageNode: React.ReactElement,
540
+ message: NonNullable<MessageUIComponentProps['message']>
541
+ ) => React.ReactNode
537
542
  }> = ({
538
543
  onBack,
539
544
  showBackButton,
@@ -548,6 +553,7 @@ const ChannelViewInner: React.FC<{
548
553
  chatbotVotingEnabled = false,
549
554
  renderChannelBanner,
550
555
  customChannelActions,
556
+ renderMessage,
551
557
  }) => {
552
558
  const { channel } = useChannelStateContext()
553
559
  const infoDialogRef = useRef<HTMLDialogElement>(null)
@@ -593,9 +599,21 @@ const ChannelViewInner: React.FC<{
593
599
  <>
594
600
  <WithComponents
595
601
  overrides={{
596
- Message: (props: MessageUIComponentProps) => (
597
- <CustomMessage {...props} chatbotVotingEnabled={chatbotVotingEnabled} />
598
- ),
602
+ Message: (props: MessageUIComponentProps) => {
603
+ const { message } = useMessageContext('ChannelView')
604
+ const messageNode = (
605
+ <CustomMessage
606
+ {...props}
607
+ chatbotVotingEnabled={chatbotVotingEnabled}
608
+ />
609
+ )
610
+
611
+ if (!renderMessage || !message) {
612
+ return messageNode
613
+ }
614
+
615
+ return renderMessage(messageNode, message)
616
+ },
599
617
  }}
600
618
  >
601
619
  <Window>
@@ -672,6 +690,7 @@ export const ChannelView = React.memo<ChannelViewProps>(
672
690
  chatbotVotingEnabled = false,
673
691
  renderChannelBanner,
674
692
  customChannelActions,
693
+ renderMessage,
675
694
  }) => {
676
695
  // Custom send message handler that:
677
696
  // 1. Applies messageMetadata if provided
@@ -747,6 +766,7 @@ export const ChannelView = React.memo<ChannelViewProps>(
747
766
  chatbotVotingEnabled={chatbotVotingEnabled}
748
767
  renderChannelBanner={renderChannelBanner}
749
768
  customChannelActions={customChannelActions}
769
+ renderMessage={renderMessage}
750
770
  />
751
771
  </Channel>
752
772
  </div>
@@ -38,6 +38,7 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
38
38
  renderMessagePreview,
39
39
  renderChannelBanner,
40
40
  customChannelActions,
41
+ renderMessage,
41
42
  }) => {
42
43
  const {
43
44
  service,
@@ -497,6 +498,7 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
497
498
  showStarButton={showStarButton}
498
499
  chatbotVotingEnabled={chatbotVotingEnabled}
499
500
  customChannelActions={customChannelActions}
501
+ renderMessage={renderMessage}
500
502
  />
501
503
  </div>
502
504
  ) : initialParticipantFilter ? (
package/src/types.ts CHANGED
@@ -162,6 +162,21 @@ export interface ChannelViewProps {
162
162
  * Use the exported ActionButton for consistent styling.
163
163
  */
164
164
  customChannelActions?: React.ReactNode
165
+ /**
166
+ * Custom render function for decorating each message in the message list.
167
+ * Receives the default message node and the message object.
168
+ *
169
+ * @example
170
+ * renderMessage={(messageNode, message) => (
171
+ * <MessageDecorator isStarred={Boolean(message.pinned)}>
172
+ * {messageNode}
173
+ * </MessageDecorator>
174
+ * )}
175
+ */
176
+ renderMessage?: (
177
+ messageNode: React.ReactElement,
178
+ message: LocalMessage
179
+ ) => React.ReactNode
165
180
  }
166
181
 
167
182
  /**
@@ -182,6 +197,7 @@ export type ChannelViewPassthroughProps = Pick<
182
197
  | 'chatbotVotingEnabled'
183
198
  | 'renderChannelBanner'
184
199
  | 'customChannelActions'
200
+ | 'renderMessage'
185
201
  >
186
202
 
187
203
  /**