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