1import { StackNavigationProp } from '@react-navigation/stack';
2import * as Location from 'expo-location';
3import React from 'react';
4import { ScrollView, StyleSheet, View } from 'react-native';
5
6import ListButton from '../../components/ListButton';
7import SimpleActionDemo from '../../components/SimpleActionDemo';
8
9type SetValueType = (value: any) => any;
10type Subscription = { remove: () => any };
11type SubscriptionDemoProps = {
12  title: string;
13  subscribe: (setValue: SetValueType) => Subscription | Promise<Subscription>;
14};
15
16function SubscriptionDemo(props: SubscriptionDemoProps) {
17  const [subscription, setSubscription] = React.useState<Subscription | null>(null);
18
19  const toggle = React.useCallback(
20    async (setValue: SetValueType) => {
21      if (subscription) {
22        setValue(undefined);
23        subscription.remove();
24        setSubscription(null);
25      } else {
26        setSubscription(await props.subscribe(setValue));
27      }
28    },
29    [subscription]
30  );
31
32  React.useEffect(() => {
33    return () => {
34      subscription?.remove();
35    };
36  }, [subscription]);
37
38  return <SimpleActionDemo title={props.title} action={toggle} />;
39}
40
41export default class LocationScreen extends React.Component<{
42  navigation: StackNavigationProp<{ BackgroundLocationMap: undefined; Geofencing: undefined }>;
43}> {
44  static navigationOptions = {
45    title: 'Location',
46  };
47
48  _goToGeofencingMap = () => {
49    this.props.navigation.navigate('Geofencing');
50  };
51
52  renderLocationMapButton() {
53    return (
54      <View style={{ marginTop: 30, paddingHorizontal: 10 }}>
55        <ListButton onPress={this._goToGeofencingMap} title="Geofencing map" />
56      </View>
57    );
58  }
59
60  render() {
61    return (
62      <ScrollView style={styles.scrollView}>
63        <SimpleActionDemo
64          title="requestPermissionsAsync (legacy)"
65          action={() => Location.requestPermissionsAsync()}
66        />
67        <SimpleActionDemo
68          title="getPermissionsAsync (legacy)"
69          action={() => Location.getPermissionsAsync()}
70        />
71        <SimpleActionDemo
72          title="requestForegroundPermissionsAsync"
73          action={() => Location.requestForegroundPermissionsAsync()}
74        />
75        <SimpleActionDemo
76          title="getForegroundPermissionsAsync"
77          action={() => Location.getForegroundPermissionsAsync()}
78        />
79        <SimpleActionDemo
80          title="requestBackgroundPermissionsAsync"
81          action={async () => Location.requestBackgroundPermissionsAsync()}
82        />
83        <SimpleActionDemo
84          title="getBackgroundPermissionsAsync"
85          action={() => Location.getBackgroundPermissionsAsync()}
86        />
87        <SimpleActionDemo
88          title="hasServicesEnabledAsync"
89          action={() => Location.hasServicesEnabledAsync()}
90        />
91        <SimpleActionDemo
92          title="getProviderStatusAsync"
93          action={() => Location.getProviderStatusAsync()}
94        />
95        <SimpleActionDemo
96          title="getCurrentPositionAsync – lowest accuracy"
97          action={() =>
98            Location.getCurrentPositionAsync({ accuracy: Location.LocationAccuracy.Lowest })
99          }
100        />
101        <SimpleActionDemo
102          title="getCurrentPositionAsync – balanced accuracy"
103          action={() => Location.getCurrentPositionAsync()}
104        />
105        <SimpleActionDemo
106          title="getLastKnownPositionAsync"
107          action={() => Location.getLastKnownPositionAsync()}
108        />
109        <SubscriptionDemo
110          title="watchPositionAsync"
111          subscribe={(setValue) => Location.watchPositionAsync({}, setValue)}
112        />
113        <SimpleActionDemo title="getHeadingAsync" action={() => Location.getHeadingAsync()} />
114        <SubscriptionDemo
115          title="watchHeadingAsync"
116          subscribe={(setValue) => Location.watchHeadingAsync(setValue)}
117        />
118        {this.renderLocationMapButton()}
119      </ScrollView>
120    );
121  }
122}
123
124const styles = StyleSheet.create({
125  scrollView: {
126    paddingTop: 10,
127  },
128});
129