Untitled
unknown
plain_text
3 months ago
27 kB
8
Indexable
const ComponentFunction = function() {
// @section:imports @depends:[]
const React = require('react');
const { useState, useEffect, useContext, useMemo, useCallback } = React;
const { View, Text, StyleSheet, ScrollView, TouchableOpacity, Modal, Alert, Platform, StatusBar, ActivityIndicator, Dimensions, Animated } = require('react-native');
const { MaterialIcons } = require('@expo/vector-icons');
const { createBottomTabNavigator } = require('@react-navigation/bottom-tabs');
const { useSafeAreaInsets } = require('react-native-safe-area-context');
// @end:imports
// @section:constants @depends:[]
var TAB_BAR_HEIGHT = Platform.OS === 'web' ? 56 : 49;
var SCROLL_EXTRA_PADDING = 16;
var WEB_TAB_BAR_PADDING = 90;
var FAB_SPACING = 16;
var { width: screenWidth, height: screenHeight } = Dimensions.get('window');
// @end:constants
// @section:theme @depends:[]
const storageStrategy = 'local';
const primaryColor = '#FF6B35';
const accentColor = '#FFD23F';
const backgroundColor = '#1A1A2E';
const cardColor = '#16213E';
const textPrimary = '#EEEEE4';
const textSecondary = '#A8A8A8';
const designStyle = 'playful';
// @end:theme
// @section:navigation-setup @depends:[]
const Tab = createBottomTabNavigator();
// @end:navigation-setup
// @section:ThemeContext @depends:[theme]
const ThemeContext = React.createContext();
const ThemeProvider = function(props) {
const darkModeState = useState(false);
const darkMode = darkModeState[0];
const setDarkMode = darkModeState[1];
const lightTheme = useMemo(function() {
return {
colors: {
primary: primaryColor,
accent: accentColor,
background: backgroundColor,
card: cardColor,
textPrimary: textPrimary,
textSecondary: textSecondary,
border: '#0F3460',
success: '#00FF88',
error: '#FF3366',
warning: accentColor
}
};
}, []);
const darkTheme = useMemo(function() {
return {
colors: {
primary: primaryColor,
accent: accentColor,
background: '#0B0B1A',
card: '#16213E',
textPrimary: textPrimary,
textSecondary: textSecondary,
border: '#0F3460',
success: '#00FF88',
error: '#FF3366',
warning: accentColor
}
};
}, []);
const theme = darkMode ? darkTheme : lightTheme;
const toggleDarkMode = useCallback(function() {
setDarkMode(function(prev) { return !prev; });
}, []);
const value = useMemo(function() {
return {
theme: theme,
darkMode: darkMode,
toggleDarkMode: toggleDarkMode,
designStyle: designStyle
};
}, [theme, darkMode, toggleDarkMode]);
return React.createElement(ThemeContext.Provider, { value: value }, props.children);
};
const useTheme = function() {
return useContext(ThemeContext);
};
// @end:ThemeContext
// @section:ChargingHook @depends:[ThemeContext]
const useChargingStatus = function() {
const isChargingState = useState(false);
const isCharging = isChargingState[0];
const setIsCharging = isChargingState[1];
const batteryLevelState = useState(75);
const batteryLevel = batteryLevelState[0];
const setBatteryLevel = batteryLevelState[1];
useEffect(function() {
const interval = setInterval(function() {
if (Math.random() < 0.1) {
setIsCharging(function(prev) { return !prev; });
}
setBatteryLevel(function(prevLevel) {
if (isCharging && prevLevel < 100) {
return Math.min(100, prevLevel + 1);
} else if (!isCharging && prevLevel > 0) {
return Math.max(0, prevLevel - 0.5);
}
return prevLevel;
});
}, 1000);
return function() {
clearInterval(interval);
};
}, [isCharging]);
const toggleCharging = useCallback(function() {
setIsCharging(function(prev) { return !prev; });
}, []);
return {
isCharging: isCharging,
batteryLevel: batteryLevel,
toggleCharging: toggleCharging
};
};
// @end:ChargingHook
// @section:LockScreen-animations @depends:[]
const useCoinAnimation = function() {
const coinAnimState = useState(new Animated.Value(0));
const coinAnim = coinAnimState[0];
const pulseAnimState = useState(new Animated.Value(1));
const pulseAnim = pulseAnimState[0];
useEffect(function() {
const coinAnimation = Animated.loop(
Animated.sequence([
Animated.timing(coinAnim, {
toValue: 1,
duration: 2000,
useNativeDriver: true,
}),
Animated.timing(coinAnim, {
toValue: 0,
duration: 500,
useNativeDriver: true,
}),
])
);
const pulseAnimation = Animated.loop(
Animated.sequence([
Animated.timing(pulseAnim, {
toValue: 1.1,
duration: 1000,
useNativeDriver: true,
}),
Animated.timing(pulseAnim, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}),
])
);
coinAnimation.start();
pulseAnimation.start();
return function() {
coinAnimation.stop();
pulseAnimation.stop();
};
}, []);
return { coinAnim: coinAnim, pulseAnim: pulseAnim };
};
// @end:LockScreen-animations
// @section:LockScreen-CoinSlot @depends:[styles]
const CoinSlotDisplay = function(props) {
const theme = props.theme;
const animations = props.animations;
const coinTranslateY = animations.coinAnim.interpolate({
inputRange: [0, 1],
outputRange: [-50, 200],
});
return React.createElement(View, { style: styles.coinSlotContainer, componentId: 'coin-slot-display' },
React.createElement(View, { style: [styles.coinSlot, { backgroundColor: theme.colors.card }], componentId: 'coin-slot' },
React.createElement(View, { style: [styles.coinSlotOpening, { borderColor: theme.colors.border }], componentId: 'coin-slot-opening' },
React.createElement(Text, { style: [styles.coinSlotText, { color: theme.colors.textSecondary }], componentId: 'coin-slot-text' }, 'INSERT COIN')
)
),
React.createElement(Animated.View, {
style: [
styles.coin,
{
backgroundColor: accentColor,
transform: [{ translateY: coinTranslateY }]
}
],
componentId: 'animated-coin'
},
React.createElement(Text, { style: styles.coinText, componentId: 'coin-symbol' }, '¢')
)
);
};
// @end:LockScreen-CoinSlot
// @section:LockScreen-ChargingDisplay @depends:[styles]
const ChargingDisplay = function(props) {
const theme = props.theme;
const batteryLevel = props.batteryLevel;
const onUnlock = props.onUnlock;
return React.createElement(View, { style: styles.chargingContainer, componentId: 'charging-display' },
React.createElement(MaterialIcons, {
name: 'battery-charging-full',
size: 120,
color: theme.colors.success,
componentId: 'charging-icon'
}),
React.createElement(Text, { style: [styles.chargingTitle, { color: theme.colors.success }], componentId: 'charging-title' }, 'CHARGING'),
React.createElement(Text, { style: [styles.batteryText, { color: theme.colors.textPrimary }], componentId: 'battery-level' }, batteryLevel + '%'),
React.createElement(View, { style: [styles.batteryBar, { backgroundColor: theme.colors.card }], componentId: 'battery-bar-bg' },
React.createElement(View, {
style: [
styles.batteryFill,
{
backgroundColor: theme.colors.success,
width: batteryLevel + '%'
}
],
componentId: 'battery-fill'
})
),
React.createElement(TouchableOpacity, {
style: [styles.unlockButton, { backgroundColor: theme.colors.primary }],
onPress: onUnlock,
componentId: 'unlock-button'
},
React.createElement(MaterialIcons, { name: 'lock-open', size: 32, color: '#FFFFFF', componentId: 'unlock-icon' }),
React.createElement(Text, { style: styles.unlockButtonText, componentId: 'unlock-text' }, 'UNLOCK DEVICE')
)
);
};
// @end:LockScreen-ChargingDisplay
// @section:LockScreen @depends:[ThemeContext,ChargingHook,LockScreen-animations,LockScreen-CoinSlot,LockScreen-ChargingDisplay,styles]
const LockScreen = function() {
const themeContext = useTheme();
const theme = themeContext.theme;
const insets = useSafeAreaInsets();
const chargingStatus = useChargingStatus();
const animations = useCoinAnimation();
const unlockedState = useState(false);
const unlocked = unlockedState[0];
const setUnlocked = unlockedState[1];
const handleUnlock = useCallback(function() {
if (chargingStatus.isCharging) {
setUnlocked(true);
}
}, [chargingStatus.isCharging]);
if (!chargingStatus.isCharging) {
return React.createElement(View, { style: [styles.container, { backgroundColor: theme.colors.background }], componentId: 'lock-screen' },
React.createElement(StatusBar, { barStyle: 'light-content', backgroundColor: theme.colors.background }),
React.createElement(View, { style: { paddingTop: insets.top }, componentId: 'status-bar-padding' },
React.createElement(View, { style: styles.header, componentId: 'lock-header' },
React.createElement(Text, { style: [styles.gameTitle, { color: theme.colors.primary }], componentId: 'game-title' }, 'COINTAB'),
React.createElement(Text, { style: [styles.gameSubtitle, { color: theme.colors.accent }], componentId: 'game-subtitle' }, 'ARCADE EDITION')
),
React.createElement(View, { style: styles.statusContainer, componentId: 'charging-status' },
React.createElement(TouchableOpacity, {
style: [styles.debugButton, { backgroundColor: theme.colors.card }],
onPress: chargingStatus.toggleCharging,
componentId: 'debug-toggle'
},
React.createElement(Text, { style: [styles.debugButtonText, { color: theme.colors.textPrimary }], componentId: 'debug-text' }, 'Toggle Charging (Demo)')
),
React.createElement(View, { style: styles.statusIndicator, componentId: 'status-indicator' },
React.createElement(MaterialIcons, {
name: chargingStatus.isCharging ? 'power' : 'power-off',
size: 24,
color: chargingStatus.isCharging ? theme.colors.success : theme.colors.error,
componentId: 'status-icon'
}),
React.createElement(Text, {
style: [
styles.statusText,
{ color: chargingStatus.isCharging ? theme.colors.success : theme.colors.error }
],
componentId: 'status-text'
}, chargingStatus.isCharging ? 'CONNECTED' : '')
)
),
React.createElement(View, { style: styles.mainContent, componentId: 'main-content' },
chargingStatus.isCharging ?
React.createElement(ChargingDisplay, {
theme: theme,
batteryLevel: Math.round(chargingStatus.batteryLevel),
onUnlock: handleUnlock,
componentId: 'charging-display'
}) :
React.createElement(View, { style: styles.insertCoinSection, componentId: 'insert-coin-section' },
React.createElement(CoinSlotDisplay, {
theme: theme,
animations: animations,
componentId: 'coin-slot-display'
}),
React.createElement(Animated.View, {
style: [
styles.insertCoinContainer,
{ transform: [{ scale: animations.pulseAnim }] }
],
componentId: 'insert-coin-container'
},
React.createElement(Text, { style: [styles.insertCoinText, { color: theme.colors.primary }], componentId: 'insert-coin-text' }, 'INSERT COIN'),
React.createElement(Text, { style: [styles.insertCoinSubtext, { color: theme.colors.accent }], componentId: 'insert-coin-subtext' }, 'TO PLAY')
),
React.createElement(Text, { style: [styles.instructionText, { color: theme.colors.textSecondary }], componentId: 'instruction-text' }, 'Connect your charger to continue')
)
),
React.createElement(View, { style: styles.footer, componentId: 'lock-footer' },
React.createElement(Text, { style: [styles.footerText, { color: theme.colors.textSecondary }], componentId: 'footer-text' }, 'Keep your device charged!'),
React.createElement(View, { style: styles.arcadeElements, componentId: 'arcade-elements' },
React.createElement(Text, { style: [styles.arcadeText, { color: theme.colors.accent }], componentId: 'arcade-text-1' }, '◆'),
React.createElement(Text, { style: [styles.arcadeText, { color: theme.colors.primary }], componentId: 'arcade-text-2' }, '♦'),
React.createElement(Text, { style: [styles.arcadeText, { color: theme.colors.accent }], componentId: 'arcade-text-3' }, '◆')
)
)
)
);
}
return null;
};
// @end:LockScreen
// @section:SettingsScreen @depends:[ThemeContext,styles]
const SettingsScreen = function() {
const themeContext = useTheme();
const theme = themeContext.theme;
const insets = useSafeAreaInsets();
const scrollBottomPadding = Platform.OS === 'web' ? WEB_TAB_BAR_PADDING : (TAB_BAR_HEIGHT + insets.bottom + SCROLL_EXTRA_PADDING);
const scrollTopPadding = insets.top;
return React.createElement(ScrollView, {
style: { flex: 1, backgroundColor: theme.colors.background },
contentContainerStyle: { paddingTop: scrollTopPadding, paddingBottom: scrollBottomPadding },
componentId: 'settings-scroll'
},
React.createElement(View, { style: styles.settingsContainer, componentId: 'settings-content' },
React.createElement(Text, { style: [styles.settingsTitle, { color: theme.colors.textPrimary }], componentId: 'settings-title' }, 'Cointab Settings'),
React.createElement(View, { style: [styles.settingsCard, { backgroundColor: theme.colors.card }], componentId: 'about-card' },
React.createElement(MaterialIcons, { name: 'info', size: 32, color: theme.colors.primary, componentId: 'info-icon' }),
React.createElement(Text, { style: [styles.cardTitle, { color: theme.colors.textPrimary }], componentId: 'about-title' }, 'About Cointab'),
React.createElement(Text, { style: [styles.cardDescription, { color: theme.colors.textSecondary }], componentId: 'about-description' },
'A fun lock screen alternative that encourages healthy charging habits. Your device can only be unlocked when connected to a charger.'
)
),
React.createElement(View, { style: [styles.settingsCard, { backgroundColor: theme.colors.card }], componentId: 'features-card' },
React.createElement(MaterialIcons, { name: 'featured-play-list', size: 32, color: theme.colors.accent, componentId: 'features-icon' }),
React.createElement(Text, { style: [styles.cardTitle, { color: theme.colors.textPrimary }], componentId: 'features-title' }, 'Features'),
React.createElement(View, { style: styles.featuresList, componentId: 'features-list' },
React.createElement(Text, { style: [styles.featureItem, { color: theme.colors.textSecondary }], componentId: 'feature-1' }, '• Real-time charging detection'),
React.createElement(Text, { style: [styles.featureItem, { color: theme.colors.textSecondary }], componentId: 'feature-2' }, '• Arcade-style interface'),
React.createElement(Text, { style: [styles.featureItem, { color: theme.colors.textSecondary }], componentId: 'feature-3' }, '• Battery level monitoring'),
React.createElement(Text, { style: [styles.featureItem, { color: theme.colors.textSecondary }], componentId: 'feature-4' }, '• Healthy charging habits')
)
),
React.createElement(View, { style: [styles.settingsCard, { backgroundColor: theme.colors.card }], componentId: 'instructions-card' },
React.createElement(MaterialIcons, { name: 'help', size: 32, color: theme.colors.success, componentId: 'help-icon' }),
React.createElement(Text, { style: [styles.cardTitle, { color: theme.colors.textPrimary }], componentId: 'instructions-title' }, 'How to Use'),
React.createElement(View, { style: styles.instructionsList, componentId: 'instructions-list' },
React.createElement(Text, { style: [styles.instructionItem, { color: theme.colors.textSecondary }], componentId: 'instruction-1' }, '1. When not charging: See "Insert Coin" screen'),
React.createElement(Text, { style: [styles.instructionItem, { color: theme.colors.textSecondary }], componentId: 'instruction-2' }, '2. Connect your charger to enable unlock'),
React.createElement(Text, { style: [styles.instructionItem, { color: theme.colors.textSecondary }], componentId: 'instruction-3' }, '3. Tap "Unlock Device" when charging'),
React.createElement(Text, { style: [styles.instructionItem, { color: theme.colors.textSecondary }], componentId: 'instruction-4' }, '4. Enjoy your fully charged device!')
)
)
)
);
};
// @end:SettingsScreen
// @section:TabNavigator @depends:[LockScreen,SettingsScreen,navigation-setup]
const TabNavigator = function() {
const themeContext = useTheme();
const theme = themeContext.theme;
const insets = useSafeAreaInsets();
return React.createElement(Tab.Navigator, {
screenOptions: function() {
return {
headerShown: false,
tabBarStyle: {
position: 'absolute',
bottom: 0,
height: TAB_BAR_HEIGHT + insets.bottom,
borderTopWidth: 0,
backgroundColor: theme.colors.card,
borderTopColor: theme.colors.border,
},
tabBarItemStyle: { padding: 0 },
tabBarActiveTintColor: theme.colors.primary,
tabBarInactiveTintColor: theme.colors.textSecondary,
tabBarLabelStyle: { fontSize: 12, fontWeight: 'bold' }
};
},
componentId: 'main-navigator'
},
React.createElement(Tab.Screen, {
name: 'Lock',
component: LockScreen,
options: {
tabBarIcon: function(props) {
return React.createElement(MaterialIcons, {
name: 'lock',
size: 24,
color: props.color,
componentId: 'tab-lock-icon'
});
}
},
componentId: 'lock-tab'
}),
React.createElement(Tab.Screen, {
name: 'Settings',
component: SettingsScreen,
options: {
tabBarIcon: function(props) {
return React.createElement(MaterialIcons, {
name: 'settings',
size: 24,
color: props.color,
componentId: 'tab-settings-icon'
});
}
},
componentId: 'settings-tab'
})
);
};
// @end:TabNavigator
// @section:styles @depends:[theme,constants]
const styles = StyleSheet.create({
container: {
flex: 1,
width: '100%',
height: '100%',
},
header: {
alignItems: 'center',
paddingVertical: 20,
},
gameTitle: {
fontSize: 32,
fontWeight: 'bold',
letterSpacing: 3,
textShadowColor: 'rgba(255, 107, 53, 0.3)',
textShadowOffset: { width: 0, height: 2 },
textShadowRadius: 4,
},
gameSubtitle: {
fontSize: 14,
fontWeight: 'bold',
letterSpacing: 2,
marginTop: 4,
},
statusContainer: {
alignItems: 'center',
paddingHorizontal: 20,
marginBottom: 20,
},
debugButton: {
paddingHorizontal: 20,
paddingVertical: 10,
borderRadius: 20,
marginBottom: 16,
borderWidth: 1,
borderColor: '#0F3460',
},
debugButtonText: {
fontSize: 14,
fontWeight: 'bold',
},
statusIndicator: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'rgba(22, 33, 62, 0.8)',
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 20,
borderWidth: 1,
borderColor: '#0F3460',
},
statusText: {
fontSize: 14,
fontWeight: 'bold',
marginLeft: 8,
letterSpacing: 1,
},
mainContent: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingHorizontal: 20,
},
insertCoinSection: {
alignItems: 'center',
width: '100%',
},
coinSlotContainer: {
alignItems: 'center',
marginBottom: 40,
height: 250,
justifyContent: 'center',
position: 'relative',
},
coinSlot: {
width: 200,
height: 120,
borderRadius: 20,
justifyContent: 'center',
alignItems: 'center',
borderWidth: 3,
borderColor: '#0F3460',
shadowColor: '#000000',
shadowOffset: { width: 0, height: 8 },
shadowOpacity: 0.3,
shadowRadius: 15,
elevation: 10,
},
coinSlotOpening: {
width: 120,
height: 8,
borderWidth: 2,
borderRadius: 4,
backgroundColor: '#000000',
},
coinSlotText: {
fontSize: 10,
fontWeight: 'bold',
letterSpacing: 1,
position: 'absolute',
bottom: -20,
},
coin: {
width: 40,
height: 40,
borderRadius: 20,
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
shadowColor: '#FFD23F',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.5,
shadowRadius: 8,
elevation: 8,
},
coinText: {
fontSize: 24,
fontWeight: 'bold',
color: '#1A1A2E',
},
insertCoinContainer: {
alignItems: 'center',
marginBottom: 30,
},
insertCoinText: {
fontSize: 28,
fontWeight: 'bold',
letterSpacing: 3,
textShadowColor: 'rgba(255, 107, 53, 0.3)',
textShadowOffset: { width: 0, height: 2 },
textShadowRadius: 4,
},
insertCoinSubtext: {
fontSize: 20,
fontWeight: 'bold',
letterSpacing: 2,
marginTop: 4,
},
instructionText: {
fontSize: 16,
textAlign: 'center',
fontStyle: 'italic',
},
chargingContainer: {
alignItems: 'center',
width: '100%',
},
chargingTitle: {
fontSize: 24,
fontWeight: 'bold',
letterSpacing: 2,
marginTop: 16,
marginBottom: 8,
},
batteryText: {
fontSize: 48,
fontWeight: 'bold',
marginBottom: 16,
},
batteryBar: {
width: 200,
height: 20,
borderRadius: 10,
marginBottom: 32,
overflow: 'hidden',
borderWidth: 2,
borderColor: '#0F3460',
},
batteryFill: {
height: '100%',
borderRadius: 8,
},
unlockButton: {
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 32,
paddingVertical: 16,
borderRadius: 25,
shadowColor: '#FF6B35',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
elevation: 8,
},
unlockButtonText: {
color: '#FFFFFF',
fontSize: 18,
fontWeight: 'bold',
marginLeft: 12,
letterSpacing: 1,
},
unlockedContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
unlockedTitle: {
fontSize: 24,
fontWeight: 'bold',
letterSpacing: 2,
marginTop: 20,
textAlign: 'center',
},
unlockedSubtitle: {
fontSize: 16,
textAlign: 'center',
marginTop: 8,
},
footer: {
alignItems: 'center',
paddingVertical: 20,
},
footerText: {
fontSize: 14,
marginBottom: 12,
},
arcadeElements: {
flexDirection: 'row',
alignItems: 'center',
},
arcadeText: {
fontSize: 20,
marginHorizontal: 8,
},
settingsContainer: {
padding: 20,
},
settingsTitle: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 24,
},
settingsCard: {
padding: 20,
borderRadius: 16,
marginBottom: 16,
borderWidth: 1,
borderColor: '#0F3460',
shadowColor: '#000000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.1,
shadowRadius: 8,
elevation: 4,
},
cardTitle: {
fontSize: 18,
fontWeight: 'bold',
marginTop: 12,
marginBottom: 8,
},
cardDescription: {
fontSize: 14,
lineHeight: 20,
},
featuresList: {
marginTop: 8,
},
featureItem: {
fontSize: 14,
marginBottom: 4,
lineHeight: 18,
},
instructionsList: {
marginTop: 8,
},
instructionItem: {
fontSize: 14,
marginBottom: 6,
lineHeight: 18,
},
});
// @end:styles
// @section:return @depends:[ThemeProvider,TabNavigator]
return React.createElement(ThemeProvider, null,
React.createElement(View, { style: { flex: 1, width: '100%', height: '100%', overflow: 'hidden' }, componentId: 'app-container' },
React.createElement(TabNavigator)
)
);
// @end:return
};
return ComponentFunction;Editor is loading...
Leave a Comment