@linktr.ee/messaging-react 3.14.5 → 3.15.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/dist/{Card-Dy9dBg7f.js → Card-CjyK4Spa.js} +2 -2
- package/dist/{Card-Dy9dBg7f.js.map → Card-CjyK4Spa.js.map} +1 -1
- package/dist/{Card-Ce3PVNyH.cjs → Card-U1PmVIQ9.cjs} +2 -2
- package/dist/{Card-Ce3PVNyH.cjs.map → Card-U1PmVIQ9.cjs.map} +1 -1
- package/dist/{index-DMYxJz1w.js → index-DdVzOymJ.js} +1968 -2314
- package/dist/index-DdVzOymJ.js.map +1 -0
- package/dist/index-NcnnPWrl.cjs +2 -0
- package/dist/index-NcnnPWrl.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +6 -7
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/ChannelHeaderRedesign.tsx +60 -57
- package/src/components/ChannelView.stories.tsx +0 -19
- package/src/components/ChannelView.test.tsx +20 -72
- package/src/components/ChannelView.tsx +12 -422
- package/src/components/MessagingShell/index.tsx +0 -2
- package/src/types.ts +5 -7
- package/dist/index-BdzqW4jX.cjs +0 -2
- package/dist/index-BdzqW4jX.cjs.map +0 -1
- package/dist/index-DMYxJz1w.js.map +0 -1
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ArrowLeftIcon,
|
|
3
|
-
CaretRightIcon,
|
|
4
|
-
SparkleIcon,
|
|
5
|
-
StarIcon,
|
|
6
|
-
} from '@phosphor-icons/react'
|
|
7
1
|
import classNames from 'classnames'
|
|
8
2
|
import React, { useCallback, useEffect, useRef } from 'react'
|
|
9
3
|
import { Channel as ChannelType } from 'stream-chat'
|
|
@@ -13,18 +7,12 @@ import {
|
|
|
13
7
|
MessageList,
|
|
14
8
|
useMessageContext,
|
|
15
9
|
useChannelStateContext,
|
|
16
|
-
useChatContext,
|
|
17
10
|
WithComponents,
|
|
18
11
|
MessageUIComponentProps,
|
|
19
12
|
} from 'stream-chat-react'
|
|
20
13
|
|
|
21
|
-
import { useChannelStar } from '../hooks/useChannelStar'
|
|
22
14
|
import type { ChannelViewProps } from '../types'
|
|
23
|
-
import { resolveConversationParticipant } from '../utils/resolveConversationParticipant'
|
|
24
|
-
import { resolveParticipantDisplayName } from '../utils/resolveParticipantDisplayName'
|
|
25
15
|
|
|
26
|
-
import { Avatar } from './Avatar'
|
|
27
|
-
import { ChannelActionsMenu } from './ChannelActionsMenu'
|
|
28
16
|
import { ChannelHeaderRedesign } from './ChannelHeaderRedesign'
|
|
29
17
|
import { CustomDateSeparator } from './CustomDateSeparator'
|
|
30
18
|
import { CustomMessage } from './CustomMessage'
|
|
@@ -36,339 +24,6 @@ import { DmAgentEnabledContext } from './CustomTypingIndicator/DmAgentContext'
|
|
|
36
24
|
import { ChannelEmptyState } from './MessagingShell/ChannelEmptyState'
|
|
37
25
|
import { LoadingState } from './MessagingShell/LoadingState'
|
|
38
26
|
|
|
39
|
-
const ICON_BTN_CLASS =
|
|
40
|
-
'size-10 rounded-full hover:bg-[#E5E4E1] flex items-center justify-center transition-colors duration-150 focus-ring'
|
|
41
|
-
|
|
42
|
-
const DM_AGENT_HEADER_HELPER_TEXT = 'Replies instantly with AI assistant'
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Custom channel header component
|
|
46
|
-
*/
|
|
47
|
-
const CustomChannelHeader: React.FC<{
|
|
48
|
-
onBack?: () => void
|
|
49
|
-
showBackButton: boolean
|
|
50
|
-
showStarButton?: boolean
|
|
51
|
-
dmAgentEnabled?: boolean
|
|
52
|
-
onLeaveConversation?: (channel: ChannelType) => void
|
|
53
|
-
onBlockParticipant?: (participantId?: string) => void
|
|
54
|
-
showDeleteConversation?: boolean
|
|
55
|
-
showBlockParticipant?: boolean
|
|
56
|
-
showReportParticipant?: boolean
|
|
57
|
-
onDeleteConversationClick?: () => void
|
|
58
|
-
onBlockParticipantClick?: () => void
|
|
59
|
-
onReportParticipantClick?: () => void
|
|
60
|
-
customChannelActions?: React.ReactNode
|
|
61
|
-
renderChannelActions?: React.ReactNode
|
|
62
|
-
showChannelInfo?: boolean
|
|
63
|
-
onParticipantNameClick?: () => void
|
|
64
|
-
renderHeaderTitleBadges?: ChannelViewProps['renderHeaderTitleBadges']
|
|
65
|
-
}> = ({
|
|
66
|
-
onBack,
|
|
67
|
-
showBackButton,
|
|
68
|
-
showStarButton = false,
|
|
69
|
-
dmAgentEnabled = false,
|
|
70
|
-
onLeaveConversation,
|
|
71
|
-
onBlockParticipant,
|
|
72
|
-
showDeleteConversation = true,
|
|
73
|
-
showBlockParticipant = true,
|
|
74
|
-
showReportParticipant = true,
|
|
75
|
-
onDeleteConversationClick,
|
|
76
|
-
onBlockParticipantClick,
|
|
77
|
-
onReportParticipantClick,
|
|
78
|
-
customChannelActions,
|
|
79
|
-
renderChannelActions,
|
|
80
|
-
showChannelInfo = true,
|
|
81
|
-
onParticipantNameClick,
|
|
82
|
-
renderHeaderTitleBadges,
|
|
83
|
-
}) => {
|
|
84
|
-
const { channel } = useChannelStateContext()
|
|
85
|
-
const { client } = useChatContext()
|
|
86
|
-
|
|
87
|
-
// Get participant info (excluding current user)
|
|
88
|
-
const participant = React.useMemo(
|
|
89
|
-
() =>
|
|
90
|
-
resolveConversationParticipant(
|
|
91
|
-
channel.state?.members,
|
|
92
|
-
client?.userID,
|
|
93
|
-
channel.type
|
|
94
|
-
),
|
|
95
|
-
[channel.state?.members, client?.userID, channel.type]
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
const participantName = resolveParticipantDisplayName(participant?.user)
|
|
99
|
-
const participantImage = participant?.user?.image
|
|
100
|
-
const isStarred = useChannelStar(channel)
|
|
101
|
-
const headerTitleBadges = renderHeaderTitleBadges?.({
|
|
102
|
-
channel,
|
|
103
|
-
participant,
|
|
104
|
-
})
|
|
105
|
-
const mobileParticipantIdentityClassName =
|
|
106
|
-
'flex max-w-full flex-col items-center gap-1 rounded-[12px] px-1 py-0.5 text-center text-xs font-medium text-black/90'
|
|
107
|
-
const desktopParticipantIdentityClassName =
|
|
108
|
-
'flex min-w-0 max-w-full items-center gap-4 rounded-[12px] px-1 py-0.5 text-left text-black/90'
|
|
109
|
-
const participantTitle = (
|
|
110
|
-
<>
|
|
111
|
-
<span className="min-w-0 truncate">{participantName}</span>
|
|
112
|
-
{headerTitleBadges && (
|
|
113
|
-
<span className="shrink-0">{headerTitleBadges}</span>
|
|
114
|
-
)}
|
|
115
|
-
</>
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
const handleStarClick = async () => {
|
|
119
|
-
try {
|
|
120
|
-
if (isStarred) {
|
|
121
|
-
await channel.unpin()
|
|
122
|
-
} else {
|
|
123
|
-
await channel.pin()
|
|
124
|
-
}
|
|
125
|
-
} catch (error) {
|
|
126
|
-
console.error(
|
|
127
|
-
'[CustomChannelHeader] Failed to update pinned status:',
|
|
128
|
-
error
|
|
129
|
-
)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return (
|
|
134
|
-
<div className="@container">
|
|
135
|
-
<div className="grid grid-cols-[1fr_auto_1fr] w-full items-center @lg:hidden px-6 py-3">
|
|
136
|
-
<div className="flex items-center gap-2">
|
|
137
|
-
{showBackButton && (
|
|
138
|
-
<button
|
|
139
|
-
className={classNames(
|
|
140
|
-
ICON_BTN_CLASS,
|
|
141
|
-
'messaging-channel-view-back-button-mobile bg-[#F1F0EE]'
|
|
142
|
-
)}
|
|
143
|
-
onClick={onBack || (() => {})}
|
|
144
|
-
type="button"
|
|
145
|
-
aria-label="Back to conversations"
|
|
146
|
-
>
|
|
147
|
-
<ArrowLeftIcon className="size-5 text-black/90" />
|
|
148
|
-
</button>
|
|
149
|
-
)}
|
|
150
|
-
</div>
|
|
151
|
-
<div
|
|
152
|
-
className="flex flex-col gap-1 items-center"
|
|
153
|
-
data-dd-privacy="mask"
|
|
154
|
-
>
|
|
155
|
-
{onParticipantNameClick ? (
|
|
156
|
-
<button
|
|
157
|
-
type="button"
|
|
158
|
-
onClick={onParticipantNameClick}
|
|
159
|
-
aria-label={`View details for ${participantName}`}
|
|
160
|
-
className={classNames(
|
|
161
|
-
mobileParticipantIdentityClassName,
|
|
162
|
-
'appearance-none border-0 bg-transparent transition-opacity hover:opacity-70 focus-ring focus-visible:outline-none'
|
|
163
|
-
)}
|
|
164
|
-
>
|
|
165
|
-
<Avatar
|
|
166
|
-
id={participant?.user?.id || channel.id || 'unknown'}
|
|
167
|
-
name={participantName}
|
|
168
|
-
image={participantImage}
|
|
169
|
-
starred={showStarButton && isStarred}
|
|
170
|
-
dmAgentEnabled={dmAgentEnabled}
|
|
171
|
-
size={48}
|
|
172
|
-
/>
|
|
173
|
-
<span className="flex max-w-full items-center gap-0.5">
|
|
174
|
-
{participantTitle}
|
|
175
|
-
<CaretRightIcon className="size-3 shrink-0" weight="bold" />
|
|
176
|
-
</span>
|
|
177
|
-
{dmAgentEnabled && (
|
|
178
|
-
<div className="flex items-center gap-1 text-[10px] leading-3 text-black/55">
|
|
179
|
-
<SparkleIcon className="size-3 shrink-0 text-black/55" />
|
|
180
|
-
<span>{DM_AGENT_HEADER_HELPER_TEXT}</span>
|
|
181
|
-
</div>
|
|
182
|
-
)}
|
|
183
|
-
</button>
|
|
184
|
-
) : (
|
|
185
|
-
<div className={mobileParticipantIdentityClassName}>
|
|
186
|
-
<Avatar
|
|
187
|
-
id={participant?.user?.id || channel.id || 'unknown'}
|
|
188
|
-
name={participantName}
|
|
189
|
-
image={participantImage}
|
|
190
|
-
starred={showStarButton && isStarred}
|
|
191
|
-
dmAgentEnabled={dmAgentEnabled}
|
|
192
|
-
size={48}
|
|
193
|
-
/>
|
|
194
|
-
<p className="flex max-w-full items-center justify-center gap-0.5">
|
|
195
|
-
{participantTitle}
|
|
196
|
-
<CaretRightIcon
|
|
197
|
-
className="invisible size-3 shrink-0"
|
|
198
|
-
weight="bold"
|
|
199
|
-
/>
|
|
200
|
-
</p>
|
|
201
|
-
{dmAgentEnabled && (
|
|
202
|
-
<div className="flex items-center gap-1 text-[10px] leading-3 text-black/55">
|
|
203
|
-
<SparkleIcon className="size-3 shrink-0 text-black/55" />
|
|
204
|
-
<span>{DM_AGENT_HEADER_HELPER_TEXT}</span>
|
|
205
|
-
</div>
|
|
206
|
-
)}
|
|
207
|
-
</div>
|
|
208
|
-
)}
|
|
209
|
-
</div>
|
|
210
|
-
<div className="flex justify-end items-center gap-2">
|
|
211
|
-
{showStarButton && (
|
|
212
|
-
<button
|
|
213
|
-
className={ICON_BTN_CLASS}
|
|
214
|
-
onClick={handleStarClick}
|
|
215
|
-
type="button"
|
|
216
|
-
aria-label={
|
|
217
|
-
isStarred ? 'Unstar conversation' : 'Star conversation'
|
|
218
|
-
}
|
|
219
|
-
>
|
|
220
|
-
<StarIcon
|
|
221
|
-
className={classNames('size-5', {
|
|
222
|
-
'text-yellow-600': isStarred,
|
|
223
|
-
'text-black/90': !isStarred,
|
|
224
|
-
})}
|
|
225
|
-
weight={isStarred ? 'duotone' : 'regular'}
|
|
226
|
-
/>
|
|
227
|
-
</button>
|
|
228
|
-
)}
|
|
229
|
-
{showChannelInfo &&
|
|
230
|
-
(renderChannelActions !== undefined ? (
|
|
231
|
-
renderChannelActions
|
|
232
|
-
) : (
|
|
233
|
-
<ChannelActionsMenu
|
|
234
|
-
channel={channel}
|
|
235
|
-
participant={participant}
|
|
236
|
-
showDeleteConversation={showDeleteConversation}
|
|
237
|
-
showBlockParticipant={showBlockParticipant}
|
|
238
|
-
showReportParticipant={showReportParticipant}
|
|
239
|
-
onLeaveConversation={onLeaveConversation}
|
|
240
|
-
onBlockParticipant={onBlockParticipant}
|
|
241
|
-
onDeleteConversationClick={onDeleteConversationClick}
|
|
242
|
-
onBlockParticipantClick={onBlockParticipantClick}
|
|
243
|
-
onReportParticipantClick={onReportParticipantClick}
|
|
244
|
-
customChannelActions={customChannelActions}
|
|
245
|
-
triggerClassName={classNames(ICON_BTN_CLASS, 'bg-[#F1F0EE]')}
|
|
246
|
-
/>
|
|
247
|
-
))}
|
|
248
|
-
</div>
|
|
249
|
-
</div>
|
|
250
|
-
<div className="px-6 py-3 hidden @lg:flex items-center justify-between gap-3 min-h-12 border-b border-b-black/[0.08]">
|
|
251
|
-
<div className="flex items-center gap-4 min-w-0" data-dd-privacy="mask">
|
|
252
|
-
{showBackButton && onBack && (
|
|
253
|
-
<button
|
|
254
|
-
className={classNames(
|
|
255
|
-
ICON_BTN_CLASS,
|
|
256
|
-
'messaging-channel-view-back-button-desktop'
|
|
257
|
-
)}
|
|
258
|
-
type="button"
|
|
259
|
-
onClick={onBack}
|
|
260
|
-
aria-label="Back to conversations"
|
|
261
|
-
>
|
|
262
|
-
<ArrowLeftIcon className="size-5 text-black/90" />
|
|
263
|
-
</button>
|
|
264
|
-
)}
|
|
265
|
-
{onParticipantNameClick ? (
|
|
266
|
-
<button
|
|
267
|
-
type="button"
|
|
268
|
-
onClick={onParticipantNameClick}
|
|
269
|
-
aria-label={`View details for ${participantName}`}
|
|
270
|
-
className={classNames(
|
|
271
|
-
desktopParticipantIdentityClassName,
|
|
272
|
-
'appearance-none border-0 bg-transparent transition-opacity hover:opacity-70 focus-ring focus-visible:outline-none'
|
|
273
|
-
)}
|
|
274
|
-
>
|
|
275
|
-
<Avatar
|
|
276
|
-
id={participant?.user?.id || channel.id || 'unknown'}
|
|
277
|
-
name={participantName}
|
|
278
|
-
image={participantImage}
|
|
279
|
-
starred={showStarButton && isStarred}
|
|
280
|
-
dmAgentEnabled={dmAgentEnabled}
|
|
281
|
-
size={48}
|
|
282
|
-
/>
|
|
283
|
-
<div className="min-w-0">
|
|
284
|
-
<h1 className="flex min-w-0 items-center gap-1 font-medium text-black/90">
|
|
285
|
-
{participantTitle}
|
|
286
|
-
<CaretRightIcon className="size-4 shrink-0" weight="bold" />
|
|
287
|
-
</h1>
|
|
288
|
-
{dmAgentEnabled && (
|
|
289
|
-
<div className="mt-0.5 flex items-center gap-1 text-[10px] leading-3 text-black/55">
|
|
290
|
-
<SparkleIcon className="size-3 shrink-0 text-black/55" />
|
|
291
|
-
<span className="truncate">
|
|
292
|
-
{DM_AGENT_HEADER_HELPER_TEXT}
|
|
293
|
-
</span>
|
|
294
|
-
</div>
|
|
295
|
-
)}
|
|
296
|
-
</div>
|
|
297
|
-
</button>
|
|
298
|
-
) : (
|
|
299
|
-
<div className={desktopParticipantIdentityClassName}>
|
|
300
|
-
<Avatar
|
|
301
|
-
id={participant?.user?.id || channel.id || 'unknown'}
|
|
302
|
-
name={participantName}
|
|
303
|
-
image={participantImage}
|
|
304
|
-
starred={showStarButton && isStarred}
|
|
305
|
-
dmAgentEnabled={dmAgentEnabled}
|
|
306
|
-
size={48}
|
|
307
|
-
/>
|
|
308
|
-
<div className="min-w-0">
|
|
309
|
-
<h1 className="flex min-w-0 items-center gap-1 font-medium text-black/90">
|
|
310
|
-
{participantTitle}
|
|
311
|
-
<CaretRightIcon
|
|
312
|
-
className="invisible size-4 shrink-0"
|
|
313
|
-
weight="bold"
|
|
314
|
-
/>
|
|
315
|
-
</h1>
|
|
316
|
-
{dmAgentEnabled && (
|
|
317
|
-
<div className="mt-0.5 flex items-center gap-1 text-[10px] leading-3 text-black/55">
|
|
318
|
-
<SparkleIcon className="size-3 shrink-0 text-black/55" />
|
|
319
|
-
<span className="truncate">
|
|
320
|
-
{DM_AGENT_HEADER_HELPER_TEXT}
|
|
321
|
-
</span>
|
|
322
|
-
</div>
|
|
323
|
-
)}
|
|
324
|
-
</div>
|
|
325
|
-
</div>
|
|
326
|
-
)}
|
|
327
|
-
</div>
|
|
328
|
-
<div className="flex items-center gap-2">
|
|
329
|
-
{showStarButton && (
|
|
330
|
-
<button
|
|
331
|
-
className={ICON_BTN_CLASS}
|
|
332
|
-
onClick={handleStarClick}
|
|
333
|
-
type="button"
|
|
334
|
-
aria-label={
|
|
335
|
-
isStarred ? 'Unstar conversation' : 'Star conversation'
|
|
336
|
-
}
|
|
337
|
-
>
|
|
338
|
-
<StarIcon
|
|
339
|
-
className={classNames('size-6', {
|
|
340
|
-
'text-yellow-600': isStarred,
|
|
341
|
-
'text-black/90': !isStarred,
|
|
342
|
-
})}
|
|
343
|
-
weight={isStarred ? 'duotone' : 'regular'}
|
|
344
|
-
/>
|
|
345
|
-
</button>
|
|
346
|
-
)}
|
|
347
|
-
{showChannelInfo &&
|
|
348
|
-
(renderChannelActions !== undefined ? (
|
|
349
|
-
renderChannelActions
|
|
350
|
-
) : (
|
|
351
|
-
<ChannelActionsMenu
|
|
352
|
-
channel={channel}
|
|
353
|
-
participant={participant}
|
|
354
|
-
showDeleteConversation={showDeleteConversation}
|
|
355
|
-
showBlockParticipant={showBlockParticipant}
|
|
356
|
-
showReportParticipant={showReportParticipant}
|
|
357
|
-
onLeaveConversation={onLeaveConversation}
|
|
358
|
-
onBlockParticipant={onBlockParticipant}
|
|
359
|
-
onDeleteConversationClick={onDeleteConversationClick}
|
|
360
|
-
onBlockParticipantClick={onBlockParticipantClick}
|
|
361
|
-
onReportParticipantClick={onReportParticipantClick}
|
|
362
|
-
customChannelActions={customChannelActions}
|
|
363
|
-
triggerClassName={ICON_BTN_CLASS}
|
|
364
|
-
/>
|
|
365
|
-
))}
|
|
366
|
-
</div>
|
|
367
|
-
</div>
|
|
368
|
-
</div>
|
|
369
|
-
)
|
|
370
|
-
}
|
|
371
|
-
|
|
372
27
|
/**
|
|
373
28
|
* Inner component that has access to channel context
|
|
374
29
|
*/
|
|
@@ -392,14 +47,12 @@ const ChannelViewInner: React.FC<{
|
|
|
392
47
|
showStarButton?: boolean
|
|
393
48
|
chatbotVotingEnabled?: boolean
|
|
394
49
|
renderChannelBanner?: () => React.ReactNode
|
|
395
|
-
renderHeaderTitleBadges?: ChannelViewProps['renderHeaderTitleBadges']
|
|
396
50
|
customChannelActions?: React.ReactNode
|
|
397
51
|
renderChannelActions?: React.ReactNode
|
|
398
52
|
renderMessage?: (
|
|
399
53
|
messageNode: React.ReactElement,
|
|
400
54
|
message: NonNullable<MessageUIComponentProps['message']>
|
|
401
55
|
) => React.ReactNode
|
|
402
|
-
dmAgentEnabled?: boolean
|
|
403
56
|
viewerLanguage?: string
|
|
404
57
|
showChannelInfo?: boolean
|
|
405
58
|
onParticipantNameClick?: () => void
|
|
@@ -423,48 +76,16 @@ const ChannelViewInner: React.FC<{
|
|
|
423
76
|
showStarButton = false,
|
|
424
77
|
chatbotVotingEnabled = false,
|
|
425
78
|
renderChannelBanner,
|
|
426
|
-
renderHeaderTitleBadges,
|
|
427
79
|
customChannelActions,
|
|
428
80
|
renderChannelActions,
|
|
429
81
|
renderMessage,
|
|
430
|
-
dmAgentEnabled = false,
|
|
431
82
|
viewerLanguage,
|
|
432
83
|
showChannelInfo = true,
|
|
433
84
|
onParticipantNameClick,
|
|
434
85
|
composerInput,
|
|
435
86
|
}) => {
|
|
436
87
|
const { channel } = useChannelStateContext()
|
|
437
|
-
const { client } = useChatContext()
|
|
438
88
|
|
|
439
|
-
// Get participant info (the other channel member)
|
|
440
|
-
const participant = React.useMemo(
|
|
441
|
-
() =>
|
|
442
|
-
resolveConversationParticipant(
|
|
443
|
-
channel.state?.members,
|
|
444
|
-
client?.userID,
|
|
445
|
-
channel.type
|
|
446
|
-
),
|
|
447
|
-
[channel.state?.members, client?.userID, channel.type]
|
|
448
|
-
)
|
|
449
|
-
|
|
450
|
-
const currentMember = React.useMemo(() => {
|
|
451
|
-
const myUserId = client?.userID
|
|
452
|
-
if (!myUserId) return undefined
|
|
453
|
-
const members = Object.values(channel.state?.members || {})
|
|
454
|
-
return members.find((member) => member.user?.id === myUserId)
|
|
455
|
-
}, [client?.userID, channel.state?.members])
|
|
456
|
-
|
|
457
|
-
const currentUserIsAccount =
|
|
458
|
-
(currentMember?.user as { is_account?: boolean } | undefined)?.is_account ??
|
|
459
|
-
(currentMember as { is_account?: boolean } | undefined)?.is_account
|
|
460
|
-
const participantIsAccount =
|
|
461
|
-
(participant?.user as { is_account?: boolean } | undefined)?.is_account ??
|
|
462
|
-
(participant as { is_account?: boolean } | undefined)?.is_account
|
|
463
|
-
|
|
464
|
-
const showDmAgentHeader =
|
|
465
|
-
dmAgentEnabled &&
|
|
466
|
-
currentUserIsAccount === false &&
|
|
467
|
-
participantIsAccount === true
|
|
468
89
|
const hasVisibleMessages = channel.state.messages.some(
|
|
469
90
|
(message) => message.type !== 'deleted'
|
|
470
91
|
)
|
|
@@ -473,14 +94,13 @@ const ChannelViewInner: React.FC<{
|
|
|
473
94
|
{renderChannelBanner()}
|
|
474
95
|
</React.Fragment>
|
|
475
96
|
) : null
|
|
476
|
-
const
|
|
97
|
+
const channelHeader = (
|
|
477
98
|
<ChannelHeaderRedesign
|
|
478
99
|
className="-mx-[var(--str-chat\_\_spacing-2)] px-[var(--str-chat\_\_spacing-2)] md:-mx-[min(var(--str-chat\_\_spacing-10),4%)] md:px-[min(var(--str-chat\_\_spacing-10),4%)]"
|
|
479
100
|
onBack={onBack}
|
|
480
101
|
showBackButton={showBackButton}
|
|
481
102
|
showChannelInfo={showChannelInfo}
|
|
482
103
|
showStarButton={showStarButton}
|
|
483
|
-
dmAgentEnabled={showDmAgentHeader}
|
|
484
104
|
onLeaveConversation={onLeaveConversation}
|
|
485
105
|
onBlockParticipant={onBlockParticipant}
|
|
486
106
|
showDeleteConversation={showDeleteConversation}
|
|
@@ -493,7 +113,7 @@ const ChannelViewInner: React.FC<{
|
|
|
493
113
|
renderChannelActions={renderChannelActions}
|
|
494
114
|
onParticipantNameClick={onParticipantNameClick}
|
|
495
115
|
/>
|
|
496
|
-
)
|
|
116
|
+
)
|
|
497
117
|
|
|
498
118
|
// Prevents all message instances from unmounting when ChannelViewInner re-renders
|
|
499
119
|
const MessageOverride = useCallback(
|
|
@@ -528,33 +148,6 @@ const ChannelViewInner: React.FC<{
|
|
|
528
148
|
}}
|
|
529
149
|
>
|
|
530
150
|
<Window>
|
|
531
|
-
{/* Custom Channel Header */}
|
|
532
|
-
{!onParticipantNameClick && (
|
|
533
|
-
<>
|
|
534
|
-
<div key="lt-channel-header">
|
|
535
|
-
<CustomChannelHeader
|
|
536
|
-
onBack={onBack}
|
|
537
|
-
showBackButton={showBackButton}
|
|
538
|
-
showChannelInfo={showChannelInfo}
|
|
539
|
-
showStarButton={showStarButton}
|
|
540
|
-
dmAgentEnabled={showDmAgentHeader}
|
|
541
|
-
onLeaveConversation={onLeaveConversation}
|
|
542
|
-
onBlockParticipant={onBlockParticipant}
|
|
543
|
-
showDeleteConversation={showDeleteConversation}
|
|
544
|
-
showBlockParticipant={showBlockParticipant}
|
|
545
|
-
showReportParticipant={showReportParticipant}
|
|
546
|
-
onDeleteConversationClick={onDeleteConversationClick}
|
|
547
|
-
onBlockParticipantClick={onBlockParticipantClick}
|
|
548
|
-
onReportParticipantClick={onReportParticipantClick}
|
|
549
|
-
customChannelActions={customChannelActions}
|
|
550
|
-
renderChannelActions={renderChannelActions}
|
|
551
|
-
renderHeaderTitleBadges={renderHeaderTitleBadges}
|
|
552
|
-
/>
|
|
553
|
-
</div>
|
|
554
|
-
{channelBanner}
|
|
555
|
-
</>
|
|
556
|
-
)}
|
|
557
|
-
|
|
558
151
|
{composerInput ? (
|
|
559
152
|
<div className="messaging-channel-layout relative flex min-h-0 flex-1 flex-col">
|
|
560
153
|
{/* Message List */}
|
|
@@ -563,11 +156,11 @@ const ChannelViewInner: React.FC<{
|
|
|
563
156
|
className="messaging-channel-message-list messaging-channel-message-list--floating relative min-h-0 flex-1 overflow-hidden"
|
|
564
157
|
>
|
|
565
158
|
{/* Stream only renders MessageList.head when there are messages, so
|
|
566
|
-
empty
|
|
567
|
-
{
|
|
159
|
+
empty channels need the header and banner in normal flow. */}
|
|
160
|
+
{!hasVisibleMessages && (
|
|
568
161
|
<div className="str-chat__list">
|
|
569
162
|
<div className="str-chat__message-list-scroll">
|
|
570
|
-
{
|
|
163
|
+
{channelHeader}
|
|
571
164
|
{channelBanner}
|
|
572
165
|
</div>
|
|
573
166
|
</div>
|
|
@@ -575,9 +168,9 @@ const ChannelViewInner: React.FC<{
|
|
|
575
168
|
|
|
576
169
|
<MessageList
|
|
577
170
|
head={
|
|
578
|
-
|
|
171
|
+
hasVisibleMessages ? (
|
|
579
172
|
<div className="sticky top-0 z-10">
|
|
580
|
-
{
|
|
173
|
+
{channelHeader}
|
|
581
174
|
{channelBanner}
|
|
582
175
|
</div>
|
|
583
176
|
) : undefined
|
|
@@ -612,11 +205,11 @@ const ChannelViewInner: React.FC<{
|
|
|
612
205
|
className="flex-1 overflow-hidden relative"
|
|
613
206
|
>
|
|
614
207
|
{/* Stream only renders MessageList.head when there are messages, so
|
|
615
|
-
empty
|
|
616
|
-
{
|
|
208
|
+
empty channels need the header and banner in normal flow. */}
|
|
209
|
+
{!hasVisibleMessages && (
|
|
617
210
|
<div className="str-chat__list">
|
|
618
211
|
<div className="str-chat__message-list-scroll">
|
|
619
|
-
{
|
|
212
|
+
{channelHeader}
|
|
620
213
|
{channelBanner}
|
|
621
214
|
</div>
|
|
622
215
|
</div>
|
|
@@ -624,9 +217,9 @@ const ChannelViewInner: React.FC<{
|
|
|
624
217
|
|
|
625
218
|
<MessageList
|
|
626
219
|
head={
|
|
627
|
-
|
|
220
|
+
hasVisibleMessages ? (
|
|
628
221
|
<div className="sticky top-0 z-10">
|
|
629
|
-
{
|
|
222
|
+
{channelHeader}
|
|
630
223
|
{channelBanner}
|
|
631
224
|
</div>
|
|
632
225
|
) : undefined
|
|
@@ -690,7 +283,6 @@ export const ChannelView = React.memo<ChannelViewProps>(
|
|
|
690
283
|
showStarButton = false,
|
|
691
284
|
chatbotVotingEnabled = false,
|
|
692
285
|
renderChannelBanner,
|
|
693
|
-
renderHeaderTitleBadges,
|
|
694
286
|
customChannelActions,
|
|
695
287
|
renderChannelActions,
|
|
696
288
|
renderMessage,
|
|
@@ -805,10 +397,8 @@ export const ChannelView = React.memo<ChannelViewProps>(
|
|
|
805
397
|
composerDisabled={composerDisabled}
|
|
806
398
|
composerDisabledReason={composerDisabledReason}
|
|
807
399
|
showStarButton={showStarButton}
|
|
808
|
-
dmAgentEnabled={dmAgentEnabled}
|
|
809
400
|
chatbotVotingEnabled={chatbotVotingEnabled}
|
|
810
401
|
renderChannelBanner={renderChannelBanner}
|
|
811
|
-
renderHeaderTitleBadges={renderHeaderTitleBadges}
|
|
812
402
|
customChannelActions={customChannelActions}
|
|
813
403
|
renderChannelActions={renderChannelActions}
|
|
814
404
|
renderMessage={renderMessage}
|
|
@@ -31,7 +31,6 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
|
|
|
31
31
|
onMessageSent,
|
|
32
32
|
chatbotVotingEnabled = false,
|
|
33
33
|
viewerLanguage,
|
|
34
|
-
renderHeaderTitleBadges,
|
|
35
34
|
renderChannelBanner,
|
|
36
35
|
customChannelActions,
|
|
37
36
|
renderChannelActions,
|
|
@@ -258,7 +257,6 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
|
|
|
258
257
|
onMessageSent={onMessageSent}
|
|
259
258
|
chatbotVotingEnabled={chatbotVotingEnabled}
|
|
260
259
|
viewerLanguage={viewerLanguage}
|
|
261
|
-
renderHeaderTitleBadges={renderHeaderTitleBadges}
|
|
262
260
|
customChannelActions={customChannelActions}
|
|
263
261
|
renderChannelActions={renderChannelActions}
|
|
264
262
|
onParticipantNameClick={onParticipantNameClick}
|
package/src/types.ts
CHANGED
|
@@ -268,8 +268,8 @@ export interface ChannelViewProps {
|
|
|
268
268
|
showStarButton?: boolean
|
|
269
269
|
|
|
270
270
|
/**
|
|
271
|
-
*
|
|
272
|
-
*
|
|
271
|
+
* @deprecated No longer rendered. The redesigned header shows built-in paid
|
|
272
|
+
* and starred badges instead. Kept temporarily so existing call sites type-check.
|
|
273
273
|
*/
|
|
274
274
|
renderHeaderTitleBadges?: (context: {
|
|
275
275
|
channel: Channel
|
|
@@ -399,10 +399,9 @@ export interface ChannelViewProps {
|
|
|
399
399
|
composerInput?: ComponentType
|
|
400
400
|
|
|
401
401
|
/**
|
|
402
|
-
* Fired when the participant
|
|
403
|
-
* provided, the name
|
|
404
|
-
*
|
|
405
|
-
* renders as plain text.
|
|
402
|
+
* Fired when the participant identity in the channel header is clicked. When
|
|
403
|
+
* provided, the avatar + name pill render as a button with a trailing caret;
|
|
404
|
+
* when omitted, they render as non-interactive chrome.
|
|
406
405
|
*
|
|
407
406
|
* @example
|
|
408
407
|
* onParticipantNameClick={() => openThreadContentDialog()}
|
|
@@ -425,7 +424,6 @@ export type ChannelViewPassthroughProps = Pick<
|
|
|
425
424
|
| 'onMessageSent'
|
|
426
425
|
| 'chatbotVotingEnabled'
|
|
427
426
|
| 'viewerLanguage'
|
|
428
|
-
| 'renderHeaderTitleBadges'
|
|
429
427
|
| 'renderChannelBanner'
|
|
430
428
|
| 'customChannelActions'
|
|
431
429
|
| 'renderChannelActions'
|