@linktr.ee/messaging-react 3.15.3 → 3.16.0-rc-1785214411
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-BGmgW1l2.cjs → Card-5EWmE6sS.cjs} +2 -2
- package/dist/{Card-BGmgW1l2.cjs.map → Card-5EWmE6sS.cjs.map} +1 -1
- package/dist/{Card-CdouSSmP.js → Card-C9Zg6RqU.js} +2 -2
- package/dist/{Card-CdouSSmP.js.map → Card-C9Zg6RqU.js.map} +1 -1
- package/dist/assets/index.css +1 -1
- package/dist/index-2STuN782.cjs +2 -0
- package/dist/index-2STuN782.cjs.map +1 -0
- package/dist/{index-B5xEngCd.js → index-vYOR0x6o.js} +558 -540
- package/dist/index-vYOR0x6o.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/src/components/CustomMessage/SentMessageDeliveryStatus.test.tsx +54 -4
- package/src/components/CustomMessage/SentMessageDeliveryStatus.tsx +61 -24
- package/src/styles.css +5 -2
- package/dist/index-B5xEngCd.js.map +0 -1
- package/dist/index-BfEoDUXO.cjs +0 -2
- package/dist/index-BfEoDUXO.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-2STuN782.cjs");exports.ActionButton=e.ActionButton;exports.Avatar=e.Avatar;exports.ChannelEmptyState=e.ChannelEmptyState;exports.ChannelList=e.ChannelList;exports.ChannelView=e.ChannelView;exports.CustomMessageProvider=e.CustomMessageProvider;exports.FaqList=e.FaqList;exports.FaqListItem=e.FaqListItem;exports.LinkAttachment=e.LinkAttachment;exports.LockedAttachment=e.LockedAttachment;exports.MediaMessage=e.MediaMessage;exports.MessageAttachment=e.MessageAttachment;exports.MessageBubble=e.MessageBubble;exports.MessageVoteButtons=e.MessageVoteButtons;exports.MessagingProvider=e.MessagingProvider;exports.MessagingShell=e.MessagingShell;exports.buildCompactMetaLabel=e.buildCompactMetaLabel;exports.formatFileSize=e.formatFileSize;exports.formatRelativeTime=e.formatRelativeTime;exports.getFileExtensionLabel=e.getFileExtensionLabel;exports.getMessageDisplayText=e.getMessageDisplayText;exports.isLinkAttachment=e.isLinkAttachment;exports.isUuidLike=e.isUuidLike;exports.messageAttachmentGroupPositionFromStream=e.bubbleGroupPositionFromStream;exports.normalizeLanguageCode=e.normalizeLanguageCode;exports.optimizeMessagingAttachmentUrl=e.optimizeMessagingAttachmentUrl;exports.resolveConversationParticipant=e.resolveConversationParticipant;exports.resolveLinkAttachment=e.resolveLinkAttachment;exports.resolveMediaFromMessage=e.resolveMediaFromMessage;exports.resolveParticipantDisplayName=e.resolveParticipantDisplayName;exports.useComposerLocked=e.useComposerLocked;exports.useCustomMessage=e.useCustomMessage;exports.useMessageVote=e.useMessageVote;exports.useMessaging=e.useMessaging;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
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 L, k as h, l as p, m as d, n as v, p as C, q as A, s as k, t as F, u as b, v as P, w as f, x, o as y, y as z, z as B, B as S, D as q, E as D, G as E, H as V, I as w } from "./index-
|
|
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 L, k as h, l as p, m as d, n as v, p as C, q as A, s as k, t as F, u as b, v as P, w as f, x, o as y, y as z, z as B, B as S, D as q, E as D, G as E, H as V, I as w } from "./index-vYOR0x6o.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.
|
|
3
|
+
"version": "3.16.0-rc-1785214411",
|
|
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": "
|
|
53
|
+
"@linktr.ee/messaging-core": "2.3.0-rc-1785214411",
|
|
54
54
|
"@phosphor-icons/react": "^2.1.10"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
@@ -13,8 +13,8 @@ import { SentMessageDeliveryStatus } from './SentMessageDeliveryStatus'
|
|
|
13
13
|
// error, not in a thread) and only exposes a terminal state once a message is
|
|
14
14
|
// stored — Stream's tested code. What this component owns is the "Delivered"
|
|
15
15
|
// label wired into the terminal slots (sent/delivered/read), its "latest
|
|
16
|
-
// message in the thread" gate derived from live channel state
|
|
17
|
-
//
|
|
16
|
+
// message in the thread" gate derived from live channel state. Mock
|
|
17
|
+
// `MessageStatus` to render the slots it was handed,
|
|
18
18
|
// and the context hooks the label reads.
|
|
19
19
|
vi.mock('stream-chat-react', () => ({
|
|
20
20
|
useMessageContext: vi.fn(),
|
|
@@ -135,13 +135,63 @@ describe('SentMessageDeliveryStatus', () => {
|
|
|
135
135
|
}
|
|
136
136
|
})
|
|
137
137
|
|
|
138
|
-
it('
|
|
138
|
+
it('renders "Sending" in the sending slot for the latest message', () => {
|
|
139
139
|
mockedUseMessageContext.mockReturnValue({
|
|
140
|
-
message: { id: 'own-2' },
|
|
140
|
+
message: { id: 'own-2', status: 'sending' },
|
|
141
|
+
} as never)
|
|
142
|
+
|
|
143
|
+
renderWithProviders(<SentMessageDeliveryStatus />)
|
|
144
|
+
|
|
145
|
+
expect(screen.getByTestId('sending-slot')).toHaveTextContent(/sending/i)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('does not render "Sending" for an earlier message', () => {
|
|
149
|
+
mockedUseMessageContext.mockReturnValue({
|
|
150
|
+
message: { id: 'own-1', status: 'sending' },
|
|
141
151
|
} as never)
|
|
142
152
|
|
|
143
153
|
renderWithProviders(<SentMessageDeliveryStatus />)
|
|
144
154
|
|
|
145
155
|
expect(screen.getByTestId('sending-slot')).toBeEmptyDOMElement()
|
|
146
156
|
})
|
|
157
|
+
|
|
158
|
+
it('renders "Failed to send" for every own failed message', () => {
|
|
159
|
+
mockedUseMessageContext.mockReturnValue({
|
|
160
|
+
message: { id: 'own-1', status: 'failed', type: 'regular' },
|
|
161
|
+
isMyMessage: () => true,
|
|
162
|
+
threadList: false,
|
|
163
|
+
} as never)
|
|
164
|
+
|
|
165
|
+
renderWithProviders(<SentMessageDeliveryStatus />)
|
|
166
|
+
|
|
167
|
+
expect(screen.getByTestId('sent-message-failed-status')).toHaveTextContent(
|
|
168
|
+
/failed to send/i
|
|
169
|
+
)
|
|
170
|
+
expect(screen.queryByTestId('sending-slot')).not.toBeInTheDocument()
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it('does not render failure status for a received message or thread message', () => {
|
|
174
|
+
mockedUseMessageContext.mockReturnValue({
|
|
175
|
+
message: { id: 'own-1', status: 'failed', type: 'regular' },
|
|
176
|
+
isMyMessage: () => false,
|
|
177
|
+
threadList: false,
|
|
178
|
+
} as never)
|
|
179
|
+
|
|
180
|
+
const { rerender } = renderWithProviders(<SentMessageDeliveryStatus />)
|
|
181
|
+
|
|
182
|
+
expect(
|
|
183
|
+
screen.queryByTestId('sent-message-failed-status')
|
|
184
|
+
).not.toBeInTheDocument()
|
|
185
|
+
|
|
186
|
+
mockedUseMessageContext.mockReturnValue({
|
|
187
|
+
message: { id: 'own-1', status: 'failed', type: 'regular' },
|
|
188
|
+
isMyMessage: () => true,
|
|
189
|
+
threadList: true,
|
|
190
|
+
} as never)
|
|
191
|
+
rerender(<SentMessageDeliveryStatus />)
|
|
192
|
+
|
|
193
|
+
expect(
|
|
194
|
+
screen.queryByTestId('sent-message-failed-status')
|
|
195
|
+
).not.toBeInTheDocument()
|
|
196
|
+
})
|
|
147
197
|
})
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ChecksIcon,
|
|
3
|
+
CircleNotchIcon,
|
|
4
|
+
WarningCircleIcon,
|
|
5
|
+
} from '@phosphor-icons/react'
|
|
2
6
|
import {
|
|
3
7
|
MessageStatus,
|
|
4
8
|
useChannelStateContext,
|
|
@@ -6,8 +10,8 @@ import {
|
|
|
6
10
|
} from 'stream-chat-react'
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
|
-
*
|
|
10
|
-
* (sent / delivered / read).
|
|
13
|
+
* Message status stamps for sending and terminal `MessageStatus` states
|
|
14
|
+
* (sent / delivered / read), plus failed messages.
|
|
11
15
|
*
|
|
12
16
|
* Two reasons this is more than a static label:
|
|
13
17
|
*
|
|
@@ -16,9 +20,7 @@ import {
|
|
|
16
20
|
* branches aren't gated to the last message. So we override all three
|
|
17
21
|
* terminal slots with this same label (never Stream's default delivered
|
|
18
22
|
* icon / read avatars — Read is out of scope) and re-apply the "latest
|
|
19
|
-
* message in the thread" gate ourselves
|
|
20
|
-
* viewer's sent message while it is still the last message in the channel,
|
|
21
|
-
* and disappears as soon as a reply arrives after it.
|
|
23
|
+
* message in the thread" gate ourselves.
|
|
22
24
|
*
|
|
23
25
|
* 2. We derive "latest message" from **live channel state**, not the message
|
|
24
26
|
* context's `lastOwnMessage`/`lastReceivedId`. Stream's `Message` is
|
|
@@ -36,7 +38,7 @@ import {
|
|
|
36
38
|
* Rendered inside stream's `.str-chat__message-status` span, which supplies
|
|
37
39
|
* the flex layout; icon and copy are styled via that span in `styles.css`.
|
|
38
40
|
*/
|
|
39
|
-
const
|
|
41
|
+
const useIsLatestRealMessage = () => {
|
|
40
42
|
const { message } = useMessageContext('SentMessageDeliveryStatus')
|
|
41
43
|
const { messages } = useChannelStateContext('SentMessageDeliveryStatus')
|
|
42
44
|
|
|
@@ -62,9 +64,11 @@ const DeliveredStatus = () => {
|
|
|
62
64
|
return undefined
|
|
63
65
|
})()
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
return message.id === lastMessageId
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const DeliveredStatus = () => {
|
|
71
|
+
if (!useIsLatestRealMessage()) return null
|
|
68
72
|
|
|
69
73
|
return (
|
|
70
74
|
<>
|
|
@@ -74,8 +78,27 @@ const DeliveredStatus = () => {
|
|
|
74
78
|
)
|
|
75
79
|
}
|
|
76
80
|
|
|
77
|
-
|
|
78
|
-
|
|
81
|
+
const SendingStatus = () => {
|
|
82
|
+
if (!useIsLatestRealMessage()) return null
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<>
|
|
86
|
+
<CircleNotchIcon
|
|
87
|
+
className="sent-message-status__spinner animate-spin"
|
|
88
|
+
weight="bold"
|
|
89
|
+
aria-hidden="true"
|
|
90
|
+
/>
|
|
91
|
+
<span data-testid="sent-message-sending-status">Sending</span>
|
|
92
|
+
</>
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const FailedStatus = () => (
|
|
97
|
+
<span className="str-chat__message-status sent-message-status--failed">
|
|
98
|
+
<WarningCircleIcon weight="bold" aria-hidden="true" />
|
|
99
|
+
<span data-testid="sent-message-failed-status">Failed to send</span>
|
|
100
|
+
</span>
|
|
101
|
+
)
|
|
79
102
|
|
|
80
103
|
/**
|
|
81
104
|
* Delivery status beneath the viewer's most recent sent message (MES-1036):
|
|
@@ -85,16 +108,30 @@ const NoStatus = () => null
|
|
|
85
108
|
* Built on stream-chat-react's `MessageStatus`, which owns the gating we keep
|
|
86
109
|
* — own message, not an error, not inside a thread — and only surfaces a
|
|
87
110
|
* terminal (sending/sent/delivered/read) state once the message is stored.
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* computed from live channel state rather than the context's props).
|
|
111
|
+
* Sending uses the same latest-message-in-thread gate, while failed messages
|
|
112
|
+
* bypass `MessageStatus` because it has no failed slot and are shown on every
|
|
113
|
+
* own, non-thread failed message.
|
|
92
114
|
*/
|
|
93
|
-
export const SentMessageDeliveryStatus = () =>
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
)
|
|
115
|
+
export const SentMessageDeliveryStatus = () => {
|
|
116
|
+
const { isMyMessage, message, threadList } = useMessageContext(
|
|
117
|
+
'SentMessageDeliveryStatus'
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if (
|
|
121
|
+
message.status === 'failed' &&
|
|
122
|
+
isMyMessage() &&
|
|
123
|
+
message.type !== 'error' &&
|
|
124
|
+
!threadList
|
|
125
|
+
) {
|
|
126
|
+
return <FailedStatus />
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<MessageStatus
|
|
131
|
+
MessageSentStatus={DeliveredStatus}
|
|
132
|
+
MessageDeliveredStatus={DeliveredStatus}
|
|
133
|
+
MessageReadStatus={DeliveredStatus}
|
|
134
|
+
MessageSendingStatus={SendingStatus}
|
|
135
|
+
/>
|
|
136
|
+
)
|
|
137
|
+
}
|
package/src/styles.css
CHANGED
|
@@ -583,7 +583,7 @@
|
|
|
583
583
|
align-items: flex-end;
|
|
584
584
|
}
|
|
585
585
|
|
|
586
|
-
/*
|
|
586
|
+
/* Message delivery status under sent messages (MES-1036/MES-1296).
|
|
587
587
|
`SentMessageDeliveryStatus` renders it through stream's `MessageStatus`,
|
|
588
588
|
whose `.str-chat__message-status` span is the grid item here (right-aligned
|
|
589
589
|
via the outer grid's `justify-items: end`). Stream emits that span for every
|
|
@@ -595,7 +595,7 @@
|
|
|
595
595
|
gap: 4px;
|
|
596
596
|
padding-block-start: 4px;
|
|
597
597
|
padding-inline-end: 16px;
|
|
598
|
-
font-size:
|
|
598
|
+
font-size: 10px;
|
|
599
599
|
line-height: 1.4;
|
|
600
600
|
color: var(--str-chat__text-low-emphasis-color, rgba(0, 0, 0, 0.5));
|
|
601
601
|
}
|
|
@@ -611,6 +611,9 @@
|
|
|
611
611
|
.str-chat__li .str-chat__message--me .str-chat__message-status svg path {
|
|
612
612
|
fill: currentColor;
|
|
613
613
|
}
|
|
614
|
+
.str-chat__li .str-chat__message--me .sent-message-status--failed {
|
|
615
|
+
color: var(--str-chat__message-error-color, #d92d20);
|
|
616
|
+
}
|
|
614
617
|
|
|
615
618
|
/* Channel list load-more button overrides */
|
|
616
619
|
.str-chat__channel-list .str-chat__load-more-button__button {
|