diff options
author | devin ivy <devinivy@gmail.com> | 2024-06-20 17:45:52 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-20 17:45:52 -0400 |
commit | 51f5e6bf900685ef92191f22949d09035733c682 (patch) | |
tree | 7e613992c1b131f4fe082a794ae9c32555d87b12 /bskyogcard/src/components/StarterPack.tsx | |
parent | eac4668d7312b35721e147e808c181b2be0256bf (diff) | |
download | voidsky-51f5e6bf900685ef92191f22949d09035733c682.tar.zst |
Bsky link card service (#4547)
* setup bskycard * quick proof of concept for png card generation * bskycard: use jsx * bskycard: 3x5 profile layout * bskycard: add butterfly overlay * bskycard: tidy * bskycard: separate and reorganize * bskycard: tidy * bskycard: tidy * bskycard: tidy * bskycard: poc of transparent overlay and box shadow * bskycard: reorg impl into src/ directory * bskycard: use more standard app structure * bskycard: setup dockerfile, fix build * bskycard: support for x-origin-verify * bskycard: card layout, filter images based on labels * bskycard: tidy * bskycard: support cluster mode * bskycard: handle error fetching starter pack info * bskycard: tidy * bskycard: fix leak on failed image fetch * bskycard: build workflow * bskyogcard: rename from bskycard * bskyogcard: fix some express plumbing * bskyogcard: add cdn tags, tidy
Diffstat (limited to 'bskyogcard/src/components/StarterPack.tsx')
-rw-r--r-- | bskyogcard/src/components/StarterPack.tsx | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/bskyogcard/src/components/StarterPack.tsx b/bskyogcard/src/components/StarterPack.tsx new file mode 100644 index 000000000..f73442190 --- /dev/null +++ b/bskyogcard/src/components/StarterPack.tsx @@ -0,0 +1,149 @@ +/* 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)) + } + 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: 65, + }}> + {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> + ) +} |