1import Constants from 'expo-constants';
2import React from 'react';
3import { ScrollView, View } from 'react-native';
4
5import HeadingText from '../components/HeadingText';
6import MonoText from '../components/MonoText';
7import Colors from '../constants/Colors';
8
9interface State {
10  value?: string | (() => void);
11  error?: Error;
12}
13
14class ExpoConstant extends React.Component<{ value?: any; name: string }, State> {
15  readonly state: State = {};
16
17  componentDidMount() {
18    this.updateValue();
19  }
20
21  async updateValue() {
22    let value = this.props.value;
23
24    if (!value) {
25      value = Constants[this.props.name];
26    }
27    if (typeof value === 'function') {
28      try {
29        value = await this.props.value();
30      } catch (error) {
31        console.error(error);
32        this.setState({ error: error.message });
33      }
34    }
35    if (typeof value === 'object') {
36      value = JSON.stringify(value, null, 2);
37    } else if (typeof value === 'boolean') {
38      value = value ? 'true' : 'false';
39    }
40    this.setState({ value });
41  }
42
43  render() {
44    const { value, error } = this.state;
45    const { name } = this.props;
46
47    if (!value || typeof value === 'function') {
48      return null;
49    }
50
51    return (
52      <View style={{ marginBottom: 10 }}>
53        <HeadingText>{name}</HeadingText>
54        <MonoText containerStyle={error && { borderColor: 'red' }}>
55          {error?.message ?? value}
56        </MonoText>
57      </View>
58    );
59  }
60}
61
62// Ignore deprecated properties
63const IGNORED_CONSTANTS = ['__unsafeNoWarnManifest', 'linkingUrl'];
64
65export default class ConstantsScreen extends React.PureComponent {
66  render() {
67    return (
68      <ScrollView style={{ padding: 10, flex: 1, backgroundColor: Colors.greyBackground }}>
69        {Object.keys(Constants)
70          .filter((value) => !IGNORED_CONSTANTS.includes(value))
71          .sort()
72          .map((key) => {
73            if (typeof Constants[key] === 'function') return null;
74            return <ExpoConstant name={key} key={key} />;
75          })}
76        <ExpoConstant name="webViewUserAgent" value={() => Constants.getWebViewUserAgentAsync()} />
77      </ScrollView>
78    );
79  }
80}
81