@linktr.ee/messaging-react 3.6.0 → 3.6.1-rc-1783305041
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-J8f28GLS.js → Card-BF8hqtLR.js} +3 -3
- package/dist/{Card-J8f28GLS.js.map → Card-BF8hqtLR.js.map} +1 -1
- package/dist/{Card-DzT94KFC.cjs → Card-BJrIwVBx.cjs} +2 -2
- package/dist/{Card-DzT94KFC.cjs.map → Card-BJrIwVBx.cjs.map} +1 -1
- package/dist/{Card-DmjLrV64.cjs → Card-Cavq6QXu.cjs} +2 -2
- package/dist/{Card-DmjLrV64.cjs.map → Card-Cavq6QXu.cjs.map} +1 -1
- package/dist/{Card-ra-g17Ur.js → Card-CsPLNSTP.js} +2 -2
- package/dist/{Card-ra-g17Ur.js.map → Card-CsPLNSTP.js.map} +1 -1
- package/dist/{Card-Cb4yfxFK.cjs → Card-HcMDKbWd.cjs} +2 -2
- package/dist/{Card-Cb4yfxFK.cjs.map → Card-HcMDKbWd.cjs.map} +1 -1
- package/dist/{Card-COTwOzVb.js → Card-_SSVVgkv.js} +2 -2
- package/dist/{Card-COTwOzVb.js.map → Card-_SSVVgkv.js.map} +1 -1
- package/dist/{LockedThumbnail-CVq5LPXE.js → LockedThumbnail-Bqz_Fq66.js} +2 -2
- package/dist/{LockedThumbnail-CVq5LPXE.js.map → LockedThumbnail-Bqz_Fq66.js.map} +1 -1
- package/dist/{LockedThumbnail-Ds_vBmYm.cjs → LockedThumbnail-DN3UoQvw.cjs} +2 -2
- package/dist/{LockedThumbnail-Ds_vBmYm.cjs.map → LockedThumbnail-DN3UoQvw.cjs.map} +1 -1
- package/dist/assets/index.css +1 -1
- package/dist/index-BoB8DqqZ.cjs +2 -0
- package/dist/index-BoB8DqqZ.cjs.map +1 -0
- package/dist/{index-D1XVCH1o.js → index-C4ipGbuZ.js} +1216 -1190
- package/dist/index-C4ipGbuZ.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/CustomMessage.stories.tsx +35 -0
- package/src/components/CustomMessage/SentMessageDeliveryStatus.test.tsx +72 -0
- package/src/components/CustomMessage/SentMessageDeliveryStatus.tsx +49 -0
- package/src/components/CustomMessage/StreamAttachmentMessage.test.tsx +33 -0
- package/src/components/CustomMessage/StreamAttachmentMessage.tsx +9 -3
- package/src/components/CustomMessage/index.tsx +18 -4
- package/src/styles.css +19 -1
- package/dist/index-D1XVCH1o.js.map +0 -1
- package/dist/index-hvrSZScU.cjs +0 -2
- package/dist/index-hvrSZScU.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-BoB8DqqZ.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-C4ipGbuZ.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.
|
|
3
|
+
"version": "3.6.1-rc-1783305041",
|
|
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": "
|
|
41
|
+
"@linktr.ee/messaging-core": "2.3.0-rc-1783305041",
|
|
42
42
|
"@phosphor-icons/react": "^2.1.10"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
@@ -225,6 +225,41 @@ Default.args = {
|
|
|
225
225
|
],
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
+
// MES-1036: "✓✓ Delivered" appears below only the most recent *sent*
|
|
229
|
+
// message. Every mock message carries status: 'received', and stream's
|
|
230
|
+
// MessageList derives `lastOwnMessage`, so the indicator lands on the last
|
|
231
|
+
// creator message ("Talk soon!") and not on the earlier sent bubble.
|
|
232
|
+
export const DeliveredStatus: StoryFn<TemplateProps> = Template.bind({})
|
|
233
|
+
DeliveredStatus.args = {
|
|
234
|
+
messages: [
|
|
235
|
+
{
|
|
236
|
+
id: 'msg-1',
|
|
237
|
+
text: 'Hey, did you get my last message?',
|
|
238
|
+
user: storyUsers.visitor,
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
id: 'msg-2',
|
|
242
|
+
text: 'Yes! Just replying now.',
|
|
243
|
+
user: storyUsers.creator,
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
id: 'msg-3',
|
|
247
|
+
text: 'Sounds good.',
|
|
248
|
+
user: storyUsers.visitor,
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
id: 'msg-4',
|
|
252
|
+
text: 'Let me know if you need anything else.',
|
|
253
|
+
user: storyUsers.creator,
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
id: 'msg-5',
|
|
257
|
+
text: 'Talk soon!',
|
|
258
|
+
user: storyUsers.creator,
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
}
|
|
262
|
+
|
|
228
263
|
export const WithTipTag: StoryFn<TemplateProps> = Template.bind({})
|
|
229
264
|
WithTipTag.args = {
|
|
230
265
|
messages: [
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { LocalMessage } from 'stream-chat'
|
|
2
|
+
import { describe, expect, it } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import { renderWithProviders, screen } from '../../test/utils'
|
|
5
|
+
|
|
6
|
+
import { SentMessageDeliveryStatus } from './SentMessageDeliveryStatus'
|
|
7
|
+
|
|
8
|
+
const baseMessage = {
|
|
9
|
+
id: 'message-1',
|
|
10
|
+
status: 'received',
|
|
11
|
+
type: 'regular',
|
|
12
|
+
} as unknown as LocalMessage
|
|
13
|
+
|
|
14
|
+
const renderStatus = (
|
|
15
|
+
props: Partial<{
|
|
16
|
+
message: LocalMessage
|
|
17
|
+
isMyMessage: boolean
|
|
18
|
+
lastOwnMessageId?: string
|
|
19
|
+
}> = {}
|
|
20
|
+
) =>
|
|
21
|
+
renderWithProviders(
|
|
22
|
+
<SentMessageDeliveryStatus
|
|
23
|
+
message={props.message ?? baseMessage}
|
|
24
|
+
isMyMessage={props.isMyMessage ?? true}
|
|
25
|
+
lastOwnMessageId={props.lastOwnMessageId ?? 'message-1'}
|
|
26
|
+
/>
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
describe('SentMessageDeliveryStatus', () => {
|
|
30
|
+
it('renders "Delivered" for the last own message once Stream has received it', () => {
|
|
31
|
+
renderStatus()
|
|
32
|
+
|
|
33
|
+
expect(
|
|
34
|
+
screen.getByTestId('sent-message-delivery-status')
|
|
35
|
+
).toBeInTheDocument()
|
|
36
|
+
expect(screen.getByText(/delivered/i)).toBeInTheDocument()
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('renders nothing when the message is not authored by the viewer', () => {
|
|
40
|
+
const { container } = renderStatus({ isMyMessage: false })
|
|
41
|
+
|
|
42
|
+
expect(container).toBeEmptyDOMElement()
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('renders nothing when this is not the last own message', () => {
|
|
46
|
+
const { container } = renderStatus({ lastOwnMessageId: 'message-2' })
|
|
47
|
+
|
|
48
|
+
expect(container).toBeEmptyDOMElement()
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it.each(['sending', 'failed'] as const)(
|
|
52
|
+
'renders nothing while the message status is %s',
|
|
53
|
+
(status) => {
|
|
54
|
+
const { container } = renderStatus({
|
|
55
|
+
message: { ...baseMessage, status } as unknown as LocalMessage,
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
expect(container).toBeEmptyDOMElement()
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
it('renders nothing for error messages', () => {
|
|
63
|
+
const { container } = renderStatus({
|
|
64
|
+
message: {
|
|
65
|
+
...baseMessage,
|
|
66
|
+
type: 'error',
|
|
67
|
+
} as unknown as LocalMessage,
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
expect(container).toBeEmptyDOMElement()
|
|
71
|
+
})
|
|
72
|
+
})
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ChecksIcon } from '@phosphor-icons/react'
|
|
2
|
+
import type { LocalMessage } from 'stream-chat'
|
|
3
|
+
|
|
4
|
+
interface SentMessageDeliveryStatusProps {
|
|
5
|
+
message: LocalMessage
|
|
6
|
+
/** Result of the message context's `isMyMessage()` for this message. */
|
|
7
|
+
isMyMessage: boolean
|
|
8
|
+
/** `id` of the viewer's most recent own message, from `lastOwnMessage`. */
|
|
9
|
+
lastOwnMessageId?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* "✓✓ Delivered" indicator shown beneath the viewer's most recent **sent**
|
|
14
|
+
* message, right-aligned (MES-1036).
|
|
15
|
+
*
|
|
16
|
+
* "Delivered" fires once Stream confirms the message is stored on the backend
|
|
17
|
+
* (`status === 'received'`) and updates live as that status flips. It renders
|
|
18
|
+
* only on the last own message in the thread — never on earlier bubbles, and
|
|
19
|
+
* never on error messages. Read receipts are intentionally out of scope per
|
|
20
|
+
* the ticket.
|
|
21
|
+
*
|
|
22
|
+
* The "is this the last own message?" decision comes from stream-chat-react's
|
|
23
|
+
* `lastOwnMessage` (via `MessageContext`); the parent must re-render this
|
|
24
|
+
* subtree when `lastOwnMessage` changes so the label hops to a newer message.
|
|
25
|
+
*/
|
|
26
|
+
export const SentMessageDeliveryStatus = ({
|
|
27
|
+
message,
|
|
28
|
+
isMyMessage,
|
|
29
|
+
lastOwnMessageId,
|
|
30
|
+
}: SentMessageDeliveryStatusProps) => {
|
|
31
|
+
const isLastOwnMessage =
|
|
32
|
+
isMyMessage &&
|
|
33
|
+
message.type !== 'error' &&
|
|
34
|
+
lastOwnMessageId === message.id
|
|
35
|
+
|
|
36
|
+
if (!isLastOwnMessage || message.status !== 'received') {
|
|
37
|
+
return null
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div
|
|
42
|
+
className="str-chat__message-delivery-status"
|
|
43
|
+
data-testid="sent-message-delivery-status"
|
|
44
|
+
>
|
|
45
|
+
<ChecksIcon size={14} weight="bold" aria-hidden="true" />
|
|
46
|
+
<span>Delivered</span>
|
|
47
|
+
</div>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
@@ -5,8 +5,41 @@ import { renderWithProviders, screen } from '../../test/utils'
|
|
|
5
5
|
|
|
6
6
|
import StreamAttachmentMessage, {
|
|
7
7
|
linkCaptionDuplicatesAttachmentUrl,
|
|
8
|
+
linkCardPropsFromStreamAttachment,
|
|
8
9
|
} from './StreamAttachmentMessage'
|
|
9
10
|
|
|
11
|
+
describe('linkCardPropsFromStreamAttachment', () => {
|
|
12
|
+
it('uses the featured layout when a thumbnail is present', () => {
|
|
13
|
+
expect(
|
|
14
|
+
linkCardPropsFromStreamAttachment({
|
|
15
|
+
type: 'link',
|
|
16
|
+
og_scrape_url: 'https://linktr.ee/someone',
|
|
17
|
+
image_url: 'https://cdn.example.com/thumb.jpg',
|
|
18
|
+
}).layout
|
|
19
|
+
).toBe('featured')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('uses the classic layout for a plain link with no thumbnail', () => {
|
|
23
|
+
expect(
|
|
24
|
+
linkCardPropsFromStreamAttachment({
|
|
25
|
+
type: 'link',
|
|
26
|
+
og_scrape_url: 'https://linktr.ee/someone',
|
|
27
|
+
}).layout
|
|
28
|
+
).toBe('classic')
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('keeps the featured layout for a playable clip with no thumbnail so the player renders', () => {
|
|
32
|
+
expect(
|
|
33
|
+
linkCardPropsFromStreamAttachment({
|
|
34
|
+
type: 'link',
|
|
35
|
+
og_scrape_url: 'https://linktr.ee/someone',
|
|
36
|
+
asset_url: 'https://cdn.example.com/clip.mp3',
|
|
37
|
+
mime_type: 'audio/mpeg',
|
|
38
|
+
}).layout
|
|
39
|
+
).toBe('featured')
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
10
43
|
describe('linkCaptionDuplicatesAttachmentUrl', () => {
|
|
11
44
|
it('suppresses captions that are just the link plus punctuation', () => {
|
|
12
45
|
expect(
|
|
@@ -2,6 +2,7 @@ import React from 'react'
|
|
|
2
2
|
import type { Attachment } from 'stream-chat'
|
|
3
3
|
|
|
4
4
|
import LinkAttachment from '../LinkAttachment'
|
|
5
|
+
import { isPlayableMedia } from '../LinkAttachment/components/_shared/CardThumbnail'
|
|
5
6
|
import MessageAttachment from '../MessageAttachment'
|
|
6
7
|
import type { BubbleGroupPosition } from '../MessageAttachment/types'
|
|
7
8
|
|
|
@@ -62,6 +63,8 @@ export function linkCardPropsFromStreamAttachment(a: Attachment) {
|
|
|
62
63
|
const thumbnailUrl =
|
|
63
64
|
trimToUndefined((a as { image_url?: string }).image_url) ??
|
|
64
65
|
trimToUndefined((a as { thumb_url?: string }).thumb_url)
|
|
66
|
+
const sourceUrl = trimToUndefined(a.asset_url)
|
|
67
|
+
const mimeType = trimToUndefined(a.mime_type)
|
|
65
68
|
|
|
66
69
|
return {
|
|
67
70
|
title: trimToUndefined((a as { title?: string }).title),
|
|
@@ -70,9 +73,12 @@ export function linkCardPropsFromStreamAttachment(a: Attachment) {
|
|
|
70
73
|
thumbnailUrl,
|
|
71
74
|
// Playable clip embedded in a link preview — lets LinkAttachment render its
|
|
72
75
|
// native video/audio player in the hero instead of a static thumbnail.
|
|
73
|
-
sourceUrl
|
|
74
|
-
layout:
|
|
75
|
-
|
|
76
|
+
sourceUrl,
|
|
77
|
+
layout:
|
|
78
|
+
thumbnailUrl || isPlayableMedia(mimeType, sourceUrl)
|
|
79
|
+
? 'featured'
|
|
80
|
+
: 'classic',
|
|
81
|
+
mimeType,
|
|
76
82
|
} as const
|
|
77
83
|
}
|
|
78
84
|
|
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
isTipOnlyMessage,
|
|
47
47
|
} from './MessageTag'
|
|
48
48
|
import { MessageVoteButtons } from './MessageVoteButtons'
|
|
49
|
+
import { SentMessageDeliveryStatus } from './SentMessageDeliveryStatus'
|
|
49
50
|
import StreamAttachmentMessage, {
|
|
50
51
|
buildOrderedAttachmentSegments,
|
|
51
52
|
} from './StreamAttachmentMessage'
|
|
@@ -74,6 +75,7 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
74
75
|
highlighted,
|
|
75
76
|
isMessageAIGenerated,
|
|
76
77
|
isMyMessage,
|
|
78
|
+
lastOwnMessage,
|
|
77
79
|
message,
|
|
78
80
|
renderText,
|
|
79
81
|
threadList,
|
|
@@ -213,15 +215,17 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
213
215
|
isChatbot && isMine && hasRenderableAttachments
|
|
214
216
|
// Route generic Stream attachments through the toolkit renderer only when it
|
|
215
217
|
// can faithfully own the whole message. Quoted replies (attachments are
|
|
216
|
-
// suppressed there), polls,
|
|
217
|
-
// default branch so their Poll / StreamedMessageText / message-text
|
|
218
|
-
// is preserved — the accompanying
|
|
218
|
+
// suppressed there), polls, AI-streamed, and chatbot messages fall through to
|
|
219
|
+
// the default branch so their Poll / StreamedMessageText / message-text and
|
|
220
|
+
// chatbot attribution (MessageTag) handling is preserved — the accompanying
|
|
221
|
+
// message text and attribution must never be dropped.
|
|
219
222
|
const canRenderAttachmentsInToolkit =
|
|
220
223
|
hasAttachmentSegments &&
|
|
221
224
|
allAttachmentsRepresented &&
|
|
222
225
|
!message.quoted_message &&
|
|
223
226
|
!poll &&
|
|
224
|
-
!isAIGenerated
|
|
227
|
+
!isAIGenerated &&
|
|
228
|
+
!isChatbot
|
|
225
229
|
|
|
226
230
|
return (
|
|
227
231
|
<>
|
|
@@ -395,6 +399,11 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
395
399
|
)}
|
|
396
400
|
</div>
|
|
397
401
|
)}
|
|
402
|
+
<SentMessageDeliveryStatus
|
|
403
|
+
message={message}
|
|
404
|
+
isMyMessage={isMine}
|
|
405
|
+
lastOwnMessageId={lastOwnMessage?.id}
|
|
406
|
+
/>
|
|
398
407
|
{showReplyCountButton && (
|
|
399
408
|
<MessageRepliesCountButton
|
|
400
409
|
onClick={handleOpenThread}
|
|
@@ -414,6 +423,11 @@ const MemoizedCustomMessage = React.memo(
|
|
|
414
423
|
(prev, next) => {
|
|
415
424
|
if (prev.chatbotVotingEnabled !== next.chatbotVotingEnabled) return false
|
|
416
425
|
if (prev.viewerLanguage !== next.viewerLanguage) return false
|
|
426
|
+
// `lastOwnMessage` drives the "Delivered" indicator's placement
|
|
427
|
+
// (`SentMessageDeliveryStatus`). `areMessageUIPropsEqual` doesn't compare
|
|
428
|
+
// it, so without this a stale "Delivered" would linger on the previous
|
|
429
|
+
// bubble after a newer message is sent — re-render when it changes.
|
|
430
|
+
if (prev.lastOwnMessage?.id !== next.lastOwnMessage?.id) return false
|
|
417
431
|
return areMessageUIPropsEqual(prev, next)
|
|
418
432
|
}
|
|
419
433
|
) as typeof CustomMessageWithContext
|
package/src/styles.css
CHANGED
|
@@ -351,12 +351,16 @@
|
|
|
351
351
|
column-gap: 0.25rem;
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
-
/* Outer grid for me (outgoing) messages —
|
|
354
|
+
/* Outer grid for me (outgoing) messages — footer + delivery-status rows
|
|
355
|
+
after message. `delivery-status` carries the "Delivered" receipt on the
|
|
356
|
+
last sent message (MES-1036); the row collapses to 0 height on messages
|
|
357
|
+
that don't render it. */
|
|
355
358
|
.str-chat__li .str-chat__message--me {
|
|
356
359
|
grid-template-areas:
|
|
357
360
|
'message-reminder'
|
|
358
361
|
'message'
|
|
359
362
|
'footer'
|
|
363
|
+
'delivery-status'
|
|
360
364
|
'replies'
|
|
361
365
|
'translation-notice'
|
|
362
366
|
'custom-metadata'
|
|
@@ -412,6 +416,20 @@
|
|
|
412
416
|
align-items: flex-end;
|
|
413
417
|
}
|
|
414
418
|
|
|
419
|
+
/* "✓✓ Delivered" delivery status under the last sent message (MES-1036).
|
|
420
|
+
Right-aligned via the outer grid's `justify-items: end`. */
|
|
421
|
+
.str-chat__li .str-chat__message-delivery-status {
|
|
422
|
+
grid-area: delivery-status;
|
|
423
|
+
display: inline-flex;
|
|
424
|
+
align-items: center;
|
|
425
|
+
gap: 2px;
|
|
426
|
+
padding-block-start: 2px;
|
|
427
|
+
padding-inline-end: 4px;
|
|
428
|
+
font-size: 12px;
|
|
429
|
+
line-height: 1.4;
|
|
430
|
+
color: var(--str-chat__text-low-emphasis-color, rgba(0, 0, 0, 0.5));
|
|
431
|
+
}
|
|
432
|
+
|
|
415
433
|
/* Channel list load-more button overrides */
|
|
416
434
|
.str-chat__channel-list .str-chat__load-more-button__button {
|
|
417
435
|
background-color: #121110;
|