@linktr.ee/messaging-react 3.18.0-rc-1785370958 → 3.18.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-DSBTvt4P.cjs → Card-DdJcz7Np.cjs} +2 -2
- package/dist/{Card-DSBTvt4P.cjs.map → Card-DdJcz7Np.cjs.map} +1 -1
- package/dist/{Card-DYZ6LTkw.js → Card-owYJxu9h.js} +2 -2
- package/dist/{Card-DYZ6LTkw.js.map → Card-owYJxu9h.js.map} +1 -1
- package/dist/{index-BiPvv2eN.cjs → index-BQ4mQDo2.cjs} +2 -2
- package/dist/index-BQ4mQDo2.cjs.map +1 -0
- package/dist/{index-N1OOJmAH.js → index-CsPg1TYf.js} +6 -6
- package/dist/index-CsPg1TYf.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/src/components/LinkAttachment/LinkAttachment.test.tsx +35 -0
- package/src/components/LinkAttachment/components/Composer/Card.tsx +5 -2
- package/src/components/LinkAttachment/components/Received/Card.tsx +7 -3
- package/src/components/LinkAttachment/components/Sent/Card.tsx +4 -1
- package/src/components/LinkAttachment/components/_shared/CardThumbnail.tsx +5 -1
- package/src/components/LinkAttachment/types.ts +5 -0
- package/dist/index-BiPvv2eN.cjs.map +0 -1
- package/dist/index-N1OOJmAH.js.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-BQ4mQDo2.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.d.ts
CHANGED
|
@@ -697,6 +697,11 @@ export declare interface LinkAttachmentBaseProps {
|
|
|
697
697
|
* text bars and ignores `accentColor` (there is no image yet). `'failed'`
|
|
698
698
|
* renders the fallback chin with whatever text is available. Defaults to
|
|
699
699
|
* `'ready'`.
|
|
700
|
+
*
|
|
701
|
+
* `'loading'` outranks the hero shape that `mimeType` + `sourceUrl` would
|
|
702
|
+
* otherwise select: a card mid-scrape does not yet know what the asset is, so
|
|
703
|
+
* it renders the skeleton rather than a live `<audio>` / `<video>` player
|
|
704
|
+
* beside the skeleton's own text bars.
|
|
700
705
|
*/
|
|
701
706
|
status?: LinkAttachmentStatus;
|
|
702
707
|
}
|
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-CsPg1TYf.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.18.0
|
|
3
|
+
"version": "3.18.0",
|
|
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": "2.
|
|
53
|
+
"@linktr.ee/messaging-core": "^2.2.0",
|
|
54
54
|
"@phosphor-icons/react": "^2.1.10"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
@@ -261,6 +261,41 @@ describe('LinkAttachment accent chin (MES-1349)', () => {
|
|
|
261
261
|
expect(screen.getByText(CARD_PROPS.title)).toHaveStyle({ color: '#040403' })
|
|
262
262
|
})
|
|
263
263
|
|
|
264
|
+
it('lets a loading status outrank the audio hero on all three cards', () => {
|
|
265
|
+
// `status` and `mimeType`/`sourceUrl` are independent public props, and a
|
|
266
|
+
// caller can set both. Before this, `CardThumbnail`'s audio fast path ran
|
|
267
|
+
// ahead of the loading branch, so Sent/Received mounted a live `<audio>`
|
|
268
|
+
// player beside `CardBody`'s skeleton bars and Composer's own audio path
|
|
269
|
+
// dropped the skeleton and its `aria-busy` region altogether.
|
|
270
|
+
const LOADING_AUDIO = {
|
|
271
|
+
mimeType: 'audio/mpeg',
|
|
272
|
+
sourceUrl: 'https://cdn.example.com/clip.mp3',
|
|
273
|
+
status: 'loading' as const,
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
for (const card of [
|
|
277
|
+
<LinkAttachment.Sent key="s" {...LOADING_AUDIO} />,
|
|
278
|
+
<LinkAttachment.Received key="r" {...LOADING_AUDIO} />,
|
|
279
|
+
<LinkAttachment.Composer
|
|
280
|
+
key="c"
|
|
281
|
+
{...LOADING_AUDIO}
|
|
282
|
+
onDismiss={() => {}}
|
|
283
|
+
/>,
|
|
284
|
+
]) {
|
|
285
|
+
const { container, unmount } = renderWithProviders(card)
|
|
286
|
+
|
|
287
|
+
expect(container.querySelector('audio')).toBeNull()
|
|
288
|
+
const busy = screen.getByLabelText('Loading link preview')
|
|
289
|
+
expect(busy).toHaveAttribute('aria-busy', 'true')
|
|
290
|
+
// The skeleton keeps its 250px box: the audio shell is intrinsic-height,
|
|
291
|
+
// and a `flex-1` hero inside it would collapse to zero.
|
|
292
|
+
expect(busy.className).toContain('h-[250px]')
|
|
293
|
+
expect(container.querySelectorAll('.animate-pulse')).toHaveLength(3)
|
|
294
|
+
|
|
295
|
+
unmount()
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
|
|
264
299
|
it('paints the bubble tail in the accent for the last card in a run only', async () => {
|
|
265
300
|
const { unmount } = renderWithProviders(
|
|
266
301
|
<LinkAttachment.Sent
|
|
@@ -104,8 +104,11 @@ const ComposerCard: React.FC<ComposerCardProps> = ({
|
|
|
104
104
|
|
|
105
105
|
// Audio cards collapse to just the native player — render the dismiss
|
|
106
106
|
// button as an inline sibling so it always has its own space and never
|
|
107
|
-
// overlaps the audio control's volume/menu buttons.
|
|
108
|
-
|
|
107
|
+
// overlaps the audio control's volume/menu buttons. Skipped while loading:
|
|
108
|
+
// this path has no `CardBody` and no `busy`, so taking it during a scrape
|
|
109
|
+
// would drop the skeleton and its `aria-busy` region entirely, and we do not
|
|
110
|
+
// yet know the asset is audio anyway.
|
|
111
|
+
if (isAudio && !chin.isLoading) {
|
|
109
112
|
return (
|
|
110
113
|
<CardShell variant="dark" bgClassName={AUDIO_BG_CLASS}>
|
|
111
114
|
<div className="flex items-center gap-2 pr-3">
|
|
@@ -73,9 +73,13 @@ const ReceivedCard: React.FC<ReceivedCardProps> = ({
|
|
|
73
73
|
? normalizedUrl
|
|
74
74
|
: undefined
|
|
75
75
|
const shellOnClick = cta == null && !isPlayingMedia ? onClick : undefined
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
// A loading card is not yet an audio card: the scrape that would tell us has
|
|
77
|
+
// not returned, so it keeps the ordinary 250px skeleton rather than the
|
|
78
|
+
// intrinsic-height audio shell (whose `flex-1` hero would collapse to 0).
|
|
79
|
+
const audioBg =
|
|
80
|
+
status !== 'loading' && isPlayableAudio(mimeType, sourceUrl)
|
|
81
|
+
? AUDIO_BG_CLASS
|
|
82
|
+
: undefined
|
|
79
83
|
|
|
80
84
|
// When a CTA is set the shell isn't interactive — the CTA owns the
|
|
81
85
|
// click target. Forward the card-level `onClick` to the CTA so
|
|
@@ -76,7 +76,10 @@ const SentCard: React.FC<SentCardProps> = ({
|
|
|
76
76
|
const shellOnClick =
|
|
77
77
|
cta == null && !isPlayingMedia && shellHref != null ? onClick : undefined
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
// A loading card is not yet an audio card: the scrape that would tell us has
|
|
80
|
+
// not returned, so it keeps the ordinary 250px skeleton rather than the
|
|
81
|
+
// intrinsic-height audio shell (whose `flex-1` hero would collapse to 0).
|
|
82
|
+
const isAudio = status !== 'loading' && isPlayableAudio(mimeType, sourceUrl)
|
|
80
83
|
const chin = useChinPalette({
|
|
81
84
|
variant: 'dark',
|
|
82
85
|
accentColor,
|
|
@@ -95,7 +95,11 @@ const CardThumbnail: React.FC<CardThumbnailProps> = ({
|
|
|
95
95
|
const isPlayableVideo = !!sourceUrl && sourceType === 'video'
|
|
96
96
|
const optimizedThumbnailUrl = optimizeMessagingAttachmentUrl(thumbnailUrl)
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
// `!isLoading` first, deliberately: while the scrape is in flight we do not
|
|
99
|
+
// yet know what the asset is, so honouring a `mimeType` the caller happens to
|
|
100
|
+
// have set already would mount a live player next to `CardBody`'s skeleton
|
|
101
|
+
// bars. The loading branch below owns every hero shape (MES-1349).
|
|
102
|
+
if (!isLoading && isPlayableAudio(mimeType, sourceUrl)) {
|
|
99
103
|
// Audio collapses the hero entirely — the native player sits inside
|
|
100
104
|
// the card chrome with a bit of padding so the card background
|
|
101
105
|
// (typically `bg-[#F2F3F4]`) is visible around it.
|
|
@@ -95,6 +95,11 @@ export interface LinkAttachmentBaseProps {
|
|
|
95
95
|
* text bars and ignores `accentColor` (there is no image yet). `'failed'`
|
|
96
96
|
* renders the fallback chin with whatever text is available. Defaults to
|
|
97
97
|
* `'ready'`.
|
|
98
|
+
*
|
|
99
|
+
* `'loading'` outranks the hero shape that `mimeType` + `sourceUrl` would
|
|
100
|
+
* otherwise select: a card mid-scrape does not yet know what the asset is, so
|
|
101
|
+
* it renders the skeleton rather than a live `<audio>` / `<video>` player
|
|
102
|
+
* beside the skeleton's own text bars.
|
|
98
103
|
*/
|
|
99
104
|
status?: LinkAttachmentStatus
|
|
100
105
|
}
|