@linktr.ee/messaging-react 3.6.2-rc-1783307602 → 3.6.2-rc-1783311170
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-BqePrWk0.js → Card-CJh6R76n.js} +2 -2
- package/dist/{Card-BqePrWk0.js.map → Card-CJh6R76n.js.map} +1 -1
- package/dist/{Card-DQGYnsjO.cjs → Card-CK1jw1VU.cjs} +2 -2
- package/dist/{Card-DQGYnsjO.cjs.map → Card-CK1jw1VU.cjs.map} +1 -1
- package/dist/{Card-bm6JeM03.cjs → Card-CSwQT3wz.cjs} +2 -2
- package/dist/{Card-bm6JeM03.cjs.map → Card-CSwQT3wz.cjs.map} +1 -1
- package/dist/{Card-Dlb_74PT.cjs → Card-DQtg7wWP.cjs} +2 -2
- package/dist/{Card-Dlb_74PT.cjs.map → Card-DQtg7wWP.cjs.map} +1 -1
- package/dist/{Card-CS_6M9I_.js → Card-DUoHKAuh.js} +2 -2
- package/dist/{Card-CS_6M9I_.js.map → Card-DUoHKAuh.js.map} +1 -1
- package/dist/{Card-CYD26x1-.js → Card-DnEyeR_d.js} +3 -3
- package/dist/{Card-CYD26x1-.js.map → Card-DnEyeR_d.js.map} +1 -1
- package/dist/{LockedThumbnail-C3kgiGFK.cjs → LockedThumbnail-BZLpmTpY.cjs} +2 -2
- package/dist/{LockedThumbnail-C3kgiGFK.cjs.map → LockedThumbnail-BZLpmTpY.cjs.map} +1 -1
- package/dist/{LockedThumbnail-DC782hvV.js → LockedThumbnail-C_F2Sw-9.js} +2 -2
- package/dist/{LockedThumbnail-DC782hvV.js.map → LockedThumbnail-C_F2Sw-9.js.map} +1 -1
- package/dist/{index-DaF1G1q2.js → index-DcEVHNS3.js} +490 -483
- package/dist/index-DcEVHNS3.js.map +1 -0
- package/dist/index-LP0PQJxl.cjs +2 -0
- package/dist/index-LP0PQJxl.cjs.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 +50 -21
- package/src/components/CustomMessage/SentMessageDeliveryStatus.tsx +42 -24
- package/dist/index-DaF1G1q2.js.map +0 -1
- package/dist/index-eVxxkfK6.cjs +0 -2
- package/dist/index-eVxxkfK6.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-LP0PQJxl.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.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.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 d, m as p, n as v, o as C, p as A, q as k, s as F, t as P, u as b, v as f, w as x, x as y, y as S, z as q, B as z, D as B, E as D, G as E } 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 d, m as p, n as v, o as C, p as A, q as k, s as F, t as P, u as b, v as f, w as x, x as y, y as S, z as q, B as z, D as B, E as D, G as E } from "./index-DcEVHNS3.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.6.2-rc-
|
|
3
|
+
"version": "3.6.2-rc-1783311170",
|
|
4
4
|
"description": "React messaging components built on messaging-core for web applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@linktr.ee/component-library": "11.8.6",
|
|
41
|
-
"@linktr.ee/messaging-core": "2.3.0-rc-
|
|
41
|
+
"@linktr.ee/messaging-core": "2.3.0-rc-1783311170",
|
|
42
42
|
"@phosphor-icons/react": "^2.1.10"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
@@ -1,27 +1,35 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import { useMessageContext } from 'stream-chat-react'
|
|
3
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
4
|
|
|
4
|
-
import { renderWithProviders, screen } from '../../test/utils'
|
|
5
|
+
import { renderWithProviders, screen, within } from '../../test/utils'
|
|
5
6
|
|
|
6
7
|
import { SentMessageDeliveryStatus } from './SentMessageDeliveryStatus'
|
|
7
8
|
|
|
8
|
-
// stream-chat-react's `MessageStatus` owns the gating (own message, not
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
// `MessageStatus` to render the slots it was handed
|
|
9
|
+
// stream-chat-react's `MessageStatus` owns the outer gating (own message, not
|
|
10
|
+
// error, not in a thread) and the state machine — Stream's tested code. What
|
|
11
|
+
// this component owns is the "Delivered" label wired into the terminal slots
|
|
12
|
+
// (sent/delivered/read), its "last own message" self-gate, and suppressing
|
|
13
|
+
// the sending spinner. Mock `MessageStatus` to render the slots it was handed,
|
|
14
|
+
// and `useMessageContext` to feed the label's self-gate.
|
|
13
15
|
vi.mock('stream-chat-react', () => ({
|
|
16
|
+
useMessageContext: vi.fn(),
|
|
14
17
|
MessageStatus: ({
|
|
15
18
|
MessageSentStatus,
|
|
19
|
+
MessageDeliveredStatus,
|
|
20
|
+
MessageReadStatus,
|
|
16
21
|
MessageSendingStatus,
|
|
17
|
-
}:
|
|
18
|
-
MessageSentStatus: React.ComponentType
|
|
19
|
-
MessageSendingStatus: React.ComponentType
|
|
20
|
-
}) => (
|
|
22
|
+
}: Record<string, React.ComponentType>) => (
|
|
21
23
|
<div>
|
|
22
24
|
<div data-testid="sent-slot">
|
|
23
25
|
<MessageSentStatus />
|
|
24
26
|
</div>
|
|
27
|
+
<div data-testid="delivered-slot">
|
|
28
|
+
<MessageDeliveredStatus />
|
|
29
|
+
</div>
|
|
30
|
+
<div data-testid="read-slot">
|
|
31
|
+
<MessageReadStatus />
|
|
32
|
+
</div>
|
|
25
33
|
<div data-testid="sending-slot">
|
|
26
34
|
<MessageSendingStatus />
|
|
27
35
|
</div>
|
|
@@ -29,24 +37,45 @@ vi.mock('stream-chat-react', () => ({
|
|
|
29
37
|
),
|
|
30
38
|
}))
|
|
31
39
|
|
|
40
|
+
const mockedUseMessageContext = vi.mocked(useMessageContext)
|
|
41
|
+
|
|
42
|
+
const TERMINAL_SLOTS = ['sent-slot', 'delivered-slot', 'read-slot'] as const
|
|
43
|
+
|
|
32
44
|
describe('SentMessageDeliveryStatus', () => {
|
|
33
|
-
|
|
45
|
+
beforeEach(() => {
|
|
46
|
+
mockedUseMessageContext.mockReturnValue({
|
|
47
|
+
lastOwnMessage: { id: 'message-1' },
|
|
48
|
+
message: { id: 'message-1' },
|
|
49
|
+
} as never)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('renders "Delivered" in every terminal slot for the last own message', () => {
|
|
53
|
+
// delivered/read fire ahead of sent in receipt channels, so all three
|
|
54
|
+
// must show the label — never Stream's default delivered icon / read
|
|
55
|
+
// avatars.
|
|
34
56
|
renderWithProviders(<SentMessageDeliveryStatus />)
|
|
35
57
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
58
|
+
for (const slot of TERMINAL_SLOTS) {
|
|
59
|
+
expect(
|
|
60
|
+
within(screen.getByTestId(slot)).getByText('Delivered')
|
|
61
|
+
).toBeInTheDocument()
|
|
62
|
+
}
|
|
39
63
|
})
|
|
40
64
|
|
|
41
|
-
it('renders
|
|
42
|
-
|
|
65
|
+
it('renders nothing in the terminal slots when it is not the last own message', () => {
|
|
66
|
+
mockedUseMessageContext.mockReturnValue({
|
|
67
|
+
lastOwnMessage: { id: 'message-2' },
|
|
68
|
+
message: { id: 'message-1' },
|
|
69
|
+
} as never)
|
|
70
|
+
|
|
71
|
+
renderWithProviders(<SentMessageDeliveryStatus />)
|
|
43
72
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
73
|
+
for (const slot of TERMINAL_SLOTS) {
|
|
74
|
+
expect(screen.getByTestId(slot)).toBeEmptyDOMElement()
|
|
75
|
+
}
|
|
47
76
|
})
|
|
48
77
|
|
|
49
|
-
it('suppresses the sending spinner', () => {
|
|
78
|
+
it('always suppresses the sending spinner', () => {
|
|
50
79
|
renderWithProviders(<SentMessageDeliveryStatus />)
|
|
51
80
|
|
|
52
81
|
expect(screen.getByTestId('sending-slot')).toBeEmptyDOMElement()
|
|
@@ -1,20 +1,38 @@
|
|
|
1
1
|
import { ChecksIcon } from '@phosphor-icons/react'
|
|
2
|
-
import { MessageStatus } from 'stream-chat-react'
|
|
2
|
+
import { MessageStatus, useMessageContext } from 'stream-chat-react'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* "✓✓ Delivered" label wired into `MessageStatus`
|
|
5
|
+
* "✓✓ Delivered" label, wired into *every* terminal `MessageStatus` state
|
|
6
|
+
* (sent / delivered / read).
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* `MessageStatus` picks its `delivered` and `read` branches ahead of `sent`
|
|
9
|
+
* whenever Stream has `deliveredTo` / `readBy` for the message — and, unlike
|
|
10
|
+
* `sent`, those branches are *not* gated to the last own message. So in a
|
|
11
|
+
* channel that has receipts we must (a) replace Stream's default delivered
|
|
12
|
+
* icon / read avatars with our label — otherwise the required "Delivered"
|
|
13
|
+
* label disappears and an out-of-scope read receipt would show — and (b)
|
|
14
|
+
* re-apply the "last own message only" gate ourselves, since the
|
|
15
|
+
* delivered/read branches would otherwise render on every read own message.
|
|
16
|
+
*
|
|
17
|
+
* Rendered inside stream's `.str-chat__message-status` span, which supplies
|
|
18
|
+
* the flex layout; icon and copy are styled via that span in `styles.css`.
|
|
11
19
|
*/
|
|
12
|
-
const DeliveredStatus = () =>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
)
|
|
20
|
+
const DeliveredStatus = () => {
|
|
21
|
+
const { lastOwnMessage, message } = useMessageContext(
|
|
22
|
+
'SentMessageDeliveryStatus'
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
if (lastOwnMessage?.id !== message.id) {
|
|
26
|
+
return null
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<>
|
|
31
|
+
<ChecksIcon weight="bold" aria-hidden="true" />
|
|
32
|
+
<span data-testid="sent-message-delivery-status">Delivered</span>
|
|
33
|
+
</>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
18
36
|
|
|
19
37
|
/** Suppresses a MessageStatus slot we don't want to render. */
|
|
20
38
|
const NoStatus = () => null
|
|
@@ -24,26 +42,26 @@ const NoStatus = () => null
|
|
|
24
42
|
* a right-aligned "✓✓ Delivered" that appears once Stream confirms the
|
|
25
43
|
* message is stored and updates live.
|
|
26
44
|
*
|
|
27
|
-
* Built on stream-chat-react's `MessageStatus`, which
|
|
28
|
-
*
|
|
29
|
-
*
|
|
45
|
+
* Built on stream-chat-react's `MessageStatus`, which owns the gating we want
|
|
46
|
+
* — own message, not an error, and not inside a thread — plus the
|
|
47
|
+
* sending/sent/delivered/read state machine.
|
|
30
48
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* are ever enabled, give `MessageDeliveredStatus` / `MessageReadStatus` their
|
|
38
|
-
* own labels here.
|
|
49
|
+
* Scope is "Delivered" only (no Sending / Read). Stream's `sent` state maps
|
|
50
|
+
* to "Delivered" for a backend-confirmed (`status === 'received'`) last own
|
|
51
|
+
* message; its `delivered`/`read` states (only populated in channels with
|
|
52
|
+
* per-recipient receipts) also render the same "Delivered" label via
|
|
53
|
+
* {@link DeliveredStatus} so we never surface a read receipt. The sending
|
|
54
|
+
* spinner is suppressed.
|
|
39
55
|
*
|
|
40
|
-
* `
|
|
56
|
+
* `DeliveredStatus` reads `lastOwnMessage` from the message context, so
|
|
41
57
|
* `CustomMessage`'s memo comparator must re-render when it changes (see
|
|
42
58
|
* `index.tsx`) for the label to hop to a newer message.
|
|
43
59
|
*/
|
|
44
60
|
export const SentMessageDeliveryStatus = () => (
|
|
45
61
|
<MessageStatus
|
|
46
62
|
MessageSentStatus={DeliveredStatus}
|
|
63
|
+
MessageDeliveredStatus={DeliveredStatus}
|
|
64
|
+
MessageReadStatus={DeliveredStatus}
|
|
47
65
|
MessageSendingStatus={NoStatus}
|
|
48
66
|
/>
|
|
49
67
|
)
|