import { Alert, Linking } from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import { isIOS } from './deviceInfo';
import I18n from '../i18n';
import { showErrorAlert } from './info';
import { STORE_REVIEW_LINK } from '../constants/links';
import { isFDroidBuild } from '../constants/environment';
import { logEvent, events } from './log';
const store = isIOS ? 'App Store' : 'Play Store';
const reviewKey = 'reviewKey';
const reviewDelay = 2000;
const numberOfDays = 7;
const numberOfPositiveEvent = 5;
const daysBetween = (date1, date2) => {
const one_day = 1000 * 60 * 60 * 24;
const date1_ms = date1.getTime();
const date2_ms = date2.getTime();
const difference_ms = date2_ms - date1_ms;
return Math.round(difference_ms / one_day);
};
const onCancelPress = () => {
try {
const data = JSON.stringify({ doneReview: true });
return AsyncStorage.setItem(reviewKey, data);
} catch (e) {
// do nothing
}
export const onReviewPress = async() => {
logEvent(events.SE_REVIEW_THIS_APP);
await onCancelPress();
const supported = await Linking.canOpenURL(STORE_REVIEW_LINK);
if (supported) {
Linking.openURL(STORE_REVIEW_LINK);
logEvent(events.SE_REVIEW_THIS_APP_F);
showErrorAlert(I18n.t('Review_app_unable_store', { store }));
const onAskMeLaterPress = () => {
const data = JSON.stringify({ lastReview: new Date().getTime() });
const onReviewButton = { text: I18n.t('Review_app_yes'), onPress: onReviewPress };
const onAskMeLaterButton = { text: I18n.t('Review_app_later'), onPress: onAskMeLaterPress };
const onCancelButton = { text: I18n.t('Review_app_no'), onPress: onCancelPress };
const askReview = () => Alert.alert(
I18n.t('Review_app_title'),
I18n.t('Review_app_desc', { store }),
isIOS
? [onReviewButton, onAskMeLaterButton, onCancelButton]
: [onAskMeLaterButton, onCancelButton, onReviewButton],
{
cancelable: true,
onDismiss: onAskMeLaterPress
);
const tryReview = async() => {
const data = await AsyncStorage.getItem(reviewKey) || '{}';
const reviewData = JSON.parse(data);
const { lastReview = 0, doneReview = false } = reviewData;
const lastReviewDate = new Date(lastReview);
// if ask me later was pressed earlier, we can ask for review only after {{numberOfDays}} days
// if there's no review and it wasn't dismissed by the user
if (daysBetween(lastReviewDate, new Date()) >= numberOfDays && !doneReview) {
setTimeout(askReview, reviewDelay);
class ReviewApp {
positiveEventCount = 0;
pushPositiveEvent = () => {
if (!isFDroidBuild) {
if (this.positiveEventCount >= numberOfPositiveEvent) {
return;
this.positiveEventCount += 1;
if (this.positiveEventCount === numberOfPositiveEvent) {
tryReview();
export const Review = new ReviewApp();