@linktr.ee/messaging-react 3.4.2 → 3.5.0-rc-1782480113
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-BKalDyyu.js → Card-D34G7gvm.js} +2 -2
- package/dist/{Card-BKalDyyu.js.map → Card-D34G7gvm.js.map} +1 -1
- package/dist/{Card-DxroYNrS.cjs → Card-DIFgYVKx.cjs} +2 -2
- package/dist/{Card-DxroYNrS.cjs.map → Card-DIFgYVKx.cjs.map} +1 -1
- package/dist/{Card-mpVcQ8-W.js → Card-DVDoFfkP.js} +3 -3
- package/dist/{Card-mpVcQ8-W.js.map → Card-DVDoFfkP.js.map} +1 -1
- package/dist/{Card-V-bNUxcw.cjs → Card-DhAhEetQ.cjs} +2 -2
- package/dist/{Card-V-bNUxcw.cjs.map → Card-DhAhEetQ.cjs.map} +1 -1
- package/dist/{Card-CphU_jG-.js → Card-Dy1Qj3MR.js} +2 -2
- package/dist/{Card-CphU_jG-.js.map → Card-Dy1Qj3MR.js.map} +1 -1
- package/dist/{Card-DFy_ZvFH.cjs → Card-yHlBBfOt.cjs} +2 -2
- package/dist/{Card-DFy_ZvFH.cjs.map → Card-yHlBBfOt.cjs.map} +1 -1
- package/dist/{LockedThumbnail-BD7qtcso.js → LockedThumbnail-1S_Rjelj.js} +2 -2
- package/dist/{LockedThumbnail-BD7qtcso.js.map → LockedThumbnail-1S_Rjelj.js.map} +1 -1
- package/dist/{LockedThumbnail-B3W7upHs.cjs → LockedThumbnail-P2BVsLli.cjs} +2 -2
- package/dist/{LockedThumbnail-B3W7upHs.cjs.map → LockedThumbnail-P2BVsLli.cjs.map} +1 -1
- package/dist/index-BZjaMDgI.cjs +2 -0
- package/dist/index-BZjaMDgI.cjs.map +1 -0
- package/dist/{index-CjwQ2Hj3.js → index-CgczmQkU.js} +1160 -1150
- package/dist/index-CgczmQkU.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +18 -0
- package/dist/index.js +18 -17
- package/package.json +2 -2
- package/src/components/ChannelList/CustomChannelPreview.test.tsx +38 -0
- package/src/components/ChannelList/CustomChannelPreview.tsx +5 -6
- package/src/components/ChannelView.test.tsx +35 -0
- package/src/components/ChannelView.tsx +6 -0
- package/src/components/VerifiedBadge/index.tsx +25 -0
- package/src/index.ts +2 -0
- package/src/stream-custom-data.ts +8 -0
- package/dist/index-CjwQ2Hj3.js.map +0 -1
- package/dist/index-tI-4cxV1.cjs +0 -2
- package/dist/index-tI-4cxV1.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-BZjaMDgI.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.VerifiedBadge=e.VerifiedBadge;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.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
|
@@ -1423,6 +1423,17 @@ declare interface UseMessageVoteResult {
|
|
|
1423
1423
|
*/
|
|
1424
1424
|
export declare const useMessaging: () => MessagingContextValue;
|
|
1425
1425
|
|
|
1426
|
+
/**
|
|
1427
|
+
* Linktree verification badge shown next to the name of a verified profile.
|
|
1428
|
+
* Rendered when a participant's Stream user has `is_verified` set to true.
|
|
1429
|
+
*/
|
|
1430
|
+
export declare const VerifiedBadge: default_2.FC<VerifiedBadgeProps>;
|
|
1431
|
+
|
|
1432
|
+
export declare interface VerifiedBadgeProps {
|
|
1433
|
+
className?: string;
|
|
1434
|
+
size?: number;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1426
1437
|
declare interface VideoAttachmentSharedProps extends MessageAttachmentBaseProps {
|
|
1427
1438
|
/** Single video — convenience for the most common case. */
|
|
1428
1439
|
src?: string;
|
|
@@ -1495,6 +1506,13 @@ declare module 'stream-chat' {
|
|
|
1495
1506
|
*/
|
|
1496
1507
|
chatbot_paused?: boolean;
|
|
1497
1508
|
}
|
|
1509
|
+
interface CustomUserData {
|
|
1510
|
+
/**
|
|
1511
|
+
* Whether the user is a verified Linktree profile. When true, a
|
|
1512
|
+
* verification badge is shown next to their name in messaging.
|
|
1513
|
+
*/
|
|
1514
|
+
is_verified?: boolean;
|
|
1515
|
+
}
|
|
1498
1516
|
interface CustomMessageData {
|
|
1499
1517
|
/**
|
|
1500
1518
|
* When true, hides the date timestamp in system messages.
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as s, b as t, C as i, c as o, d as n, e as m, F as g, f as r, L as l, h as M, M as u, i as L, j as c, k as d, l as h, V as p, m as C, n as v, o as A, p as k, q as F, s as f, t as V, u as b, v as x, w as y, x as B, y as P, z as S, B as q, D as z, E as D } from "./index-CgczmQkU.js";
|
|
2
2
|
export {
|
|
3
|
-
|
|
3
|
+
s as ActionButton,
|
|
4
4
|
t as Avatar,
|
|
5
5
|
i as ChannelEmptyState,
|
|
6
6
|
o as ChannelList,
|
|
@@ -13,23 +13,24 @@ export {
|
|
|
13
13
|
u as MediaMessage,
|
|
14
14
|
L as MessageAttachment,
|
|
15
15
|
c as MessageVoteButtons,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
p as
|
|
19
|
-
C as
|
|
20
|
-
v as
|
|
21
|
-
A as
|
|
22
|
-
k as
|
|
23
|
-
F as
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
d as MessagingProvider,
|
|
17
|
+
h as MessagingShell,
|
|
18
|
+
p as VerifiedBadge,
|
|
19
|
+
C as buildCompactMetaLabel,
|
|
20
|
+
v as formatFileSize,
|
|
21
|
+
A as formatRelativeTime,
|
|
22
|
+
k as getFileExtensionLabel,
|
|
23
|
+
F as getMessageDisplayText,
|
|
24
|
+
f as isLinkAttachment,
|
|
25
|
+
V as isUuidLike,
|
|
26
|
+
b as messageAttachmentGroupPositionFromStream,
|
|
26
27
|
x as normalizeLanguageCode,
|
|
27
28
|
y as resolveLinkAttachment,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
B as resolveMediaFromMessage,
|
|
30
|
+
P as resolveParticipantDisplayName,
|
|
31
|
+
S as useComposerLocked,
|
|
32
|
+
q as useCustomMessage,
|
|
33
|
+
z as useMessageVote,
|
|
33
34
|
D as useMessaging
|
|
34
35
|
};
|
|
35
36
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linktr.ee/messaging-react",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0-rc-1782480113",
|
|
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-1782480113",
|
|
42
42
|
"@phosphor-icons/react": "^2.1.10"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
@@ -101,6 +101,44 @@ describe('CustomChannelPreview', () => {
|
|
|
101
101
|
expect(screen.getByText('Unknown member')).toBeInTheDocument()
|
|
102
102
|
})
|
|
103
103
|
|
|
104
|
+
it('shows the verification badge when the participant is verified', () => {
|
|
105
|
+
const channel = createMockChannel([])
|
|
106
|
+
channel.state.members['participant-1'] = {
|
|
107
|
+
user: { id: 'participant-1', name: 'Alice', is_verified: true },
|
|
108
|
+
user_id: 'participant-1',
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
renderWithProviders(
|
|
112
|
+
<CustomChannelPreview {...defaultProps} channel={channel} />
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
expect(screen.getByLabelText('Verified')).toBeInTheDocument()
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('does not show the verification badge when the participant is not verified', () => {
|
|
119
|
+
const channel = createMockChannel([])
|
|
120
|
+
channel.state.members['participant-1'] = {
|
|
121
|
+
user: { id: 'participant-1', name: 'Alice', is_verified: false },
|
|
122
|
+
user_id: 'participant-1',
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
renderWithProviders(
|
|
126
|
+
<CustomChannelPreview {...defaultProps} channel={channel} />
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
expect(screen.queryByLabelText('Verified')).not.toBeInTheDocument()
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
it('does not show the verification badge when is_verified is absent', () => {
|
|
133
|
+
const channel = createMockChannel([])
|
|
134
|
+
|
|
135
|
+
renderWithProviders(
|
|
136
|
+
<CustomChannelPreview {...defaultProps} channel={channel} />
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
expect(screen.queryByLabelText('Verified')).not.toBeInTheDocument()
|
|
140
|
+
})
|
|
141
|
+
|
|
104
142
|
it('shows the latest non-system message when the last message is a system message', () => {
|
|
105
143
|
const channel = createMockChannel([
|
|
106
144
|
{
|
|
@@ -8,6 +8,7 @@ import { getMessageDisplayText } from '../../utils/getMessageDisplayText'
|
|
|
8
8
|
import { resolveParticipantDisplayName } from '../../utils/resolveParticipantDisplayName'
|
|
9
9
|
import { Avatar } from '../Avatar'
|
|
10
10
|
import { isChatbotMessage } from '../CustomMessage/MessageTag'
|
|
11
|
+
import { VerifiedBadge } from '../VerifiedBadge'
|
|
11
12
|
|
|
12
13
|
import { useChannelListContext } from './ChannelListContext'
|
|
13
14
|
|
|
@@ -48,6 +49,7 @@ const CustomChannelPreview = React.memo<ChannelPreviewUIComponentProps>(
|
|
|
48
49
|
)
|
|
49
50
|
const participantName = resolveParticipantDisplayName(participant?.user)
|
|
50
51
|
const participantImage = participant?.user?.image
|
|
52
|
+
const isParticipantVerified = participant?.user?.is_verified === true
|
|
51
53
|
|
|
52
54
|
// Get last non-system message for preview
|
|
53
55
|
const lastMessage = (() => {
|
|
@@ -146,15 +148,12 @@ const CustomChannelPreview = React.memo<ChannelPreviewUIComponentProps>(
|
|
|
146
148
|
<div className="flex-1 min-w-0 flex flex-col gap-1">
|
|
147
149
|
{/* Name and timestamp row */}
|
|
148
150
|
<div className="flex items-center justify-between gap-2">
|
|
149
|
-
<h3
|
|
150
|
-
className={classNames(
|
|
151
|
-
'text-sm font-medium truncate text-[#191918]'
|
|
152
|
-
)}
|
|
153
|
-
>
|
|
151
|
+
<h3 className="flex min-w-0 items-center gap-1 text-sm font-medium text-[#191918]">
|
|
154
152
|
{isChannelStarred && (
|
|
155
153
|
<span className="sr-only">Starred conversation. </span>
|
|
156
154
|
)}
|
|
157
|
-
{participantName}
|
|
155
|
+
<span className="min-w-0 truncate">{participantName}</span>
|
|
156
|
+
{isParticipantVerified && <VerifiedBadge />}
|
|
158
157
|
</h3>
|
|
159
158
|
{lastMessageTime && (
|
|
160
159
|
<span className="text-xs text-[#717070] flex-shrink-0">
|
|
@@ -106,6 +106,7 @@ const createChannel = ({
|
|
|
106
106
|
name?: string
|
|
107
107
|
username?: string
|
|
108
108
|
is_account?: boolean
|
|
109
|
+
is_verified?: boolean
|
|
109
110
|
}
|
|
110
111
|
} = {}) =>
|
|
111
112
|
({
|
|
@@ -475,6 +476,40 @@ describe('ChannelView', () => {
|
|
|
475
476
|
expect(screen.getAllByText('Unknown member').length).toBeGreaterThan(0)
|
|
476
477
|
})
|
|
477
478
|
|
|
479
|
+
it('shows the verification badge in the header when the participant is verified', () => {
|
|
480
|
+
renderWithProviders(
|
|
481
|
+
<ChannelView
|
|
482
|
+
channel={createChannel({
|
|
483
|
+
otherUser: {
|
|
484
|
+
id: 'linker-1',
|
|
485
|
+
name: 'Linker',
|
|
486
|
+
is_account: true,
|
|
487
|
+
is_verified: true,
|
|
488
|
+
},
|
|
489
|
+
})}
|
|
490
|
+
/>
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
expect(screen.getAllByLabelText('Verified').length).toBeGreaterThan(0)
|
|
494
|
+
})
|
|
495
|
+
|
|
496
|
+
it('does not show the verification badge in the header when the participant is not verified', () => {
|
|
497
|
+
renderWithProviders(
|
|
498
|
+
<ChannelView
|
|
499
|
+
channel={createChannel({
|
|
500
|
+
otherUser: {
|
|
501
|
+
id: 'linker-1',
|
|
502
|
+
name: 'Linker',
|
|
503
|
+
is_account: true,
|
|
504
|
+
is_verified: false,
|
|
505
|
+
},
|
|
506
|
+
})}
|
|
507
|
+
/>
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
expect(screen.queryByLabelText('Verified')).not.toBeInTheDocument()
|
|
511
|
+
})
|
|
512
|
+
|
|
478
513
|
it('fires onMessageLinkClick with the href and undefined message when the link is not inside a message wrapper', () => {
|
|
479
514
|
const handler = vi.fn()
|
|
480
515
|
const { container } = renderWithProviders(
|
|
@@ -32,6 +32,7 @@ import CustomTypingIndicator from './CustomTypingIndicator'
|
|
|
32
32
|
import { DmAgentEnabledContext } from './CustomTypingIndicator/DmAgentContext'
|
|
33
33
|
import { ChannelEmptyState } from './MessagingShell/ChannelEmptyState'
|
|
34
34
|
import { LoadingState } from './MessagingShell/LoadingState'
|
|
35
|
+
import { VerifiedBadge } from './VerifiedBadge'
|
|
35
36
|
|
|
36
37
|
const ICON_BTN_CLASS =
|
|
37
38
|
'size-10 rounded-full hover:bg-[#E5E4E1] flex items-center justify-center transition-colors duration-150 focus-ring'
|
|
@@ -92,6 +93,7 @@ const CustomChannelHeader: React.FC<{
|
|
|
92
93
|
|
|
93
94
|
const participantName = resolveParticipantDisplayName(participant?.user)
|
|
94
95
|
const participantImage = participant?.user?.image
|
|
96
|
+
const isParticipantVerified = participant?.user?.is_verified === true
|
|
95
97
|
const isStarred = useChannelStar(channel)
|
|
96
98
|
const headerTitleBadges = renderHeaderTitleBadges?.({
|
|
97
99
|
channel,
|
|
@@ -148,6 +150,7 @@ const CustomChannelHeader: React.FC<{
|
|
|
148
150
|
className="flex max-w-full items-center gap-0.5 rounded text-center text-xs font-medium text-black/90 transition-opacity hover:opacity-70"
|
|
149
151
|
>
|
|
150
152
|
<span className="min-w-0 truncate">{participantName}</span>
|
|
153
|
+
{isParticipantVerified && <VerifiedBadge />}
|
|
151
154
|
{headerTitleBadges && (
|
|
152
155
|
<span className="shrink-0">{headerTitleBadges}</span>
|
|
153
156
|
)}
|
|
@@ -156,6 +159,7 @@ const CustomChannelHeader: React.FC<{
|
|
|
156
159
|
) : (
|
|
157
160
|
<p className="flex max-w-full items-center justify-center gap-1 text-center text-xs font-medium text-black/90">
|
|
158
161
|
<span className="min-w-0 truncate">{participantName}</span>
|
|
162
|
+
{isParticipantVerified && <VerifiedBadge />}
|
|
159
163
|
{headerTitleBadges && (
|
|
160
164
|
<span className="shrink-0">{headerTitleBadges}</span>
|
|
161
165
|
)}
|
|
@@ -241,6 +245,7 @@ const CustomChannelHeader: React.FC<{
|
|
|
241
245
|
className="flex min-w-0 max-w-full items-center gap-1 rounded font-medium text-black/90 transition-opacity hover:opacity-70"
|
|
242
246
|
>
|
|
243
247
|
<span className="min-w-0 truncate">{participantName}</span>
|
|
248
|
+
{isParticipantVerified && <VerifiedBadge />}
|
|
244
249
|
{headerTitleBadges && (
|
|
245
250
|
<span className="shrink-0">{headerTitleBadges}</span>
|
|
246
251
|
)}
|
|
@@ -249,6 +254,7 @@ const CustomChannelHeader: React.FC<{
|
|
|
249
254
|
) : (
|
|
250
255
|
<h1 className="flex min-w-0 items-center gap-1 font-medium text-black/90">
|
|
251
256
|
<span className="min-w-0 truncate">{participantName}</span>
|
|
257
|
+
{isParticipantVerified && <VerifiedBadge />}
|
|
252
258
|
{headerTitleBadges && (
|
|
253
259
|
<span className="shrink-0">{headerTitleBadges}</span>
|
|
254
260
|
)}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SealCheckIcon } from '@phosphor-icons/react'
|
|
2
|
+
import classNames from 'classnames'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
|
|
5
|
+
export interface VerifiedBadgeProps {
|
|
6
|
+
className?: string
|
|
7
|
+
size?: number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Linktree verification badge shown next to the name of a verified profile.
|
|
12
|
+
* Rendered when a participant's Stream user has `is_verified` set to true.
|
|
13
|
+
*/
|
|
14
|
+
export const VerifiedBadge: React.FC<VerifiedBadgeProps> = ({
|
|
15
|
+
className,
|
|
16
|
+
size = 16,
|
|
17
|
+
}) => (
|
|
18
|
+
<SealCheckIcon
|
|
19
|
+
weight="fill"
|
|
20
|
+
size={size}
|
|
21
|
+
className={classNames('shrink-0 text-[#1D9BF0]', className)}
|
|
22
|
+
aria-label="Verified"
|
|
23
|
+
role="img"
|
|
24
|
+
/>
|
|
25
|
+
)
|
package/src/index.ts
CHANGED
|
@@ -10,6 +10,8 @@ export { default as LockedAttachment } from './components/LockedAttachment'
|
|
|
10
10
|
export { default as LinkAttachment } from './components/LinkAttachment'
|
|
11
11
|
export { default as MessageAttachment } from './components/MessageAttachment'
|
|
12
12
|
export { Avatar } from './components/Avatar'
|
|
13
|
+
export { VerifiedBadge } from './components/VerifiedBadge'
|
|
14
|
+
export type { VerifiedBadgeProps } from './components/VerifiedBadge'
|
|
13
15
|
export { FaqList } from './components/FaqList'
|
|
14
16
|
export { FaqListItem } from './components/FaqList/FaqListItem'
|
|
15
17
|
export { ChannelEmptyState } from './components/MessagingShell/ChannelEmptyState'
|
|
@@ -98,6 +98,14 @@ declare module 'stream-chat' {
|
|
|
98
98
|
chatbot_paused?: boolean
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
interface CustomUserData {
|
|
102
|
+
/**
|
|
103
|
+
* Whether the user is a verified Linktree profile. When true, a
|
|
104
|
+
* verification badge is shown next to their name in messaging.
|
|
105
|
+
*/
|
|
106
|
+
is_verified?: boolean
|
|
107
|
+
}
|
|
108
|
+
|
|
101
109
|
interface CustomMessageData {
|
|
102
110
|
/**
|
|
103
111
|
* When true, hides the date timestamp in system messages.
|