From eaf0081623154df995e81f2ae430a723539df800 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 10 Sep 2024 16:20:19 -0500 Subject: [PATCH] WIP, avi not working on web --- src/components/dialogs/nudges/TenMillion.tsx | 443 +++++++++++-------- src/lib/canvas.ts | 15 + src/view/com/util/UserAvatar.tsx | 4 + 3 files changed, 276 insertions(+), 186 deletions(-) create mode 100644 src/lib/canvas.ts diff --git a/src/components/dialogs/nudges/TenMillion.tsx b/src/components/dialogs/nudges/TenMillion.tsx index 86905697..2be5e349 100644 --- a/src/components/dialogs/nudges/TenMillion.tsx +++ b/src/components/dialogs/nudges/TenMillion.tsx @@ -1,10 +1,12 @@ import React from 'react' import {View} from 'react-native' import ViewShot from 'react-native-view-shot' +import {Image} from 'expo-image' import {moderateProfile} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {getCanvas} from '#/lib/canvas' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeHandle} from '#/lib/strings/handles' import {isNative} from '#/platform/detection' @@ -32,6 +34,7 @@ import {Image_Stroke2_Corner0_Rounded as ImageIcon} from '#/components/icons/Ima import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' +const DEBUG = false const RATIO = 8 / 10 const WIDTH = 2000 const HEIGHT = WIDTH * RATIO @@ -47,6 +50,22 @@ function getFontSize(count: number) { } } +function Frame({children}: {children: React.ReactNode}) { + return ( + + {children} + + ) +} + export function TenMillion() { const t = useTheme() const lightTheme = useTheme('light') @@ -54,7 +73,6 @@ export function TenMillion() { const {controls} = useContext() const {gtMobile} = useBreakpoints() const {openComposer} = useComposerControls() - const imageRef = React.useRef(null) const {currentAccount} = useSession() const {isLoading: isProfileLoading, data: profile} = useProfileQuery({ did: currentAccount!.did, @@ -65,32 +83,236 @@ export function TenMillion() { ? moderateProfile(profile, moderationOpts) : undefined }, [profile, moderationOpts]) + const [uri, setUri] = React.useState(null) - const isLoading = isProfileLoading || !moderation || !profile + const isLoadingData = isProfileLoading || !moderation || !profile + const isLoadingImage = !uri - const userNumber = 56738 + const userNumber = 56738 // TODO + + const captureInProgress = React.useRef(false) + const imageRef = React.useRef(null) const share = () => { - if (imageRef.current && imageRef.current.capture) { - imageRef.current.capture().then(uri => { - controls.tenMillion.close(() => { - setTimeout(() => { - openComposer({ - text: '10 milly, babyyy', - imageUris: [ - { - uri, - width: WIDTH, - height: HEIGHT, - }, - ], - }) - }, 1e3) - }) + if (uri) { + controls.tenMillion.close(() => { + setTimeout(() => { + openComposer({ + text: '10 milly, babyyy', + imageUris: [ + { + uri, + width: WIDTH, + height: HEIGHT, + }, + ], + }) + }, 1e3) }) } } + const onCanvasReady = async () => { + if ( + imageRef.current && + imageRef.current.capture && + !captureInProgress.current + ) { + captureInProgress.current = true + const uri = await imageRef.current.capture() + setUri(uri) + } + } + + const download = async () => { + if (uri) { + const canvas = await getCanvas(uri) + const imgHref = canvas + .toDataURL('image/png') + .replace('image/png', 'image/octet-stream') + const link = document.createElement('a') + link.setAttribute('download', `Bluesky 10M Users.png`) + link.setAttribute('href', imgHref) + link.click() + } + } + + const canvas = isLoadingData ? null : ( + + + + + + + + + + + + + + {/* Centered content */} + + + + Celebrating {formatCount(i18n, 10000000)} users + {' '} + 🎉 + + + + # + + {i18n.number(userNumber)} + + + {/* End centered content */} + + + + + + + {sanitizeDisplayName( + profile.displayName || + sanitizeHandle(profile.handle), + moderation.ui('displayName'), + )} + + + + {sanitizeHandle(profile.handle, '@')} + + + {profile.createdAt && ( + + {i18n.date(profile.createdAt, { + dateStyle: 'long', + })} + + )} + + + + + + + + + + + + ) + return ( @@ -101,7 +323,6 @@ export function TenMillion() { { padding: 0, }, - // gtMobile ? {width: 'auto', maxWidth: 400, minWidth: 200} : a.w_full, ]}> - + - - - - - {isLoading ? ( - - ) : ( - - - - - - {/* Centered content */} - - - - Celebrating {formatCount(i18n, 10000000)} users - {' '} - 🎉 - - - - # - - {i18n.number(userNumber)} - - - {/* End centered content */} - - - - - - - {sanitizeDisplayName( - profile.displayName || - sanitizeHandle(profile.handle), - moderation.ui('displayName'), - )} - - - - {sanitizeHandle(profile.handle, '@')} - - - {profile.createdAt && ( - - {i18n.date(profile.createdAt, { - dateStyle: 'long', - })} - - )} - - - - - - )} - - + style={[a.absolute, a.inset_0, a.align_center, a.justify_center]}> + + {isLoadingData || isLoadingImage ? ( + + ) : ( + + )} - + + + {canvas} + onPress={download}>