@linktr.ee/messaging-react 3.4.2-rc-1782453771 → 3.4.2-rc-1782480798
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-ql9pImRa.js → Card-BKi2g6x-.js} +2 -2
- package/dist/{Card-ql9pImRa.js.map → Card-BKi2g6x-.js.map} +1 -1
- package/dist/{Card-BIa-47Ne.cjs → Card-BMmrCMqJ.cjs} +2 -2
- package/dist/{Card-BIa-47Ne.cjs.map → Card-BMmrCMqJ.cjs.map} +1 -1
- package/dist/{Card-BaXLsSK2.js → Card-BYu6OBuX.js} +2 -2
- package/dist/{Card-BaXLsSK2.js.map → Card-BYu6OBuX.js.map} +1 -1
- package/dist/{Card-BkVj6kGN.cjs → Card-DtIjtWy6.cjs} +2 -2
- package/dist/{Card-BkVj6kGN.cjs.map → Card-DtIjtWy6.cjs.map} +1 -1
- package/dist/{Card-52LnCirC.js → Card-DvE5BCPf.js} +3 -3
- package/dist/{Card-52LnCirC.js.map → Card-DvE5BCPf.js.map} +1 -1
- package/dist/{Card-CcTyYY9N.cjs → Card-VO-i6CuV.cjs} +2 -2
- package/dist/{Card-CcTyYY9N.cjs.map → Card-VO-i6CuV.cjs.map} +1 -1
- package/dist/{LockedThumbnail-D0ASm7LP.cjs → LockedThumbnail-Cl8uwCxM.cjs} +2 -2
- package/dist/{LockedThumbnail-D0ASm7LP.cjs.map → LockedThumbnail-Cl8uwCxM.cjs.map} +1 -1
- package/dist/{LockedThumbnail-C3YOnS-o.js → LockedThumbnail-DTkd_kEt.js} +2 -2
- package/dist/{LockedThumbnail-C3YOnS-o.js.map → LockedThumbnail-DTkd_kEt.js.map} +1 -1
- package/dist/index-CSSe9eu7.cjs +2 -0
- package/dist/index-CSSe9eu7.cjs.map +1 -0
- package/dist/{index-CbWEp3Zs.js → index-IzhF38yj.js} +3447 -3212
- package/dist/index-IzhF38yj.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +25 -13
- package/dist/index.js +14 -13
- package/package.json +2 -2
- package/src/components/ChannelList/CustomChannelPreview.stories.tsx +0 -63
- package/src/components/ChannelList/CustomChannelPreview.test.tsx +8 -58
- package/src/components/ChannelList/CustomChannelPreview.tsx +10 -7
- package/src/components/ChannelView.stories.tsx +7 -38
- package/src/components/ChannelView.test.tsx +15 -29
- package/src/components/ChannelView.tsx +9 -19
- package/src/components/CustomMessage/StreamAttachmentMessage.test.tsx +109 -0
- package/src/components/CustomMessage/StreamAttachmentMessage.tsx +408 -0
- package/src/components/CustomMessage/index.tsx +42 -0
- package/src/components/CustomMessageInput/CustomMessageInput.test.tsx +34 -0
- package/src/components/CustomMessageInput/index.tsx +23 -1
- package/src/components/MessagingShell/index.tsx +2 -0
- package/src/hooks/useChannelStar.ts +6 -9
- package/src/index.ts +1 -0
- package/src/stream-custom-data.ts +1 -16
- package/src/types.ts +18 -0
- package/dist/index-CbWEp3Zs.js.map +0 -1
- package/dist/index-DkqM2z_j.cjs +0 -2
- package/dist/index-DkqM2z_j.cjs.map +0 -1
- package/src/components/ParticipantBadges.tsx +0 -39
|
@@ -204,6 +204,40 @@ describe('CustomMessageInput', () => {
|
|
|
204
204
|
).toBeInTheDocument()
|
|
205
205
|
})
|
|
206
206
|
|
|
207
|
+
it('renders a custom composerInput in place of the default composer', () => {
|
|
208
|
+
mockChannelData = {}
|
|
209
|
+
|
|
210
|
+
renderWithProviders(
|
|
211
|
+
<CustomMessageInput
|
|
212
|
+
composerInput={() => (
|
|
213
|
+
<div data-testid="custom-composer">custom composer</div>
|
|
214
|
+
)}
|
|
215
|
+
/>
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
// The host-owned composer renders instead of the built-in textarea/send.
|
|
219
|
+
expect(screen.getByTestId('custom-composer')).toBeInTheDocument()
|
|
220
|
+
expect(screen.queryByTestId('textarea-composer')).not.toBeInTheDocument()
|
|
221
|
+
// It is still mounted inside Stream's <MessageInput> so it keeps the
|
|
222
|
+
// message-input context (send pipeline, attachments, previews).
|
|
223
|
+
expect(screen.getByTestId('stream-message-input')).toBeInTheDocument()
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
it('keeps the frozen wrapper around a custom composerInput', () => {
|
|
227
|
+
mockChannelData = { frozen: true }
|
|
228
|
+
|
|
229
|
+
const { container } = renderWithProviders(
|
|
230
|
+
<CustomMessageInput
|
|
231
|
+
composerInput={() => <div data-testid="custom-composer" />}
|
|
232
|
+
/>
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
const messageInput = container.querySelector('.message-input')
|
|
236
|
+
expect(messageInput).toHaveAttribute('aria-disabled', 'true')
|
|
237
|
+
expect(messageInput).toHaveAttribute('inert')
|
|
238
|
+
expect(screen.getByTestId('custom-composer')).toBeInTheDocument()
|
|
239
|
+
})
|
|
240
|
+
|
|
207
241
|
it('does not render the locked panel when the composer is not disabled', () => {
|
|
208
242
|
mockChannelData = {}
|
|
209
243
|
|
|
@@ -23,6 +23,15 @@ import { CustomLinkPreviewList } from '../CustomLinkPreviewList'
|
|
|
23
23
|
*/
|
|
24
24
|
const ComposerLockedContext = React.createContext(false)
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Read the composer's locked (frozen-channel) state from inside a custom
|
|
28
|
+
* composer supplied via `composerInput`. Returns true when the channel is
|
|
29
|
+
* frozen; mirror the default composer by rendering the textarea read-only and
|
|
30
|
+
* disabling the send control.
|
|
31
|
+
*/
|
|
32
|
+
export const useComposerLocked = (): boolean =>
|
|
33
|
+
useContext(ComposerLockedContext)
|
|
34
|
+
|
|
26
35
|
const DefaultSendButton: React.FC<{
|
|
27
36
|
sendMessage: () => void
|
|
28
37
|
disabled?: boolean
|
|
@@ -101,6 +110,18 @@ export interface CustomMessageInputProps {
|
|
|
101
110
|
* `disabled` is true.
|
|
102
111
|
*/
|
|
103
112
|
disabledReason?: string
|
|
113
|
+
/**
|
|
114
|
+
* Replace the inner composer — the textarea + send arrangement rendered
|
|
115
|
+
* inside Stream's `<MessageInput>` — with a host-owned component. When
|
|
116
|
+
* provided it is passed to Stream as the `Input` component, so it runs inside
|
|
117
|
+
* the message-input context and can drive sending, attachments, and previews
|
|
118
|
+
* via the Stream hooks (`useMessageInputContext`,
|
|
119
|
+
* `useMessageComposerHasSendableData`, `TextareaComposer`, …). The outer
|
|
120
|
+
* frozen/`renderActions`/`renderFooter` wrapper is unchanged; read
|
|
121
|
+
* `useComposerLocked()` to honour the frozen state. Defaults to the built-in
|
|
122
|
+
* composer.
|
|
123
|
+
*/
|
|
124
|
+
composerInput?: React.ComponentType
|
|
104
125
|
}
|
|
105
126
|
|
|
106
127
|
export const CustomMessageInput: React.FC<CustomMessageInputProps> = ({
|
|
@@ -108,6 +129,7 @@ export const CustomMessageInput: React.FC<CustomMessageInputProps> = ({
|
|
|
108
129
|
renderFooter,
|
|
109
130
|
disabled = false,
|
|
110
131
|
disabledReason,
|
|
132
|
+
composerInput,
|
|
111
133
|
}) => {
|
|
112
134
|
const { channel } = useChannelStateContext()
|
|
113
135
|
const isFrozen = channel?.data?.frozen === true
|
|
@@ -143,7 +165,7 @@ export const CustomMessageInput: React.FC<CustomMessageInputProps> = ({
|
|
|
143
165
|
</div>
|
|
144
166
|
)}
|
|
145
167
|
<ComposerLockedContext.Provider value={isFrozen}>
|
|
146
|
-
<MessageInput Input={CustomMessageInputInner} />
|
|
168
|
+
<MessageInput Input={composerInput ?? CustomMessageInputInner} />
|
|
147
169
|
</ComposerLockedContext.Provider>
|
|
148
170
|
</div>
|
|
149
171
|
{renderFooter?.()}
|
|
@@ -39,6 +39,7 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
|
|
|
39
39
|
renderMessage,
|
|
40
40
|
onMessageLinkClick,
|
|
41
41
|
showChannelInfo,
|
|
42
|
+
composerInput,
|
|
42
43
|
}) => {
|
|
43
44
|
const {
|
|
44
45
|
client,
|
|
@@ -264,6 +265,7 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
|
|
|
264
265
|
renderMessage={renderMessage}
|
|
265
266
|
onMessageLinkClick={onMessageLinkClick}
|
|
266
267
|
showChannelInfo={showChannelInfo}
|
|
268
|
+
composerInput={composerInput}
|
|
267
269
|
/>
|
|
268
270
|
</div>
|
|
269
271
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react'
|
|
2
|
-
import
|
|
2
|
+
import { Channel, Event } from 'stream-chat'
|
|
3
3
|
|
|
4
4
|
export const useChannelStar = (channel?: Channel) => {
|
|
5
5
|
const [isChannelStarred, setIsChannelStarred] = useState(
|
|
@@ -15,18 +15,15 @@ export const useChannelStar = (channel?: Channel) => {
|
|
|
15
15
|
setIsChannelStarred(!!channel.state.membership?.pinned_at)
|
|
16
16
|
|
|
17
17
|
const handleMemberUpdate = (event: Event) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (!currentUserId || memberUserId !== currentUserId) return
|
|
22
|
-
|
|
23
|
-
setIsChannelStarred(!!event.member?.pinned_at)
|
|
18
|
+
setIsChannelStarred(
|
|
19
|
+
event?.member ? !!event.member.pinned_at : !!channel.state.membership?.pinned_at
|
|
20
|
+
)
|
|
24
21
|
}
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
channel.on('member.updated', handleMemberUpdate)
|
|
27
24
|
|
|
28
25
|
return () => {
|
|
29
|
-
|
|
26
|
+
channel.off('member.updated', handleMemberUpdate)
|
|
30
27
|
}
|
|
31
28
|
}, [channel])
|
|
32
29
|
|
package/src/index.ts
CHANGED
|
@@ -30,6 +30,7 @@ export { MessagingProvider } from './providers/MessagingProvider'
|
|
|
30
30
|
export { CustomMessageProvider } from './components/CustomMessage/context'
|
|
31
31
|
|
|
32
32
|
// Hooks
|
|
33
|
+
export { useComposerLocked } from './components/CustomMessageInput'
|
|
33
34
|
export { useMessaging } from './hooks/useMessaging'
|
|
34
35
|
export { useMessageVote } from './hooks/useMessageVote'
|
|
35
36
|
export { useCustomMessage } from './components/CustomMessage/context'
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* Stream Chat custom data type augmentation.
|
|
3
3
|
*
|
|
4
4
|
* This file extends Stream Chat's type system by augmenting their empty
|
|
5
|
-
* CustomMessageData
|
|
6
|
-
* interfaces with our custom properties.
|
|
5
|
+
* CustomMessageData and CustomChannelData interfaces with our custom properties.
|
|
7
6
|
*
|
|
8
7
|
* @see https://getstream.io/chat/docs/sdk/react/guides/typescript_and_custom_data_types/
|
|
9
8
|
*
|
|
@@ -99,14 +98,6 @@ declare module 'stream-chat' {
|
|
|
99
98
|
chatbot_paused?: boolean
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
interface CustomMemberData {
|
|
103
|
-
/**
|
|
104
|
-
* Whether the member should be identified as a customer in participant UI.
|
|
105
|
-
* Stored on the channel member so it is scoped to this conversation.
|
|
106
|
-
*/
|
|
107
|
-
customer?: boolean
|
|
108
|
-
}
|
|
109
|
-
|
|
110
101
|
interface CustomMessageData {
|
|
111
102
|
/**
|
|
112
103
|
* When true, hides the date timestamp in system messages.
|
|
@@ -124,10 +115,4 @@ declare module 'stream-chat' {
|
|
|
124
115
|
*/
|
|
125
116
|
dm_agent_system_type?: DmAgentSystemType
|
|
126
117
|
}
|
|
127
|
-
|
|
128
|
-
interface CustomUserData {
|
|
129
|
-
is_account?: boolean
|
|
130
|
-
is_follower?: boolean
|
|
131
|
-
username?: string
|
|
132
|
-
}
|
|
133
118
|
}
|
package/src/types.ts
CHANGED
|
@@ -324,6 +324,23 @@ export interface ChannelViewProps {
|
|
|
324
324
|
*/
|
|
325
325
|
attachmentPreviewList?: ComponentType
|
|
326
326
|
|
|
327
|
+
/**
|
|
328
|
+
* Replace the entire inner composer — the textarea + send arrangement — with
|
|
329
|
+
* a host-owned component. Passed to Stream's `<MessageInput>` as the `Input`
|
|
330
|
+
* component, so it runs inside the message-input context and reuses the
|
|
331
|
+
* library's send pipeline (`doSendMessageRequest`, message metadata, DM-agent
|
|
332
|
+
* suppression), attachments, and previews via the Stream hooks
|
|
333
|
+
* (`useMessageInputContext`, `useMessageComposerHasSendableData`,
|
|
334
|
+
* `TextareaComposer`, …). Use it when a surface needs a different composer
|
|
335
|
+
* layout (e.g. a full-width textarea above a toolbar row) than the default.
|
|
336
|
+
*
|
|
337
|
+
* The outer wrapper — frozen handling and the `renderMessageInputActions` /
|
|
338
|
+
* `renderMessageInputFooter` slots — is unchanged. Read the exported
|
|
339
|
+
* `useComposerLocked()` hook to honour the frozen state. Defaults to the
|
|
340
|
+
* built-in composer when omitted.
|
|
341
|
+
*/
|
|
342
|
+
composerInput?: ComponentType
|
|
343
|
+
|
|
327
344
|
/**
|
|
328
345
|
* Fired when the participant's name in the channel header is clicked. When
|
|
329
346
|
* provided, the name renders as a button with a trailing caret (an affordance
|
|
@@ -359,6 +376,7 @@ export type ChannelViewPassthroughProps = Pick<
|
|
|
359
376
|
| 'renderMessage'
|
|
360
377
|
| 'onMessageLinkClick'
|
|
361
378
|
| 'showChannelInfo'
|
|
379
|
+
| 'composerInput'
|
|
362
380
|
>
|
|
363
381
|
|
|
364
382
|
/**
|