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