@linktr.ee/messaging-react 1.33.3 → 1.34.0-rc-1777521550
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-KHDSM8Zs.js +195 -0
- package/dist/Card-KHDSM8Zs.js.map +1 -0
- package/dist/Card-mHUN_YWq.js +167 -0
- package/dist/Card-mHUN_YWq.js.map +1 -0
- package/dist/assets/index.css +1 -1
- package/dist/{index-Ydi1pTAi.js → index-DWk0f1PF.js} +266 -263
- package/dist/index-DWk0f1PF.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/CustomMessage/index.tsx +8 -5
- package/src/components/LockedAttachment/LockedAttachment.stories.tsx +41 -54
- package/src/components/LockedAttachment/components/Creator/Card.tsx +55 -23
- package/src/components/LockedAttachment/components/Creator/CardThumbnail.tsx +2 -2
- package/src/components/LockedAttachment/components/Visitor/Card.tsx +9 -16
- package/src/components/LockedAttachment/components/Visitor/CardActions.tsx +3 -12
- package/src/components/LockedAttachment/components/Visitor/CardThumbnail.tsx +2 -2
- package/src/components/MediaMessage/MediaMessage.stories.tsx +29 -61
- package/src/components/MediaMessage/index.tsx +1 -1
- package/src/providers/MessagingProvider.test.tsx +126 -0
- package/src/styles.css +29 -3
- package/dist/Card-BfA8wq8O.js +0 -181
- package/dist/Card-BfA8wq8O.js.map +0 -1
- package/dist/Card-Bpud_enW.js +0 -177
- package/dist/Card-Bpud_enW.js.map +0 -1
- package/dist/index-Ydi1pTAi.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -233,8 +233,10 @@ export declare interface ChannelViewProps {
|
|
|
233
233
|
export declare interface CreatorCardProps extends LockedAttachmentBaseProps {
|
|
234
234
|
placeholderTitle?: string;
|
|
235
235
|
placeholderAmountText?: string;
|
|
236
|
+
isUnlocking?: boolean;
|
|
236
237
|
onDismiss?: () => void;
|
|
237
|
-
onPreviewClick?: () =>
|
|
238
|
+
onPreviewClick?: () => void;
|
|
239
|
+
onFetchSource?: () => Promise<LockedAttachmentSource | void>;
|
|
238
240
|
}
|
|
239
241
|
|
|
240
242
|
export declare const CustomMessageProvider: Provider<Partial<CustomMessageRegistry>>;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as e, a as t, C as i, b as n, c as o, d as g, F as r, e as m, L as u, f as M, h as c, i as l, j as h, P as C, k as P, u as d, l as L, m as p, n as v } from "./index-
|
|
1
|
+
import { A as e, a as t, C as i, b as n, c as o, d as g, F as r, e as m, L as u, f as M, h as c, i as l, j as h, P as C, k as P, u as d, l as L, m as p, n as v } from "./index-DWk0f1PF.js";
|
|
2
2
|
export {
|
|
3
3
|
e as ActionButton,
|
|
4
4
|
t as Avatar,
|
package/package.json
CHANGED
|
@@ -208,7 +208,7 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
208
208
|
}}
|
|
209
209
|
>
|
|
210
210
|
{isAttachment ? (
|
|
211
|
-
<div className=
|
|
211
|
+
<div className="str-chat__message-bubble-wrapper">
|
|
212
212
|
{isMine ? (
|
|
213
213
|
<LockedAttachment.Creator
|
|
214
214
|
title={message.metadata?.attachment_title}
|
|
@@ -217,6 +217,11 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
217
217
|
amountText={message.metadata?.amount_text}
|
|
218
218
|
detail={message.metadata?.attachment_detail}
|
|
219
219
|
paymentStatus={message.metadata?.payment_status}
|
|
220
|
+
isUnlocking={isUnlocking(message.id)}
|
|
221
|
+
onPreviewClick={() => onUnlockClick?.(message, channel)}
|
|
222
|
+
onFetchSource={async () =>
|
|
223
|
+
await onFetchSource?.(message, channel)
|
|
224
|
+
}
|
|
220
225
|
/>
|
|
221
226
|
) : (
|
|
222
227
|
<LockedAttachment.Visitor
|
|
@@ -235,10 +240,8 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
235
240
|
/>
|
|
236
241
|
)}
|
|
237
242
|
{message.text && (
|
|
238
|
-
<div className="str-chat__message-bubble
|
|
239
|
-
<
|
|
240
|
-
<MessageText message={message} renderText={renderText} />
|
|
241
|
-
</div>
|
|
243
|
+
<div className="str-chat__message-bubble">
|
|
244
|
+
<MessageText message={message} renderText={renderText} />
|
|
242
245
|
</div>
|
|
243
246
|
)}
|
|
244
247
|
</div>
|
|
@@ -21,7 +21,7 @@ const AUDIO_SOURCE = '/audio-source.mp3'
|
|
|
21
21
|
|
|
22
22
|
const meta: Meta = {
|
|
23
23
|
title: 'Components/LockedAttachment',
|
|
24
|
-
parameters: { layout: '
|
|
24
|
+
parameters: { layout: 'fullscreen' },
|
|
25
25
|
}
|
|
26
26
|
export default meta
|
|
27
27
|
|
|
@@ -62,10 +62,19 @@ const VARIANTS = [
|
|
|
62
62
|
thumbnailUnlockedUrl: DOCUMENT_THUMBNAIL,
|
|
63
63
|
sourceUrl: DOCUMENT_SOURCE,
|
|
64
64
|
},
|
|
65
|
+
{
|
|
66
|
+
label: 'Unknown',
|
|
67
|
+
title: 'Unknown Attachment',
|
|
68
|
+
mimeType: 'application/octet-stream',
|
|
69
|
+
detail: '2.4 MB',
|
|
70
|
+
thumbnailUrl: undefined,
|
|
71
|
+
thumbnailUnlockedUrl: undefined,
|
|
72
|
+
sourceUrl: DOCUMENT_SOURCE,
|
|
73
|
+
},
|
|
65
74
|
]
|
|
66
75
|
|
|
67
76
|
const Table = ({ children }: { children: React.ReactNode }) => (
|
|
68
|
-
<div className="p-12">
|
|
77
|
+
<div className="min-h-screen w-full p-12 bg-[#F9F7F4]">
|
|
69
78
|
<table className="border-separate border-spacing-4">{children}</table>
|
|
70
79
|
</div>
|
|
71
80
|
)
|
|
@@ -90,8 +99,9 @@ const TableHead = ({
|
|
|
90
99
|
</thead>
|
|
91
100
|
)
|
|
92
101
|
|
|
93
|
-
export const
|
|
102
|
+
export const Received: StoryFn = () => {
|
|
94
103
|
const [isPaid, setPaid] = useState<string | undefined>()
|
|
104
|
+
const [isUnlocking, setUnlocking] = useState<string | undefined>()
|
|
95
105
|
|
|
96
106
|
return (
|
|
97
107
|
<Table>
|
|
@@ -118,14 +128,16 @@ export const Visitor: StoryFn = () => {
|
|
|
118
128
|
detail={detail}
|
|
119
129
|
paymentStatus={isPaid === mimeType ? 'paid' : undefined}
|
|
120
130
|
amountText="AU$9.99"
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
})
|
|
131
|
+
isUnlocking={isUnlocking === mimeType}
|
|
132
|
+
onUnlockClick={() => {
|
|
133
|
+
setUnlocking(mimeType)
|
|
134
|
+
setTimeout(() => {
|
|
135
|
+
setUnlocking(undefined)
|
|
136
|
+
setPaid(mimeType)
|
|
137
|
+
}, 1500)
|
|
128
138
|
}}
|
|
139
|
+
onDownloadClick={() => alert('Download clicked')}
|
|
140
|
+
onFetchSource={async () => ({ sourceUrl: sourceUrl, thumbnailUrl: thumbnailUnlockedUrl })}
|
|
129
141
|
/>
|
|
130
142
|
</td>
|
|
131
143
|
)
|
|
@@ -133,9 +145,9 @@ export const Visitor: StoryFn = () => {
|
|
|
133
145
|
</tr>
|
|
134
146
|
<tr>
|
|
135
147
|
<td className="text-xs text-right font-medium text-black/40 pr-4 align-top pt-2">
|
|
136
|
-
|
|
148
|
+
Unlocked
|
|
137
149
|
</td>
|
|
138
|
-
{VARIANTS.map(({ title, mimeType, detail, thumbnailUrl }) => (
|
|
150
|
+
{VARIANTS.map(({ title, mimeType, detail, thumbnailUrl, thumbnailUnlockedUrl, sourceUrl }) => (
|
|
139
151
|
<td key={mimeType} className="align-top">
|
|
140
152
|
<LockedAttachment.Visitor
|
|
141
153
|
title={title}
|
|
@@ -146,51 +158,18 @@ export const Visitor: StoryFn = () => {
|
|
|
146
158
|
paymentStatus="paid"
|
|
147
159
|
onUnlockClick={() => alert('Unlock clicked')}
|
|
148
160
|
onDownloadClick={() => alert('Download clicked')}
|
|
161
|
+
onFetchSource={async () => ({ sourceUrl: sourceUrl, thumbnailUrl: thumbnailUnlockedUrl })}
|
|
149
162
|
/>
|
|
150
163
|
</td>
|
|
151
164
|
))}
|
|
152
165
|
</tr>
|
|
153
|
-
|
|
154
|
-
<td className="text-xs text-right font-medium text-black/40 pr-4 align-top pt-2">
|
|
155
|
-
Unlocked
|
|
156
|
-
</td>
|
|
157
|
-
{VARIANTS.map(
|
|
158
|
-
({
|
|
159
|
-
title,
|
|
160
|
-
mimeType,
|
|
161
|
-
detail,
|
|
162
|
-
thumbnailUrl,
|
|
163
|
-
thumbnailUnlockedUrl,
|
|
164
|
-
sourceUrl,
|
|
165
|
-
}) => (
|
|
166
|
-
<td key={mimeType} className="align-top">
|
|
167
|
-
<LockedAttachment.Visitor
|
|
168
|
-
title={title}
|
|
169
|
-
thumbnailUrl={thumbnailUrl}
|
|
170
|
-
mimeType={mimeType}
|
|
171
|
-
detail={detail}
|
|
172
|
-
amountText="AU$9.99"
|
|
173
|
-
paymentStatus="paid"
|
|
174
|
-
onUnlockClick={() => console.log('Unlock clicked')}
|
|
175
|
-
onDownloadClick={() => alert('Download clicked')}
|
|
176
|
-
onFetchSource={async () => {
|
|
177
|
-
await new Promise((resolve) => setTimeout(resolve, 500))
|
|
178
|
-
return Promise.resolve({
|
|
179
|
-
sourceUrl: sourceUrl,
|
|
180
|
-
thumbnailUrl: thumbnailUnlockedUrl,
|
|
181
|
-
})
|
|
182
|
-
}}
|
|
183
|
-
/>
|
|
184
|
-
</td>
|
|
185
|
-
)
|
|
186
|
-
)}
|
|
187
|
-
</tr>
|
|
166
|
+
|
|
188
167
|
</tbody>
|
|
189
168
|
</Table>
|
|
190
169
|
)
|
|
191
170
|
}
|
|
192
171
|
|
|
193
|
-
export const
|
|
172
|
+
export const Sent: StoryFn = () => (
|
|
194
173
|
<Table>
|
|
195
174
|
<TableHead variants={VARIANTS} />
|
|
196
175
|
<tbody>
|
|
@@ -213,10 +192,10 @@ export const Creator: StoryFn = () => (
|
|
|
213
192
|
thumbnailUrl={thumbnailUrl}
|
|
214
193
|
mimeType={mimeType}
|
|
215
194
|
detail={detail}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
thumbnailUrl: thumbnailUnlockedUrl
|
|
219
|
-
}
|
|
195
|
+
onFetchSource={async () => {
|
|
196
|
+
await new Promise((resolve) => setTimeout(resolve, 1500))
|
|
197
|
+
return { sourceUrl: sourceUrl, thumbnailUrl: thumbnailUnlockedUrl }
|
|
198
|
+
}}
|
|
220
199
|
/>
|
|
221
200
|
</td>
|
|
222
201
|
)
|
|
@@ -243,7 +222,7 @@ export const Creator: StoryFn = () => (
|
|
|
243
222
|
<td className="text-xs text-right font-medium text-black/40 pr-4 align-top pt-2">
|
|
244
223
|
Sent
|
|
245
224
|
</td>
|
|
246
|
-
{VARIANTS.map(({ title, mimeType, detail, thumbnailUrl }) => (
|
|
225
|
+
{VARIANTS.map(({ title, mimeType, detail, thumbnailUrl, thumbnailUnlockedUrl, sourceUrl }) => (
|
|
247
226
|
<td key={mimeType} className="align-top">
|
|
248
227
|
<LockedAttachment.Creator
|
|
249
228
|
title={title}
|
|
@@ -251,6 +230,10 @@ export const Creator: StoryFn = () => (
|
|
|
251
230
|
mimeType={mimeType}
|
|
252
231
|
detail={detail}
|
|
253
232
|
amountText="AU$9.99"
|
|
233
|
+
onFetchSource={async () => {
|
|
234
|
+
await new Promise((resolve) => setTimeout(resolve, 1500))
|
|
235
|
+
return { sourceUrl: sourceUrl, thumbnailUrl: thumbnailUnlockedUrl }
|
|
236
|
+
}}
|
|
254
237
|
/>
|
|
255
238
|
</td>
|
|
256
239
|
))}
|
|
@@ -259,7 +242,7 @@ export const Creator: StoryFn = () => (
|
|
|
259
242
|
<td className="text-xs text-right font-medium text-black/40 pr-4 align-top pt-2">
|
|
260
243
|
Sold
|
|
261
244
|
</td>
|
|
262
|
-
{VARIANTS.map(({ title, mimeType, detail, thumbnailUrl }) => (
|
|
245
|
+
{VARIANTS.map(({ title, mimeType, detail, thumbnailUrl, thumbnailUnlockedUrl, sourceUrl }) => (
|
|
263
246
|
<td key={mimeType} className="align-top">
|
|
264
247
|
<LockedAttachment.Creator
|
|
265
248
|
title={title}
|
|
@@ -268,6 +251,10 @@ export const Creator: StoryFn = () => (
|
|
|
268
251
|
detail={detail}
|
|
269
252
|
amountText="AU$9.99"
|
|
270
253
|
paymentStatus="paid"
|
|
254
|
+
onFetchSource={async () => {
|
|
255
|
+
await new Promise((resolve) => setTimeout(resolve, 1500))
|
|
256
|
+
return { sourceUrl: sourceUrl, thumbnailUrl: thumbnailUnlockedUrl }
|
|
257
|
+
}}
|
|
271
258
|
/>
|
|
272
259
|
</td>
|
|
273
260
|
))}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
XIcon,
|
|
8
8
|
} from '@phosphor-icons/react'
|
|
9
9
|
import classNames from 'classnames'
|
|
10
|
-
import React, { useCallback, useState } from 'react'
|
|
10
|
+
import React, { useCallback, useRef, useState } from 'react'
|
|
11
11
|
|
|
12
12
|
import type {
|
|
13
13
|
LockedAttachmentBaseProps,
|
|
@@ -21,8 +21,10 @@ import CardThumbnail from './CardThumbnail'
|
|
|
21
21
|
export interface CreatorCardProps extends LockedAttachmentBaseProps {
|
|
22
22
|
placeholderTitle?: string
|
|
23
23
|
placeholderAmountText?: string
|
|
24
|
+
isUnlocking?: boolean
|
|
24
25
|
onDismiss?: () => void
|
|
25
|
-
onPreviewClick?: () =>
|
|
26
|
+
onPreviewClick?: () => void
|
|
27
|
+
onFetchSource?: () => Promise<LockedAttachmentSource | void>
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
const CreatorCard: React.FC<CreatorCardProps> = ({
|
|
@@ -34,29 +36,56 @@ const CreatorCard: React.FC<CreatorCardProps> = ({
|
|
|
34
36
|
placeholderTitle = 'Attachment title',
|
|
35
37
|
placeholderAmountText,
|
|
36
38
|
paymentStatus,
|
|
39
|
+
isUnlocking,
|
|
37
40
|
onDismiss,
|
|
38
41
|
onPreviewClick,
|
|
42
|
+
onFetchSource,
|
|
39
43
|
}) => {
|
|
40
44
|
const [source, setSource] = useState<LockedAttachmentSource | undefined>()
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
const
|
|
45
|
+
const [isPreviewVisible, setIsPreviewVisible] = useState(false)
|
|
46
|
+
const [isLoadingPreview, setLoadingPreview] = useState(false)
|
|
47
|
+
const fetchingRef = useRef(false)
|
|
48
|
+
|
|
49
|
+
const effectiveSourceUrl = isPreviewVisible ? source?.sourceUrl : undefined
|
|
50
|
+
const effectiveThumbnailUrl = isPreviewVisible ? (source?.thumbnailUrl ?? thumbnailUrl) : thumbnailUrl
|
|
51
|
+
const isBusy = isLoadingPreview || isUnlocking
|
|
52
|
+
|
|
53
|
+
const handleToggle = useCallback(async () => {
|
|
54
|
+
onPreviewClick?.()
|
|
55
|
+
if (isPreviewVisible) {
|
|
56
|
+
setIsPreviewVisible(false)
|
|
57
|
+
return
|
|
58
|
+
}
|
|
46
59
|
if (source) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
setSource(onPreviewClick())
|
|
60
|
+
setIsPreviewVisible(true)
|
|
61
|
+
return
|
|
50
62
|
}
|
|
51
|
-
|
|
63
|
+
if (!onFetchSource) return
|
|
64
|
+
if (fetchingRef.current) return
|
|
65
|
+
fetchingRef.current = true
|
|
66
|
+
setLoadingPreview(true)
|
|
67
|
+
try {
|
|
68
|
+
const result = await onFetchSource()
|
|
69
|
+
if (result) {
|
|
70
|
+
setSource(result)
|
|
71
|
+
setIsPreviewVisible(true)
|
|
72
|
+
}
|
|
73
|
+
} finally {
|
|
74
|
+
fetchingRef.current = false
|
|
75
|
+
setLoadingPreview(false)
|
|
76
|
+
}
|
|
77
|
+
}, [isPreviewVisible, source, onPreviewClick, onFetchSource])
|
|
78
|
+
|
|
79
|
+
const toggleHandler = onFetchSource || onPreviewClick ? handleToggle : undefined
|
|
52
80
|
|
|
53
81
|
return (
|
|
54
|
-
<div className="relative w-[280px] select-none overflow-hidden rounded-[24px] bg-
|
|
82
|
+
<div className="relative w-[280px] select-none overflow-hidden rounded-[24px] bg-[#121110] shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_4px_8px_rgba(0,0,0,0.06)]">
|
|
55
83
|
<CardHeader
|
|
56
84
|
onDismiss={onDismiss}
|
|
57
|
-
onToggle={
|
|
58
|
-
isExpanded={
|
|
85
|
+
onToggle={isBusy ? undefined : toggleHandler}
|
|
86
|
+
isExpanded={isPreviewVisible}
|
|
59
87
|
paymentStatus={paymentStatus}
|
|
88
|
+
isLoading={isBusy}
|
|
60
89
|
/>
|
|
61
90
|
|
|
62
91
|
<CardThumbnail
|
|
@@ -64,12 +93,12 @@ const CreatorCard: React.FC<CreatorCardProps> = ({
|
|
|
64
93
|
sourceUrl={effectiveSourceUrl}
|
|
65
94
|
thumbnailUrl={effectiveThumbnailUrl}
|
|
66
95
|
mimeType={mimeType}
|
|
67
|
-
onToggle={
|
|
96
|
+
onToggle={isBusy ? undefined : toggleHandler}
|
|
68
97
|
/>
|
|
69
98
|
|
|
70
|
-
<div className="px-4 pb-3 pt-3
|
|
99
|
+
<div className="px-4 pb-3 pt-3">
|
|
71
100
|
<p
|
|
72
|
-
className={classNames('mb-
|
|
101
|
+
className={classNames('mb-0.5 truncate text-base font-medium', {
|
|
73
102
|
'text-white/30': !title,
|
|
74
103
|
'text-white': !!title,
|
|
75
104
|
})}
|
|
@@ -90,11 +119,8 @@ const CreatorCard: React.FC<CreatorCardProps> = ({
|
|
|
90
119
|
{paymentStatus === 'paid' ? (
|
|
91
120
|
<React.Fragment>
|
|
92
121
|
<span className="text-xs font-medium text-white/55">•</span>
|
|
93
|
-
<span className="text-xs font-medium text-[#
|
|
94
|
-
<CheckCircleIcon
|
|
95
|
-
className="size-4 text-[#4ade80]"
|
|
96
|
-
weight="bold"
|
|
97
|
-
/>
|
|
122
|
+
<span className="text-xs font-medium text-[#34c759]">Sold</span>
|
|
123
|
+
<CheckCircleIcon className="size-4 text-[#34c759]" weight="bold" />
|
|
98
124
|
</React.Fragment>
|
|
99
125
|
) : (
|
|
100
126
|
<React.Fragment>
|
|
@@ -120,6 +146,7 @@ interface CardHeaderProps {
|
|
|
120
146
|
onToggle?: () => void
|
|
121
147
|
isExpanded?: boolean
|
|
122
148
|
paymentStatus?: PaymentStatus
|
|
149
|
+
isLoading?: boolean
|
|
123
150
|
}
|
|
124
151
|
|
|
125
152
|
const CardHeader: React.FC<CardHeaderProps> = ({
|
|
@@ -127,6 +154,7 @@ const CardHeader: React.FC<CardHeaderProps> = ({
|
|
|
127
154
|
onToggle,
|
|
128
155
|
isExpanded,
|
|
129
156
|
paymentStatus,
|
|
157
|
+
isLoading,
|
|
130
158
|
}) => {
|
|
131
159
|
if (onDismiss) {
|
|
132
160
|
return (
|
|
@@ -160,7 +188,11 @@ const CardHeader: React.FC<CardHeaderProps> = ({
|
|
|
160
188
|
|
|
161
189
|
return (
|
|
162
190
|
<div className="absolute top-3 z-50 flex size-8 items-center justify-center rounded-full bg-black/60 text-white left-3">
|
|
163
|
-
|
|
191
|
+
{isLoading ? (
|
|
192
|
+
<span className="size-4 animate-spin rounded-full border-2 border-white/30 border-t-white" />
|
|
193
|
+
) : (
|
|
194
|
+
<Icon className="size-4" weight="fill" />
|
|
195
|
+
)}
|
|
164
196
|
</div>
|
|
165
197
|
)
|
|
166
198
|
}
|
|
@@ -27,7 +27,7 @@ const CardThumbnail: React.FC<CardThumbnailProps> = ({
|
|
|
27
27
|
type="button"
|
|
28
28
|
disabled={!onToggle}
|
|
29
29
|
className={classNames(
|
|
30
|
-
'relative block w-full overflow-hidden border-0 bg-
|
|
30
|
+
'relative block w-full overflow-hidden border-0 bg-white/10 p-0 text-left appearance-none',
|
|
31
31
|
{ 'cursor-pointer': !!onToggle, 'cursor-default': !onToggle }
|
|
32
32
|
)}
|
|
33
33
|
onClick={onToggle}
|
|
@@ -51,7 +51,7 @@ const CardThumbnail: React.FC<CardThumbnailProps> = ({
|
|
|
51
51
|
) : (
|
|
52
52
|
<div className="aspect-video flex items-center justify-center">
|
|
53
53
|
{renderTypeIcon(mimeType, {
|
|
54
|
-
className: 'size-12 text-
|
|
54
|
+
className: 'size-12 text-white/20',
|
|
55
55
|
weight: 'regular',
|
|
56
56
|
})}
|
|
57
57
|
</div>
|
|
@@ -111,37 +111,30 @@ const VisitorCard: React.FC<VisitorCardProps> = ({
|
|
|
111
111
|
paymentStatus={paymentStatus}
|
|
112
112
|
/>
|
|
113
113
|
|
|
114
|
-
<div className="px-4 pb-3 pt-3
|
|
115
|
-
<p className="mb-
|
|
114
|
+
<div className="px-4 pb-3 pt-3">
|
|
115
|
+
<p className="mb-0.5 truncate text-base font-medium text-black">
|
|
116
116
|
{title}
|
|
117
117
|
</p>
|
|
118
118
|
<div className="flex items-center gap-1">
|
|
119
119
|
{renderTypeIcon(mimeType, {
|
|
120
|
-
className: 'size-5 shrink-0 text-
|
|
120
|
+
className: 'size-5 shrink-0 text-black/55',
|
|
121
121
|
weight: 'regular',
|
|
122
122
|
})}
|
|
123
123
|
|
|
124
124
|
{detail && (
|
|
125
|
-
<span className="text-xs font-medium text-
|
|
125
|
+
<span className="text-xs font-medium text-black/55">{detail}</span>
|
|
126
126
|
)}
|
|
127
127
|
|
|
128
128
|
{paymentStatus === 'paid' ? (
|
|
129
129
|
<React.Fragment>
|
|
130
|
-
<span className="text-xs font-medium text-
|
|
131
|
-
<span className="text-xs font-medium text-[#
|
|
132
|
-
|
|
133
|
-
</span>
|
|
134
|
-
<CheckCircleIcon
|
|
135
|
-
className="size-4 text-[#4ade80]"
|
|
136
|
-
weight="bold"
|
|
137
|
-
/>
|
|
130
|
+
<span className="text-xs font-medium text-black/55">•</span>
|
|
131
|
+
<span className="text-xs font-medium text-[#008236]">Purchased</span>
|
|
132
|
+
<CheckCircleIcon className="size-4 text-[#008236]" weight="bold" />
|
|
138
133
|
</React.Fragment>
|
|
139
134
|
) : amountText != null ? (
|
|
140
135
|
<React.Fragment>
|
|
141
|
-
<span className="text-xs font-medium text-
|
|
142
|
-
<span className="text-xs font-medium text-
|
|
143
|
-
{amountText}
|
|
144
|
-
</span>
|
|
136
|
+
<span className="text-xs font-medium text-black/55">•</span>
|
|
137
|
+
<span className="text-xs font-medium text-black/55">{amountText}</span>
|
|
145
138
|
</React.Fragment>
|
|
146
139
|
) : null}
|
|
147
140
|
</div>
|
|
@@ -26,10 +26,10 @@ const CardActions: React.FC<CardActionsProps> = (props) => {
|
|
|
26
26
|
type="button"
|
|
27
27
|
onClick={onUnlockClicked}
|
|
28
28
|
disabled={isUnlocking}
|
|
29
|
-
className="mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-
|
|
29
|
+
className="mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white hover:bg-[#2a2928] disabled:opacity-70"
|
|
30
30
|
>
|
|
31
31
|
{isUnlocking ? (
|
|
32
|
-
<
|
|
32
|
+
<span className="size-4 animate-spin rounded-full border-2 border-white/30 border-t-white" />
|
|
33
33
|
) : (
|
|
34
34
|
<React.Fragment>
|
|
35
35
|
<LockSimpleIcon className="size-4" weight="fill" />
|
|
@@ -47,7 +47,7 @@ const CardActions: React.FC<CardActionsProps> = (props) => {
|
|
|
47
47
|
target="_blank"
|
|
48
48
|
rel="noopener noreferrer"
|
|
49
49
|
onClick={onDownloadClicked}
|
|
50
|
-
className="mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-
|
|
50
|
+
className="mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none !text-white hover:bg-[#2a2928]"
|
|
51
51
|
>
|
|
52
52
|
<DownloadSimpleIcon className="size-4" weight="bold" />
|
|
53
53
|
Download
|
|
@@ -58,14 +58,5 @@ const CardActions: React.FC<CardActionsProps> = (props) => {
|
|
|
58
58
|
return null
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
const LoadingDots: React.FC = () => {
|
|
62
|
-
return (
|
|
63
|
-
<span className="flex items-center gap-1">
|
|
64
|
-
<span className="size-1 rounded-full bg-white animate-bounce [animation-delay:-0.3s]" />
|
|
65
|
-
<span className="size-1 rounded-full bg-white animate-bounce [animation-delay:-0.15s]" />
|
|
66
|
-
<span className="size-1 rounded-full bg-white animate-bounce" />
|
|
67
|
-
</span>
|
|
68
|
-
)
|
|
69
|
-
}
|
|
70
61
|
|
|
71
62
|
export default CardActions
|
|
@@ -38,11 +38,11 @@ const CardThumbnail: React.FC<CardThumbnailProps> = ({
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
return (
|
|
41
|
-
<div className="relative overflow-hidden bg-black/5">
|
|
41
|
+
<div className="relative aspect-video overflow-hidden bg-black/5">
|
|
42
42
|
<img
|
|
43
43
|
src={sourceType === 'document' ? thumbnailUrl : sourceUrl}
|
|
44
44
|
alt={title}
|
|
45
|
-
className={`
|
|
45
|
+
className={`absolute inset-0 h-full w-full object-contain transition-opacity duration-300 ${sourceReady ? 'opacity-100' : 'opacity-0'}`}
|
|
46
46
|
draggable={false}
|
|
47
47
|
onLoad={() => setSourceReady(true)}
|
|
48
48
|
/>
|