about summary refs log tree commit diff
path: root/src/components/dialogs/nudges/TenMillion.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/dialogs/nudges/TenMillion.tsx')
-rw-r--r--src/components/dialogs/nudges/TenMillion.tsx330
1 files changed, 287 insertions, 43 deletions
diff --git a/src/components/dialogs/nudges/TenMillion.tsx b/src/components/dialogs/nudges/TenMillion.tsx
index 9b5d5eae6..869056977 100644
--- a/src/components/dialogs/nudges/TenMillion.tsx
+++ b/src/components/dialogs/nudges/TenMillion.tsx
@@ -1,25 +1,74 @@
 import React from 'react'
-import {useLingui} from '@lingui/react'
-import {msg} from '@lingui/macro'
 import {View} from 'react-native'
 import ViewShot from 'react-native-view-shot'
+import {moderateProfile} from '@atproto/api'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 
-import {atoms as a, useBreakpoints, tokens} from '#/alf'
+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 {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 {Text} from '#/components/Typography'
+import {useContext} from '#/components/dialogs/nudges'
+import {Divider} from '#/components/Divider'
 import {GradientFill} from '#/components/GradientFill'
-import {Button, ButtonText} from '#/components/Button'
-import {useComposerControls} from 'state/shell'
+import {ArrowOutOfBox_Stroke2_Corner0_Rounded as Share} from '#/components/icons/ArrowOutOfBox'
+import {Image_Stroke2_Corner0_Rounded as ImageIcon} from '#/components/icons/Image'
+import {Loader} from '#/components/Loader'
+import {Text} from '#/components/Typography'
 
-import {useContext} from '#/components/dialogs/nudges'
+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
+  }
+}
 
 export function TenMillion() {
-  const {_} = useLingui()
+  const t = useTheme()
+  const lightTheme = useTheme('light')
+  const {_, i18n} = useLingui()
   const {controls} = useContext()
   const {gtMobile} = useBreakpoints()
   const {openComposer} = useComposerControls()
-
   const imageRef = React.useRef<ViewShot>(null)
+  const {currentAccount} = useSession()
+  const {isLoading: isProfileLoading, data: profile} = useProfileQuery({
+    did: currentAccount!.did,
+  }) // TODO PWI
+  const moderationOpts = useModerationOpts()
+  const moderation = React.useMemo(() => {
+    return profile && moderationOpts
+      ? moderateProfile(profile, moderationOpts)
+      : undefined
+  }, [profile, moderationOpts])
+
+  const isLoading = isProfileLoading || !moderation || !profile
+
+  const userNumber = 56738
 
   const share = () => {
     if (imageRef.current && imageRef.current.capture) {
@@ -31,8 +80,8 @@ export function TenMillion() {
               imageUris: [
                 {
                   uri,
-                  width: 1000,
-                  height: 1000,
+                  width: WIDTH,
+                  height: HEIGHT,
                 },
               ],
             })
@@ -48,52 +97,247 @@ export function TenMillion() {
 
       <Dialog.ScrollableInner
         label={_(msg`Ten Million`)}
-        style={
-          [
-            // gtMobile ? {width: 'auto', maxWidth: 400, minWidth: 200} : a.w_full,
-          ]
-        }>
+        style={[
+          {
+            padding: 0,
+          },
+          // gtMobile ? {width: 'auto', maxWidth: 400, minWidth: 200} : a.w_full,
+        ]}>
         <View
           style={[
-            a.relative,
-            a.w_full,
+            a.rounded_md,
             a.overflow_hidden,
-            {
-              paddingTop: '100%',
+            isNative && {
+              borderTopLeftRadius: 40,
+              borderTopRightRadius: 40,
             },
           ]}>
-          <ViewShot
-            ref={imageRef}
-            options={{width: 2e3, height: 2e3}}
-            style={[a.absolute, a.inset_0]}>
+          <ThemeProvider theme="light">
             <View
               style={[
-                a.absolute,
-                a.inset_0,
-                a.align_center,
-                a.justify_center,
+                a.relative,
+                a.w_full,
+                a.overflow_hidden,
+                {
+                  paddingTop: '80%',
+                },
+              ]}>
+              <ViewShot
+                ref={imageRef}
+                options={{width: WIDTH, height: HEIGHT}}
+                style={[a.absolute, a.inset_0]}>
+                <View
+                  style={[
+                    a.absolute,
+                    a.inset_0,
+                    a.align_center,
+                    a.justify_center,
+                    {
+                      top: -1,
+                      bottom: -1,
+                      left: -1,
+                      right: -1,
+                      paddingVertical: 32,
+                      paddingHorizontal: 48,
+                    },
+                  ]}>
+                  <GradientFill gradient={tokens.gradients.bonfire} />
+
+                  {isLoading ? (
+                    <Loader size="xl" fill="white" />
+                  ) : (
+                    <View
+                      style={[
+                        a.flex_1,
+                        a.w_full,
+                        a.align_center,
+                        a.justify_center,
+                        a.rounded_md,
+                        {
+                          backgroundColor: 'white',
+                          shadowRadius: 32,
+                          shadowOpacity: 0.1,
+                          elevation: 24,
+                          shadowColor: tokens.gradients.bonfire.values[0][1],
+                        },
+                      ]}>
+                      <View
+                        style={[
+                          a.absolute,
+                          a.px_xl,
+                          a.py_xl,
+                          {
+                            top: 0,
+                            left: 0,
+                          },
+                        ]}>
+                        <Logomark fill={t.palette.primary_500} width={36} />
+                      </View>
+
+                      {/* Centered content */}
+                      <View
+                        style={[
+                          {
+                            paddingBottom: 48,
+                          },
+                        ]}>
+                        <Text
+                          style={[
+                            a.text_md,
+                            a.font_bold,
+                            a.text_center,
+                            a.pb_xs,
+                            lightTheme.atoms.text_contrast_medium,
+                          ]}>
+                          <Trans>
+                            Celebrating {formatCount(i18n, 10000000)} users
+                          </Trans>{' '}
+                          🎉
+                        </Text>
+                        <Text
+                          style={[
+                            a.relative,
+                            a.text_center,
+                            {
+                              fontStyle: 'italic',
+                              fontSize: getFontSize(userNumber),
+                              fontWeight: '900',
+                              letterSpacing: -2,
+                            },
+                          ]}>
+                          <Text
+                            style={[
+                              a.absolute,
+                              {
+                                color: t.palette.primary_500,
+                                fontSize: 32,
+                                left: -18,
+                                top: 8,
+                              },
+                            ]}>
+                            #
+                          </Text>
+                          {i18n.number(userNumber)}
+                        </Text>
+                      </View>
+                      {/* End centered content */}
+
+                      <View
+                        style={[
+                          a.absolute,
+                          a.px_xl,
+                          a.py_xl,
+                          {
+                            bottom: 0,
+                            left: 0,
+                            right: 0,
+                          },
+                        ]}>
+                        <View style={[a.flex_row, a.align_center, a.gap_sm]}>
+                          <UserAvatar
+                            size={36}
+                            avatar={profile.avatar}
+                            moderation={moderation.ui('avatar')}
+                          />
+                          <View style={[a.gap_2xs, a.flex_1]}>
+                            <Text style={[a.text_sm, a.font_bold]}>
+                              {sanitizeDisplayName(
+                                profile.displayName ||
+                                  sanitizeHandle(profile.handle),
+                                moderation.ui('displayName'),
+                              )}
+                            </Text>
+                            <View style={[a.flex_row, a.justify_between]}>
+                              <Text
+                                style={[
+                                  a.text_sm,
+                                  a.font_semibold,
+                                  lightTheme.atoms.text_contrast_medium,
+                                ]}>
+                                {sanitizeHandle(profile.handle, '@')}
+                              </Text>
+
+                              {profile.createdAt && (
+                                <Text
+                                  style={[
+                                    a.text_sm,
+                                    a.font_semibold,
+                                    lightTheme.atoms.text_contrast_low,
+                                  ]}>
+                                  {i18n.date(profile.createdAt, {
+                                    dateStyle: 'long',
+                                  })}
+                                </Text>
+                              )}
+                            </View>
+                          </View>
+                        </View>
+                      </View>
+                    </View>
+                  )}
+                </View>
+              </ViewShot>
+            </View>
+          </ThemeProvider>
+
+          <View style={[gtMobile ? a.p_2xl : a.p_xl]}>
+            <Text
+              style={[
+                a.text_5xl,
+                a.pb_lg,
                 {
-                  top: -1,
-                  bottom: -1,
-                  left: -1,
-                  right: -1,
+                  fontWeight: '900',
                 },
               ]}>
-              <GradientFill gradient={tokens.gradients.midnight} />
+              You're part of the next wave of the internet.
+            </Text>
+
+            <Text style={[a.leading_snug, a.text_lg, a.pb_xl]}>
+              Online culture is too important to be controlled by a few
+              corporations.{' '}
+              <Text style={[a.leading_snug, a.text_lg, a.italic]}>
+                We’re dedicated to building an open foundation for the social
+                internet so that we can all shape its future.
+              </Text>
+            </Text>
+
+            <Divider />
+
+            <View
+              style={[
+                a.flex_row,
+                a.align_center,
+                a.justify_end,
+                a.gap_md,
+                a.pt_xl,
+              ]}>
+              <Text style={[a.text_md, a.italic, t.atoms.text_contrast_medium]}>
+                Brag a little ;)
+              </Text>
 
-              <Text>10 milly, babyyy</Text>
+              <Button
+                label={_(msg`Share image externally`)}
+                size="large"
+                variant="solid"
+                color="secondary"
+                shape="square"
+                onPress={share}>
+                <ButtonIcon icon={Share} />
+              </Button>
+              <Button
+                label={_(msg`Share image in post`)}
+                size="large"
+                variant="solid"
+                color="primary"
+                onPress={share}>
+                <ButtonText>{_(msg`Share post`)}</ButtonText>
+                <ButtonIcon position="right" icon={ImageIcon} />
+              </Button>
             </View>
-          </ViewShot>
+          </View>
         </View>
 
-        <Button
-          label={_(msg`Generate`)}
-          size="medium"
-          variant="solid"
-          color="primary"
-          onPress={share}>
-          <ButtonText>{_(msg`Generate`)}</ButtonText>
-        </Button>
+        <Dialog.Close />
       </Dialog.ScrollableInner>
     </Dialog.Outer>
   )