bsky-app/bskyogcard/src/components/StarterPack.tsx

153 lines
4.4 KiB
TypeScript

/* eslint-disable bsky-internal/avoid-unwrapped-text */
import React from 'react'
import {AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api'
import {Butterfly} from './Butterfly.js'
import {Img} from './Img.js'
export const STARTERPACK_HEIGHT = 630
export const STARTERPACK_WIDTH = 1200
export const TILE_SIZE = STARTERPACK_HEIGHT / 3
const GRADIENT_TOP = '#0A7AFF'
const GRADIENT_BOTTOM = '#59B9FF'
const IMAGE_STROKE = '#359CFF'
export function StarterPack(props: {
starterPack: AppBskyGraphDefs.StarterPackView
images: Map<string, Buffer>
}) {
const {starterPack, images} = props
const record = AppBskyGraphStarterpack.isRecord(starterPack.record)
? starterPack.record
: null
const imagesArray = [...images.values()]
const imageOfCreator = images.get(starterPack.creator.did)
const imagesExceptCreator = [...images.entries()]
.filter(([did]) => did !== starterPack.creator.did)
.map(([, image]) => image)
const imagesAcross: Buffer[] = []
if (imageOfCreator) {
if (imagesExceptCreator.length >= 6) {
imagesAcross.push(...imagesExceptCreator.slice(0, 3))
imagesAcross.push(imageOfCreator)
imagesAcross.push(...imagesExceptCreator.slice(3, 6))
} else {
const firstHalf = Math.floor(imagesExceptCreator.length / 2)
imagesAcross.push(...imagesExceptCreator.slice(0, firstHalf))
imagesAcross.push(imageOfCreator)
imagesAcross.push(
...imagesExceptCreator.slice(firstHalf, imagesExceptCreator.length),
)
}
} else {
imagesAcross.push(...imagesExceptCreator.slice(0, 7))
}
const isLongTitle = record ? record.name.length > 30 : false
return (
<div
style={{
display: 'flex',
justifyContent: 'center',
width: STARTERPACK_WIDTH,
height: STARTERPACK_HEIGHT,
backgroundColor: 'black',
color: 'white',
fontFamily: 'Inter',
}}>
{/* image tiles */}
<div
style={{
display: 'flex',
flexWrap: 'wrap',
alignItems: 'stretch',
width: TILE_SIZE * 6,
height: TILE_SIZE * 3,
}}>
{[...Array(18)].map((_, i) => {
const image = imagesArray.at(i % imagesArray.length)
return (
<div
key={i}
style={{
display: 'flex',
height: TILE_SIZE,
width: TILE_SIZE,
}}>
{image && <Img height="100%" width="100%" src={image} />}
</div>
)
})}
{/* background overlay */}
<div
style={{
display: 'flex',
width: '100%',
height: '100%',
position: 'absolute',
backgroundImage: `linear-gradient(to bottom, ${GRADIENT_TOP}, ${GRADIENT_BOTTOM})`,
opacity: 0.9,
}}
/>
</div>
{/* foreground text & images */}
<div
style={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
width: '100%',
height: '100%',
position: 'absolute',
color: 'white',
}}>
<div
style={{
color: 'white',
padding: 60,
fontSize: 40,
}}>
JOIN THE CONVERSATION
</div>
<div style={{display: 'flex'}}>
{imagesAcross.map((image, i) => {
return (
<div
key={i}
style={{
display: 'flex',
height: 172 + 15 * 2,
width: 172 + 15 * 2,
margin: -15,
border: `15px solid ${IMAGE_STROKE}`,
borderRadius: '50%',
overflow: 'hidden',
}}>
<Img height="100%" width="100%" src={image} />
</div>
)
})}
</div>
<div
style={{
padding: '75px 30px 0px',
fontSize: isLongTitle ? 55 : 65,
display: 'flex',
textAlign: 'center',
}}>
{record?.name || 'Starter Pack'}
</div>
<div
style={{
display: 'flex',
fontSize: 40,
justifyContent: 'center',
padding: '30px 30px 10px',
}}>
on <Butterfly width="65" style={{margin: '-7px 10px 0'}} /> Bluesky
</div>
</div>
</div>
)
}