1import { useFocusEffect } from '@react-navigation/native';
2import { StackNavigationProp } from '@react-navigation/stack';
3import * as TaskManager from 'expo-task-manager';
4import React from 'react';
5import { ScrollView, StyleSheet, View } from 'react-native';
6
7import Button from '../components/Button';
8import HeadingText from '../components/HeadingText';
9import MonoText from '../components/MonoText';
10
11export default function TaskManagerScreen(props: {
12  navigation: StackNavigationProp<{
13    BackgroundLocationMap: undefined;
14    Geofencing: undefined;
15    BackgroundFetch: undefined;
16  }>;
17}) {
18  const [tasks, setTasks] = React.useState<TaskManager.RegisteredTask[]>([]);
19
20  const updateRegisteredTasks = async () => {
21    const tasks = await TaskManager.getRegisteredTasksAsync();
22    setTasks(tasks);
23  };
24
25  const onFocus = React.useCallback(() => {
26    let isActive = true;
27    TaskManager.getRegisteredTasksAsync().then(tasks => {
28      if (isActive) setTasks(tasks);
29    });
30    return () => (isActive = false);
31  }, [setTasks]);
32
33  useFocusEffect(onFocus);
34
35  const unregisterTask = async (taskName: string) => {
36    await TaskManager.unregisterTaskAsync(taskName);
37    await updateRegisteredTasks();
38  };
39
40  const unregisterAllTasks = async () => {
41    await TaskManager.unregisterAllTasksAsync();
42    await updateRegisteredTasks();
43  };
44
45  const renderButtons = () => {
46    const buttons = tasks.map(({ taskName }) => {
47      return (
48        <Button
49          key={taskName}
50          style={styles.button}
51          title={`Unregister '${taskName}'`}
52          onPress={() => unregisterTask(taskName)}
53        />
54      );
55    });
56
57    return (
58      <View style={styles.buttons}>
59        {buttons}
60        {tasks!.length > 0 && (
61          <Button
62            style={styles.button}
63            buttonStyle={{ backgroundColor: 'red' }}
64            title="Unregister all tasks"
65            onPress={unregisterAllTasks}
66          />
67        )}
68        {renderNavigationButtons()}
69      </View>
70    );
71  };
72
73  const renderNavigationButtons = () => {
74    return (
75      <View>
76        <Button
77          style={styles.button}
78          buttonStyle={{ backgroundColor: 'green' }}
79          title="Go to background location screen"
80          onPress={() => props.navigation.navigate('BackgroundLocationMap')}
81        />
82        <Button
83          style={styles.button}
84          buttonStyle={{ backgroundColor: 'green' }}
85          title="Go to geofencing screen"
86          onPress={() => props.navigation.navigate('Geofencing')}
87        />
88        <Button
89          style={styles.button}
90          buttonStyle={{ backgroundColor: 'green' }}
91          title="Go to background fetch screen"
92          onPress={() => props.navigation.navigate('BackgroundFetch')}
93        />
94      </View>
95    );
96  };
97
98  if (!tasks) {
99    return null;
100  }
101
102  return (
103    <ScrollView contentContainerStyle={styles.container}>
104      <HeadingText>Registered tasks</HeadingText>
105      <MonoText>{JSON.stringify(tasks, null, 2)}</MonoText>
106      {renderButtons()}
107    </ScrollView>
108  );
109}
110
111TaskManagerScreen.navigationOptions = {
112  title: 'TaskManager',
113};
114
115const styles = StyleSheet.create({
116  screen: {
117    flex: 1,
118  },
119  container: {
120    padding: 10,
121  },
122  buttons: {
123    padding: 10,
124  },
125  button: {
126    marginVertical: 10,
127  },
128});
129