@linktr.ee/messaging-react 1.8.4 → 1.8.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/package.json
CHANGED
|
@@ -13,6 +13,9 @@ const meta: Meta<ComponentProps> = {
|
|
|
13
13
|
layout: 'centered',
|
|
14
14
|
},
|
|
15
15
|
decorators: [(Story) => <Story />],
|
|
16
|
+
args: {
|
|
17
|
+
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
18
|
+
},
|
|
16
19
|
}
|
|
17
20
|
export default meta
|
|
18
21
|
|
|
@@ -32,6 +35,12 @@ const createMockChannel = (options: {
|
|
|
32
35
|
lastMessageText?: string
|
|
33
36
|
lastMessageTime?: Date
|
|
34
37
|
unreadCount?: number
|
|
38
|
+
lastMessageAttachments?: Array<{
|
|
39
|
+
asset_url?: string
|
|
40
|
+
image_url?: string
|
|
41
|
+
og_scrape_url?: string
|
|
42
|
+
thumb_url?: string
|
|
43
|
+
}>
|
|
35
44
|
}): Channel => {
|
|
36
45
|
const {
|
|
37
46
|
id,
|
|
@@ -41,6 +50,7 @@ const createMockChannel = (options: {
|
|
|
41
50
|
lastMessageText = 'Hey! How are you doing?',
|
|
42
51
|
lastMessageTime = new Date(),
|
|
43
52
|
unreadCount = 0,
|
|
53
|
+
lastMessageAttachments,
|
|
44
54
|
} = options
|
|
45
55
|
|
|
46
56
|
return {
|
|
@@ -64,19 +74,21 @@ const createMockChannel = (options: {
|
|
|
64
74
|
user_id: participantId,
|
|
65
75
|
},
|
|
66
76
|
},
|
|
67
|
-
messages:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
messages:
|
|
78
|
+
lastMessageText || lastMessageAttachments
|
|
79
|
+
? ([
|
|
80
|
+
{
|
|
81
|
+
id: `msg-${id}-1`,
|
|
82
|
+
text: lastMessageText,
|
|
83
|
+
created_at: lastMessageTime.toISOString(),
|
|
84
|
+
user: {
|
|
85
|
+
id: participantId,
|
|
86
|
+
name: participantName,
|
|
87
|
+
},
|
|
88
|
+
attachments: lastMessageAttachments,
|
|
76
89
|
},
|
|
77
|
-
|
|
78
|
-
] as
|
|
79
|
-
: ([] as LocalMessage[]),
|
|
90
|
+
] as unknown as LocalMessage[])
|
|
91
|
+
: ([] as LocalMessage[]),
|
|
80
92
|
unreadCount,
|
|
81
93
|
},
|
|
82
94
|
} as unknown as Channel
|
|
@@ -100,7 +112,6 @@ Default.args = {
|
|
|
100
112
|
lastMessageText: 'Hey! How are you doing?',
|
|
101
113
|
lastMessageTime: new Date(),
|
|
102
114
|
}),
|
|
103
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
104
115
|
}
|
|
105
116
|
|
|
106
117
|
export const Selected: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -119,7 +130,6 @@ Selected.args = {
|
|
|
119
130
|
participantId: 'participant-2',
|
|
120
131
|
participantImage: 'https://i.pravatar.cc/150?img=3',
|
|
121
132
|
}),
|
|
122
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
123
133
|
}
|
|
124
134
|
|
|
125
135
|
export const WithUnreadMessages: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -133,7 +143,6 @@ WithUnreadMessages.args = {
|
|
|
133
143
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 15), // 15 minutes ago
|
|
134
144
|
unreadCount: 3,
|
|
135
145
|
}),
|
|
136
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
137
146
|
}
|
|
138
147
|
|
|
139
148
|
export const ManyUnreadMessages: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -147,7 +156,6 @@ ManyUnreadMessages.args = {
|
|
|
147
156
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 60), // 1 hour ago
|
|
148
157
|
unreadCount: 127,
|
|
149
158
|
}),
|
|
150
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
151
159
|
}
|
|
152
160
|
|
|
153
161
|
export const NoAvatar: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -159,7 +167,6 @@ NoAvatar.args = {
|
|
|
159
167
|
lastMessageText: 'Thanks for your help!',
|
|
160
168
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 30), // 30 minutes ago
|
|
161
169
|
}),
|
|
162
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
163
170
|
}
|
|
164
171
|
|
|
165
172
|
export const NoMessages: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -171,7 +178,6 @@ NoMessages.args = {
|
|
|
171
178
|
participantImage: 'https://i.pravatar.cc/150?img=6',
|
|
172
179
|
lastMessageText: '',
|
|
173
180
|
}),
|
|
174
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
175
181
|
}
|
|
176
182
|
|
|
177
183
|
export const LongMessage: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -185,7 +191,6 @@ LongMessage.args = {
|
|
|
185
191
|
'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.',
|
|
186
192
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 60 * 2), // 2 hours ago
|
|
187
193
|
}),
|
|
188
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
189
194
|
}
|
|
190
195
|
|
|
191
196
|
export const LongName: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -197,7 +202,6 @@ LongName.args = {
|
|
|
197
202
|
lastMessageText: 'Nice to meet you!',
|
|
198
203
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 45), // 45 minutes ago
|
|
199
204
|
}),
|
|
200
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
201
205
|
}
|
|
202
206
|
|
|
203
207
|
export const SelectedWithUnread: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -216,7 +220,6 @@ SelectedWithUnread.args = {
|
|
|
216
220
|
participantName: 'Helen Park',
|
|
217
221
|
participantId: 'participant-9',
|
|
218
222
|
}),
|
|
219
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
220
223
|
}
|
|
221
224
|
|
|
222
225
|
export const MultipleChannels: StoryFn = () => {
|
|
@@ -289,7 +292,6 @@ WithUrl.args = {
|
|
|
289
292
|
lastMessageText: 'https://example.com/page',
|
|
290
293
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 8), // 8 minutes ago
|
|
291
294
|
}),
|
|
292
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
293
295
|
}
|
|
294
296
|
|
|
295
297
|
export const WithVeryLongUrl: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -303,7 +305,6 @@ WithVeryLongUrl.args = {
|
|
|
303
305
|
'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',
|
|
304
306
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 20), // 20 minutes ago
|
|
305
307
|
}),
|
|
306
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
307
308
|
}
|
|
308
309
|
|
|
309
310
|
// Time-based stories
|
|
@@ -317,7 +318,6 @@ JustNow.args = {
|
|
|
317
318
|
lastMessageText: 'I just sent this!',
|
|
318
319
|
lastMessageTime: new Date(Date.now() - 1000 * 30), // 30 seconds ago
|
|
319
320
|
}),
|
|
320
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
321
321
|
}
|
|
322
322
|
|
|
323
323
|
export const FiveMinutesAgo: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -330,7 +330,6 @@ FiveMinutesAgo.args = {
|
|
|
330
330
|
lastMessageText: 'Be right back',
|
|
331
331
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 5), // 5 minutes ago
|
|
332
332
|
}),
|
|
333
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
334
333
|
}
|
|
335
334
|
|
|
336
335
|
export const ThreeHoursAgo: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -343,7 +342,6 @@ ThreeHoursAgo.args = {
|
|
|
343
342
|
lastMessageText: 'Got it, thanks!',
|
|
344
343
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 60 * 3), // 3 hours ago
|
|
345
344
|
}),
|
|
346
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
347
345
|
}
|
|
348
346
|
|
|
349
347
|
export const Yesterday: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -356,7 +354,6 @@ Yesterday.args = {
|
|
|
356
354
|
lastMessageText: 'See you tomorrow',
|
|
357
355
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 60 * 30), // 30 hours ago
|
|
358
356
|
}),
|
|
359
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
360
357
|
}
|
|
361
358
|
|
|
362
359
|
export const ThreeDaysAgo: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -369,7 +366,6 @@ ThreeDaysAgo.args = {
|
|
|
369
366
|
lastMessageText: 'Have a great weekend!',
|
|
370
367
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 60 * 24 * 3), // 3 days ago
|
|
371
368
|
}),
|
|
372
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
373
369
|
}
|
|
374
370
|
|
|
375
371
|
export const LastWeek: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -382,7 +378,6 @@ LastWeek.args = {
|
|
|
382
378
|
lastMessageText: 'Talk to you next week',
|
|
383
379
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 60 * 24 * 7), // 1 week ago
|
|
384
380
|
}),
|
|
385
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
386
381
|
}
|
|
387
382
|
|
|
388
383
|
export const TwoWeeksAgo: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -395,7 +390,6 @@ TwoWeeksAgo.args = {
|
|
|
395
390
|
lastMessageText: 'Sounds good',
|
|
396
391
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 60 * 24 * 14), // 2 weeks ago
|
|
397
392
|
}),
|
|
398
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
399
393
|
}
|
|
400
394
|
|
|
401
395
|
export const OneMonthAgo: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -408,7 +402,6 @@ OneMonthAgo.args = {
|
|
|
408
402
|
lastMessageText: 'Happy New Year!',
|
|
409
403
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30), // 1 month ago
|
|
410
404
|
}),
|
|
411
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
412
405
|
}
|
|
413
406
|
|
|
414
407
|
export const SixMonthsAgo: StoryFn<ComponentProps> = Template.bind({})
|
|
@@ -421,7 +414,6 @@ SixMonthsAgo.args = {
|
|
|
421
414
|
lastMessageText: 'Long time no talk!',
|
|
422
415
|
lastMessageTime: new Date(Date.now() - 1000 * 60 * 60 * 24 * 180), // 6 months ago
|
|
423
416
|
}),
|
|
424
|
-
onChannelSelect: (channel) => console.log('Channel selected:', channel.id),
|
|
425
417
|
}
|
|
426
418
|
|
|
427
419
|
export const TimeVariations: StoryFn = () => {
|
|
@@ -521,3 +513,92 @@ export const TimeVariations: StoryFn = () => {
|
|
|
521
513
|
</div>
|
|
522
514
|
)
|
|
523
515
|
}
|
|
516
|
+
|
|
517
|
+
// Message text fallback stories
|
|
518
|
+
export const WithAttachmentAssetUrl: StoryFn<ComponentProps> = Template.bind({})
|
|
519
|
+
WithAttachmentAssetUrl.args = {
|
|
520
|
+
channel: createMockChannel({
|
|
521
|
+
id: 'channel-attachment-asset',
|
|
522
|
+
participantName: 'Tom Wilson',
|
|
523
|
+
participantId: 'participant-attachment-asset',
|
|
524
|
+
participantImage: 'https://i.pravatar.cc/150?img=30',
|
|
525
|
+
lastMessageText: '', // No text, only attachment
|
|
526
|
+
lastMessageTime: new Date(Date.now() - 1000 * 60 * 10), // 10 minutes ago
|
|
527
|
+
lastMessageAttachments: [
|
|
528
|
+
{
|
|
529
|
+
asset_url: 'https://example.com/document.pdf',
|
|
530
|
+
},
|
|
531
|
+
],
|
|
532
|
+
}),
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
export const WithAttachmentImageUrl: StoryFn<ComponentProps> = Template.bind({})
|
|
536
|
+
WithAttachmentImageUrl.args = {
|
|
537
|
+
channel: createMockChannel({
|
|
538
|
+
id: 'channel-attachment-image',
|
|
539
|
+
participantName: 'Uma Patel',
|
|
540
|
+
participantId: 'participant-attachment-image',
|
|
541
|
+
participantImage: 'https://i.pravatar.cc/150?img=31',
|
|
542
|
+
lastMessageText: '', // No text, only attachment
|
|
543
|
+
lastMessageTime: new Date(Date.now() - 1000 * 60 * 15), // 15 minutes ago
|
|
544
|
+
lastMessageAttachments: [
|
|
545
|
+
{
|
|
546
|
+
image_url: 'https://example.com/image.jpg',
|
|
547
|
+
},
|
|
548
|
+
],
|
|
549
|
+
}),
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
export const WithAttachmentOgScrapeUrl: StoryFn<ComponentProps> = Template.bind(
|
|
553
|
+
{}
|
|
554
|
+
)
|
|
555
|
+
WithAttachmentOgScrapeUrl.args = {
|
|
556
|
+
channel: createMockChannel({
|
|
557
|
+
id: 'channel-attachment-og',
|
|
558
|
+
participantName: 'Victor Zhang',
|
|
559
|
+
participantId: 'participant-attachment-og',
|
|
560
|
+
participantImage: 'https://i.pravatar.cc/150?img=32',
|
|
561
|
+
lastMessageText: '', // No text, only attachment
|
|
562
|
+
lastMessageTime: new Date(Date.now() - 1000 * 60 * 7), // 7 minutes ago
|
|
563
|
+
lastMessageAttachments: [
|
|
564
|
+
{
|
|
565
|
+
og_scrape_url: 'https://example.com/article',
|
|
566
|
+
},
|
|
567
|
+
],
|
|
568
|
+
}),
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
export const WithAttachmentThumbUrl: StoryFn<ComponentProps> = Template.bind({})
|
|
572
|
+
WithAttachmentThumbUrl.args = {
|
|
573
|
+
channel: createMockChannel({
|
|
574
|
+
id: 'channel-attachment-thumb',
|
|
575
|
+
participantName: 'Wendy Kim',
|
|
576
|
+
participantId: 'participant-attachment-thumb',
|
|
577
|
+
participantImage: 'https://i.pravatar.cc/150?img=33',
|
|
578
|
+
lastMessageText: '', // No text, only attachment
|
|
579
|
+
lastMessageTime: new Date(Date.now() - 1000 * 60 * 12), // 12 minutes ago
|
|
580
|
+
lastMessageAttachments: [
|
|
581
|
+
{
|
|
582
|
+
thumb_url: 'https://example.com/thumb.jpg',
|
|
583
|
+
},
|
|
584
|
+
],
|
|
585
|
+
}),
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
export const WithLongAttachmentUrl: StoryFn<ComponentProps> = Template.bind({})
|
|
589
|
+
WithLongAttachmentUrl.args = {
|
|
590
|
+
channel: createMockChannel({
|
|
591
|
+
id: 'channel-attachment-long',
|
|
592
|
+
participantName: 'Xavier Cruz',
|
|
593
|
+
participantId: 'participant-attachment-long',
|
|
594
|
+
participantImage: 'https://i.pravatar.cc/150?img=34',
|
|
595
|
+
lastMessageText: '', // No text, only attachment
|
|
596
|
+
lastMessageTime: new Date(Date.now() - 1000 * 60 * 20), // 20 minutes ago
|
|
597
|
+
lastMessageAttachments: [
|
|
598
|
+
{
|
|
599
|
+
asset_url:
|
|
600
|
+
'https://example.com/very/long/path/to/file/with/many/segments/document-with-very-long-name-that-should-be-truncated.pdf',
|
|
601
|
+
},
|
|
602
|
+
],
|
|
603
|
+
}),
|
|
604
|
+
}
|
|
@@ -35,7 +35,21 @@ const CustomChannelPreview: React.FC<
|
|
|
35
35
|
// Get last message and format timestamp
|
|
36
36
|
const lastMessage =
|
|
37
37
|
channel?.state?.messages?.[channel.state.messages.length - 1]
|
|
38
|
-
|
|
38
|
+
|
|
39
|
+
// Fallback order: text -> attachment URL -> "No messages yet"
|
|
40
|
+
const getLastMessageText = () => {
|
|
41
|
+
if (lastMessage?.text) return lastMessage.text
|
|
42
|
+
|
|
43
|
+
const attachment = lastMessage?.attachments?.[0]
|
|
44
|
+
if (attachment?.asset_url) return attachment.asset_url
|
|
45
|
+
if (attachment?.image_url) return attachment.image_url
|
|
46
|
+
if (attachment?.og_scrape_url) return attachment.og_scrape_url
|
|
47
|
+
if (attachment?.thumb_url) return attachment.thumb_url
|
|
48
|
+
|
|
49
|
+
return 'No messages yet'
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const lastMessageText = getLastMessageText()
|
|
39
53
|
const lastMessageTime = lastMessage?.created_at
|
|
40
54
|
? formatRelativeTime(new Date(lastMessage.created_at))
|
|
41
55
|
: ''
|