Skip to content

Commit

Permalink
Add store review prompt
Browse files Browse the repository at this point in the history
  • Loading branch information
wyne committed Mar 27, 2024
1 parent 7bf58f6 commit c4c693e
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 1 deletion.
8 changes: 7 additions & 1 deletion redux/SettingsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface SettingsState {
onboarded: string | undefined;
showPointParticles: boolean;
interactionType: InteractionType;
lastStoreReviewPrompt: number;
};

const initialState: SettingsState = {
Expand All @@ -24,6 +25,7 @@ const initialState: SettingsState = {
onboarded: undefined,
showPointParticles: true,
interactionType: InteractionType.SwipeVertical,
lastStoreReviewPrompt: 0,
};

const settingsSlice = createSlice({
Expand Down Expand Up @@ -55,7 +57,10 @@ const settingsSlice = createSlice({
const appVersion = new SemVer(Application.nativeApplicationVersion || '0.0.0');
console.log(`Setting Onboarded Version: ${appVersion}`);
state.onboarded = valid(appVersion) || '0.0.0';
}
},
setLastStoreReviewPrompt(state, action: PayloadAction<number>) {
state.lastStoreReviewPrompt = action.payload;
},
}
});

Expand All @@ -68,6 +73,7 @@ export const {
setOnboardedVersion,
toggleshowPointParticles,
setInteractionType,
setLastStoreReviewPrompt,
} = settingsSlice.actions;

export default settingsSlice.reducer;
9 changes: 9 additions & 0 deletions redux/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { InteractionType } from '../src/components/Interactions/InteractionType';

import { selectGameById } from './GamesSlice';
import { RootState } from './store'; // Import your RootState type

export const selectInteractionType = (state: RootState) => {
Expand All @@ -13,3 +14,11 @@ export const selectInteractionType = (state: RootState) => {

return safeInteractionType;
};

export const selectCurrentGame = (state: RootState) => {
const currentGameId = state.settings.currentGameId;
if (!currentGameId) return;

return selectGameById(state, currentGameId);
};
export const selectLastStoreReviewPrompt = (state: RootState) => state.settings.lastStoreReviewPrompt;
1 change: 1 addition & 0 deletions redux/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const settingsPersistConfig = {
'onboarded',
'showPointParticles',
'interactionType',
'lastStoreReviewPrompt',
],
};

Expand Down
36 changes: 36 additions & 0 deletions src/components/Buttons/HomeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ import React from 'react';
import analytics from '@react-native-firebase/analytics';
import { ParamListBase } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import * as StoreReview from 'expo-store-review';
import { Platform } from 'react-native';
import { Icon } from 'react-native-elements/dist/icons/Icon';

import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import { selectCurrentGame, selectLastStoreReviewPrompt } from '../../../redux/selectors';
import { setLastStoreReviewPrompt } from '../../../redux/SettingsSlice';
import { systemBlue } from '../../constants';

import HeaderButton from './HeaderButton';
Expand All @@ -14,10 +19,41 @@ interface Props {
}

const HomeButton: React.FunctionComponent<Props> = ({ navigation }) => {
const gameCount = useAppSelector((state) => state.games.ids.length);
const currentGame = useAppSelector(selectCurrentGame);
const roundCurrent = currentGame?.roundCurrent || 0;
const lastStoreReviewPrompt = useAppSelector(selectLastStoreReviewPrompt);
const dispatch = useAppDispatch();

const storePrompt = async () => {
const now = Date.now();
const daysSinceLastPrompt = (now - lastStoreReviewPrompt) / (1000 * 60 * 60 * 24);

if (gameCount < 3) { return; }
if (roundCurrent < 1) { return; }
if (daysSinceLastPrompt < 180) { return; }

console.log("Prompt for review");

dispatch(setLastStoreReviewPrompt(Date.now()));

const isAvailable = await StoreReview.isAvailableAsync();
if (isAvailable) {
const platform = Platform.OS;
if (platform === 'ios') {
StoreReview.requestReview();
} else if (platform === 'android') {
StoreReview.requestReview();
}
}
};

return (
<HeaderButton accessibilityLabel='Home' onPress={async () => {
navigation.navigate("List");
await analytics().logEvent('menu');

storePrompt();
}}>
<Icon name="bars"
type="font-awesome-5"
Expand Down

0 comments on commit c4c693e

Please sign in to comment.