Instantly share code, notes, and snippets.
Last active
April 1, 2025 09:40
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save pylixonly/a47bd70a362258c0fc8cd06dcee8b08f to your computer and use it in GitHub Desktop.
Unpublished code for Bunny Premium™️ upselling
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { hideSheet, showSheet } from "@lib/ui/sheets"; | |
import { createStyles } from "@lib/ui/styles"; | |
import { NavigationNative, tokens } from "@metro/common"; | |
import { ActionSheet, Button, PressableScale, Text } from "@metro/common/components"; | |
import { debounce } from "es-toolkit"; | |
import { useEffect, useLayoutEffect, useState } from "react"; | |
import { ActivityIndicator, ScrollView, TouchableOpacity, View } from "react-native"; | |
const showPaymentError = debounce(() => { | |
showSheet( | |
"bunny-payment-sheet", | |
() => { | |
const [loading, setLoading] = useState(true); | |
useEffect(() => { | |
setTimeout(() => { | |
setLoading(false); | |
}, 2000); | |
}, []); | |
if (loading) { | |
return <ActionSheet> | |
<ActivityIndicator /> | |
</ActionSheet>; | |
} | |
return <ActionSheet> | |
<View style={{ padding: 8, gap: 8 }}> | |
<Text variant="heading-lg/bold">Payment Error</Text> | |
<Text variant="text-md/medium" style={{ marginBottom: 16 }}> | |
Your payment could not be processed. Please try again later. | |
</Text> | |
<Button | |
size="lg" | |
text="Close" | |
onPress={() => hideSheet("bunny-payment-sheet")} | |
/> | |
</View> | |
</ActionSheet>; | |
} | |
); | |
}, 50); | |
const PremiumScreen = () => { | |
const styles = useStyles(); | |
const navigation = NavigationNative.useNavigation(); | |
const [selectedPlan, setSelectedPlan] = useState<null | "basic" | "pro" | "ultimate">(null); | |
useLayoutEffect(() => { | |
navigation.setOptions({ | |
headerShown: false, | |
}); | |
}, [navigation]); | |
const renderFeature = (icon: any, text: any) => ( | |
<View style={styles.featureRow}> | |
<Text style={styles.featureIcon}>{icon}</Text> | |
<Text variant="text-md/medium">{text}</Text> | |
</View> | |
); | |
return ( | |
<ScrollView style={styles.container}> | |
<TouchableOpacity | |
style={styles.backButton} | |
onPress={() => navigation.goBack()} | |
> | |
<Text variant="eyebrow">← Back</Text> | |
</TouchableOpacity> | |
<View | |
style={styles.header} | |
> | |
<Text style={{ textAlign: "center" }} variant="display-md">Bunny Premium</Text> | |
<Text style={{ textAlign: "center" }} variant="text-md/medium"> | |
Starting tomorrow, the Bunny client mod will switch to a paid subscription model. Without an active premium subscription, Bunny will stop working on this device. Below are the available subscription tiers: | |
</Text> | |
</View> | |
<View style={styles.content}> | |
<View style={styles.planContainer}> | |
<PressableScale | |
style={[styles.planCard, selectedPlan === "basic" && styles.selectedPlan]} | |
onPress={() => setSelectedPlan("basic")} | |
> | |
<Text variant="heading-md/bold">Bunny Basic</Text> | |
<Text variant="heading-xl/bold">$4.99/month</Text> | |
<Text variant="text-md/medium" color="text-muted" style={styles.planDescription}> | |
Basic features with minor inconveniences | |
</Text> | |
{renderFeature("🫷", "Unskippable ads every 10 minutes")} | |
{renderFeature("🔌", "Install up to 5 plugins")} | |
{renderFeature("💬", "Cooldown 1 message/hour")} | |
</PressableScale> | |
<PressableScale | |
style={[styles.planCard, selectedPlan === "pro" && styles.selectedPlan]} | |
onPress={() => setSelectedPlan("pro")} | |
> | |
<View style={styles.popularTag}> | |
<Text variant="eyebrow" color="white">POPULAR</Text> | |
</View> | |
<Text variant="heading-md/bold">Bunny Pro</Text> | |
<Text variant="heading-xl/bold">$9.99/month</Text> | |
<Text variant="text-md/medium" color="text-muted" style={styles.planDescription}>Premium upgrades for power users</Text> | |
{renderFeature("⏩", "Skip ads after 5 seconds")} | |
{renderFeature("🔌", "Access up to 10 plugins")} | |
{renderFeature("💬", "Cooldown 2 messages/min")} | |
</PressableScale> | |
<PressableScale | |
style={[styles.planCard, selectedPlan === "ultimate" && styles.selectedPlan]} | |
onPress={() => setSelectedPlan("ultimate")} | |
> | |
<Text variant="heading-md/bold">Bunny Ultimate</Text> | |
<Text variant="heading-xl/bold">$19.99/month</Text> | |
<Text variant="text-md/medium" color="text-muted" style={styles.planDescription}>Legendary Bunny experience</Text> | |
{renderFeature("📺", "No ads, but your data are still tracked")} | |
{renderFeature("🔌", "Unlimited plugins")} | |
{renderFeature("💬", "Cooldown 5 messages/min")} | |
</PressableScale> | |
</View> | |
<Button | |
grow={true} | |
size="lg" | |
style={{ marginBottom: 24 }} | |
text={selectedPlan ? "Unlock Premium Features" : "Select a Plan"} | |
onPress={showPaymentError} | |
disabled={!selectedPlan} | |
/> | |
<Text variant="text-xs/normal" color="text-muted"> | |
Terms and conditions apply, including but not limited to: quantum entanglement of your data, | |
Schrödinger's plugin cap (it exists and doesn't exist simultaneously), and the occasional invocation | |
of the Bunnyverse's interdimensional licensing agreement. Proceed at your own risk. | |
</Text> | |
</View> | |
</ScrollView> | |
); | |
}; | |
const useStyles = createStyles(() => ({ | |
backButton: { | |
position: "absolute", | |
top: 16, | |
left: 16, | |
zIndex: 1, | |
}, | |
container: { | |
flex: 1, | |
}, | |
header: { | |
gap: 8, | |
paddingBottom: 8, | |
paddingTop: 64, | |
paddingHorizontal: 16, | |
alignItems: "center", | |
}, | |
content: { | |
padding: 16, | |
}, | |
planContainer: { | |
marginBottom: 24, | |
}, | |
planCard: { | |
backgroundColor: tokens.colors.CARD_PRIMARY_BG, | |
borderRadius: 12, | |
padding: 16, | |
marginBottom: 16, | |
borderWidth: 2, | |
borderColor: "transparent", | |
}, | |
selectedPlan: { | |
borderColor: tokens.colors.BG_BRAND, | |
backgroundColor: tokens.colors.CARD_SECONDARY_BG, | |
}, | |
popularTag: { | |
position: "absolute", | |
right: 0, | |
top: 0, | |
backgroundColor: tokens.colors.BG_BRAND, | |
paddingHorizontal: 8, | |
paddingVertical: 4, | |
borderTopRightRadius: 10, | |
borderBottomLeftRadius: 10, | |
}, | |
planDescription: { | |
marginBottom: 16, | |
fontStyle: "italic", | |
}, | |
featureRow: { | |
flexDirection: "row", | |
alignItems: "center", | |
marginBottom: 8, | |
}, | |
featureIcon: { | |
height: 16, | |
fontSize: 12, | |
marginRight: 8, | |
} | |
})); | |
export default PremiumScreen; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment