diff --git a/src/App.native.tsx b/src/App.native.tsx
index 780d4058f9..95625bdff5 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}>
+
diff --git a/src/App.web.tsx b/src/App.web.tsx
index 3017a3a264..79120ffdbf 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() {
+
diff --git a/src/components/dialogs/nudges/TenMillion.tsx b/src/components/dialogs/nudges/TenMillion.tsx
new file mode 100644
index 0000000000..9b5d5eae62
--- /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(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 (
+
+
+
+
+
+
+
+
+
+ 10 milly, babyyy
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/dialogs/nudges/index.tsx b/src/components/dialogs/nudges/index.tsx
new file mode 100644
index 0000000000..357d4e2b40
--- /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({
+ // @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 (
+
+
+
+ )
+}
diff --git a/src/lib/hooks/useIntentHandler.ts b/src/lib/hooks/useIntentHandler.ts
index 8cccda48fb..67f1c2c386 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 42696139e0..ee1ed66226 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}
/>