1import Slider from '@react-native-community/slider';
2import * as Brightness from 'expo-brightness';
3import React from 'react';
4import { ScrollView, Text, View } from 'react-native';
5
6import Button from '../components/Button';
7import HeadingText from '../components/HeadingText';
8import { useResolvedValue } from '../utilities/useResolvedValue';
9
10const brightnessTypes: string[] = ['Brightness', 'SystemBrightness'];
11
12export default function BrightnessScreen() {
13  const [isAvailable, error] = useResolvedValue(Brightness.isAvailableAsync);
14
15  const warning = React.useMemo(() => {
16    if (error) {
17      return `An unknown error occurred while checking the API availability: ${error.message}`;
18    } else if (isAvailable === null) {
19      return 'Checking availability...';
20    } else if (isAvailable === false) {
21      return 'Brightness API is not available on this platform.';
22    }
23    return null;
24  }, [error, isAvailable]);
25
26  if (warning) {
27    return (
28      <View style={{ justifyContent: 'center', alignItems: 'center', flex: 1 }}>
29        <Text>{warning}</Text>
30      </View>
31    );
32  }
33
34  return <BrightnessView />;
35}
36
37function BrightnessView() {
38  const [brightness] = useResolvedValue(Brightness.getBrightnessAsync);
39  const [systemBrightness] = useResolvedValue(Brightness.getSystemBrightnessAsync);
40  const [sliderBrightness, setBrightness] = React.useState<Record<string, number>>({});
41
42  const [systemBrightnessPermissionGranted, setSystemBrightnessPermissionGranted] = React.useState(
43    false
44  );
45
46  React.useEffect(() => {
47    async function initialize() {
48      const { granted } = await Brightness.getPermissionsAsync();
49      setSystemBrightnessPermissionGranted(granted);
50    }
51
52    initialize();
53  }, []);
54
55  function alertBrightnessAsync(type: string) {
56    (type === 'Brightness'
57      ? Brightness.getBrightnessAsync()
58      : Brightness.getSystemBrightnessAsync()
59    ).then(value => {
60      alert(value);
61    });
62  }
63
64  function updateBrightnessAsync(value: number, type: string) {
65    setBrightness(brightness => ({ ...brightness, [type]: value }));
66    if (type === 'Brightness') {
67      Brightness.setBrightnessAsync(value);
68    } else {
69      Brightness.setSystemBrightnessAsync(value);
70    }
71  }
72
73  const initBrightness: Record<string, number | null> = {
74    Brightness: brightness,
75    SystemBrightness: systemBrightness,
76  };
77
78  const views = brightnessTypes.map(type => {
79    const currentBrightness = initBrightness[type] ?? 0;
80    return (
81      <View key={type} style={{ padding: 20 }}>
82        <HeadingText>{type}</HeadingText>
83        {/* you can attempt to request permission even if already granted, but it will noop */}
84        {type === 'SystemBrightness' && (
85          <Button
86            title={`Request permissions ${
87              systemBrightnessPermissionGranted ? ' (already granted)' : ''
88            }`}
89            onPress={async () => {
90              const { granted } = await Brightness.requestPermissionsAsync();
91              setSystemBrightnessPermissionGranted(granted);
92            }}
93            style={{ marginTop: 15 }}
94          />
95        )}
96        <Button
97          title={'get' + type + 'Async'}
98          onPress={() => alertBrightnessAsync(type)}
99          style={{ marginTop: 15, marginBottom: 20 }}
100        />
101        <Text style={{ marginBottom: -2 }}>
102          {'set' + type + 'Async: '}
103          {(sliderBrightness[type] || currentBrightness).toFixed(3)}
104        </Text>
105        <Slider
106          value={currentBrightness}
107          disabled={type === 'SystemBrightness' && !systemBrightnessPermissionGranted}
108          onValueChange={value => updateBrightnessAsync(value, type)}
109        />
110      </View>
111    );
112  });
113  return <ScrollView style={{ flex: 1 }}>{views}</ScrollView>;
114}
115
116BrightnessScreen.navigationOptions = {
117  title: 'Brightness',
118};
119