@linktr.ee/messaging-react 3.10.0-rc-1783660962 → 3.10.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-B-L2MST4.js +107 -0
- package/dist/Card-B-L2MST4.js.map +1 -0
- package/dist/Card-B56QxJW3.cjs +2 -0
- package/dist/Card-B56QxJW3.cjs.map +1 -0
- package/dist/Card-Bqh-BQaX.js +132 -0
- package/dist/Card-Bqh-BQaX.js.map +1 -0
- package/dist/Card-ZCE6Lhfc.cjs +2 -0
- package/dist/Card-ZCE6Lhfc.cjs.map +1 -0
- package/dist/Card-g4JD-2ES.js +163 -0
- package/dist/Card-g4JD-2ES.js.map +1 -0
- package/dist/Card-wac6AMNc.cjs +2 -0
- package/dist/Card-wac6AMNc.cjs.map +1 -0
- package/dist/LockedThumbnail-BAQmoIff.js +220 -0
- package/dist/LockedThumbnail-BAQmoIff.js.map +1 -0
- package/dist/LockedThumbnail-Cr0Gqs3Y.cjs +2 -0
- package/dist/LockedThumbnail-Cr0Gqs3Y.cjs.map +1 -0
- package/dist/assets/index.css +1 -1
- package/dist/index-BPhZyaxT.cjs +2 -0
- package/dist/index-BPhZyaxT.cjs.map +1 -0
- package/dist/{index-DFZrAiLB.js → index-BxzzWK4K.js} +1249 -1276
- package/dist/index-BxzzWK4K.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +101 -164
- package/dist/index.js +1 -1
- package/dist/testing.d.ts +0 -1
- package/package.json +2 -2
- package/src/components/ChannelList/CustomChannelPreview.test.tsx +0 -95
- package/src/components/ChannelList/CustomChannelPreview.tsx +9 -21
- package/src/components/CustomMessage/CustomMessage.stories.tsx +1 -54
- package/src/components/CustomMessage/MessageTag.tsx +0 -8
- package/src/components/CustomMessage/context.tsx +1 -1
- package/src/components/CustomMessage/index.tsx +42 -76
- package/src/components/CustomMessageInput/CustomMessageInput.stories.tsx +3 -5
- package/src/components/LockedAttachment/LockedAttachment.stories.tsx +450 -0
- package/src/components/LockedAttachment/components/Composer/Card.tsx +221 -0
- package/src/components/LockedAttachment/components/Composer/index.ts +2 -0
- package/src/components/LockedAttachment/components/Received/Card.tsx +191 -0
- package/src/components/{CustomMessage/LockedAttachment/components/Media → LockedAttachment/components/Received}/CardActions.tsx +2 -9
- package/src/components/LockedAttachment/components/Received/index.ts +2 -0
- package/src/components/LockedAttachment/components/Sent/Card.tsx +177 -0
- package/src/components/LockedAttachment/components/Sent/index.ts +2 -0
- package/src/components/{CustomMessage/LockedAttachment → LockedAttachment}/components/_shared/CardBody.tsx +7 -8
- package/src/components/{CustomMessage/LockedAttachment → LockedAttachment}/components/_shared/GalleryThumbnail.tsx +39 -31
- package/src/components/LockedAttachment/components/_shared/LockBadge.tsx +39 -0
- package/src/components/{CustomMessage/LockedAttachment/components/_shared/MediaShell.tsx → LockedAttachment/components/_shared/LockedCardShell.tsx} +8 -8
- package/src/components/{CustomMessage/LockedAttachment/components/_shared/SingleThumbnail.tsx → LockedAttachment/components/_shared/LockedThumbnail.tsx} +7 -11
- package/src/components/LockedAttachment/index.tsx +63 -0
- package/src/components/LockedAttachment/types.ts +51 -0
- package/src/index.ts +8 -3
- package/src/stream-custom-data.ts +0 -1
- package/src/styles.css +0 -12
- package/src/types.ts +1 -1
- package/dist/Card-415OfRhw.cjs +0 -2
- package/dist/Card-415OfRhw.cjs.map +0 -1
- package/dist/Card-CyWdUMCB.cjs +0 -2
- package/dist/Card-CyWdUMCB.cjs.map +0 -1
- package/dist/Card-V5d6qhDT.js +0 -694
- package/dist/Card-V5d6qhDT.js.map +0 -1
- package/dist/Card-qS17qnN0.js +0 -103
- package/dist/Card-qS17qnN0.js.map +0 -1
- package/dist/LoadingDots-Ct3WmVlT.js +0 -59
- package/dist/LoadingDots-Ct3WmVlT.js.map +0 -1
- package/dist/LoadingDots-D9GGphgM.cjs +0 -2
- package/dist/LoadingDots-D9GGphgM.cjs.map +0 -1
- package/dist/index-Bx_zjNMR.cjs +0 -2
- package/dist/index-Bx_zjNMR.cjs.map +0 -1
- package/dist/index-DFZrAiLB.js.map +0 -1
- package/src/components/CustomMessage/LockedAttachment/LockedAttachment.stories.tsx +0 -541
- package/src/components/CustomMessage/LockedAttachment/LockedAttachment.test.tsx +0 -117
- package/src/components/CustomMessage/LockedAttachment/components/Media/Card.tsx +0 -358
- package/src/components/CustomMessage/LockedAttachment/components/Media/types.ts +0 -79
- package/src/components/CustomMessage/LockedAttachment/components/Text/Card.tsx +0 -153
- package/src/components/CustomMessage/LockedAttachment/components/Text/types.ts +0 -58
- package/src/components/CustomMessage/LockedAttachment/components/_shared/CardThumbnail.tsx +0 -92
- package/src/components/CustomMessage/LockedAttachment/components/_shared/LoadingDots.tsx +0 -36
- package/src/components/CustomMessage/LockedAttachment/components/_shared/LockBadge.tsx +0 -63
- package/src/components/CustomMessage/LockedAttachment/components/_shared/PreviewToggle.tsx +0 -58
- package/src/components/CustomMessage/LockedAttachment/components/_shared/PriceLockRow.tsx +0 -21
- package/src/components/CustomMessage/LockedAttachment/components/_shared/PurchaseStatusBadge.tsx +0 -74
- package/src/components/CustomMessage/LockedAttachment/components/_shared/SkeletonTextLines.tsx +0 -29
- package/src/components/CustomMessage/LockedAttachment/components/_shared/TextShell.tsx +0 -28
- package/src/components/CustomMessage/LockedAttachment/components/_shared/usePreviewToggle.test.ts +0 -67
- package/src/components/CustomMessage/LockedAttachment/components/_shared/usePreviewToggle.ts +0 -89
- package/src/components/CustomMessage/LockedAttachment/components/_shared/useReceivedSource.ts +0 -83
- package/src/components/CustomMessage/LockedAttachment/index.tsx +0 -105
- package/src/components/CustomMessage/LockedAttachment/types.ts +0 -44
|
@@ -32,17 +32,17 @@ import {
|
|
|
32
32
|
import { useMessageVote } from '../../hooks/useMessageVote'
|
|
33
33
|
import { getMessageDisplayText } from '../../utils/getMessageDisplayText'
|
|
34
34
|
import { Avatar } from '../Avatar'
|
|
35
|
+
import LockedAttachment from '../LockedAttachment'
|
|
35
36
|
import { isLinkAttachment } from '../MediaMessage'
|
|
36
|
-
import {
|
|
37
|
+
import {
|
|
38
|
+
bubbleGroupPositionFromStream as messageAttachmentGroupPositionFromStream,
|
|
39
|
+
} from '../MessageAttachment'
|
|
37
40
|
|
|
38
41
|
import { useCustomMessage } from './context'
|
|
39
|
-
import LockedAttachment from './LockedAttachment'
|
|
40
42
|
import {
|
|
41
43
|
MessageTag,
|
|
42
44
|
isAttachmentMessage,
|
|
43
45
|
isChatbotMessage,
|
|
44
|
-
isMediaAttachmentMessage,
|
|
45
|
-
isTextAttachmentMessage,
|
|
46
46
|
isTipOnlyMessage,
|
|
47
47
|
} from './MessageTag'
|
|
48
48
|
import { MessageVoteButtons } from './MessageVoteButtons'
|
|
@@ -145,12 +145,13 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
145
145
|
(total, segment) => total + segment.attachments.length,
|
|
146
146
|
0
|
|
147
147
|
) === (finalAttachments?.length ?? 0)
|
|
148
|
-
const streamAttachmentGroupPosition =
|
|
149
|
-
|
|
148
|
+
const streamAttachmentGroupPosition = messageAttachmentGroupPositionFromStream(
|
|
149
|
+
{
|
|
150
150
|
endOfGroup,
|
|
151
151
|
firstOfGroup,
|
|
152
152
|
groupedByUser,
|
|
153
|
-
}
|
|
153
|
+
}
|
|
154
|
+
)
|
|
154
155
|
|
|
155
156
|
if (isDateSeparatorMessage(message)) {
|
|
156
157
|
return null
|
|
@@ -225,26 +226,6 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
225
226
|
!isAIGenerated &&
|
|
226
227
|
!isChatbot
|
|
227
228
|
|
|
228
|
-
const sharedLockedTextProps = {
|
|
229
|
-
contentType: 'text' as const,
|
|
230
|
-
amountText: message.metadata?.amount_text,
|
|
231
|
-
paymentStatus: message.metadata?.payment_status,
|
|
232
|
-
renderedText: message.text && (
|
|
233
|
-
<MessageText message={displayMessage} renderText={renderText} />
|
|
234
|
-
),
|
|
235
|
-
}
|
|
236
|
-
const sharedLockedMediaProps = {
|
|
237
|
-
contentType: 'media' as const,
|
|
238
|
-
title: message.metadata?.attachment_title,
|
|
239
|
-
mimeType: message.metadata?.attachment_mime_type,
|
|
240
|
-
thumbnailUrl: message.metadata?.attachment_thumbnail,
|
|
241
|
-
amountText: message.metadata?.amount_text,
|
|
242
|
-
detail: message.metadata?.attachment_detail,
|
|
243
|
-
paymentStatus: message.metadata?.payment_status,
|
|
244
|
-
onFetchSource: onFetchSource
|
|
245
|
-
? () => onFetchSource(message, channel)
|
|
246
|
-
: undefined,
|
|
247
|
-
}
|
|
248
229
|
return (
|
|
249
230
|
<>
|
|
250
231
|
{editing && (
|
|
@@ -295,61 +276,43 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
295
276
|
marginInlineStart: 0,
|
|
296
277
|
}}
|
|
297
278
|
>
|
|
298
|
-
{
|
|
299
|
-
<MessageTag message={message} standalone />
|
|
300
|
-
) : isTextAttachmentMessage(message) ? (
|
|
279
|
+
{isAttachment ? (
|
|
301
280
|
<div className="str-chat__message-bubble-wrapper">
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
<LockedAttachment
|
|
306
|
-
{
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
{
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
/>
|
|
316
|
-
)}
|
|
317
|
-
{!isMine && MessageActions && <MessageActions />}
|
|
318
|
-
</div>
|
|
319
|
-
</div>
|
|
320
|
-
) : isMediaAttachmentMessage(message) ? (
|
|
321
|
-
<div className="str-chat__message-bubble-wrapper">
|
|
322
|
-
<div className="flex items-center gap-2">
|
|
323
|
-
{isMine && MessageActions && <MessageActions />}
|
|
324
|
-
{isMine ? (
|
|
325
|
-
<LockedAttachment
|
|
326
|
-
{...sharedLockedMediaProps}
|
|
327
|
-
isMine={true}
|
|
328
|
-
onPreviewClick={() =>
|
|
329
|
-
onUnlockClick
|
|
330
|
-
? onUnlockClick(message, channel)
|
|
331
|
-
: undefined
|
|
281
|
+
{isMine ? (
|
|
282
|
+
<div className="flex items-center gap-2">
|
|
283
|
+
{MessageActions && <MessageActions />}
|
|
284
|
+
<LockedAttachment.Sent
|
|
285
|
+
title={message.metadata?.attachment_title}
|
|
286
|
+
mimeType={message.metadata?.attachment_mime_type}
|
|
287
|
+
thumbnailUrl={message.metadata?.attachment_thumbnail}
|
|
288
|
+
amountText={message.metadata?.amount_text}
|
|
289
|
+
detail={message.metadata?.attachment_detail}
|
|
290
|
+
paymentStatus={message.metadata?.payment_status}
|
|
291
|
+
onPreviewClick={() => onUnlockClick?.(message, channel)}
|
|
292
|
+
onFetchSource={async () =>
|
|
293
|
+
await onFetchSource?.(message, channel)
|
|
332
294
|
}
|
|
333
295
|
/>
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
296
|
+
</div>
|
|
297
|
+
) : (
|
|
298
|
+
<div className="flex items-center gap-2">
|
|
299
|
+
<LockedAttachment.Received
|
|
300
|
+
title={message.metadata?.attachment_title}
|
|
301
|
+
mimeType={message.metadata?.attachment_mime_type}
|
|
302
|
+
thumbnailUrl={message.metadata?.attachment_thumbnail}
|
|
303
|
+
amountText={message.metadata?.amount_text}
|
|
304
|
+
detail={message.metadata?.attachment_detail}
|
|
305
|
+
paymentStatus={message.metadata?.payment_status}
|
|
338
306
|
isUnlocking={isUnlocking(message.id)}
|
|
339
|
-
onUnlockClick={() =>
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
: undefined
|
|
343
|
-
}
|
|
344
|
-
onDownloadClick={() =>
|
|
345
|
-
onDownloadClick
|
|
346
|
-
? onDownloadClick(message, channel)
|
|
347
|
-
: undefined
|
|
307
|
+
onUnlockClick={() => onUnlockClick?.(message, channel)}
|
|
308
|
+
onFetchSource={async () =>
|
|
309
|
+
await onFetchSource?.(message, channel)
|
|
348
310
|
}
|
|
311
|
+
onDownloadClick={() => onDownloadClick?.(message, channel)}
|
|
349
312
|
/>
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
313
|
+
{MessageActions && <MessageActions />}
|
|
314
|
+
</div>
|
|
315
|
+
)}
|
|
353
316
|
{message.text && (
|
|
354
317
|
<div className="str-chat__message-bubble">
|
|
355
318
|
<MessageText
|
|
@@ -359,6 +322,9 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
359
322
|
</div>
|
|
360
323
|
)}
|
|
361
324
|
</div>
|
|
325
|
+
) : isTipOnly ? (
|
|
326
|
+
/* Tip-only messages render as a standalone bubble */
|
|
327
|
+
<MessageTag message={message} standalone />
|
|
362
328
|
) : canRenderAttachmentsInToolkit ? (
|
|
363
329
|
<StreamAttachmentMessage
|
|
364
330
|
groupPosition={streamAttachmentGroupPosition}
|
|
@@ -5,7 +5,7 @@ import { QueryChannelAPIResponse, StreamChat } from 'stream-chat'
|
|
|
5
5
|
import { Channel, Chat, type SendButtonProps } from 'stream-chat-react'
|
|
6
6
|
|
|
7
7
|
import { createMockStreamChatClient } from '../../testing/createMockStreamChatClient'
|
|
8
|
-
import LockedAttachment from '../
|
|
8
|
+
import LockedAttachment from '../LockedAttachment'
|
|
9
9
|
|
|
10
10
|
import { CustomMessageInput } from '.'
|
|
11
11
|
|
|
@@ -229,9 +229,7 @@ WithAttachments.parameters = {
|
|
|
229
229
|
export const WithPaidAttachment: StoryFn<WrapperProps> = (args) => <Wrapper {...args} />
|
|
230
230
|
WithPaidAttachment.args = {
|
|
231
231
|
attachmentPreviewList: () => (
|
|
232
|
-
<LockedAttachment
|
|
233
|
-
isPreview
|
|
234
|
-
contentType="media"
|
|
232
|
+
<LockedAttachment.Composer
|
|
235
233
|
title="Exclusive Content"
|
|
236
234
|
mimeType="image/jpeg"
|
|
237
235
|
thumbnailUrl="https://picsum.photos/seed/paid/320/180"
|
|
@@ -268,7 +266,7 @@ WithPaidAttachment.parameters = {
|
|
|
268
266
|
docs: {
|
|
269
267
|
description: {
|
|
270
268
|
story:
|
|
271
|
-
"Message input with a paid attachment staged inside the input bubble. Uses `Channel`'s `AttachmentPreviewList` override to render a `LockedAttachment
|
|
269
|
+
"Message input with a paid attachment staged inside the input bubble. Uses `Channel`'s `AttachmentPreviewList` override to render a `LockedAttachment.Composer` card at the top of the input. `onDismiss` removes it; `onEditClick` reopens the paid content wizard.",
|
|
272
270
|
},
|
|
273
271
|
},
|
|
274
272
|
}
|
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
import type { Meta, StoryFn } from '@storybook/react'
|
|
2
|
+
import React, { useState } from 'react'
|
|
3
|
+
|
|
4
|
+
import type { LockedAttachmentGalleryItem } from './types'
|
|
5
|
+
|
|
6
|
+
import LockedAttachment from '.'
|
|
7
|
+
|
|
8
|
+
const VIDEO_THUMBNAIL_BLURRED = '/video-thumbnail-blurred.jpg'
|
|
9
|
+
const VIDEO_THUMBNAIL = '/video-thumbnail.jpg'
|
|
10
|
+
const VIDEO_SOURCE = '/video-source.mp4'
|
|
11
|
+
|
|
12
|
+
const IMAGE_THUMBNAIL_BLURRED = '/image-thumbnail-blurred.jpg'
|
|
13
|
+
const IMAGE_THUMBNAIL = '/image-thumbnail.jpg'
|
|
14
|
+
const IMAGE_SOURCE = '/image-source.jpg'
|
|
15
|
+
|
|
16
|
+
const DOCUMENT_THUMBNAIL_BLURRED = '/document-thumbnail-blurred.jpg'
|
|
17
|
+
const DOCUMENT_THUMBNAIL = '/document-thumbnail.jpg'
|
|
18
|
+
const DOCUMENT_SOURCE = '/document-source.pdf'
|
|
19
|
+
|
|
20
|
+
const AUDIO_THUMBNAIL_BLURRED = '/audio-thumbnail-blurred.jpg'
|
|
21
|
+
const AUDIO_THUMBNAIL = '/audio-thumbnail.jpg'
|
|
22
|
+
const AUDIO_SOURCE = '/audio-source.mp3'
|
|
23
|
+
|
|
24
|
+
const meta: Meta = {
|
|
25
|
+
title: 'LockedAttachment',
|
|
26
|
+
parameters: { layout: 'fullscreen' },
|
|
27
|
+
}
|
|
28
|
+
export default meta
|
|
29
|
+
|
|
30
|
+
const VARIANTS = [
|
|
31
|
+
{
|
|
32
|
+
label: 'Video',
|
|
33
|
+
title: "Alicia's Workout Plan",
|
|
34
|
+
mimeType: 'video/mp4',
|
|
35
|
+
detail: '1:20',
|
|
36
|
+
thumbnailUrl: VIDEO_THUMBNAIL_BLURRED,
|
|
37
|
+
thumbnailUnlockedUrl: VIDEO_THUMBNAIL,
|
|
38
|
+
sourceUrl: VIDEO_SOURCE,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
label: 'Audio',
|
|
42
|
+
title: 'Morning Meditation',
|
|
43
|
+
mimeType: 'audio/mpeg',
|
|
44
|
+
detail: '4:35',
|
|
45
|
+
thumbnailUrl: AUDIO_THUMBNAIL_BLURRED,
|
|
46
|
+
thumbnailUnlockedUrl: AUDIO_THUMBNAIL,
|
|
47
|
+
sourceUrl: AUDIO_SOURCE,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
label: 'Image',
|
|
51
|
+
title: 'Picture of my cat',
|
|
52
|
+
mimeType: 'image/jpeg',
|
|
53
|
+
detail: '3.2 MB',
|
|
54
|
+
thumbnailUrl: IMAGE_THUMBNAIL_BLURRED,
|
|
55
|
+
thumbnailUnlockedUrl: IMAGE_THUMBNAIL,
|
|
56
|
+
sourceUrl: IMAGE_SOURCE,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
label: 'Document',
|
|
60
|
+
title: 'Strength Training Guide',
|
|
61
|
+
mimeType: 'application/zip',
|
|
62
|
+
detail: '14 files',
|
|
63
|
+
thumbnailUrl: DOCUMENT_THUMBNAIL_BLURRED,
|
|
64
|
+
thumbnailUnlockedUrl: DOCUMENT_THUMBNAIL,
|
|
65
|
+
sourceUrl: DOCUMENT_SOURCE,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
label: 'Unknown',
|
|
69
|
+
title: 'Unknown Attachment',
|
|
70
|
+
mimeType: 'application/octet-stream',
|
|
71
|
+
detail: '2.4 MB',
|
|
72
|
+
thumbnailUrl: undefined,
|
|
73
|
+
thumbnailUnlockedUrl: undefined,
|
|
74
|
+
sourceUrl: DOCUMENT_SOURCE,
|
|
75
|
+
},
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* A mixed-media collection (a video + 3 photos) used by the Gallery stories
|
|
80
|
+
* below. Each `LockedAttachment.*` card accepts a `gallery` prop and renders
|
|
81
|
+
* a carousel of these items when 2+ items are provided.
|
|
82
|
+
*/
|
|
83
|
+
const GALLERY_ITEMS: LockedAttachmentGalleryItem[] = [
|
|
84
|
+
{
|
|
85
|
+
mimeType: 'video/mp4',
|
|
86
|
+
thumbnailUrl: VIDEO_THUMBNAIL_BLURRED,
|
|
87
|
+
sourceUrl: VIDEO_SOURCE,
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
mimeType: 'image/jpeg',
|
|
91
|
+
thumbnailUrl: IMAGE_THUMBNAIL_BLURRED,
|
|
92
|
+
sourceUrl: IMAGE_SOURCE,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
mimeType: 'image/jpeg',
|
|
96
|
+
thumbnailUrl: DOCUMENT_THUMBNAIL_BLURRED,
|
|
97
|
+
sourceUrl: DOCUMENT_SOURCE,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
mimeType: 'image/jpeg',
|
|
101
|
+
thumbnailUrl: AUDIO_THUMBNAIL_BLURRED,
|
|
102
|
+
sourceUrl: AUDIO_SOURCE,
|
|
103
|
+
},
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
const GALLERY_DETAIL = '1 video, 3 photos'
|
|
107
|
+
const GALLERY_TITLE = 'Workout Guide'
|
|
108
|
+
|
|
109
|
+
const Table = ({ children }: { children: React.ReactNode }) => (
|
|
110
|
+
<div className="min-h-screen w-full p-12 bg-[#F9F7F4]">
|
|
111
|
+
<table className="border-separate border-spacing-4">{children}</table>
|
|
112
|
+
</div>
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
const TableHead = ({
|
|
116
|
+
variants,
|
|
117
|
+
}: {
|
|
118
|
+
variants: { label: string; mimeType: string }[]
|
|
119
|
+
}) => (
|
|
120
|
+
<thead>
|
|
121
|
+
<tr>
|
|
122
|
+
<th className="text-left text-xs font-medium text-black/40 pb-2" />
|
|
123
|
+
{variants.map(({ label, mimeType }) => (
|
|
124
|
+
<th
|
|
125
|
+
key={mimeType}
|
|
126
|
+
className="text-left text-xs font-medium text-black/40 pb-2"
|
|
127
|
+
>
|
|
128
|
+
{label}
|
|
129
|
+
</th>
|
|
130
|
+
))}
|
|
131
|
+
</tr>
|
|
132
|
+
</thead>
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
export const Composer: StoryFn = () => (
|
|
136
|
+
<Table>
|
|
137
|
+
<TableHead variants={VARIANTS} />
|
|
138
|
+
<tbody>
|
|
139
|
+
<tr>
|
|
140
|
+
<td className="text-xs text-right font-medium text-black/40 pr-4 align-top pt-2">
|
|
141
|
+
Preview
|
|
142
|
+
</td>
|
|
143
|
+
{VARIANTS.map(
|
|
144
|
+
({
|
|
145
|
+
mimeType,
|
|
146
|
+
detail,
|
|
147
|
+
thumbnailUrl,
|
|
148
|
+
thumbnailUnlockedUrl,
|
|
149
|
+
sourceUrl,
|
|
150
|
+
}) => (
|
|
151
|
+
<td key={mimeType} className="align-top">
|
|
152
|
+
<LockedAttachment.Composer
|
|
153
|
+
placeholderTitle="Attachment title"
|
|
154
|
+
placeholderAmountText="AU$0.00"
|
|
155
|
+
thumbnailUrl={thumbnailUrl}
|
|
156
|
+
mimeType={mimeType}
|
|
157
|
+
detail={detail}
|
|
158
|
+
onFetchSource={async () => {
|
|
159
|
+
await new Promise((resolve) => setTimeout(resolve, 1500))
|
|
160
|
+
return {
|
|
161
|
+
sourceUrl: sourceUrl,
|
|
162
|
+
thumbnailUrl: thumbnailUnlockedUrl,
|
|
163
|
+
}
|
|
164
|
+
}}
|
|
165
|
+
/>
|
|
166
|
+
</td>
|
|
167
|
+
)
|
|
168
|
+
)}
|
|
169
|
+
</tr>
|
|
170
|
+
<tr>
|
|
171
|
+
<td className="text-xs text-right font-medium text-black/40 pr-4 align-top pt-2">
|
|
172
|
+
Pending
|
|
173
|
+
</td>
|
|
174
|
+
{VARIANTS.map(({ title, mimeType, detail, thumbnailUrl }) => (
|
|
175
|
+
<td key={mimeType} className="align-top">
|
|
176
|
+
<LockedAttachment.Composer
|
|
177
|
+
title={title}
|
|
178
|
+
thumbnailUrl={thumbnailUrl}
|
|
179
|
+
mimeType={mimeType}
|
|
180
|
+
detail={detail}
|
|
181
|
+
amountText="AU$9.99"
|
|
182
|
+
onDismiss={() => alert('Dismissed')}
|
|
183
|
+
/>
|
|
184
|
+
</td>
|
|
185
|
+
))}
|
|
186
|
+
</tr>
|
|
187
|
+
</tbody>
|
|
188
|
+
</Table>
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
export const Sent: StoryFn = () => (
|
|
192
|
+
<Table>
|
|
193
|
+
<TableHead variants={VARIANTS} />
|
|
194
|
+
<tbody>
|
|
195
|
+
<tr>
|
|
196
|
+
<td className="text-xs text-right font-medium text-black/40 pr-4 align-top pt-2">
|
|
197
|
+
Sent
|
|
198
|
+
</td>
|
|
199
|
+
{VARIANTS.map(
|
|
200
|
+
({
|
|
201
|
+
title,
|
|
202
|
+
mimeType,
|
|
203
|
+
detail,
|
|
204
|
+
thumbnailUrl,
|
|
205
|
+
thumbnailUnlockedUrl,
|
|
206
|
+
sourceUrl,
|
|
207
|
+
}) => (
|
|
208
|
+
<td key={mimeType} className="align-top">
|
|
209
|
+
<LockedAttachment.Sent
|
|
210
|
+
title={title}
|
|
211
|
+
thumbnailUrl={thumbnailUrl}
|
|
212
|
+
mimeType={mimeType}
|
|
213
|
+
detail={detail}
|
|
214
|
+
amountText="AU$9.99"
|
|
215
|
+
onFetchSource={async () => {
|
|
216
|
+
await new Promise((resolve) => setTimeout(resolve, 1500))
|
|
217
|
+
return {
|
|
218
|
+
sourceUrl: sourceUrl,
|
|
219
|
+
thumbnailUrl: thumbnailUnlockedUrl,
|
|
220
|
+
}
|
|
221
|
+
}}
|
|
222
|
+
/>
|
|
223
|
+
</td>
|
|
224
|
+
)
|
|
225
|
+
)}
|
|
226
|
+
</tr>
|
|
227
|
+
<tr>
|
|
228
|
+
<td className="text-xs text-right font-medium text-black/40 pr-4 align-top pt-2">
|
|
229
|
+
Sold
|
|
230
|
+
</td>
|
|
231
|
+
{VARIANTS.map(
|
|
232
|
+
({
|
|
233
|
+
title,
|
|
234
|
+
mimeType,
|
|
235
|
+
detail,
|
|
236
|
+
thumbnailUrl,
|
|
237
|
+
thumbnailUnlockedUrl,
|
|
238
|
+
sourceUrl,
|
|
239
|
+
}) => (
|
|
240
|
+
<td key={mimeType} className="align-top">
|
|
241
|
+
<LockedAttachment.Sent
|
|
242
|
+
title={title}
|
|
243
|
+
thumbnailUrl={thumbnailUrl}
|
|
244
|
+
mimeType={mimeType}
|
|
245
|
+
detail={detail}
|
|
246
|
+
amountText="AU$9.99"
|
|
247
|
+
paymentStatus="paid"
|
|
248
|
+
onFetchSource={async () => {
|
|
249
|
+
await new Promise((resolve) => setTimeout(resolve, 1500))
|
|
250
|
+
return {
|
|
251
|
+
sourceUrl: sourceUrl,
|
|
252
|
+
thumbnailUrl: thumbnailUnlockedUrl,
|
|
253
|
+
}
|
|
254
|
+
}}
|
|
255
|
+
/>
|
|
256
|
+
</td>
|
|
257
|
+
)
|
|
258
|
+
)}
|
|
259
|
+
</tr>
|
|
260
|
+
</tbody>
|
|
261
|
+
</Table>
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
export const Gallery: StoryFn = () => {
|
|
265
|
+
const [isPaid, setPaid] = useState(false)
|
|
266
|
+
const [isUnlocking, setUnlocking] = useState(false)
|
|
267
|
+
|
|
268
|
+
return (
|
|
269
|
+
<Table>
|
|
270
|
+
<thead>
|
|
271
|
+
<tr>
|
|
272
|
+
<th className="text-left text-xs font-medium text-black/40 pb-2" />
|
|
273
|
+
<th className="text-left text-xs font-medium text-black/40 pb-2">
|
|
274
|
+
Composer
|
|
275
|
+
</th>
|
|
276
|
+
<th className="text-left text-xs font-medium text-black/40 pb-2">
|
|
277
|
+
Sent
|
|
278
|
+
</th>
|
|
279
|
+
<th className="text-left text-xs font-medium text-black/40 pb-2">
|
|
280
|
+
Received
|
|
281
|
+
</th>
|
|
282
|
+
</tr>
|
|
283
|
+
</thead>
|
|
284
|
+
<tbody>
|
|
285
|
+
<tr>
|
|
286
|
+
<td className="text-xs text-right font-medium text-black/40 pr-4 align-top pt-2">
|
|
287
|
+
Locked
|
|
288
|
+
</td>
|
|
289
|
+
<td className="align-top">
|
|
290
|
+
<LockedAttachment.Composer
|
|
291
|
+
title={GALLERY_TITLE}
|
|
292
|
+
detail={GALLERY_DETAIL}
|
|
293
|
+
amountText="AU$50.00"
|
|
294
|
+
gallery={GALLERY_ITEMS}
|
|
295
|
+
onDismiss={() => alert('Dismissed gallery')}
|
|
296
|
+
onEditClick={() => alert('Edit gallery')}
|
|
297
|
+
/>
|
|
298
|
+
</td>
|
|
299
|
+
<td className="align-top">
|
|
300
|
+
<LockedAttachment.Sent
|
|
301
|
+
title={GALLERY_TITLE}
|
|
302
|
+
detail={GALLERY_DETAIL}
|
|
303
|
+
amountText="AU$50.00"
|
|
304
|
+
gallery={GALLERY_ITEMS}
|
|
305
|
+
/>
|
|
306
|
+
</td>
|
|
307
|
+
<td className="align-top">
|
|
308
|
+
<LockedAttachment.Received
|
|
309
|
+
title={GALLERY_TITLE}
|
|
310
|
+
detail={GALLERY_DETAIL}
|
|
311
|
+
amountText="AU$50.00"
|
|
312
|
+
gallery={GALLERY_ITEMS}
|
|
313
|
+
paymentStatus={isPaid ? 'paid' : undefined}
|
|
314
|
+
isUnlocking={isUnlocking}
|
|
315
|
+
onUnlockClick={() => {
|
|
316
|
+
setUnlocking(true)
|
|
317
|
+
setTimeout(() => {
|
|
318
|
+
setUnlocking(false)
|
|
319
|
+
setPaid(true)
|
|
320
|
+
}, 1500)
|
|
321
|
+
}}
|
|
322
|
+
onDownloadClick={() => alert('Download gallery')}
|
|
323
|
+
/>
|
|
324
|
+
</td>
|
|
325
|
+
</tr>
|
|
326
|
+
<tr>
|
|
327
|
+
<td className="text-xs text-right font-medium text-black/40 pr-4 align-top pt-2">
|
|
328
|
+
Sold / Purchased
|
|
329
|
+
</td>
|
|
330
|
+
<td className="align-top">
|
|
331
|
+
<LockedAttachment.Composer
|
|
332
|
+
title={GALLERY_TITLE}
|
|
333
|
+
detail={GALLERY_DETAIL}
|
|
334
|
+
amountText="AU$50.00"
|
|
335
|
+
gallery={GALLERY_ITEMS}
|
|
336
|
+
onEditClick={() => alert('Edit gallery')}
|
|
337
|
+
/>
|
|
338
|
+
</td>
|
|
339
|
+
<td className="align-top">
|
|
340
|
+
<LockedAttachment.Sent
|
|
341
|
+
title={GALLERY_TITLE}
|
|
342
|
+
detail={GALLERY_DETAIL}
|
|
343
|
+
amountText="AU$50.00"
|
|
344
|
+
paymentStatus="paid"
|
|
345
|
+
gallery={GALLERY_ITEMS}
|
|
346
|
+
/>
|
|
347
|
+
</td>
|
|
348
|
+
<td className="align-top">
|
|
349
|
+
<LockedAttachment.Received
|
|
350
|
+
title={GALLERY_TITLE}
|
|
351
|
+
detail={GALLERY_DETAIL}
|
|
352
|
+
amountText="AU$50.00"
|
|
353
|
+
paymentStatus="paid"
|
|
354
|
+
gallery={GALLERY_ITEMS}
|
|
355
|
+
onDownloadClick={() => alert('Download gallery')}
|
|
356
|
+
/>
|
|
357
|
+
</td>
|
|
358
|
+
</tr>
|
|
359
|
+
</tbody>
|
|
360
|
+
</Table>
|
|
361
|
+
)
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export const Received: StoryFn = () => {
|
|
365
|
+
const [isPaid, setPaid] = useState<string | undefined>()
|
|
366
|
+
const [isUnlocking, setUnlocking] = useState<string | undefined>()
|
|
367
|
+
|
|
368
|
+
return (
|
|
369
|
+
<Table>
|
|
370
|
+
<TableHead variants={VARIANTS} />
|
|
371
|
+
<tbody>
|
|
372
|
+
<tr>
|
|
373
|
+
<td className="text-xs text-right font-medium text-black/40 pr-4 align-top pt-2">
|
|
374
|
+
Locked
|
|
375
|
+
</td>
|
|
376
|
+
{VARIANTS.map(
|
|
377
|
+
({
|
|
378
|
+
title,
|
|
379
|
+
mimeType,
|
|
380
|
+
detail,
|
|
381
|
+
thumbnailUrl,
|
|
382
|
+
thumbnailUnlockedUrl,
|
|
383
|
+
sourceUrl,
|
|
384
|
+
}) => (
|
|
385
|
+
<td key={mimeType} className="align-top">
|
|
386
|
+
<LockedAttachment.Received
|
|
387
|
+
title={title}
|
|
388
|
+
thumbnailUrl={thumbnailUrl}
|
|
389
|
+
mimeType={mimeType}
|
|
390
|
+
detail={detail}
|
|
391
|
+
paymentStatus={isPaid === mimeType ? 'paid' : undefined}
|
|
392
|
+
amountText="AU$9.99"
|
|
393
|
+
isUnlocking={isUnlocking === mimeType}
|
|
394
|
+
onUnlockClick={() => {
|
|
395
|
+
setUnlocking(mimeType)
|
|
396
|
+
setTimeout(() => {
|
|
397
|
+
setUnlocking(undefined)
|
|
398
|
+
setPaid(mimeType)
|
|
399
|
+
}, 1500)
|
|
400
|
+
}}
|
|
401
|
+
onDownloadClick={() => alert('Download clicked')}
|
|
402
|
+
onFetchSource={async () => ({
|
|
403
|
+
sourceUrl: sourceUrl,
|
|
404
|
+
thumbnailUrl: thumbnailUnlockedUrl,
|
|
405
|
+
})}
|
|
406
|
+
/>
|
|
407
|
+
</td>
|
|
408
|
+
)
|
|
409
|
+
)}
|
|
410
|
+
</tr>
|
|
411
|
+
<tr>
|
|
412
|
+
<td className="text-xs text-right font-medium text-black/40 pr-4 align-top pt-2">
|
|
413
|
+
Unlocked
|
|
414
|
+
</td>
|
|
415
|
+
{VARIANTS.map(
|
|
416
|
+
({
|
|
417
|
+
title,
|
|
418
|
+
mimeType,
|
|
419
|
+
detail,
|
|
420
|
+
thumbnailUrl,
|
|
421
|
+
thumbnailUnlockedUrl,
|
|
422
|
+
sourceUrl,
|
|
423
|
+
}) => (
|
|
424
|
+
<td key={mimeType} className="align-top">
|
|
425
|
+
<LockedAttachment.Received
|
|
426
|
+
title={title}
|
|
427
|
+
thumbnailUrl={thumbnailUrl}
|
|
428
|
+
mimeType={mimeType}
|
|
429
|
+
detail={detail}
|
|
430
|
+
amountText="AU$9.99"
|
|
431
|
+
paymentStatus="paid"
|
|
432
|
+
onUnlockClick={() => alert('Unlock clicked')}
|
|
433
|
+
onDownloadClick={() => alert('Download clicked')}
|
|
434
|
+
onFetchSource={async () => ({
|
|
435
|
+
sourceUrl: sourceUrl,
|
|
436
|
+
thumbnailUrl: thumbnailUnlockedUrl,
|
|
437
|
+
})}
|
|
438
|
+
/>
|
|
439
|
+
</td>
|
|
440
|
+
)
|
|
441
|
+
)}
|
|
442
|
+
</tr>
|
|
443
|
+
</tbody>
|
|
444
|
+
</Table>
|
|
445
|
+
)
|
|
446
|
+
}
|
|
447
|
+
// LockedAttachment.Received autoplays the video preview once paid; even with
|
|
448
|
+
// our SMIL/CSS animation freeze the <video> element advances frames
|
|
449
|
+
// independently and produces a non-deterministic snapshot. Skip in Chromatic.
|
|
450
|
+
Received.parameters = { chromatic: { disableSnapshot: true } }
|