@linktr.ee/messaging-react 3.37.0-rc-1786190741 → 3.37.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.
Files changed (91) hide show
  1. package/README.md +4 -4
  2. package/dist/Card-415OfRhw.cjs.map +1 -1
  3. package/dist/{Card-DVMzYquF.js → Card-D4PPD5qa.js} +8 -11
  4. package/dist/Card-D4PPD5qa.js.map +1 -0
  5. package/dist/Card-Dxk_Ggxw.cjs.map +1 -1
  6. package/dist/{Card-DaJtDL7m.js → Card-qS17qnN0.js} +6 -15
  7. package/dist/Card-qS17qnN0.js.map +1 -0
  8. package/dist/LoadingDots-Ct3WmVlT.js.map +1 -1
  9. package/dist/LoadingDots-D9GGphgM.cjs.map +1 -1
  10. package/dist/index-D7A8U8GQ.cjs.map +1 -1
  11. package/dist/{index-BOBIiAuD.js → index-DGmVyxHy.js} +62 -87
  12. package/dist/index-DGmVyxHy.js.map +1 -0
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.js +1 -1
  15. package/package.json +2 -2
  16. package/src/components/ActionButton/ActionButton.stories.tsx +2 -0
  17. package/src/components/ActionButton/ActionButton.test.tsx +55 -60
  18. package/src/components/ActionButton/index.tsx +14 -13
  19. package/src/components/AttachmentCard/AttachmentCard.stories.tsx +3 -1
  20. package/src/components/AttachmentCard/MediaPlayer.tsx +7 -9
  21. package/src/components/AttachmentCard/index.tsx +2 -6
  22. package/src/components/Avatar/Avatar.stories.tsx +5 -17
  23. package/src/components/Avatar/index.tsx +23 -13
  24. package/src/components/ChannelView.test.tsx +10 -6
  25. package/src/components/CustomMessage/CustomMessage.stories.tsx +2 -7
  26. package/src/components/CustomMessage/CustomMessage.test.tsx +3 -5
  27. package/src/components/CustomMessage/LockedAttachment/LockedAttachment.test.tsx +4 -5
  28. package/src/components/CustomMessage/LockedAttachment/components/Text/Card.tsx +4 -2
  29. package/src/components/CustomMessage/LockedAttachment/components/_shared/CardBody.tsx +6 -9
  30. package/src/components/CustomMessage/LockedAttachment/components/_shared/CardThumbnail.tsx +3 -1
  31. package/src/components/CustomMessage/LockedAttachment/components/_shared/GalleryThumbnail.tsx +4 -1
  32. package/src/components/CustomMessage/LockedAttachment/components/_shared/PurchaseStatusBadge.tsx +1 -0
  33. package/src/components/CustomMessage/LockedAttachment/components/_shared/SingleThumbnail.tsx +4 -1
  34. package/src/components/CustomMessage/LockedAttachment/components/_shared/SkeletonTextLines.tsx +2 -7
  35. package/src/components/CustomMessage/LockedAttachment/types.ts +3 -4
  36. package/src/components/CustomMessage/MessageAttachmentConversations.stories.tsx +86 -89
  37. package/src/components/CustomMessage/MessageVoteButtons.tsx +1 -4
  38. package/src/components/CustomMessage/SentMessageDeliveryStatus.test.tsx +10 -13
  39. package/src/components/CustomMessage/SentMessageDeliveryStatus.tsx +4 -1
  40. package/src/components/CustomMessage/StreamAttachmentMessage.stories.tsx +4 -4
  41. package/src/components/CustomMessage/StreamAttachmentMessage.test.tsx +7 -6
  42. package/src/components/CustomMessage/context.tsx +2 -7
  43. package/src/components/CustomMessage/index.tsx +4 -1
  44. package/src/components/CustomMessageInput/CustomMessageInput.stories.tsx +11 -33
  45. package/src/components/CustomMessageInput/CustomMessageInput.test.tsx +3 -3
  46. package/src/components/CustomSystemMessage/CustomSystemMessage.test.tsx +9 -6
  47. package/src/components/CustomTypingIndicator/CustomTypingIndicator.stories.tsx +1 -4
  48. package/src/components/IconButton/index.tsx +17 -21
  49. package/src/components/LinkAttachment/LinkAttachment.test.tsx +1 -4
  50. package/src/components/LinkAttachment/components/_shared/CardCta.tsx +1 -4
  51. package/src/components/Loading/Loading.stories.tsx +4 -1
  52. package/src/components/MediaMessage/MediaMessage.stories.tsx +18 -6
  53. package/src/components/MediaMessage/MediaMessage.test.tsx +16 -30
  54. package/src/components/MediaMessage/index.tsx +14 -51
  55. package/src/components/MessageAttachment/Audio/AudioAttachment.stories.tsx +2 -4
  56. package/src/components/MessageAttachment/File/FileAttachment.stories.tsx +1 -3
  57. package/src/components/MessageAttachment/Image/ImageAttachment.stories.tsx +4 -15
  58. package/src/components/MessageAttachment/Image/index.tsx +12 -6
  59. package/src/components/MessageAttachment/MessageAttachment.test.tsx +27 -59
  60. package/src/components/MessageAttachment/Pdf/PdfAttachment.stories.tsx +1 -3
  61. package/src/components/MessageAttachment/Pdf/index.tsx +3 -2
  62. package/src/components/MessageAttachment/Video/VideoAttachment.stories.tsx +3 -11
  63. package/src/components/MessageAttachment/Video/index.tsx +14 -9
  64. package/src/components/MessageAttachment/_shared/CompactDocumentRow.tsx +3 -1
  65. package/src/components/MessageAttachment/_shared/ImageViewer.tsx +3 -1
  66. package/src/components/MessageAttachment/_shared/MediaStackGrid.tsx +1 -5
  67. package/src/components/MessageAttachment/_shared/PdfViewer.tsx +3 -1
  68. package/src/components/MessageAttachment/_shared/VideoViewer.tsx +3 -1
  69. package/src/components/MessageAttachment/_shared/fileMeta.test.ts +6 -4
  70. package/src/components/MessageAttachment/stories/StoryTable.tsx +3 -1
  71. package/src/components/MessageBubble/MessageBubble.stories.tsx +1 -5
  72. package/src/components/MessageBubble/MessageBubble.test.tsx +3 -1
  73. package/src/components/MessageBubble/components/_shared/bubbleTail.tsx +1 -2
  74. package/src/components/MessagingShell/LoadingState.stories.tsx +1 -0
  75. package/src/components/RichCard/RichCard.stories.tsx +3 -14
  76. package/src/components/RichCard/RichCard.test.tsx +4 -16
  77. package/src/components/RichCard/RichCardBody.tsx +3 -11
  78. package/src/components/RichCard/RichCardCard.tsx +3 -1
  79. package/src/components/RichCard/RichCardImages.tsx +4 -2
  80. package/src/components/SearchInput/SearchInput.stories.tsx +1 -0
  81. package/src/components/SearchInput/SearchInput.test.tsx +65 -94
  82. package/src/hooks/useChannelStar.ts +1 -3
  83. package/src/hooks/useMessaging.ts +4 -4
  84. package/src/stories/decorators/storyUser.tsx +2 -2
  85. package/src/stories/mocks.tsx +1 -4
  86. package/src/styles.css +8 -23
  87. package/src/types.ts +2 -1
  88. package/src/utils/cdnImageUrl.test.ts +1 -3
  89. package/dist/Card-DVMzYquF.js.map +0 -1
  90. package/dist/Card-DaJtDL7m.js.map +0 -1
  91. package/dist/index-BOBIiAuD.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -28,7 +28,7 @@ import { StreamChatServiceConfig } from '@linktr.ee/messaging-core';
28
28
  export declare const ActionButton: ({ variant, className, children, ...rest }: ActionButtonProps) => JSX_2.Element;
29
29
 
30
30
  export declare interface ActionButtonProps extends default_2.ButtonHTMLAttributes<HTMLButtonElement> {
31
- variant?: 'default' | 'danger';
31
+ variant?: "default" | "danger";
32
32
  }
33
33
 
34
34
  export declare type AttachmentSourceType = 'image' | 'audio' | 'video' | 'document';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as e, b as t, C as i, c as o, d as n, e as m, F as r, f as g, L as l, h as M, M as c, i as u, j as h, k as L, l as d, m as p, R as C, n as v, p as A, q as k, s as F, t as b, u as P, v as f, w as x, x as y, o as z, y as B, z as S, B as q, D, E, G as R, H as V, I as w } from "./index-BOBIiAuD.js";
1
+ import { a as e, b as t, C as i, c as o, d as n, e as m, F as r, f as g, L as l, h as M, M as c, i as u, j as h, k as L, l as d, m as p, R as C, n as v, p as A, q as k, s as F, t as b, u as P, v as f, w as x, x as y, o as z, y as B, z as S, B as q, D, E, G as R, H as V, I as w } from "./index-DGmVyxHy.js";
2
2
  export {
3
3
  e as ActionButton,
4
4
  t as Avatar,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linktr.ee/messaging-react",
3
- "version": "3.37.0-rc-1786190741",
3
+ "version": "3.37.0",
4
4
  "description": "React messaging components built on messaging-core for web applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@linktr.ee/component-library": "11.8.6",
53
- "@linktr.ee/messaging-core": "2.4.0-rc-1786190741",
53
+ "@linktr.ee/messaging-core": "^2.4.0",
54
54
  "@linktr.ee/messaging-taxonomy": "^0.9.0",
55
55
  "@phosphor-icons/react": "^2.1.10"
56
56
  },
@@ -3,6 +3,7 @@ import React from 'react'
3
3
 
4
4
  import ActionButton from '.'
5
5
 
6
+
6
7
  type ComponentProps = React.ComponentProps<typeof ActionButton>
7
8
 
8
9
  const meta: Meta<ComponentProps> = {
@@ -43,3 +44,4 @@ Disabled.args = {
43
44
  variant: 'default',
44
45
  disabled: true,
45
46
  }
47
+
@@ -1,94 +1,89 @@
1
- import { describe, it, expect, vi } from 'vitest'
1
+ import { describe, it, expect, vi } from 'vitest';
2
2
 
3
- import { renderWithProviders, screen, userEvent } from '../../test/utils'
3
+ import { renderWithProviders, screen, userEvent } from '../../test/utils';
4
4
 
5
- import ActionButton from '.'
5
+ import ActionButton from '.';
6
6
 
7
7
  describe('ActionButton', () => {
8
8
  describe('Rendering', () => {
9
9
  it('renders with children text', () => {
10
- renderWithProviders(<ActionButton>Click me</ActionButton>)
11
- expect(
12
- screen.getByRole('button', { name: 'Click me' })
13
- ).toBeInTheDocument()
14
- })
15
- })
10
+ renderWithProviders(<ActionButton>Click me</ActionButton>);
11
+ expect(screen.getByRole('button', { name: 'Click me' })).toBeInTheDocument();
12
+ });
13
+ });
16
14
 
17
15
  describe('Disabled State', () => {
18
16
  it('is disabled when disabled prop is true', () => {
19
- renderWithProviders(<ActionButton disabled>Disabled</ActionButton>)
20
- const button = screen.getByRole('button')
21
- expect(button).toBeDisabled()
22
- })
17
+ renderWithProviders(<ActionButton disabled>Disabled</ActionButton>);
18
+ const button = screen.getByRole('button');
19
+ expect(button).toBeDisabled();
20
+ });
23
21
 
24
22
  it('does not trigger onClick when disabled', async () => {
25
- const handleClick = vi.fn()
26
- const user = userEvent.setup()
27
-
23
+ const handleClick = vi.fn();
24
+ const user = userEvent.setup();
25
+
28
26
  renderWithProviders(
29
27
  <ActionButton disabled onClick={handleClick}>
30
28
  Disabled
31
29
  </ActionButton>
32
- )
30
+ );
33
31
 
34
- const button = screen.getByRole('button')
35
- await user.click(button)
32
+ const button = screen.getByRole('button');
33
+ await user.click(button);
36
34
 
37
- expect(handleClick).not.toHaveBeenCalled()
38
- })
39
- })
35
+ expect(handleClick).not.toHaveBeenCalled();
36
+ });
37
+ });
40
38
 
41
39
  describe('Click Handling', () => {
42
40
  it('calls onClick when clicked', async () => {
43
- const handleClick = vi.fn()
44
- const user = userEvent.setup()
45
-
46
- renderWithProviders(
47
- <ActionButton onClick={handleClick}>Click me</ActionButton>
48
- )
41
+ const handleClick = vi.fn();
42
+ const user = userEvent.setup();
43
+
44
+ renderWithProviders(<ActionButton onClick={handleClick}>Click me</ActionButton>);
49
45
 
50
- const button = screen.getByRole('button')
51
- await user.click(button)
46
+ const button = screen.getByRole('button');
47
+ await user.click(button);
52
48
 
53
- expect(handleClick).toHaveBeenCalledTimes(1)
54
- })
55
- })
49
+ expect(handleClick).toHaveBeenCalledTimes(1);
50
+ });
51
+ });
56
52
 
57
53
  describe('Type Attribute', () => {
58
54
  it('has button type by default', () => {
59
- renderWithProviders(<ActionButton>Default Type</ActionButton>)
60
- const button = screen.getByRole('button')
61
- expect(button).toHaveAttribute('type', 'button')
62
- })
55
+ renderWithProviders(<ActionButton>Default Type</ActionButton>);
56
+ const button = screen.getByRole('button');
57
+ expect(button).toHaveAttribute('type', 'button');
58
+ });
63
59
 
64
60
  it('can have submit type', () => {
65
- renderWithProviders(<ActionButton type="submit">Submit</ActionButton>)
66
- const button = screen.getByRole('button')
67
- expect(button).toHaveAttribute('type', 'submit')
68
- })
69
- })
61
+ renderWithProviders(<ActionButton type="submit">Submit</ActionButton>);
62
+ const button = screen.getByRole('button');
63
+ expect(button).toHaveAttribute('type', 'submit');
64
+ });
65
+ });
70
66
 
71
67
  describe('Accessibility', () => {
72
68
  it('is keyboard accessible', async () => {
73
- const handleClick = vi.fn()
74
- const user = userEvent.setup()
69
+ const handleClick = vi.fn();
70
+ const user = userEvent.setup();
71
+
72
+ renderWithProviders(<ActionButton onClick={handleClick}>Press me</ActionButton>);
75
73
 
76
- renderWithProviders(
77
- <ActionButton onClick={handleClick}>Press me</ActionButton>
78
- )
79
-
80
- const button = screen.getByRole('button')
81
- button.focus()
82
- await user.keyboard('{Enter}')
74
+ const button = screen.getByRole('button');
75
+ button.focus();
76
+ await user.keyboard('{Enter}');
83
77
 
84
- expect(handleClick).toHaveBeenCalledTimes(1)
85
- })
78
+ expect(handleClick).toHaveBeenCalledTimes(1);
79
+ });
86
80
 
87
81
  it('can be focused', () => {
88
- renderWithProviders(<ActionButton>Focus me</ActionButton>)
89
- const button = screen.getByRole('button')
90
- button.focus()
91
- expect(button).toHaveFocus()
92
- })
93
- })
94
- })
82
+ renderWithProviders(<ActionButton>Focus me</ActionButton>);
83
+ const button = screen.getByRole('button');
84
+ button.focus();
85
+ expect(button).toHaveFocus();
86
+ });
87
+ });
88
+ });
89
+
@@ -1,32 +1,33 @@
1
- import classNames from 'classnames'
2
- import React from 'react'
1
+ import classNames from "classnames";
2
+ import React from "react";
3
3
 
4
- export interface ActionButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
5
- variant?: 'default' | 'danger'
4
+ export interface ActionButtonProps
5
+ extends React.ButtonHTMLAttributes<HTMLButtonElement> {
6
+ variant?: "default" | "danger";
6
7
  }
7
8
 
8
9
  const ActionButton = ({
9
- variant = 'default',
10
+ variant = "default",
10
11
  className,
11
12
  children,
12
13
  ...rest
13
14
  }: ActionButtonProps) => {
14
- const isDanger = variant === 'danger'
15
+ const isDanger = variant === "danger";
15
16
  return (
16
17
  <button
17
18
  type="button"
18
19
  className={classNames(
19
- 'flex w-full items-center gap-3 rounded-lg px-4 py-3 text-left text-sm transition-colors focus-ring disabled:cursor-not-allowed disabled:opacity-60',
20
+ "flex w-full items-center gap-3 rounded-lg px-4 py-3 text-left text-sm transition-colors focus-ring disabled:cursor-not-allowed disabled:opacity-60",
20
21
  isDanger
21
- ? 'text-danger hover:bg-danger/50'
22
- : 'text-charcoal hover:bg-sand',
23
- className
22
+ ? "text-danger hover:bg-danger/50"
23
+ : "text-charcoal hover:bg-sand",
24
+ className,
24
25
  )}
25
26
  {...rest}
26
27
  >
27
28
  {children}
28
29
  </button>
29
- )
30
- }
30
+ );
31
+ };
31
32
 
32
- export default ActionButton
33
+ export default ActionButton;
@@ -184,7 +184,9 @@ export const AllVariants: StoryFn = () => {
184
184
  variant: 'dark',
185
185
  mimeType: 'image/png',
186
186
  detail: '1.1 MB',
187
- thumbnail: <AttachmentThumbnail mimeType="image/png" variant="dark" />,
187
+ thumbnail: (
188
+ <AttachmentThumbnail mimeType="image/png" variant="dark" />
189
+ ),
188
190
  },
189
191
  },
190
192
  {
@@ -7,7 +7,11 @@ import { renderTypeIcon } from './utils/icons'
7
7
  import { getSourceType } from './utils/mimeType'
8
8
 
9
9
  type TouchEventUnion =
10
- MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent
10
+ | MouseEvent
11
+ | TouchEvent
12
+ | React.MouseEvent
13
+ | React.TouchEvent
14
+
11
15
 
12
16
  const getClientXFromEvent = (e: TouchEventUnion): number => {
13
17
  if ('touches' in e) {
@@ -190,20 +194,14 @@ const MediaPlayer: React.FC<MediaPlayerProps> = ({
190
194
  className={`relative cursor-pointer overflow-hidden bg-black ${aspectClass}`}
191
195
  style={aspectStyle}
192
196
  onClick={(e) => {
193
- if (onContainerClick) {
194
- onContainerClick(e)
195
- return
196
- }
197
+ if (onContainerClick) { onContainerClick(e); return }
197
198
  if (manualPlayRequired) return
198
199
  if (controls) setPlaying((p) => !p)
199
200
  }}
200
201
  onKeyDown={(e) => {
201
202
  if (e.key !== 'Enter' && e.key !== ' ') return
202
203
  e.preventDefault()
203
- if (onContainerClick) {
204
- onContainerClick(e as unknown as React.MouseEvent)
205
- return
206
- }
204
+ if (onContainerClick) { onContainerClick(e as unknown as React.MouseEvent); return }
207
205
  if (manualPlayRequired) return
208
206
  if (controls) setPlaying((p) => !p)
209
207
  }}
@@ -61,14 +61,10 @@ const AttachmentCard: React.FC<AttachmentCardProps> = ({
61
61
  )}
62
62
  >
63
63
  {topLeft ? (
64
- <div className="pointer-events-auto absolute left-3 top-3 z-50">
65
- {topLeft}
66
- </div>
64
+ <div className="pointer-events-auto absolute left-3 top-3 z-50">{topLeft}</div>
67
65
  ) : null}
68
66
  {topRight ? (
69
- <div className="pointer-events-auto absolute right-3 top-3 z-50">
70
- {topRight}
71
- </div>
67
+ <div className="pointer-events-auto absolute right-3 top-3 z-50">{topRight}</div>
72
68
  ) : null}
73
69
 
74
70
  {thumbnail}
@@ -9,8 +9,8 @@ const meta: Meta<ComponentProps> = {
9
9
  title: 'Avatar',
10
10
  component: Avatar,
11
11
  parameters: {
12
- layout: 'centered',
13
- },
12
+ layout: 'centered'
13
+ }
14
14
  }
15
15
  export default meta
16
16
 
@@ -138,23 +138,11 @@ export const DifferentColors: StoryFn = () => {
138
138
  // pravatar avatar flake doesn't diff the whole grid.
139
139
  export const MixedAvatars: StoryFn = () => {
140
140
  const users = [
141
- {
142
- id: 'user-1',
143
- name: 'Alice Anderson',
144
- image: 'https://i.pravatar.cc/150?img=1',
145
- },
141
+ { id: 'user-1', name: 'Alice Anderson', image: 'https://i.pravatar.cc/150?img=1' },
146
142
  { id: 'user-2', name: 'Bob Brown' },
147
- {
148
- id: 'user-3',
149
- name: 'Carol Chen',
150
- image: 'https://i.pravatar.cc/150?img=3',
151
- },
143
+ { id: 'user-3', name: 'Carol Chen', image: 'https://i.pravatar.cc/150?img=3' },
152
144
  { id: 'user-4', name: 'David Davis' },
153
- {
154
- id: 'user-5',
155
- name: 'Emma Evans',
156
- image: 'https://i.pravatar.cc/150?img=5',
157
- },
145
+ { id: 'user-5', name: 'Emma Evans', image: 'https://i.pravatar.cc/150?img=5' },
158
146
  { id: 'user-6', name: 'Frank Foster' },
159
147
  ]
160
148
 
@@ -47,12 +47,18 @@ export const Avatar = ({
47
47
  const aiBorderWidth = size >= 40 ? 2 : 1
48
48
 
49
49
  const borderStyle =
50
- shape === 'circle' ? { borderRadius: '50%' } : { borderRadius: '1rem' }
50
+ shape === 'circle'
51
+ ? { borderRadius: '50%' }
52
+ : { borderRadius: '1rem' }
51
53
 
52
54
  const avatarInner = (
53
55
  <div className="h-full w-full overflow-hidden" style={borderStyle}>
54
56
  {image ? (
55
- <img src={image} alt="" className="h-full w-full object-cover" />
57
+ <img
58
+ src={image}
59
+ alt=""
60
+ className="h-full w-full object-cover"
61
+ />
56
62
  ) : (
57
63
  <div
58
64
  aria-hidden="true"
@@ -69,16 +75,17 @@ export const Avatar = ({
69
75
 
70
76
  return (
71
77
  <div
72
- className={classNames('relative flex-shrink-0', className)}
73
- style={
74
- {
75
- '--str-chat__avatar-size': `${size}px`,
76
- width: `${size}px`,
77
- height: `${size}px`,
78
- backgroundColor: image ? undefined : bgColor,
79
- ...borderStyle,
80
- } as React.CSSProperties
81
- }
78
+ className={classNames(
79
+ 'relative flex-shrink-0',
80
+ className
81
+ )}
82
+ style={{
83
+ '--str-chat__avatar-size': `${size}px`,
84
+ width: `${size}px`,
85
+ height: `${size}px`,
86
+ backgroundColor: image ? undefined : bgColor,
87
+ ...borderStyle,
88
+ } as React.CSSProperties}
82
89
  >
83
90
  {starred && (
84
91
  <div
@@ -90,7 +97,10 @@ export const Avatar = ({
90
97
  )}
91
98
  <div
92
99
  data-testid="avatar-ring"
93
- className={classNames('h-full w-full', 'bg-transparent')}
100
+ className={classNames(
101
+ 'h-full w-full',
102
+ 'bg-transparent'
103
+ )}
94
104
  style={{
95
105
  ...borderStyle,
96
106
  ...(dmAgentEnabled && {
@@ -345,10 +345,12 @@ describe('ChannelView', () => {
345
345
  const firstHandler = vi.fn()
346
346
  const secondHandler = vi.fn()
347
347
  const { rerender: rerenderChannel } = renderWithProviders(
348
- <ChannelView channel={createChannel()} onBroadcastClick={firstHandler} />
348
+ <ChannelView
349
+ channel={createChannel()}
350
+ onBroadcastClick={firstHandler}
351
+ />
349
352
  )
350
- const firstMessageOverride =
351
- activeComponentOverrides.Message as React.ComponentType
353
+ const firstMessageOverride = activeComponentOverrides.Message as React.ComponentType
352
354
  const MessageRowHarness = ({
353
355
  Message,
354
356
  }: {
@@ -361,10 +363,12 @@ describe('ChannelView', () => {
361
363
  expect(customMessageMounts).toHaveBeenCalledOnce()
362
364
 
363
365
  rerenderChannel(
364
- <ChannelView channel={createChannel()} onBroadcastClick={secondHandler} />
366
+ <ChannelView
367
+ channel={createChannel()}
368
+ onBroadcastClick={secondHandler}
369
+ />
365
370
  )
366
- const secondMessageOverride =
367
- activeComponentOverrides.Message as React.ComponentType
371
+ const secondMessageOverride = activeComponentOverrides.Message as React.ComponentType
368
372
 
369
373
  expect(secondMessageOverride).toBe(firstMessageOverride)
370
374
  rerenderMessageRow(<MessageRowHarness Message={secondMessageOverride} />)
@@ -26,10 +26,7 @@ import { createMockStreamChatClient } from '../../testing/createMockStreamChatCl
26
26
  import type { BroadcastNameResolver } from '../../types'
27
27
  import CustomTypingIndicator from '../CustomTypingIndicator'
28
28
 
29
- import {
30
- BroadcastNameContext,
31
- buildBroadcastNamesById,
32
- } from './BroadcastNameContext'
29
+ import { BroadcastNameContext, buildBroadcastNamesById } from './BroadcastNameContext'
33
30
  import { CustomMessageActions } from './CustomMessageActions'
34
31
 
35
32
  import { CustomMessage } from './index'
@@ -310,9 +307,7 @@ BroadcastStatus.args = {
310
307
  ],
311
308
  }
312
309
 
313
- export const BroadcastStatusNonLatest: StoryFn<TemplateProps> = Template.bind(
314
- {}
315
- )
310
+ export const BroadcastStatusNonLatest: StoryFn<TemplateProps> = Template.bind({})
316
311
  BroadcastStatusNonLatest.args = {
317
312
  messages: [
318
313
  {
@@ -130,11 +130,9 @@ describe('CustomMessage', () => {
130
130
  )
131
131
 
132
132
  rerender(<CustomMessage onBroadcastClick={secondHandler} />)
133
- screen
134
- .getByRole('button', {
135
- name: 'View broadcast July 9th Class attendees',
136
- })
137
- .click()
133
+ screen.getByRole('button', {
134
+ name: 'View broadcast July 9th Class attendees',
135
+ }).click()
138
136
 
139
137
  expect(firstHandler).not.toHaveBeenCalled()
140
138
  expect(secondHandler).toHaveBeenCalledWith({
@@ -21,10 +21,7 @@ describe('LockedAttachment (characterization)', () => {
21
21
 
22
22
  it('media mode: renders a preview toggle when a source fetcher is wired', () => {
23
23
  renderWithProviders(
24
- <MediaCard
25
- isDraft
26
- onFetchSource={vi.fn().mockResolvedValue(undefined)}
27
- />
24
+ <MediaCard isDraft onFetchSource={vi.fn().mockResolvedValue(undefined)} />
28
25
  )
29
26
  expect(
30
27
  screen.getByRole('button', { name: 'Toggle preview' })
@@ -91,7 +88,9 @@ describe('LockedAttachment (characterization)', () => {
91
88
  <MediaCard isMine={false} amountText="$5" onUnlockClick={vi.fn()} />
92
89
  )
93
90
  expect(screen.getByTestId('locked-attachment')).toBeInTheDocument()
94
- expect(screen.getByRole('button', { name: 'Unlock' })).toBeInTheDocument()
91
+ expect(
92
+ screen.getByRole('button', { name: 'Unlock' })
93
+ ).toBeInTheDocument()
95
94
  })
96
95
  })
97
96
 
@@ -24,7 +24,7 @@ const DraftTextCard: React.FC<TextCardDraftProps> = ({
24
24
  onDismiss,
25
25
  }) => (
26
26
  <TextShell isMine className="pr-8">
27
- {renderedText || <SkeletonTextLines variant="dark" />}
27
+ {renderedText || <SkeletonTextLines variant="dark" />}
28
28
  <PriceLockRow>
29
29
  <span className={amountText ? 'text-white/55' : 'text-white/30'}>
30
30
  {amountText || placeholderAmountText}
@@ -100,7 +100,9 @@ const OtherTextCard: React.FC<TextCardOtherProps> = ({
100
100
  )
101
101
  }
102
102
 
103
- const ariaLabel = isUnlocking ? 'Unlocking message.' : 'Unlock this message.'
103
+ const ariaLabel = isUnlocking
104
+ ? 'Unlocking message.'
105
+ : 'Unlock this message.'
104
106
 
105
107
  return (
106
108
  <TextShell isMine={false}>
@@ -55,15 +55,12 @@ const CardBody: React.FC<CardBodyProps> = ({
55
55
  <div className="flex min-w-0 flex-1 flex-col gap-1">
56
56
  {displayTitle.trim() !== '' && (
57
57
  <p
58
- className={classNames(
59
- 'truncate text-base font-medium leading-6',
60
- {
61
- 'text-black/90': !isDark && !titleDimmed,
62
- 'text-black/30': !isDark && titleDimmed,
63
- 'text-white/30': isDark && titleDimmed,
64
- 'text-white': isDark && !titleDimmed,
65
- }
66
- )}
58
+ className={classNames('truncate text-base font-medium leading-6', {
59
+ 'text-black/90': !isDark && !titleDimmed,
60
+ 'text-black/30': !isDark && titleDimmed,
61
+ 'text-white/30': isDark && titleDimmed,
62
+ 'text-white': isDark && !titleDimmed,
63
+ })}
67
64
  >
68
65
  {displayTitle}
69
66
  </p>
@@ -36,7 +36,9 @@ export const isGalleryCard = (
36
36
  * otherwise auto-detects the icon from `mimeType`. Returned as a ready node so
37
37
  * every card shares the same size/tone treatment.
38
38
  */
39
- export const galleryBodyIcon = (variant: CardVariant): React.ReactNode => (
39
+ export const galleryBodyIcon = (
40
+ variant: CardVariant
41
+ ): React.ReactNode => (
40
42
  <ImagesIcon
41
43
  className={
42
44
  variant === 'dark'
@@ -4,7 +4,10 @@ import React, { useState } from 'react'
4
4
 
5
5
  import { optimizeMessagingAttachmentUrl } from '../../../../../utils/cdnImageUrl'
6
6
  import { AttachmentThumbnail, getSourceType } from '../../../../AttachmentCard'
7
- import type { LockedAttachmentGalleryItem, PaymentStatus } from '../../types'
7
+ import type {
8
+ LockedAttachmentGalleryItem,
9
+ PaymentStatus,
10
+ } from '../../types'
8
11
 
9
12
  import { LockBadge } from './LockBadge'
10
13
  import type { CardVariant } from './MediaShell'
@@ -54,6 +54,7 @@ const PurchaseStatusBadge: React.FC<PurchaseStatusBadgeProps> = ({
54
54
  )
55
55
  }
56
56
 
57
+
57
58
  if (paymentStatus === 'failed' || paymentStatus === 'refunded') {
58
59
  return (
59
60
  <React.Fragment>
@@ -2,7 +2,10 @@ import classNames from 'classnames'
2
2
  import React from 'react'
3
3
 
4
4
  import { optimizeMessagingAttachmentUrl } from '../../../../../utils/cdnImageUrl'
5
- import { AttachmentThumbnail, renderTypeIcon } from '../../../../AttachmentCard'
5
+ import {
6
+ AttachmentThumbnail,
7
+ renderTypeIcon,
8
+ } from '../../../../AttachmentCard'
6
9
  import type { LockedAttachmentSource, PaymentStatus } from '../../types'
7
10
 
8
11
  import { LockBadge } from './LockBadge'
@@ -15,16 +15,11 @@ export interface SkeletonTextLinesProps {
15
15
  * support opacity modifiers on the `current` color — `bg-current/30` silently
16
16
  * produces no CSS rule at all.
17
17
  */
18
- const SkeletonTextLines: React.FC<SkeletonTextLinesProps> = ({
19
- variant = 'dark',
20
- }) => {
18
+ const SkeletonTextLines: React.FC<SkeletonTextLinesProps> = ({ variant = 'dark' }) => {
21
19
  const colour = variant === 'dark' ? 'bg-white/25' : 'bg-black/15'
22
20
 
23
21
  return (
24
- <div
25
- className="flex flex-col gap-2 str-chat__message-text my-1 animate-pulse"
26
- aria-hidden
27
- >
22
+ <div className="flex flex-col gap-2 str-chat__message-text my-1 animate-pulse" aria-hidden>
28
23
  <div className={classNames('h-3 w-40 rounded-full', colour)} />
29
24
  <div className={classNames('h-3 w-24 rounded-full', colour)} />
30
25
  </div>
@@ -39,7 +39,6 @@ export interface LockedAttachmentContextValue {
39
39
  ) => Promise<LockedAttachmentSource | void>
40
40
  }
41
41
 
42
- export const defaultLockedAttachmentContextValue: LockedAttachmentContextValue =
43
- {
44
- isUnlocking: () => false,
45
- }
42
+ export const defaultLockedAttachmentContextValue: LockedAttachmentContextValue = {
43
+ isUnlocking: () => false,
44
+ }