zio/dev^2
Eric Bailey 2024-09-09 20:57:32 -05:00
parent ae71f5ce84
commit 76c584d981
6 changed files with 163 additions and 1 deletions

View File

@ -63,6 +63,7 @@ import {Provider as PortalProvider} from '#/components/Portal'
import {Splash} from '#/Splash' import {Splash} from '#/Splash'
import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider' import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
import {AudioCategory, PlatformInfo} from '../modules/expo-bluesky-swiss-army' import {AudioCategory, PlatformInfo} from '../modules/expo-bluesky-swiss-army'
import {NudgeDialogs} from '#/components/dialogs/nudges'
SplashScreen.preventAutoHideAsync() SplashScreen.preventAutoHideAsync()
@ -131,6 +132,7 @@ function InnerApp() {
style={s.h100pct}> style={s.h100pct}>
<TestCtrls /> <TestCtrls />
<Shell /> <Shell />
<NudgeDialogs />
</GestureHandlerRootView> </GestureHandlerRootView>
</ProgressGuideProvider> </ProgressGuideProvider>
</MutedThreadsProvider> </MutedThreadsProvider>

View File

@ -50,6 +50,7 @@ import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry'
import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialogs' import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialogs'
import {Provider as PortalProvider} from '#/components/Portal' import {Provider as PortalProvider} from '#/components/Portal'
import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider' import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
import {NudgeDialogs} from '#/components/dialogs/nudges'
function InnerApp() { function InnerApp() {
const [isReady, setIsReady] = React.useState(false) const [isReady, setIsReady] = React.useState(false)
@ -113,6 +114,7 @@ function InnerApp() {
<SafeAreaProvider> <SafeAreaProvider>
<ProgressGuideProvider> <ProgressGuideProvider>
<Shell /> <Shell />
<NudgeDialogs />
</ProgressGuideProvider> </ProgressGuideProvider>
</SafeAreaProvider> </SafeAreaProvider>
</MutedThreadsProvider> </MutedThreadsProvider>

View File

@ -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>
)
}

View File

@ -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>
)
}

View File

@ -71,7 +71,7 @@ export function useIntentHandler() {
}, [incomingUrl, composeIntent, verifyEmailIntent]) }, [incomingUrl, composeIntent, verifyEmailIntent])
} }
function useComposeIntent() { export function useComposeIntent() {
const closeAllActiveElements = useCloseAllActiveElements() const closeAllActiveElements = useCloseAllActiveElements()
const {openComposer} = useComposerControls() const {openComposer} = useComposerControls()
const {hasSession} = useSession() const {hasSession} = useSession()
@ -97,6 +97,10 @@ function useComposeIntent() {
if (part.includes('https://') || part.includes('http://')) { if (part.includes('https://') || part.includes('http://')) {
return false 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 // We also should just filter out cases that don't have all the info we need
return VALID_IMAGE_REGEX.test(part) return VALID_IMAGE_REGEX.test(part)
}) })

View File

@ -63,6 +63,7 @@ export function Composer({}: {winHeight: number}) {
mention={state.mention} mention={state.mention}
openEmojiPicker={onOpenPicker} openEmojiPicker={onOpenPicker}
text={state.text} text={state.text}
imageUris={state.imageUris}
/> />
</View> </View>
<EmojiPicker state={pickerState} close={onClosePicker} /> <EmojiPicker state={pickerState} close={onClosePicker} />