@linktr.ee/messaging-react 3.3.4 → 3.3.5
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-B7AF5uOB.js → Card-B9QrjooN.js} +3 -3
- package/dist/{Card-B7AF5uOB.js.map → Card-B9QrjooN.js.map} +1 -1
- package/dist/{Card-0BgubwgM.cjs → Card-BRRlz4kq.cjs} +2 -2
- package/dist/{Card-0BgubwgM.cjs.map → Card-BRRlz4kq.cjs.map} +1 -1
- package/dist/{Card-DLmUSU4A.cjs → Card-C-FCwjGa.cjs} +2 -2
- package/dist/{Card-DLmUSU4A.cjs.map → Card-C-FCwjGa.cjs.map} +1 -1
- package/dist/{Card-DchJqvYq.js → Card-CVZzYmYW.js} +2 -2
- package/dist/{Card-DchJqvYq.js.map → Card-CVZzYmYW.js.map} +1 -1
- package/dist/{Card-CvBbAoUo.cjs → Card-D_oLlfPw.cjs} +2 -2
- package/dist/{Card-CvBbAoUo.cjs.map → Card-D_oLlfPw.cjs.map} +1 -1
- package/dist/{Card-DmPpcrSU.js → Card-DzjYyrie.js} +2 -2
- package/dist/{Card-DmPpcrSU.js.map → Card-DzjYyrie.js.map} +1 -1
- package/dist/{LockedThumbnail-BQjA4HaB.js → LockedThumbnail-CJfXY_Ut.js} +2 -2
- package/dist/{LockedThumbnail-BQjA4HaB.js.map → LockedThumbnail-CJfXY_Ut.js.map} +1 -1
- package/dist/{LockedThumbnail-D9fSb4N-.cjs → LockedThumbnail-Cth1yWnH.cjs} +2 -2
- package/dist/{LockedThumbnail-D9fSb4N-.cjs.map → LockedThumbnail-Cth1yWnH.cjs.map} +1 -1
- package/dist/index-CBtOPvxW.cjs +2 -0
- package/dist/index-CBtOPvxW.cjs.map +1 -0
- package/dist/{index-BcHUpyyw.js → index-D7eRkXoG.js} +535 -537
- package/dist/index-D7eRkXoG.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/AttachmentCard/AttachmentCard.stories.tsx +104 -0
- package/src/components/ChannelActionsMenu/ChannelActionsMenu.test.tsx +33 -8
- package/src/components/ChannelList/CustomChannelPreview.stories.tsx +55 -47
- package/src/components/ChannelView.stories.tsx +8 -7
- package/src/components/CloseButton/CloseButton.stories.tsx +31 -0
- package/src/components/CustomDateSeparator/CustomDateSeparator.stories.tsx +33 -0
- package/src/components/CustomLinkPreviewList/CustomLinkPreviewCard.stories.tsx +63 -0
- package/src/components/CustomLinkPreviewList/CustomLinkPreviewCard.tsx +57 -0
- package/src/components/CustomLinkPreviewList/index.tsx +2 -54
- package/src/components/CustomMessage/CustomMessage.stories.tsx +3 -2
- package/src/components/CustomMessage/MessageTag.stories.tsx +4 -2
- package/src/components/MediaMessage/MediaMessage.stories.tsx +4 -2
- package/src/hooks/useChannelModerationActions.ts +32 -14
- package/src/stories/decorators/storyTime.ts +31 -0
- package/dist/index-BcHUpyyw.js.map +0 -1
- package/dist/index-DTZNltUC.cjs +0 -2
- package/dist/index-DTZNltUC.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-CBtOPvxW.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.resolveLinkAttachment=e.resolveLinkAttachment;exports.resolveMediaFromMessage=e.resolveMediaFromMessage;exports.resolveParticipantDisplayName=e.resolveParticipantDisplayName;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 n, d as o, e as m, F as g, f as l, L as r, h as M, M as u, i as L, j as c, k as h, l as d, m as p, n as v, o as A, p as C, q as F, s as k, t as b, u as f, v as x, w as y, x as P, y as S, z as q, B as z, D as B } from "./index-
|
|
1
|
+
import { a as e, b as t, C as i, c as n, d as o, e as m, F as g, f as l, L as r, h as M, M as u, i as L, j as c, k as h, l as d, m as p, n as v, o as A, p as C, q as F, s as k, t as b, u as f, v as x, w as y, x as P, y as S, z as q, B as z, D as B } from "./index-D7eRkXoG.js";
|
|
2
2
|
export {
|
|
3
3
|
e as ActionButton,
|
|
4
4
|
t as Avatar,
|
package/package.json
CHANGED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { Meta, StoryFn } from '@storybook/react'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
import AttachmentCard, { AttachmentThumbnail } from '.'
|
|
5
|
+
|
|
6
|
+
type ComponentProps = React.ComponentProps<typeof AttachmentCard>
|
|
7
|
+
|
|
8
|
+
const meta: Meta<ComponentProps> = {
|
|
9
|
+
title: 'AttachmentCard',
|
|
10
|
+
component: AttachmentCard,
|
|
11
|
+
parameters: { layout: 'centered' },
|
|
12
|
+
argTypes: {
|
|
13
|
+
variant: { control: { type: 'inline-radio' }, options: ['light', 'dark'] },
|
|
14
|
+
},
|
|
15
|
+
}
|
|
16
|
+
export default meta
|
|
17
|
+
|
|
18
|
+
const IMAGE_URL = '/image-thumbnail.jpg'
|
|
19
|
+
|
|
20
|
+
const Template: StoryFn<ComponentProps> = (args) => <AttachmentCard {...args} />
|
|
21
|
+
|
|
22
|
+
export const LightImage: StoryFn<ComponentProps> = Template.bind({})
|
|
23
|
+
LightImage.args = {
|
|
24
|
+
variant: 'light',
|
|
25
|
+
title: 'sunset.jpg',
|
|
26
|
+
mimeType: 'image/jpeg',
|
|
27
|
+
detail: '2.4 MB',
|
|
28
|
+
thumbnail: (
|
|
29
|
+
<AttachmentThumbnail
|
|
30
|
+
mimeType="image/jpeg"
|
|
31
|
+
sourceUrl={IMAGE_URL}
|
|
32
|
+
title="sunset"
|
|
33
|
+
variant="light"
|
|
34
|
+
/>
|
|
35
|
+
),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const DarkImage: StoryFn<ComponentProps> = Template.bind({})
|
|
39
|
+
DarkImage.args = {
|
|
40
|
+
variant: 'dark',
|
|
41
|
+
title: 'sunset.jpg',
|
|
42
|
+
mimeType: 'image/jpeg',
|
|
43
|
+
detail: '2.4 MB',
|
|
44
|
+
thumbnail: (
|
|
45
|
+
<AttachmentThumbnail
|
|
46
|
+
mimeType="image/jpeg"
|
|
47
|
+
sourceUrl={IMAGE_URL}
|
|
48
|
+
title="sunset"
|
|
49
|
+
variant="dark"
|
|
50
|
+
/>
|
|
51
|
+
),
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const PdfPlaceholder: StoryFn<ComponentProps> = Template.bind({})
|
|
55
|
+
PdfPlaceholder.args = {
|
|
56
|
+
variant: 'light',
|
|
57
|
+
title: 'invoice.pdf',
|
|
58
|
+
mimeType: 'application/pdf',
|
|
59
|
+
detail: '120 KB',
|
|
60
|
+
thumbnail: <AttachmentThumbnail mimeType="application/pdf" variant="light" />,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const AudioPosterOnly: StoryFn<ComponentProps> = Template.bind({})
|
|
64
|
+
AudioPosterOnly.args = {
|
|
65
|
+
variant: 'dark',
|
|
66
|
+
title: 'voice-memo.m4a',
|
|
67
|
+
mimeType: 'audio/m4a',
|
|
68
|
+
detail: '0:42',
|
|
69
|
+
thumbnail: (
|
|
70
|
+
<AttachmentThumbnail
|
|
71
|
+
mimeType="audio/m4a"
|
|
72
|
+
thumbnailUrl={IMAGE_URL}
|
|
73
|
+
title="voice memo"
|
|
74
|
+
variant="dark"
|
|
75
|
+
/>
|
|
76
|
+
),
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const UntitledDark: StoryFn<ComponentProps> = Template.bind({})
|
|
80
|
+
UntitledDark.args = {
|
|
81
|
+
variant: 'dark',
|
|
82
|
+
mimeType: 'image/png',
|
|
83
|
+
detail: '1.1 MB',
|
|
84
|
+
thumbnail: <AttachmentThumbnail mimeType="image/png" variant="dark" />,
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export const WithTopBadges: StoryFn<ComponentProps> = Template.bind({})
|
|
88
|
+
WithTopBadges.args = {
|
|
89
|
+
variant: 'light',
|
|
90
|
+
title: 'receipt.pdf',
|
|
91
|
+
mimeType: 'application/pdf',
|
|
92
|
+
detail: 'Paid',
|
|
93
|
+
thumbnail: <AttachmentThumbnail mimeType="application/pdf" variant="light" />,
|
|
94
|
+
topLeft: (
|
|
95
|
+
<span className="rounded-full bg-black/80 px-2 py-0.5 text-xs font-medium text-white">
|
|
96
|
+
Locked
|
|
97
|
+
</span>
|
|
98
|
+
),
|
|
99
|
+
topRight: (
|
|
100
|
+
<span className="rounded-full bg-white/90 px-2 py-0.5 text-xs font-medium text-black">
|
|
101
|
+
$5.00
|
|
102
|
+
</span>
|
|
103
|
+
),
|
|
104
|
+
}
|
|
@@ -19,15 +19,19 @@ const { getBlockedUsersMock, blockUserMock, unBlockUserMock } = vi.hoisted(
|
|
|
19
19
|
})
|
|
20
20
|
)
|
|
21
21
|
|
|
22
|
+
// Stable service + context references — production MessagingProvider keeps
|
|
23
|
+
// the service in useState and memoizes the context value, so the hook's
|
|
24
|
+
// service-keyed lookup invalidation only fires on real swaps. Returning a
|
|
25
|
+
// new object literal each call would re-trigger the lookup every render and
|
|
26
|
+
// loop forever.
|
|
27
|
+
const mockService = {
|
|
28
|
+
getBlockedUsers: getBlockedUsersMock,
|
|
29
|
+
blockUser: blockUserMock,
|
|
30
|
+
unBlockUser: unBlockUserMock,
|
|
31
|
+
}
|
|
32
|
+
const mockContext = { service: mockService, debug: false }
|
|
22
33
|
vi.mock('../../providers/MessagingProvider', () => ({
|
|
23
|
-
useMessagingContext: () =>
|
|
24
|
-
service: {
|
|
25
|
-
getBlockedUsers: getBlockedUsersMock,
|
|
26
|
-
blockUser: blockUserMock,
|
|
27
|
-
unBlockUser: unBlockUserMock,
|
|
28
|
-
},
|
|
29
|
-
debug: false,
|
|
30
|
-
}),
|
|
34
|
+
useMessagingContext: () => mockContext,
|
|
31
35
|
}))
|
|
32
36
|
|
|
33
37
|
vi.mock('../ActionButton', () => ({
|
|
@@ -229,6 +233,27 @@ describe('ChannelActionsMenu', () => {
|
|
|
229
233
|
})
|
|
230
234
|
})
|
|
231
235
|
|
|
236
|
+
it('recovers from a blocked-status lookup failure', async () => {
|
|
237
|
+
// Suppress the expected console.error for the rejected lookup so the
|
|
238
|
+
// test output stays clean.
|
|
239
|
+
const consoleErrorSpy = vi
|
|
240
|
+
.spyOn(console, 'error')
|
|
241
|
+
.mockImplementation(() => {})
|
|
242
|
+
getBlockedUsersMock.mockRejectedValueOnce(new Error('network down'))
|
|
243
|
+
|
|
244
|
+
renderWithProviders(<ChannelActionsMenu {...defaultProps()} />)
|
|
245
|
+
await openMenu()
|
|
246
|
+
|
|
247
|
+
// The lookup rejected, but the action recovers — Block becomes actionable
|
|
248
|
+
// rather than staying stuck in the disabled spinner state.
|
|
249
|
+
await waitFor(() => {
|
|
250
|
+
const block = screen.getByText('Block').closest('button')
|
|
251
|
+
expect(block).not.toBeDisabled()
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
consoleErrorSpy.mockRestore()
|
|
255
|
+
})
|
|
256
|
+
|
|
232
257
|
it('calls onReportParticipantClick and opens the report page', async () => {
|
|
233
258
|
const onReportParticipantClick = vi.fn()
|
|
234
259
|
const windowOpenSpy = vi
|
|
@@ -7,6 +7,14 @@ import {
|
|
|
7
7
|
StreamChat,
|
|
8
8
|
} from 'stream-chat'
|
|
9
9
|
|
|
10
|
+
import {
|
|
11
|
+
daysAgo,
|
|
12
|
+
hoursAgo,
|
|
13
|
+
minutesAgo,
|
|
14
|
+
now,
|
|
15
|
+
secondsAgo,
|
|
16
|
+
} from '../../stories/decorators/storyTime'
|
|
17
|
+
|
|
10
18
|
import CustomChannelPreview from './CustomChannelPreview'
|
|
11
19
|
|
|
12
20
|
type ComponentProps = React.ComponentProps<typeof CustomChannelPreview>
|
|
@@ -54,7 +62,7 @@ const createMockChannel = (options: {
|
|
|
54
62
|
participantId,
|
|
55
63
|
participantImage,
|
|
56
64
|
lastMessageText = 'Hey! How are you doing?',
|
|
57
|
-
lastMessageTime =
|
|
65
|
+
lastMessageTime = now(),
|
|
58
66
|
unreadCount = 0,
|
|
59
67
|
lastMessageAttachments,
|
|
60
68
|
lastMessageMetadata,
|
|
@@ -134,7 +142,7 @@ Default.args = {
|
|
|
134
142
|
participantId: 'participant-1',
|
|
135
143
|
participantImage: 'https://i.pravatar.cc/150?img=2',
|
|
136
144
|
lastMessageText: 'Hey! How are you doing?',
|
|
137
|
-
lastMessageTime:
|
|
145
|
+
lastMessageTime: now(),
|
|
138
146
|
}),
|
|
139
147
|
}
|
|
140
148
|
|
|
@@ -146,7 +154,7 @@ Selected.args = {
|
|
|
146
154
|
participantId: 'participant-2',
|
|
147
155
|
participantImage: 'https://i.pravatar.cc/150?img=3',
|
|
148
156
|
lastMessageText: 'That sounds great!',
|
|
149
|
-
lastMessageTime:
|
|
157
|
+
lastMessageTime: minutesAgo(5),
|
|
150
158
|
}),
|
|
151
159
|
selectedChannel: createMockChannel({
|
|
152
160
|
id: 'channel-2',
|
|
@@ -164,7 +172,7 @@ WithUnreadMessages.args = {
|
|
|
164
172
|
participantId: 'participant-3',
|
|
165
173
|
participantImage: 'https://i.pravatar.cc/150?img=4',
|
|
166
174
|
lastMessageText: 'Did you see my last message?',
|
|
167
|
-
lastMessageTime:
|
|
175
|
+
lastMessageTime: minutesAgo(15),
|
|
168
176
|
unreadCount: 3,
|
|
169
177
|
}),
|
|
170
178
|
}
|
|
@@ -177,7 +185,7 @@ ManyUnreadMessages.args = {
|
|
|
177
185
|
participantId: 'participant-4',
|
|
178
186
|
participantImage: 'https://i.pravatar.cc/150?img=5',
|
|
179
187
|
lastMessageText: 'Please check this out!',
|
|
180
|
-
lastMessageTime:
|
|
188
|
+
lastMessageTime: hoursAgo(1),
|
|
181
189
|
unreadCount: 127,
|
|
182
190
|
}),
|
|
183
191
|
}
|
|
@@ -189,7 +197,7 @@ NoAvatar.args = {
|
|
|
189
197
|
participantName: 'Emma Davis',
|
|
190
198
|
participantId: 'participant-5',
|
|
191
199
|
lastMessageText: 'Thanks for your help!',
|
|
192
|
-
lastMessageTime:
|
|
200
|
+
lastMessageTime: minutesAgo(30),
|
|
193
201
|
}),
|
|
194
202
|
}
|
|
195
203
|
|
|
@@ -213,7 +221,7 @@ LongMessage.args = {
|
|
|
213
221
|
participantImage: 'https://i.pravatar.cc/150?img=7',
|
|
214
222
|
lastMessageText:
|
|
215
223
|
'This is a very long message that should be truncated because it contains way too much text to display in the preview. We want to make sure the component handles this gracefully.',
|
|
216
|
-
lastMessageTime:
|
|
224
|
+
lastMessageTime: hoursAgo(2),
|
|
217
225
|
}),
|
|
218
226
|
}
|
|
219
227
|
|
|
@@ -224,7 +232,7 @@ LongName.args = {
|
|
|
224
232
|
participantName: 'Alexander Christopher Wellington-Montgomery III',
|
|
225
233
|
participantId: 'participant-8',
|
|
226
234
|
lastMessageText: 'Nice to meet you!',
|
|
227
|
-
lastMessageTime:
|
|
235
|
+
lastMessageTime: minutesAgo(45),
|
|
228
236
|
}),
|
|
229
237
|
}
|
|
230
238
|
|
|
@@ -236,7 +244,7 @@ ChatbotMessage.args = {
|
|
|
236
244
|
participantId: 'participant-chatbot',
|
|
237
245
|
participantImage: 'https://i.pravatar.cc/150?img=9',
|
|
238
246
|
lastMessageText: 'Thanks for reaching out! How can I help you today?',
|
|
239
|
-
lastMessageTime:
|
|
247
|
+
lastMessageTime: minutesAgo(2),
|
|
240
248
|
lastMessageMetadata: { custom_type: 'MESSAGE_CHATBOT' },
|
|
241
249
|
}),
|
|
242
250
|
}
|
|
@@ -249,7 +257,7 @@ TipMessage.args = {
|
|
|
249
257
|
participantId: 'participant-tip',
|
|
250
258
|
participantImage: 'https://i.pravatar.cc/150?img=2',
|
|
251
259
|
lastMessageText: 'Take my money!',
|
|
252
|
-
lastMessageTime:
|
|
260
|
+
lastMessageTime: minutesAgo(3),
|
|
253
261
|
lastMessageMetadata: { custom_type: 'MESSAGE_TIP', amount_text: '$5.00' },
|
|
254
262
|
}),
|
|
255
263
|
}
|
|
@@ -262,7 +270,7 @@ PaidMessage.args = {
|
|
|
262
270
|
participantId: 'participant-paid',
|
|
263
271
|
participantImage: 'https://i.pravatar.cc/150?img=3',
|
|
264
272
|
lastMessageText: 'I paid for this message!',
|
|
265
|
-
lastMessageTime:
|
|
273
|
+
lastMessageTime: minutesAgo(10),
|
|
266
274
|
lastMessageMetadata: { custom_type: 'MESSAGE_PAID', amount_text: '$10.00' },
|
|
267
275
|
}),
|
|
268
276
|
}
|
|
@@ -275,7 +283,7 @@ PaidAttachment.args = {
|
|
|
275
283
|
participantId: 'participant-paid-attachment',
|
|
276
284
|
participantImage: 'https://i.pravatar.cc/150?img=4',
|
|
277
285
|
lastMessageText: 'Check out this exclusive photo!',
|
|
278
|
-
lastMessageTime:
|
|
286
|
+
lastMessageTime: minutesAgo(20),
|
|
279
287
|
lastMessageMetadata: {
|
|
280
288
|
custom_type: 'MESSAGE_ATTACHMENT',
|
|
281
289
|
attachment_title: 'exclusive-photo.jpg',
|
|
@@ -322,7 +330,7 @@ export const WithCustomMessagePreview: StoryFn = () => {
|
|
|
322
330
|
participantImage: 'https://i.pravatar.cc/150?img=36',
|
|
323
331
|
lastMessageText:
|
|
324
332
|
'Critical issue needs immediate attention! Please review the server logs for more details and escalate to the on-call engineer. This system outage is affecting multiple users, and we need to resolve it as soon as possible. Impacted services include messaging, notifications, and real-time updates. All hands are required to investigate and remediate the situation. If you have any questions or need additional resources, contact the incident commander immediately!',
|
|
325
|
-
lastMessageTime:
|
|
333
|
+
lastMessageTime: minutesAgo(1),
|
|
326
334
|
lastMessageMetadata: { custom_type: 'MESSAGE_URGENT' },
|
|
327
335
|
unreadCount: 3,
|
|
328
336
|
}),
|
|
@@ -332,7 +340,7 @@ export const WithCustomMessagePreview: StoryFn = () => {
|
|
|
332
340
|
participantId: 'participant-priority',
|
|
333
341
|
participantImage: 'https://i.pravatar.cc/150?img=37',
|
|
334
342
|
lastMessageText: 'High priority message',
|
|
335
|
-
lastMessageTime:
|
|
343
|
+
lastMessageTime: minutesAgo(5),
|
|
336
344
|
lastMessageMetadata: { is_priority: true },
|
|
337
345
|
unreadCount: 1,
|
|
338
346
|
}),
|
|
@@ -342,7 +350,7 @@ export const WithCustomMessagePreview: StoryFn = () => {
|
|
|
342
350
|
participantId: 'participant-vip',
|
|
343
351
|
participantImage: 'https://i.pravatar.cc/150?img=38',
|
|
344
352
|
lastMessageText: 'Thanks for the support!',
|
|
345
|
-
lastMessageTime:
|
|
353
|
+
lastMessageTime: minutesAgo(10),
|
|
346
354
|
lastMessageMetadata: { is_vip: true },
|
|
347
355
|
}),
|
|
348
356
|
createMockChannel({
|
|
@@ -351,7 +359,7 @@ export const WithCustomMessagePreview: StoryFn = () => {
|
|
|
351
359
|
participantId: 'participant-normal',
|
|
352
360
|
participantImage: 'https://i.pravatar.cc/150?img=39',
|
|
353
361
|
lastMessageText: 'Hey, how are you?',
|
|
354
|
-
lastMessageTime:
|
|
362
|
+
lastMessageTime: minutesAgo(30),
|
|
355
363
|
}),
|
|
356
364
|
]
|
|
357
365
|
|
|
@@ -379,7 +387,7 @@ SelectedWithUnread.args = {
|
|
|
379
387
|
participantId: 'participant-9',
|
|
380
388
|
participantImage: 'https://i.pravatar.cc/150?img=8',
|
|
381
389
|
lastMessageText: 'Important update!',
|
|
382
|
-
lastMessageTime:
|
|
390
|
+
lastMessageTime: minutesAgo(10),
|
|
383
391
|
unreadCount: 5,
|
|
384
392
|
}),
|
|
385
393
|
selectedChannel: createMockChannel({
|
|
@@ -401,7 +409,7 @@ export const MultipleChannels: StoryFn = () => {
|
|
|
401
409
|
participantId: 'participant-1',
|
|
402
410
|
participantImage: 'https://i.pravatar.cc/150?img=2',
|
|
403
411
|
lastMessageText: 'Hey! How are you doing?',
|
|
404
|
-
lastMessageTime:
|
|
412
|
+
lastMessageTime: now(),
|
|
405
413
|
unreadCount: 2,
|
|
406
414
|
}),
|
|
407
415
|
createMockChannel({
|
|
@@ -410,7 +418,7 @@ export const MultipleChannels: StoryFn = () => {
|
|
|
410
418
|
participantId: 'participant-2',
|
|
411
419
|
participantImage: 'https://i.pravatar.cc/150?img=3',
|
|
412
420
|
lastMessageText: 'That sounds great!',
|
|
413
|
-
lastMessageTime:
|
|
421
|
+
lastMessageTime: minutesAgo(5),
|
|
414
422
|
}),
|
|
415
423
|
createMockChannel({
|
|
416
424
|
id: 'channel-3',
|
|
@@ -418,7 +426,7 @@ export const MultipleChannels: StoryFn = () => {
|
|
|
418
426
|
participantId: 'participant-3',
|
|
419
427
|
participantImage: 'https://i.pravatar.cc/150?img=4',
|
|
420
428
|
lastMessageText: 'See you tomorrow',
|
|
421
|
-
lastMessageTime:
|
|
429
|
+
lastMessageTime: hoursAgo(1),
|
|
422
430
|
unreadCount: 15,
|
|
423
431
|
}),
|
|
424
432
|
createMockChannel({
|
|
@@ -426,7 +434,7 @@ export const MultipleChannels: StoryFn = () => {
|
|
|
426
434
|
participantName: 'David Brown',
|
|
427
435
|
participantId: 'participant-4',
|
|
428
436
|
lastMessageText: 'Thanks!',
|
|
429
|
-
lastMessageTime:
|
|
437
|
+
lastMessageTime: hoursAgo(2),
|
|
430
438
|
}),
|
|
431
439
|
]
|
|
432
440
|
|
|
@@ -457,7 +465,7 @@ WithUrl.args = {
|
|
|
457
465
|
participantId: 'participant-url',
|
|
458
466
|
participantImage: 'https://i.pravatar.cc/150?img=10',
|
|
459
467
|
lastMessageText: 'https://example.com/page',
|
|
460
|
-
lastMessageTime:
|
|
468
|
+
lastMessageTime: minutesAgo(8),
|
|
461
469
|
}),
|
|
462
470
|
}
|
|
463
471
|
|
|
@@ -470,7 +478,7 @@ WithVeryLongUrl.args = {
|
|
|
470
478
|
participantImage: 'https://i.pravatar.cc/150?img=11',
|
|
471
479
|
lastMessageText:
|
|
472
480
|
'https://example.com/very/long/path/with/many/segments/and/query/parameters?param1=value1¶m2=value2¶m3=value3¶m4=value4¶m5=very-long-value-that-makes-the-url-extremely-long',
|
|
473
|
-
lastMessageTime:
|
|
481
|
+
lastMessageTime: minutesAgo(20),
|
|
474
482
|
}),
|
|
475
483
|
}
|
|
476
484
|
|
|
@@ -483,7 +491,7 @@ JustNow.args = {
|
|
|
483
491
|
participantId: 'participant-just-now',
|
|
484
492
|
participantImage: 'https://i.pravatar.cc/150?img=12',
|
|
485
493
|
lastMessageText: 'I just sent this!',
|
|
486
|
-
lastMessageTime:
|
|
494
|
+
lastMessageTime: secondsAgo(30),
|
|
487
495
|
}),
|
|
488
496
|
}
|
|
489
497
|
|
|
@@ -495,7 +503,7 @@ FiveMinutesAgo.args = {
|
|
|
495
503
|
participantId: 'participant-5m',
|
|
496
504
|
participantImage: 'https://i.pravatar.cc/150?img=13',
|
|
497
505
|
lastMessageText: 'Be right back',
|
|
498
|
-
lastMessageTime:
|
|
506
|
+
lastMessageTime: minutesAgo(5),
|
|
499
507
|
}),
|
|
500
508
|
}
|
|
501
509
|
|
|
@@ -507,7 +515,7 @@ ThreeHoursAgo.args = {
|
|
|
507
515
|
participantId: 'participant-3h',
|
|
508
516
|
participantImage: 'https://i.pravatar.cc/150?img=14',
|
|
509
517
|
lastMessageText: 'Got it, thanks!',
|
|
510
|
-
lastMessageTime:
|
|
518
|
+
lastMessageTime: hoursAgo(3),
|
|
511
519
|
}),
|
|
512
520
|
}
|
|
513
521
|
|
|
@@ -519,7 +527,7 @@ Yesterday.args = {
|
|
|
519
527
|
participantId: 'participant-yesterday',
|
|
520
528
|
participantImage: 'https://i.pravatar.cc/150?img=15',
|
|
521
529
|
lastMessageText: 'See you tomorrow',
|
|
522
|
-
lastMessageTime:
|
|
530
|
+
lastMessageTime: hoursAgo(30),
|
|
523
531
|
}),
|
|
524
532
|
}
|
|
525
533
|
|
|
@@ -531,7 +539,7 @@ ThreeDaysAgo.args = {
|
|
|
531
539
|
participantId: 'participant-3d',
|
|
532
540
|
participantImage: 'https://i.pravatar.cc/150?img=16',
|
|
533
541
|
lastMessageText: 'Have a great weekend!',
|
|
534
|
-
lastMessageTime:
|
|
542
|
+
lastMessageTime: daysAgo(3),
|
|
535
543
|
}),
|
|
536
544
|
}
|
|
537
545
|
|
|
@@ -543,7 +551,7 @@ LastWeek.args = {
|
|
|
543
551
|
participantId: 'participant-1w',
|
|
544
552
|
participantImage: 'https://i.pravatar.cc/150?img=17',
|
|
545
553
|
lastMessageText: 'Talk to you next week',
|
|
546
|
-
lastMessageTime:
|
|
554
|
+
lastMessageTime: daysAgo(7),
|
|
547
555
|
}),
|
|
548
556
|
}
|
|
549
557
|
|
|
@@ -555,7 +563,7 @@ TwoWeeksAgo.args = {
|
|
|
555
563
|
participantId: 'participant-2w',
|
|
556
564
|
participantImage: 'https://i.pravatar.cc/150?img=18',
|
|
557
565
|
lastMessageText: 'Sounds good',
|
|
558
|
-
lastMessageTime:
|
|
566
|
+
lastMessageTime: daysAgo(14),
|
|
559
567
|
}),
|
|
560
568
|
}
|
|
561
569
|
|
|
@@ -567,7 +575,7 @@ OneMonthAgo.args = {
|
|
|
567
575
|
participantId: 'participant-1m',
|
|
568
576
|
participantImage: 'https://i.pravatar.cc/150?img=19',
|
|
569
577
|
lastMessageText: 'Happy New Year!',
|
|
570
|
-
lastMessageTime:
|
|
578
|
+
lastMessageTime: daysAgo(30),
|
|
571
579
|
}),
|
|
572
580
|
}
|
|
573
581
|
|
|
@@ -579,7 +587,7 @@ SixMonthsAgo.args = {
|
|
|
579
587
|
participantId: 'participant-6m',
|
|
580
588
|
participantImage: 'https://i.pravatar.cc/150?img=20',
|
|
581
589
|
lastMessageText: 'Long time no talk!',
|
|
582
|
-
lastMessageTime:
|
|
590
|
+
lastMessageTime: daysAgo(180),
|
|
583
591
|
}),
|
|
584
592
|
}
|
|
585
593
|
|
|
@@ -592,61 +600,61 @@ export const TimeVariations: StoryFn = () => {
|
|
|
592
600
|
{
|
|
593
601
|
id: 'time-just-now',
|
|
594
602
|
name: 'Just Now',
|
|
595
|
-
time:
|
|
603
|
+
time: secondsAgo(30),
|
|
596
604
|
message: 'Just sent',
|
|
597
605
|
},
|
|
598
606
|
{
|
|
599
607
|
id: 'time-5m',
|
|
600
608
|
name: '5 Minutes',
|
|
601
|
-
time:
|
|
609
|
+
time: minutesAgo(5),
|
|
602
610
|
message: '5 minutes ago',
|
|
603
611
|
},
|
|
604
612
|
{
|
|
605
613
|
id: 'time-30m',
|
|
606
614
|
name: '30 Minutes',
|
|
607
|
-
time:
|
|
615
|
+
time: minutesAgo(30),
|
|
608
616
|
message: '30 minutes ago',
|
|
609
617
|
},
|
|
610
618
|
{
|
|
611
619
|
id: 'time-3h',
|
|
612
620
|
name: '3 Hours',
|
|
613
|
-
time:
|
|
621
|
+
time: hoursAgo(3),
|
|
614
622
|
message: '3 hours ago',
|
|
615
623
|
},
|
|
616
624
|
{
|
|
617
625
|
id: 'time-yesterday',
|
|
618
626
|
name: 'Yesterday',
|
|
619
|
-
time:
|
|
627
|
+
time: hoursAgo(30),
|
|
620
628
|
message: 'Yesterday',
|
|
621
629
|
},
|
|
622
630
|
{
|
|
623
631
|
id: 'time-3d',
|
|
624
632
|
name: '3 Days',
|
|
625
|
-
time:
|
|
633
|
+
time: daysAgo(3),
|
|
626
634
|
message: '3 days ago',
|
|
627
635
|
},
|
|
628
636
|
{
|
|
629
637
|
id: 'time-1w',
|
|
630
638
|
name: '1 Week',
|
|
631
|
-
time:
|
|
639
|
+
time: daysAgo(7),
|
|
632
640
|
message: '1 week ago',
|
|
633
641
|
},
|
|
634
642
|
{
|
|
635
643
|
id: 'time-2w',
|
|
636
644
|
name: '2 Weeks',
|
|
637
|
-
time:
|
|
645
|
+
time: daysAgo(14),
|
|
638
646
|
message: '2 weeks ago',
|
|
639
647
|
},
|
|
640
648
|
{
|
|
641
649
|
id: 'time-1m',
|
|
642
650
|
name: '1 Month',
|
|
643
|
-
time:
|
|
651
|
+
time: daysAgo(30),
|
|
644
652
|
message: '1 month ago',
|
|
645
653
|
},
|
|
646
654
|
{
|
|
647
655
|
id: 'time-6m',
|
|
648
656
|
name: '6 Months',
|
|
649
|
-
time:
|
|
657
|
+
time: daysAgo(180),
|
|
650
658
|
message: '6 months ago',
|
|
651
659
|
},
|
|
652
660
|
]
|
|
@@ -690,7 +698,7 @@ WithAttachmentAssetUrl.args = {
|
|
|
690
698
|
participantId: 'participant-attachment-asset',
|
|
691
699
|
participantImage: 'https://i.pravatar.cc/150?img=30',
|
|
692
700
|
lastMessageText: '', // No text, only attachment
|
|
693
|
-
lastMessageTime:
|
|
701
|
+
lastMessageTime: minutesAgo(10),
|
|
694
702
|
lastMessageAttachments: [
|
|
695
703
|
{
|
|
696
704
|
asset_url: 'https://example.com/document.pdf',
|
|
@@ -707,7 +715,7 @@ WithAttachmentImageUrl.args = {
|
|
|
707
715
|
participantId: 'participant-attachment-image',
|
|
708
716
|
participantImage: 'https://i.pravatar.cc/150?img=31',
|
|
709
717
|
lastMessageText: '', // No text, only attachment
|
|
710
|
-
lastMessageTime:
|
|
718
|
+
lastMessageTime: minutesAgo(15),
|
|
711
719
|
lastMessageAttachments: [
|
|
712
720
|
{
|
|
713
721
|
image_url: 'https://example.com/image.jpg',
|
|
@@ -726,7 +734,7 @@ WithAttachmentOgScrapeUrl.args = {
|
|
|
726
734
|
participantId: 'participant-attachment-og',
|
|
727
735
|
participantImage: 'https://i.pravatar.cc/150?img=32',
|
|
728
736
|
lastMessageText: '', // No text, only attachment
|
|
729
|
-
lastMessageTime:
|
|
737
|
+
lastMessageTime: minutesAgo(7),
|
|
730
738
|
lastMessageAttachments: [
|
|
731
739
|
{
|
|
732
740
|
og_scrape_url: 'https://example.com/article',
|
|
@@ -743,7 +751,7 @@ WithAttachmentThumbUrl.args = {
|
|
|
743
751
|
participantId: 'participant-attachment-thumb',
|
|
744
752
|
participantImage: 'https://i.pravatar.cc/150?img=33',
|
|
745
753
|
lastMessageText: '', // No text, only attachment
|
|
746
|
-
lastMessageTime:
|
|
754
|
+
lastMessageTime: minutesAgo(12),
|
|
747
755
|
lastMessageAttachments: [
|
|
748
756
|
{
|
|
749
757
|
thumb_url: 'https://example.com/thumb.jpg',
|
|
@@ -760,7 +768,7 @@ WithLongAttachmentUrl.args = {
|
|
|
760
768
|
participantId: 'participant-attachment-long',
|
|
761
769
|
participantImage: 'https://i.pravatar.cc/150?img=34',
|
|
762
770
|
lastMessageText: '', // No text, only attachment
|
|
763
|
-
lastMessageTime:
|
|
771
|
+
lastMessageTime: minutesAgo(20),
|
|
764
772
|
lastMessageAttachments: [
|
|
765
773
|
{
|
|
766
774
|
asset_url:
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from 'stream-chat'
|
|
10
10
|
import { Chat } from 'stream-chat-react'
|
|
11
11
|
|
|
12
|
+
import { hoursAgo, minutesAgo, now } from '../stories/decorators/storyTime'
|
|
12
13
|
import { mockParticipants } from '../stories/mocks'
|
|
13
14
|
|
|
14
15
|
import { ChannelView } from './ChannelView'
|
|
@@ -50,8 +51,8 @@ const createMockChannel = async (
|
|
|
50
51
|
id: 'msg-1',
|
|
51
52
|
text: 'Hey! How are you doing?',
|
|
52
53
|
type: 'regular' as const,
|
|
53
|
-
created_at:
|
|
54
|
-
updated_at:
|
|
54
|
+
created_at: hoursAgo(1),
|
|
55
|
+
updated_at: hoursAgo(1),
|
|
55
56
|
user: participant,
|
|
56
57
|
html: '<p>Hey! How are you doing?</p>',
|
|
57
58
|
attachments: [],
|
|
@@ -68,8 +69,8 @@ const createMockChannel = async (
|
|
|
68
69
|
id: 'msg-2',
|
|
69
70
|
text: "I'm doing great, thanks! How about you?",
|
|
70
71
|
type: 'regular' as const,
|
|
71
|
-
created_at:
|
|
72
|
-
updated_at:
|
|
72
|
+
created_at: minutesAgo(50),
|
|
73
|
+
updated_at: minutesAgo(50),
|
|
73
74
|
user: mockUser,
|
|
74
75
|
html: "<p>I'm doing great, thanks! How about you?</p>",
|
|
75
76
|
attachments: [],
|
|
@@ -86,8 +87,8 @@ const createMockChannel = async (
|
|
|
86
87
|
id: 'msg-3',
|
|
87
88
|
text: 'Pretty good! Just working on some exciting stuff.',
|
|
88
89
|
type: 'regular' as const,
|
|
89
|
-
created_at:
|
|
90
|
-
updated_at:
|
|
90
|
+
created_at: minutesAgo(30),
|
|
91
|
+
updated_at: minutesAgo(30),
|
|
91
92
|
user: participant,
|
|
92
93
|
html: '<p>Pretty good! Just working on some exciting stuff.</p>',
|
|
93
94
|
attachments: [],
|
|
@@ -429,7 +430,7 @@ const WithStarButtonTemplate: StoryFn<ComponentProps> = (args) => {
|
|
|
429
430
|
const member: ChannelMemberResponse = {
|
|
430
431
|
user: mockUser,
|
|
431
432
|
user_id: mockUser.id,
|
|
432
|
-
pinned_at: isStarred ?
|
|
433
|
+
pinned_at: isStarred ? now().toISOString() : null,
|
|
433
434
|
}
|
|
434
435
|
|
|
435
436
|
client.dispatchEvent({
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Meta, StoryFn } from '@storybook/react'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
import { CloseButton } from '.'
|
|
5
|
+
|
|
6
|
+
type ComponentProps = React.ComponentProps<typeof CloseButton>
|
|
7
|
+
|
|
8
|
+
const meta: Meta<ComponentProps> = {
|
|
9
|
+
title: 'CloseButton',
|
|
10
|
+
component: CloseButton,
|
|
11
|
+
parameters: { layout: 'centered' },
|
|
12
|
+
argTypes: {
|
|
13
|
+
onClick: { action: 'clicked' },
|
|
14
|
+
},
|
|
15
|
+
}
|
|
16
|
+
export default meta
|
|
17
|
+
|
|
18
|
+
const Template: StoryFn<ComponentProps> = (args) => (
|
|
19
|
+
<div className="p-12">
|
|
20
|
+
<CloseButton {...args} />
|
|
21
|
+
</div>
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
export const Default: StoryFn<ComponentProps> = Template.bind({})
|
|
25
|
+
Default.args = {}
|
|
26
|
+
|
|
27
|
+
export const OnDarkSurface: StoryFn<ComponentProps> = () => (
|
|
28
|
+
<div className="bg-[#121110] p-12">
|
|
29
|
+
<CloseButton onClick={() => undefined} />
|
|
30
|
+
</div>
|
|
31
|
+
)
|