Skip to content

Instantly share code, notes, and snippets.

@HallexCosta
Last active October 7, 2023 16:26
Show Gist options
  • Save HallexCosta/8e4ade25ad891e48fbbd4f51dbc5b496 to your computer and use it in GitHub Desktop.
Save HallexCosta/8e4ade25ad891e48fbbd4f51dbc5b496 to your computer and use it in GitHub Desktop.
Awesome Timer
import React, { useState, useRef } from 'react';
import {
SafeAreaView,
StyleSheet,
Text,
View,
TouchableHighlight,
} from 'react-native';
import { Stopwatch } from 'react-native-stopwatch-timer';
import * as Notifications from 'expo-notifications';
const App = () => {
const [isStopwatchStart, setIsStopwatchStart] = useState(false);
const [resetStopwatch, setResetStopwatch] = useState(false);
const [expoPushToken, setExpoPushToken] = useState('');
const [time, setTime] = useState('');
const [notification, setNotification] = useState(false);
const notificationListener = useRef();
const responseListener = useRef();
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: false,
shouldSetBadge: false,
}),
});
React.useEffect(() => {
// register for push notifications
// registerForPushNotificationsAsync().then(token => setExpoPushToken(token));
// add category for timer controls (play, pause, and reset)
Notifications.setNotificationCategoryAsync(
'timer_controls',
[
{
identifier: 'play',
buttonTitle: 'Play ▷'
},
{
identifier: 'pause',
buttonTitle: 'Pause 𓊕',
},
{
identifier: 'reset',
buttonTitle: 'Reset',
}
]
)
// add listening on create new notification
notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
setNotification(notification);
});
// add listening on receive response from user (this is click of action buttons or the own notification)
responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
switch (response.actionIdentifier) {
case 'play':
console.log('Played')
onStart()
break
case 'pause':
console.log('Paused')
onStop()
break
case 'reset':
console.log('Reseted')
onReset()
break
default:
break;
}
});
// unsubscription notification listener and response listener
return () => {
Notifications.removeNotificationSubscription(notificationListener.current);
Notifications.removeNotificationSubscription(responseListener.current);
};
}, []);
// declare hook for update notifcation always receive new time
React.useEffect(() => {
displayNotification()
}, [time])
// handle display notification on device
async function displayNotification() {
const identifier = await Notifications.scheduleNotificationAsync({
identifier: 'timer',
content: {
title: 'Awesome Timer',
body: `Time: ${time}`,
categoryIdentifier: 'timer_controls',
},
trigger: null,
})
await Notifications.cancelScheduledNotificationAsync(identifier)
}
// handle on click start timer
const onStart = () => {
displayNotification()
setIsStopwatchStart(true);
setResetStopwatch(false);
}
// handle on click stop timer
const onStop = () => {
setIsStopwatchStart(false);
setResetStopwatch(false);
}
// handle on click reset timer
const onReset = () => {
setIsStopwatchStart(false);
setResetStopwatch(true);
// schedulePushNotification()
}
// testing code - used to simulate notification cancel
// async function schedulePushNotification(time = 10) {
// const identifier = await Notifications.scheduleNotificationAsync({
// identifier: 't',
// content: {
// title: "You've got mail! 📬",
// body: 'Here is the notification body: ' + time,
// data: {data: 'goes here'},
// },
// trigger: null,
// });
// await Notifications.cancelScheduledNotificationAsync(identifier)
// if (time > 0) {
// const delay = (t) => new Promise((resolve) => setTimeout(resolve, t * 1000))
// await delay(1)
// await schedulePushNotification(--time)
// return
// }
// }
// async function registerForPushNotificationsAsync() {
// let token;
// if (Platform.OS === 'android') {
// await Notifications.setNotificationChannelAsync('default', {
// name: 'default',
// importance: Notifications.AndroidImportance.MAX,
// vibrationPattern: [0, 250, 250, 250],
// lightColor: '#FF231F7C',
// });
// }
// if (Device.isDevice) {
// const {status: existingStatus} = await Notifications.getPermissionsAsync();
// let finalStatus = existingStatus;
// if (existingStatus !== 'granted') {
// const {status} = await Notifications.requestPermissionsAsync();
// finalStatus = status;
// }
// if (finalStatus !== 'granted') {
// alert('Failed to get device push token for push notification!');
// return;
// }
// token = (await Notifications.getExpoPushTokenAsync()).data;
// console.log(token);
// } else {
// alert('Must use a physical device for Push Notifications');
// }
// return token;
// }
return (
<SafeAreaView style={styles.container}>
<View style={styles.container}>
<Text style={styles.title}>
Example of React Native Timer and Stopwatch
</Text>
<View style={styles.sectionStyle}>
<Stopwatch
laps
secs
start={isStopwatchStart}
//To start
reset={resetStopwatch}
//To reset
options={options}
//options for the styling
getTime={(time) => setTime(time)}
/>
<TouchableHighlight
onPress={!isStopwatchStart ? onStart : onStop}>
<Text style={styles.buttonText}>
{!isStopwatchStart ? 'START' : 'STOP'}
</Text>
</TouchableHighlight>
<TouchableHighlight
onPress={onReset}>
<Text style={styles.buttonText}>RESET</Text>
</TouchableHighlight>
</View>
</View>
</SafeAreaView>
);
};
export default App;
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 10,
justifyContent: 'center',
alignItems: 'center',
},
title: {
textAlign: 'center',
fontSize: 20,
fontWeight: 'bold',
padding: 20,
},
sectionStyle: {
flex: 1,
marginTop: 32,
alignItems: 'center',
justifyContent: 'center',
},
buttonText: {
fontSize: 20,
marginTop: 10,
},
});
const options = {
container: {
backgroundColor: '#FF0000',
padding: 5,
borderRadius: 5,
width: 200,
alignItems: 'center',
},
text: {
fontSize: 25,
color: '#FFF',
marginLeft: 7,
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment