@linktr.ee/messaging-react 3.0.0 → 3.1.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-C-ZIQW_q.js → Card-BGOWR4lW.js} +2 -2
- package/dist/{Card-C-ZIQW_q.js.map → Card-BGOWR4lW.js.map} +1 -1
- package/dist/{Card-Cqld0-Ws.js → Card-BfvsO78k.js} +3 -3
- package/dist/{Card-Cqld0-Ws.js.map → Card-BfvsO78k.js.map} +1 -1
- package/dist/{Card-C46z9zz4.js → Card-BhO5jeP9.js} +2 -2
- package/dist/{Card-C46z9zz4.js.map → Card-BhO5jeP9.js.map} +1 -1
- package/dist/{Card-Cq0x0bbb.cjs → Card-CRJ4l5KM.cjs} +2 -2
- package/dist/{Card-Cq0x0bbb.cjs.map → Card-CRJ4l5KM.cjs.map} +1 -1
- package/dist/{Card-Drz28Q-Y.cjs → Card-Cq-cN9n1.cjs} +2 -2
- package/dist/{Card-Drz28Q-Y.cjs.map → Card-Cq-cN9n1.cjs.map} +1 -1
- package/dist/{Card-B7ePjYQ6.cjs → Card-NPXVehHb.cjs} +2 -2
- package/dist/{Card-B7ePjYQ6.cjs.map → Card-NPXVehHb.cjs.map} +1 -1
- package/dist/{LockedThumbnail--h4GTH41.cjs → LockedThumbnail-B8MKBVXz.cjs} +2 -2
- package/dist/{LockedThumbnail--h4GTH41.cjs.map → LockedThumbnail-B8MKBVXz.cjs.map} +1 -1
- package/dist/{LockedThumbnail-D5NHhET2.js → LockedThumbnail-Bu9jNPUi.js} +2 -2
- package/dist/{LockedThumbnail-D5NHhET2.js.map → LockedThumbnail-Bu9jNPUi.js.map} +1 -1
- package/dist/{index-BUT2yBvJ.js → index-CJEl_fID.js} +1417 -1391
- package/dist/index-CJEl_fID.js.map +1 -0
- package/dist/index-D-5Igybf.cjs +2 -0
- package/dist/index-D-5Igybf.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +33 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/ChannelInfoDialog/ChannelInfoDialog.test.tsx +43 -1
- package/src/components/ChannelInfoDialog/index.tsx +55 -37
- package/src/components/ChannelView.stories.tsx +27 -3
- package/src/components/ChannelView.test.tsx +84 -5
- package/src/components/ChannelView.tsx +30 -2
- package/src/components/CustomMessageInput/CustomMessageInput.test.tsx +40 -0
- package/src/components/CustomMessageInput/index.tsx +53 -9
- package/src/types.ts +38 -0
- package/dist/index-BUT2yBvJ.js.map +0 -1
- package/dist/index-DqNobxVj.cjs +0 -2
- package/dist/index-DqNobxVj.cjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ArrowUpIcon } from '@phosphor-icons/react'
|
|
2
|
-
import React from 'react'
|
|
2
|
+
import React, { useContext } from 'react'
|
|
3
3
|
import {
|
|
4
4
|
AttachmentPreviewList as DefaultAttachmentPreviewList,
|
|
5
5
|
MessageInput,
|
|
@@ -13,6 +13,16 @@ import {
|
|
|
13
13
|
|
|
14
14
|
import { CustomLinkPreviewList } from '../CustomLinkPreviewList'
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Carries the channel's `frozen` state down to CustomMessageInputInner, which
|
|
18
|
+
* renders the composer as a read-only/disabled input. Using a context — rather
|
|
19
|
+
* than closing the value into the `Input` component passed to Stream's
|
|
20
|
+
* <MessageInput> — keeps CustomMessageInputInner a stable reference, so the
|
|
21
|
+
* value toggling re-renders the composer instead of unmounting and remounting
|
|
22
|
+
* it (which would drop textarea focus and interrupt IME composition).
|
|
23
|
+
*/
|
|
24
|
+
const ComposerLockedContext = React.createContext(false)
|
|
25
|
+
|
|
16
26
|
const DefaultSendButton: React.FC<{
|
|
17
27
|
sendMessage: () => void
|
|
18
28
|
disabled?: boolean
|
|
@@ -30,12 +40,11 @@ const DefaultSendButton: React.FC<{
|
|
|
30
40
|
)
|
|
31
41
|
|
|
32
42
|
const CustomMessageInputInner: React.FC = () => {
|
|
33
|
-
const
|
|
43
|
+
const disabled = useContext(ComposerLockedContext)
|
|
34
44
|
const { handleSubmit } = useMessageInputContext()
|
|
35
45
|
|
|
36
46
|
const hasSendableData = useMessageComposerHasSendableData()
|
|
37
|
-
const
|
|
38
|
-
const isSendDisabled = isFrozen || !hasSendableData
|
|
47
|
+
const isSendDisabled = disabled || !hasSendableData
|
|
39
48
|
|
|
40
49
|
const {
|
|
41
50
|
SendButton = DefaultSendButton,
|
|
@@ -50,16 +59,16 @@ const CustomMessageInputInner: React.FC = () => {
|
|
|
50
59
|
<div className="flex">
|
|
51
60
|
<div className="w-full ml-2 mr-4 self-center leading-[0]">
|
|
52
61
|
<TextareaComposer
|
|
53
|
-
aria-disabled={
|
|
62
|
+
aria-disabled={disabled || undefined}
|
|
54
63
|
className="w-full resize-none outline-none leading-6"
|
|
55
64
|
// While this might usually be considered an anti-pattern, in most
|
|
56
65
|
// cases, when a message thread is rendered, we want the input to
|
|
57
66
|
// gain focus automatically.
|
|
58
67
|
// eslint-disable-next-line jsx-a11y/no-autofocus
|
|
59
|
-
autoFocus={!
|
|
68
|
+
autoFocus={!disabled}
|
|
60
69
|
maxRows={4}
|
|
61
|
-
readOnly={
|
|
62
|
-
tabIndex={
|
|
70
|
+
readOnly={disabled}
|
|
71
|
+
tabIndex={disabled ? -1 : undefined}
|
|
63
72
|
/>
|
|
64
73
|
</div>
|
|
65
74
|
<SendButton
|
|
@@ -78,15 +87,48 @@ const CustomMessageInputInner: React.FC = () => {
|
|
|
78
87
|
export interface CustomMessageInputProps {
|
|
79
88
|
renderActions?: () => React.ReactNode
|
|
80
89
|
renderFooter?: () => React.ReactNode
|
|
90
|
+
/**
|
|
91
|
+
* Replace the composer entirely with a non-interactive locked panel that
|
|
92
|
+
* shows `disabledReason`. Used by the Linktree official channel, where the
|
|
93
|
+
* linker cannot message Linktree from the inbox. Defaults to false.
|
|
94
|
+
*
|
|
95
|
+
* Distinct from the channel's `frozen` flag, which keeps the composer
|
|
96
|
+
* rendered but read-only/dimmed.
|
|
97
|
+
*/
|
|
98
|
+
disabled?: boolean
|
|
99
|
+
/**
|
|
100
|
+
* Explanatory text shown inside the locked panel. Only rendered when
|
|
101
|
+
* `disabled` is true.
|
|
102
|
+
*/
|
|
103
|
+
disabledReason?: string
|
|
81
104
|
}
|
|
82
105
|
|
|
83
106
|
export const CustomMessageInput: React.FC<CustomMessageInputProps> = ({
|
|
84
107
|
renderActions,
|
|
85
108
|
renderFooter,
|
|
109
|
+
disabled = false,
|
|
110
|
+
disabledReason,
|
|
86
111
|
}) => {
|
|
87
112
|
const { channel } = useChannelStateContext()
|
|
88
113
|
const isFrozen = channel?.data?.frozen === true
|
|
89
114
|
|
|
115
|
+
// Linktree official channel: the composer is replaced by an info panel
|
|
116
|
+
// explaining the linker cannot send messages on this thread.
|
|
117
|
+
if (disabled) {
|
|
118
|
+
return (
|
|
119
|
+
<>
|
|
120
|
+
<div className="messaging-composer-locked-panel flex w-full flex-col items-center justify-center gap-3 px-6 py-4">
|
|
121
|
+
{disabledReason ? (
|
|
122
|
+
<p className="max-w-[345px] text-center text-xs font-normal leading-[1.3] tracking-[0.12px] text-black/40">
|
|
123
|
+
{disabledReason}
|
|
124
|
+
</p>
|
|
125
|
+
) : null}
|
|
126
|
+
</div>
|
|
127
|
+
{renderFooter?.()}
|
|
128
|
+
</>
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
90
132
|
return (
|
|
91
133
|
<div className="flex flex-col gap-4 p-4">
|
|
92
134
|
<div
|
|
@@ -100,7 +142,9 @@ export const CustomMessageInput: React.FC<CustomMessageInputProps> = ({
|
|
|
100
142
|
{renderActions()}
|
|
101
143
|
</div>
|
|
102
144
|
)}
|
|
103
|
-
<
|
|
145
|
+
<ComposerLockedContext.Provider value={isFrozen}>
|
|
146
|
+
<MessageInput Input={CustomMessageInputInner} />
|
|
147
|
+
</ComposerLockedContext.Provider>
|
|
104
148
|
</div>
|
|
105
149
|
{renderFooter?.()}
|
|
106
150
|
</div>
|
package/src/types.ts
CHANGED
|
@@ -131,6 +131,44 @@ export interface ChannelViewProps {
|
|
|
131
131
|
*/
|
|
132
132
|
onReportParticipantClick?: () => void
|
|
133
133
|
|
|
134
|
+
/**
|
|
135
|
+
* Show the "Block"/"Unblock" action in the channel info dialog.
|
|
136
|
+
* Defaults to true. Set false for restricted surfaces such as the
|
|
137
|
+
* Linktree official channel, where blocking is not offered.
|
|
138
|
+
*/
|
|
139
|
+
showBlockParticipant?: boolean
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Show the "Report" action in the channel info dialog.
|
|
143
|
+
* Defaults to true. Set false for restricted surfaces such as the
|
|
144
|
+
* Linktree official channel, where reporting is not offered.
|
|
145
|
+
*/
|
|
146
|
+
showReportParticipant?: boolean
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Show the subscription/follower-status label in the channel info dialog
|
|
150
|
+
* profile card. Defaults to true. Set false for restricted surfaces such
|
|
151
|
+
* as the Linktree official channel, where subscription status is hidden.
|
|
152
|
+
*/
|
|
153
|
+
showFollowerStatus?: boolean
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Replace the message composer with a non-interactive locked panel showing
|
|
157
|
+
* `composerDisabledReason`. Defaults to false. Used by the Linktree official
|
|
158
|
+
* channel, where the linker cannot message Linktree from the inbox (they
|
|
159
|
+
* message Linktree from its public profile instead).
|
|
160
|
+
*
|
|
161
|
+
* Distinct from the channel's `frozen` flag, which keeps the composer
|
|
162
|
+
* rendered but read-only/dimmed.
|
|
163
|
+
*/
|
|
164
|
+
composerDisabled?: boolean
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Explanatory text shown inside the locked panel. Only rendered when
|
|
168
|
+
* `composerDisabled` is true.
|
|
169
|
+
*/
|
|
170
|
+
composerDisabledReason?: string
|
|
171
|
+
|
|
134
172
|
/**
|
|
135
173
|
* When true and DM agent is active on the channel (not paused),
|
|
136
174
|
* messages will be sent with skip_push and silent flags to suppress
|