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 {networkRetry} from '#/lib/async/retry'
import {getCanvas} from '#/lib/canvas'
import {shareUrl} from '#/lib/sharing'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {isNative} from '#/platform/detection'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useProfileQuery} from '#/state/queries/profile'
import {useAgent, useSession} from '#/state/session'
import {useComposerControls} from 'state/shell'
import {formatCount} from '#/view/com/util/numeric/format'
// import {UserAvatar} from '#/view/com/util/UserAvatar'
import {Logomark} from '#/view/icons/Logomark'
import {
atoms as a,
ThemeProvider,
tokens,
useBreakpoints,
useTheme,
} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import {useContext} from '#/components/dialogs/nudges'
import {OnePercent} from '#/components/dialogs/nudges/TenMillion/icons/OnePercent'
import {PointOnePercent} from '#/components/dialogs/nudges/TenMillion/icons/PointOnePercent'
import {TenPercent} from '#/components/dialogs/nudges/TenMillion/icons/TenPercent'
import {Divider} from '#/components/Divider'
import {GradientFill} from '#/components/GradientFill'
import {ArrowOutOfBox_Stroke2_Corner0_Rounded as Share} from '#/components/icons/ArrowOutOfBox'
import {Download_Stroke2_Corner0_Rounded as Download} from '#/components/icons/Download'
import {Image_Stroke2_Corner0_Rounded as ImageIcon} from '#/components/icons/Image'
import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
// import {TwentyFivePercent} from '#/components/dialogs/nudges/TenMillion/icons/TwentyFivePercent'
const DEBUG = false
const RATIO = 8 / 10
const WIDTH = 2000
const HEIGHT = WIDTH * RATIO
function getFontSize(count: number) {
const length = count.toString().length
if (length < 7) {
return 80
} else if (length < 5) {
return 100
} else {
return 70
}
}
function getPercentBadge(percent: number) {
if (percent <= 0.001) {
return PointOnePercent
} else if (percent <= 0.01) {
return OnePercent
} else if (percent <= 0.1) {
return TenPercent
}
// else if (percent <= 0.25) {
// return TwentyFivePercent
// }
return null
}
function Frame({children}: {children: React.ReactNode}) {
return (
{children}
)
}
export function TenMillion() {
const {hasSession} = useSession()
return hasSession ? : null
}
export function TenMillionInner() {
const t = useTheme()
const lightTheme = useTheme('light')
const {_, i18n} = useLingui()
const {controls} = useContext()
const {gtMobile} = useBreakpoints()
const {openComposer} = useComposerControls()
const {currentAccount} = useSession()
const {isLoading: isProfileLoading, data: profile} = useProfileQuery({
did: currentAccount!.did,
})
const moderationOpts = useModerationOpts()
const moderation = React.useMemo(() => {
return profile && moderationOpts
? moderateProfile(profile, moderationOpts)
: undefined
}, [profile, moderationOpts])
const [uri, setUri] = React.useState(null)
const [userNumber, setUserNumber] = React.useState(0)
const [error, setError] = React.useState('')
const isLoadingData =
isProfileLoading || !moderation || !profile || !userNumber
const isLoadingImage = !uri
const percent = userNumber / 10_000_000
const Badge = getPercentBadge(percent)
const agent = useAgent()
React.useEffect(() => {
async function fetchUserNumber() {
if (agent.session?.accessJwt) {
const res = await fetch(
`https://bsky.social/xrpc/com.atproto.temp.getSignupNumber`,
{
headers: {
Authorization: `Bearer ${agent.session.accessJwt}`,
},
},
)
if (!res.ok) {
throw new Error('Network request failed')
}
const data = await res.json()
if (data.number) {
setUserNumber(data.number)
}
}
}
networkRetry(3, fetchUserNumber).catch(() => {
setError(
_(
msg`Oh no! We couldn't fetch your user number. Rest assured, we're glad you're here ❤️`,
),
)
})
}, [
_,
agent.session?.accessJwt,
setUserNumber,
controls.tenMillion,
setError,
])
const sharePost = () => {
if (uri) {
controls.tenMillion.close(() => {
setTimeout(() => {
openComposer({
text: '10 milly, babyyy',
imageUris: [
{
uri,
width: WIDTH,
height: HEIGHT,
},
],
})
}, 1e3)
})
}
}
const onNativeShare = () => {
if (uri) {
controls.tenMillion.close(() => {
shareUrl(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 imageRef = React.useRef(null)
// const captureInProgress = React.useRef(false)
// const [cavasRelayout, setCanvasRelayout] = React.useState('key')
// const onCanvasReady = async () => {
// if (
// imageRef.current &&
// imageRef.current.capture &&
// !captureInProgress.current
// ) {
// captureInProgress.current = true
// setCanvasRelayout('updated')
// }
// }
const onCanvasLayout = async () => {
if (
imageRef.current &&
imageRef.current.capture // &&
// cavasRelayout === 'updated'
) {
const uri = await imageRef.current.capture()
setUri(uri)
}
}
const canvas = isLoadingData ? null : (
{/* Centered content */}
Celebrating {formatCount(i18n, 10000000)} users
{' '}
🎉
#
{i18n.number(userNumber)}
{Badge && (
)}
{/* End centered content */}
{/*
*/}
{sanitizeDisplayName(
profile.displayName ||
sanitizeHandle(profile.handle),
moderation.ui('displayName'),
)}
{sanitizeHandle(profile.handle, '@')}
{profile.createdAt && (
Joined{' '}
{i18n.date(profile.createdAt, {
dateStyle: 'long',
})}
)}
)
return (
{error ? (
(╯°□°)╯︵ ┻━┻
{error}
) : isLoadingData || isLoadingImage ? (
) : (
)}
{canvas}
Thanks for being an early part of Bluesky.
We're rebuilding the social internet together. Congratulations,
we're glad you're here.
{' '}
Brag a little!
)
}