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'; 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() => { await onCancelPress(); try { const supported = await Linking.canOpenURL(STORE_REVIEW_LINK); if (supported) { Linking.openURL(STORE_REVIEW_LINK); } } catch (e) { showErrorAlert(I18n.t('Review_app_unable_store', { store })); } }; const onAskMeLaterPress = () => { try { const data = JSON.stringify({ lastReview: new Date().getTime() }); return AsyncStorage.setItem(reviewKey, data); } catch (e) { // do nothing } }; 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 (this.positiveEventCount >= numberOfPositiveEvent) { return; } this.positiveEventCount += 1; if (this.positiveEventCount === numberOfPositiveEvent) { tryReview(); } } } export const Review = new ReviewApp();