about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/App.native.tsx2
-rw-r--r--src/App.web.tsx2
-rw-r--r--src/components/dialogs/nudges/TenMillion.tsx100
-rw-r--r--src/components/dialogs/nudges/index.tsx53
-rw-r--r--src/lib/hooks/useIntentHandler.ts6
-rw-r--r--src/view/shell/Composer.web.tsx1
6 files changed, 163 insertions, 1 deletions
diff --git a/src/App.native.tsx b/src/App.native.tsx
index 780d4058f..95625bdff 100644
--- a/src/App.native.tsx
+++ b/src/App.native.tsx
@@ -63,6 +63,7 @@ import {Provider as PortalProvider} from '#/components/Portal'
 import {Splash} from '#/Splash'
 import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
 import {AudioCategory, PlatformInfo} from '../modules/expo-bluesky-swiss-army'
+import {NudgeDialogs} from '#/components/dialogs/nudges'
 
 SplashScreen.preventAutoHideAsync()
 
@@ -131,6 +132,7 @@ function InnerApp() {
                                           style={s.h100pct}>
                                           <TestCtrls />
                                           <Shell />
+                                          <NudgeDialogs />
                                         </GestureHandlerRootView>
                                       </ProgressGuideProvider>
                                     </MutedThreadsProvider>
diff --git a/src/App.web.tsx b/src/App.web.tsx
index 3017a3a26..79120ffdb 100644
--- a/src/App.web.tsx
+++ b/src/App.web.tsx
@@ -50,6 +50,7 @@ import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry'
 import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialogs'
 import {Provider as PortalProvider} from '#/components/Portal'
 import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
+import {NudgeDialogs} from '#/components/dialogs/nudges'
 
 function InnerApp() {
   const [isReady, setIsReady] = React.useState(false)
@@ -113,6 +114,7 @@ function InnerApp() {
                                       <SafeAreaProvider>
                                         <ProgressGuideProvider>
                                           <Shell />
+                                          <NudgeDialogs />
                                         </ProgressGuideProvider>
                                       </SafeAreaProvider>
                                     </MutedThreadsProvider>
diff --git a/src/components/dialogs/nudges/TenMillion.tsx b/src/components/dialogs/nudges/TenMillion.tsx
new file mode 100644
index 000000000..9b5d5eae6
--- /dev/null
+++ b/src/components/dialogs/nudges/TenMillion.tsx
@@ -0,0 +1,100 @@
+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 {atoms as a, useBreakpoints, tokens} from '#/alf'
+import * as Dialog from '#/components/Dialog'
+import {Text} from '#/components/Typography'
+import {GradientFill} from '#/components/GradientFill'
+import {Button, ButtonText} from '#/components/Button'
+import {useComposerControls} from 'state/shell'
+
+import {useContext} from '#/components/dialogs/nudges'
+
+export function TenMillion() {
+  const {_} = useLingui()
+  const {controls} = useContext()
+  const {gtMobile} = useBreakpoints()
+  const {openComposer} = useComposerControls()
+
+  const imageRef = React.useRef<ViewShot>(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: 1000,
+                  height: 1000,
+                },
+              ],
+            })
+          }, 1e3)
+        })
+      })
+    }
+  }
+
+  return (
+    <Dialog.Outer control={controls.tenMillion}>
+      <Dialog.Handle />
+
+      <Dialog.ScrollableInner
+        label={_(msg`Ten Million`)}
+        style={
+          [
+            // gtMobile ? {width: 'auto', maxWidth: 400, minWidth: 200} : a.w_full,
+          ]
+        }>
+        <View
+          style={[
+            a.relative,
+            a.w_full,
+            a.overflow_hidden,
+            {
+              paddingTop: '100%',
+            },
+          ]}>
+          <ViewShot
+            ref={imageRef}
+            options={{width: 2e3, height: 2e3}}
+            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,
+                },
+              ]}>
+              <GradientFill gradient={tokens.gradients.midnight} />
+
+              <Text>10 milly, babyyy</Text>
+            </View>
+          </ViewShot>
+        </View>
+
+        <Button
+          label={_(msg`Generate`)}
+          size="medium"
+          variant="solid"
+          color="primary"
+          onPress={share}>
+          <ButtonText>{_(msg`Generate`)}</ButtonText>
+        </Button>
+      </Dialog.ScrollableInner>
+    </Dialog.Outer>
+  )
+}
diff --git a/src/components/dialogs/nudges/index.tsx b/src/components/dialogs/nudges/index.tsx
new file mode 100644
index 000000000..357d4e2b4
--- /dev/null
+++ b/src/components/dialogs/nudges/index.tsx
@@ -0,0 +1,53 @@
+import React from 'react'
+
+import * as Dialog from '#/components/Dialog'
+
+import {TenMillion} from '#/components/dialogs/nudges/TenMillion'
+
+type Context = {
+  controls: {
+    tenMillion: Dialog.DialogOuterProps['control']
+  }
+}
+
+const Context = React.createContext<Context>({
+  // @ts-ignore
+  controls: {}
+})
+
+export function useContext() {
+  return React.useContext(Context)
+}
+
+let SHOWN = false
+
+export function NudgeDialogs() {
+  const tenMillion = Dialog.useDialogControl()
+
+  const ctx = React.useMemo(() => {
+    return {
+      controls: {
+        tenMillion
+      }
+    }
+  }, [tenMillion])
+
+  React.useEffect(() => {
+    const t = setTimeout(() => {
+      if (!SHOWN) {
+        SHOWN = true
+        ctx.controls.tenMillion.open()
+      }
+    }, 2e3)
+
+    return () => {
+      clearTimeout(t)
+    }
+  }, [ctx])
+
+  return (
+    <Context.Provider value={ctx}>
+      <TenMillion />
+    </Context.Provider>
+  )
+}
diff --git a/src/lib/hooks/useIntentHandler.ts b/src/lib/hooks/useIntentHandler.ts
index 8cccda48f..67f1c2c38 100644
--- a/src/lib/hooks/useIntentHandler.ts
+++ b/src/lib/hooks/useIntentHandler.ts
@@ -71,7 +71,7 @@ export function useIntentHandler() {
   }, [incomingUrl, composeIntent, verifyEmailIntent])
 }
 
-function useComposeIntent() {
+export function useComposeIntent() {
   const closeAllActiveElements = useCloseAllActiveElements()
   const {openComposer} = useComposerControls()
   const {hasSession} = useSession()
@@ -97,6 +97,10 @@ function useComposeIntent() {
           if (part.includes('https://') || part.includes('http://')) {
             return false
           }
+          console.log({
+            part,
+            text: VALID_IMAGE_REGEX.test(part),
+          })
           // We also should just filter out cases that don't have all the info we need
           return VALID_IMAGE_REGEX.test(part)
         })
diff --git a/src/view/shell/Composer.web.tsx b/src/view/shell/Composer.web.tsx
index 42696139e..ee1ed6622 100644
--- a/src/view/shell/Composer.web.tsx
+++ b/src/view/shell/Composer.web.tsx
@@ -63,6 +63,7 @@ export function Composer({}: {winHeight: number}) {
           mention={state.mention}
           openEmojiPicker={onOpenPicker}
           text={state.text}
+          imageUris={state.imageUris}
         />
       </View>
       <EmojiPicker state={pickerState} close={onClosePicker} />