···1+import {useState} from 'react'
2+import {View} from 'react-native'
3+import {PrivacySensitive} from 'expo-privacy-sensitive'
4+5+import {useAppState} from '#/lib/hooks/useAppState'
6+import {isIOS} from '#/platform/detection'
7+import {atoms as a, useTheme} from '#/alf'
8+import {sizes as iconSizes} from '#/components/icons/common'
9+import {Mark as Logo} from '#/components/icons/Logo'
10+11+const ICON_SIZE = 'xl' as const
12+13+export function GrowthHack({
14+ children,
15+ align = 'right',
16+}: {
17+ children: React.ReactNode
18+ align?: 'left' | 'right'
19+}) {
20+ const t = useTheme()
21+22+ // the button has a variable width and is absolutely positioned, so we need to manually
23+ // set the minimum width of the underlying button
24+ const [width, setWidth] = useState<number | undefined>(undefined)
25+26+ const appState = useAppState()
27+28+ if (!isIOS || appState !== 'active') return children
29+30+ return (
31+ <View
32+ style={[
33+ a.relative,
34+ a.justify_center,
35+ align === 'right' ? a.align_end : a.align_start,
36+ width === undefined ? {opacity: 0} : {minWidth: width},
37+ ]}>
38+ <PrivacySensitive
39+ style={[
40+ a.absolute,
41+ a.z_10,
42+ a.flex_col,
43+ align === 'right'
44+ ? [a.right_0, a.align_end]
45+ : [a.left_0, a.align_start],
46+ // when finding the size of the button, we need the containing
47+ // element to have a concrete size otherwise the text will
48+ // collapse to 0 width. so set it to a really big number
49+ // and hide the entire thing (see above)
50+ width === undefined && {width: 10000},
51+ ]}>
52+ <View
53+ onLayout={evt => setWidth(evt.nativeEvent.layout.width)}
54+ style={[
55+ t.atoms.bg,
56+ // make sure it covers the icon! the won't always be a button
57+ {minWidth: iconSizes[ICON_SIZE], minHeight: iconSizes[ICON_SIZE]},
58+ ]}>
59+ {children}
60+ </View>
61+ </PrivacySensitive>
62+ <Logo size={ICON_SIZE} />
63+ </View>
64+ )
65+}