@linktr.ee/messaging-react 1.15.2 → 1.16.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/index.d.ts +14 -22
- package/dist/index.js +619 -595
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ChannelView.tsx +42 -4
- package/src/components/MessagingShell/index.tsx +2 -0
- package/src/types.ts +68 -71
package/package.json
CHANGED
|
@@ -9,7 +9,11 @@ import {
|
|
|
9
9
|
} from '@phosphor-icons/react'
|
|
10
10
|
import classNames from 'classnames'
|
|
11
11
|
import React, { useState, useCallback, useRef, useEffect } from 'react'
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
Channel as ChannelType,
|
|
14
|
+
ChannelMemberResponse,
|
|
15
|
+
Event,
|
|
16
|
+
} from 'stream-chat'
|
|
13
17
|
import {
|
|
14
18
|
Channel,
|
|
15
19
|
Window,
|
|
@@ -66,11 +70,17 @@ const CustomChannelHeader: React.FC<{
|
|
|
66
70
|
participant?.user?.name || participant?.user?.id || 'Unknown member'
|
|
67
71
|
const participantImage = participant?.user?.image
|
|
68
72
|
|
|
69
|
-
const [isStarred, setIsStarred] = useState(
|
|
73
|
+
const [isStarred, setIsStarred] = useState(
|
|
74
|
+
!!channel.state.membership?.pinned_at
|
|
75
|
+
)
|
|
70
76
|
|
|
71
77
|
useEffect(() => {
|
|
72
78
|
const handleMemberUpdate = (event: Event) => {
|
|
73
|
-
setIsStarred(
|
|
79
|
+
setIsStarred(
|
|
80
|
+
event?.member
|
|
81
|
+
? !!event.member.pinned_at
|
|
82
|
+
: !!channel.state.membership?.pinned_at
|
|
83
|
+
)
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
channel.on('member.updated', handleMemberUpdate)
|
|
@@ -88,7 +98,10 @@ const CustomChannelHeader: React.FC<{
|
|
|
88
98
|
await channel.pin()
|
|
89
99
|
}
|
|
90
100
|
} catch (error) {
|
|
91
|
-
console.error(
|
|
101
|
+
console.error(
|
|
102
|
+
'[CustomChannelHeader] Failed to update pinned status:',
|
|
103
|
+
error
|
|
104
|
+
)
|
|
92
105
|
}
|
|
93
106
|
}
|
|
94
107
|
|
|
@@ -614,7 +627,31 @@ export const ChannelView = React.memo<ChannelViewProps>(
|
|
|
614
627
|
onDeleteConversationClick,
|
|
615
628
|
onBlockParticipantClick,
|
|
616
629
|
onReportParticipantClick,
|
|
630
|
+
dmAgentEnabled,
|
|
617
631
|
}) => {
|
|
632
|
+
// Custom send message handler that adds skip_push and silent when DM agent is active
|
|
633
|
+
// Read chatbot_paused inside callback to get current value at send time (not stale closure)
|
|
634
|
+
const doSendMessageRequest = useCallback(
|
|
635
|
+
async (
|
|
636
|
+
_channel: ChannelType,
|
|
637
|
+
message: Parameters<ChannelType['sendMessage']>[0],
|
|
638
|
+
options?: Parameters<ChannelType['sendMessage']>[1]
|
|
639
|
+
) => {
|
|
640
|
+
const agentPaused =
|
|
641
|
+
(channel.data as { chatbot_paused?: boolean })?.chatbot_paused === true
|
|
642
|
+
const shouldSuppressNotifications = dmAgentEnabled && !agentPaused
|
|
643
|
+
|
|
644
|
+
if (shouldSuppressNotifications) {
|
|
645
|
+
return channel.sendMessage(
|
|
646
|
+
{ ...message, silent: true },
|
|
647
|
+
{ ...options, skip_push: true }
|
|
648
|
+
)
|
|
649
|
+
}
|
|
650
|
+
return channel.sendMessage(message, options)
|
|
651
|
+
},
|
|
652
|
+
[channel, dmAgentEnabled]
|
|
653
|
+
)
|
|
654
|
+
|
|
618
655
|
return (
|
|
619
656
|
<div
|
|
620
657
|
className={classNames(
|
|
@@ -628,6 +665,7 @@ export const ChannelView = React.memo<ChannelViewProps>(
|
|
|
628
665
|
EmptyStateIndicator={CustomChannelEmptyState}
|
|
629
666
|
LoadingIndicator={LoadingState}
|
|
630
667
|
DateSeparator={CustomDateSeparator}
|
|
668
|
+
doSendMessageRequest={doSendMessageRequest}
|
|
631
669
|
>
|
|
632
670
|
<ChannelViewInner
|
|
633
671
|
onBack={onBack}
|
|
@@ -30,6 +30,7 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
|
|
|
30
30
|
onDeleteConversationClick,
|
|
31
31
|
onBlockParticipantClick,
|
|
32
32
|
onReportParticipantClick,
|
|
33
|
+
dmAgentEnabled,
|
|
33
34
|
}) => {
|
|
34
35
|
const {
|
|
35
36
|
service,
|
|
@@ -475,6 +476,7 @@ export const MessagingShell: React.FC<MessagingShellProps> = ({
|
|
|
475
476
|
onDeleteConversationClick={onDeleteConversationClick}
|
|
476
477
|
onBlockParticipantClick={onBlockParticipantClick}
|
|
477
478
|
onReportParticipantClick={onReportParticipantClick}
|
|
479
|
+
dmAgentEnabled={dmAgentEnabled}
|
|
478
480
|
/>
|
|
479
481
|
</div>
|
|
480
482
|
) : initialParticipantFilter ? (
|
package/src/types.ts
CHANGED
|
@@ -51,13 +51,79 @@ export interface MessagingCapabilities {
|
|
|
51
51
|
showDeleteConversation?: boolean
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* ChannelList component props
|
|
56
|
+
*/
|
|
57
|
+
export interface ChannelListProps {
|
|
58
|
+
onChannelSelect: (channel: Channel) => void
|
|
59
|
+
selectedChannel?: Channel
|
|
60
|
+
showStartConversation?: boolean
|
|
61
|
+
onStartConversation?: () => void
|
|
62
|
+
participantLabel?: string
|
|
63
|
+
className?: string
|
|
64
|
+
filters: ChannelFilters
|
|
65
|
+
customEmptyStateIndicator?: React.ComponentType<EmptyStateIndicatorProps>
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* ChannelView component props
|
|
70
|
+
*/
|
|
71
|
+
export interface ChannelViewProps {
|
|
72
|
+
channel: Channel
|
|
73
|
+
onBack?: () => void
|
|
74
|
+
showBackButton?: boolean
|
|
75
|
+
renderMessageInputActions?: (channel: Channel) => React.ReactNode
|
|
76
|
+
onLeaveConversation?: (channel: Channel) => void
|
|
77
|
+
onBlockParticipant?: (participantId?: string) => void
|
|
78
|
+
className?: string
|
|
79
|
+
CustomChannelEmptyState?: React.ComponentType
|
|
80
|
+
/**
|
|
81
|
+
* Show the "Delete Conversation" button in channel info dialog.
|
|
82
|
+
* Defaults to true for backward compatibility.
|
|
83
|
+
*/
|
|
84
|
+
showDeleteConversation?: boolean
|
|
85
|
+
/**
|
|
86
|
+
* Analytics callback fired when "Delete Conversation" is clicked.
|
|
87
|
+
*/
|
|
88
|
+
onDeleteConversationClick?: () => void
|
|
89
|
+
/**
|
|
90
|
+
* Analytics callback fired when "Block" or "Unblock" is clicked.
|
|
91
|
+
*/
|
|
92
|
+
onBlockParticipantClick?: () => void
|
|
93
|
+
/**
|
|
94
|
+
* Analytics callback fired when "Report" is clicked.
|
|
95
|
+
*/
|
|
96
|
+
onReportParticipantClick?: () => void
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* When true and DM agent is active on the channel (not paused),
|
|
100
|
+
* messages will be sent with skip_push and silent flags to suppress
|
|
101
|
+
* notifications to the creator until the agent responds.
|
|
102
|
+
* The library reads chatbot_paused from channel.data internally.
|
|
103
|
+
*/
|
|
104
|
+
dmAgentEnabled?: boolean
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Props that MessagingShell passes through to ChannelView.
|
|
109
|
+
* ChannelViewProps is the source of truth for these props.
|
|
110
|
+
*/
|
|
111
|
+
export type ChannelViewPassthroughProps = Pick<
|
|
112
|
+
ChannelViewProps,
|
|
113
|
+
| 'renderMessageInputActions'
|
|
114
|
+
| 'CustomChannelEmptyState'
|
|
115
|
+
| 'onDeleteConversationClick'
|
|
116
|
+
| 'onBlockParticipantClick'
|
|
117
|
+
| 'onReportParticipantClick'
|
|
118
|
+
| 'dmAgentEnabled'
|
|
119
|
+
>
|
|
120
|
+
|
|
54
121
|
/**
|
|
55
122
|
* Main MessagingShell component props
|
|
56
123
|
*/
|
|
57
|
-
export interface MessagingShellProps {
|
|
124
|
+
export interface MessagingShellProps extends ChannelViewPassthroughProps {
|
|
58
125
|
capabilities?: MessagingCapabilities
|
|
59
126
|
className?: string
|
|
60
|
-
renderMessageInputActions?: (channel: Channel) => React.ReactNode
|
|
61
127
|
onChannelSelect?: (channel: Channel) => void
|
|
62
128
|
onParticipantSelect?: (participant: Participant) => void
|
|
63
129
|
|
|
@@ -80,12 +146,6 @@ export interface MessagingShellProps {
|
|
|
80
146
|
*/
|
|
81
147
|
initialParticipantData?: Participant
|
|
82
148
|
|
|
83
|
-
/**
|
|
84
|
-
* Custom empty state component to render when a channel has no messages.
|
|
85
|
-
* Useful for showing FAQs or other contextual information in empty channels.
|
|
86
|
-
*/
|
|
87
|
-
CustomChannelEmptyState?: React.ComponentType
|
|
88
|
-
|
|
89
149
|
/**
|
|
90
150
|
* Controls whether the channel list is shown. When false, the channel list
|
|
91
151
|
* is immediately hidden. Useful for direct conversation mode where you want
|
|
@@ -103,69 +163,6 @@ export interface MessagingShellProps {
|
|
|
103
163
|
* Useful for showing a custom empty state indicator when the channel list is empty.
|
|
104
164
|
*/
|
|
105
165
|
channelListCustomEmptyStateIndicator?: React.ComponentType<EmptyStateIndicatorProps>
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Analytics callback fired when "Delete Conversation" is clicked.
|
|
109
|
-
* Called before the action is performed.
|
|
110
|
-
*/
|
|
111
|
-
onDeleteConversationClick?: () => void
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Analytics callback fired when "Block" or "Unblock" is clicked.
|
|
115
|
-
* Called before the action is performed.
|
|
116
|
-
*/
|
|
117
|
-
onBlockParticipantClick?: () => void
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Analytics callback fired when "Report" is clicked.
|
|
121
|
-
* Called before the action is performed.
|
|
122
|
-
*/
|
|
123
|
-
onReportParticipantClick?: () => void
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* ChannelList component props
|
|
128
|
-
*/
|
|
129
|
-
export interface ChannelListProps {
|
|
130
|
-
onChannelSelect: (channel: Channel) => void
|
|
131
|
-
selectedChannel?: Channel
|
|
132
|
-
showStartConversation?: boolean
|
|
133
|
-
onStartConversation?: () => void
|
|
134
|
-
participantLabel?: string
|
|
135
|
-
className?: string
|
|
136
|
-
filters: ChannelFilters
|
|
137
|
-
customEmptyStateIndicator?: React.ComponentType<EmptyStateIndicatorProps>
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* ChannelView component props
|
|
142
|
-
*/
|
|
143
|
-
export interface ChannelViewProps {
|
|
144
|
-
channel: Channel
|
|
145
|
-
onBack?: () => void
|
|
146
|
-
showBackButton?: boolean
|
|
147
|
-
renderMessageInputActions?: (channel: Channel) => React.ReactNode
|
|
148
|
-
onLeaveConversation?: (channel: Channel) => void
|
|
149
|
-
onBlockParticipant?: (participantId?: string) => void
|
|
150
|
-
className?: string
|
|
151
|
-
CustomChannelEmptyState?: React.ComponentType
|
|
152
|
-
/**
|
|
153
|
-
* Show the "Delete Conversation" button in channel info dialog.
|
|
154
|
-
* Defaults to true for backward compatibility.
|
|
155
|
-
*/
|
|
156
|
-
showDeleteConversation?: boolean
|
|
157
|
-
/**
|
|
158
|
-
* Analytics callback fired when "Delete Conversation" is clicked.
|
|
159
|
-
*/
|
|
160
|
-
onDeleteConversationClick?: () => void
|
|
161
|
-
/**
|
|
162
|
-
* Analytics callback fired when "Block" or "Unblock" is clicked.
|
|
163
|
-
*/
|
|
164
|
-
onBlockParticipantClick?: () => void
|
|
165
|
-
/**
|
|
166
|
-
* Analytics callback fired when "Report" is clicked.
|
|
167
|
-
*/
|
|
168
|
-
onReportParticipantClick?: () => void
|
|
169
166
|
}
|
|
170
167
|
|
|
171
168
|
/**
|