1import React, { useCallback, useState } from 'react'; 2import { 3 ActivityIndicator, 4 PixelRatio, 5 StyleSheet, 6 Text, 7 TouchableOpacity, 8 View, 9} from 'react-native'; 10 11import MonoText from './MonoText'; 12import Colors from '../constants/Colors'; 13 14type SimpleActionDemoProps = { 15 title: string; 16 action: (setValue: (value: any) => any) => any; 17}; 18 19const SimpleActionDemo = ({ action, title }: SimpleActionDemoProps) => { 20 const [loading, setLoading] = useState(false); 21 const [value, setValue] = useState<any>(undefined); 22 23 const runAction = useCallback(async () => { 24 setLoading(true); 25 try { 26 const value = await action(setValue); 27 setValue(value); 28 } catch (error) { 29 console.error(error); 30 setValue(error); 31 } 32 setLoading(false); 33 }, [action]); 34 35 const monoContainerStyle = value instanceof Error ? styles.demoMonoContainerError : {}; 36 37 return ( 38 <View style={styles.demoContainer}> 39 <TouchableOpacity onPress={runAction}> 40 <View style={styles.demoHeaderContainer}> 41 <Text style={styles.demoHeader}>{title}</Text> 42 {loading && <ActivityIndicator style={styles.demoActivityIndicator} size={10} />} 43 </View> 44 </TouchableOpacity> 45 <View style={{ opacity: loading ? 0.4 : 1.0 }}> 46 {value !== undefined && ( 47 <MonoText containerStyle={monoContainerStyle}>{JSON.stringify(value, null, 2)}</MonoText> 48 )} 49 </View> 50 </View> 51 ); 52}; 53 54const styles = StyleSheet.create({ 55 demoContainer: { 56 paddingHorizontal: 10, 57 borderColor: Colors.border, 58 borderBottomWidth: 1.0 / PixelRatio.get(), 59 }, 60 demoHeaderContainer: { 61 flexDirection: 'row', 62 paddingVertical: 10, 63 }, 64 demoHeader: { 65 fontWeight: 'bold', 66 color: Colors.tintColor, 67 }, 68 demoActivityIndicator: { 69 flex: 1, 70 flexDirection: 'row', 71 justifyContent: 'flex-end', 72 paddingRight: 10, 73 }, 74 demoMonoContainerError: { 75 borderColor: Colors.errorBackground, 76 }, 77}); 78 79export default SimpleActionDemo; 80