Skip to content

Instantly share code, notes, and snippets.

@vemarav
Last active October 29, 2020 00:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vemarav/2cf978e5bde669f7d69ce20e30c11bc3 to your computer and use it in GitHub Desktop.
Save vemarav/2cf978e5bde669f7d69ce20e30c11bc3 to your computer and use it in GitHub Desktop.
solution for BackgroundTimer setInverval not working in app background
// file: ./BackgroundTimer.js
import { DeviceEventEmitter, NativeAppEventEmitter, Platform } from 'react-native';
import _BackgroundTimer from 'react-native-background-timer'; // v2.1.1
const EventEmitter = Platform.select({
ios: () => NativeAppEventEmitter,
android: () => DeviceEventEmitter,
})();
class BackgroundTimer {
static setInterval(callback, delay) {
_BackgroundTimer.start();
this.backgroundListener = EventEmitter.addListener("backgroundTimer", () => {
this.backgroundTimer = _BackgroundTimer.setInterval(callback, delay);
});
return this.backgroundListener;
}
static clearInterval(timer) {
if (timer) timer.remove();
if (this.backgroundTimer)
_BackgroundTimer.clearInterval(this.backgroundTimer);
_BackgroundTimer.stop();
}
}
export default BackgroundTimer;
// File: ./Timer.js
import React, { Component } from 'react';
import { Text } from './Text';
import styled from 'styled-components';
import { isFunction } from 'lodash';
import BackgroundTimer from './BackgroundTimer';
const TimerView = styled(Text)`
color: ${({ theme, color }) => color || theme.grayColor};
font-size: ${({ size }) => size || 14}px;
text-align: center;
`;
interface ITimerProps {
fontSize?: number;
color?: string;
seconds: number;
onExpiry?: () => void
}
interface ITimerState {
seconds: number;
isDone: boolean;
}
class Timer extends Component<ITimerProps, ITimerState> {
private timer?: any;
constructor(props: ITimerProps) {
super(props);
this.state = {
seconds: props.seconds,
isDone: false
}
}
componentDidMount() {
this.startTimer()
}
componentWillUnmount() {
clearInterval(this.timer);
}
componentDidUpdate() {
this.clearTimer()
}
startTimer = () => {
this.timer = BackgroundTimer.setInterval(() => {
this.setState(state => ({
seconds: state.seconds - 1,
isDone: (state.seconds - 1) === 0
}));
}, 1000);
}
clearTimer = () => {
if (this.state.isDone) {
BackgroundTimer.clearInterval(this.timer);
if (isFunction(this.props.onExpiry)) {
this.props.onExpiry()
}
}
}
restart = () => {
const { seconds = 30 } = this.props;
this.setState({ seconds, isDone: false }, this.startTimer)
}
convertToMS = (timeInSeconds: number) => {
const minutes = Math.floor(timeInSeconds / 60);
const mm = minutes > 9 ? minutes : `0${minutes}`
const seconds = Math.floor(timeInSeconds % 60);
const ss = seconds > 9 ? seconds : `0${seconds}`
return `${mm} : ${ss}`;
}
render() {
const { fontSize, color } = this.props;
return (
this.state.isDone ? this.props.children :
<TimerView size={fontSize} color={color}>
{this.convertToMS(this.state.seconds)}
</TimerView>
);
}
}
export default Timer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment