Skip to content

Commit

Permalink
Add analytics wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
wyne committed Jul 18, 2024
1 parent 21990ac commit a8a19c2
Show file tree
Hide file tree
Showing 24 changed files with 75 additions and 53 deletions.
1 change: 1 addition & 0 deletions __mocks__/Analytics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const logEvent = jest.fn();
6 changes: 3 additions & 3 deletions redux/GamesSlice.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import analytics from '@react-native-firebase/analytics';
import { PayloadAction, createAsyncThunk, createEntityAdapter, createSelector, createSlice } from '@reduxjs/toolkit';
import { getContrastRatio } from 'colorsheet';
import * as Crypto from 'expo-crypto';

import { logEvent } from '../src/Analytics';
import { getPalette } from '../src/ColorPalette';
import { SortDirectionKey, SortSelectorKey } from '../src/components/ScoreLog/SortHelper';
import logger from '../src/Logger';
Expand Down Expand Up @@ -153,7 +153,7 @@ export const asyncRematchGame = createAsyncThunk(

dispatch(setCurrentGameId(newGameId));

await analytics().logEvent('rematch_game', {
await logEvent('rematch_game', {
gameId: game.id,
});

Expand Down Expand Up @@ -226,7 +226,7 @@ export const asyncCreateGame = createAsyncThunk(

dispatch(setCurrentGameId(newGameId));

await analytics().logEvent('new_game', {
await logEvent('new_game', {
index: gameCount,
});

Expand Down
17 changes: 17 additions & 0 deletions src/Analytics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import analytics from '@react-native-firebase/analytics';

import logger from './Logger';

/**
* Logs an event to Firebase Analytics with additional logging.
* @param eventName The name of the event to log.
* @param params The parameters of the event.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const logEvent = async (eventName: string, params?: Record<string, any>) => {
// Additional logging logic here (e.g., console.log for debugging)
logger.log(`Logging event: ${eventName}`, params);

// Log the event to Firebase Analytics
await analytics().logEvent(eventName, params);
};
4 changes: 2 additions & 2 deletions src/components/AppInfo/RotatingIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';

import analytics from '@react-native-firebase/analytics';
import * as Haptics from 'expo-haptics';
import { Image } from 'expo-image';
import { TouchableWithoutFeedback } from 'react-native';
Expand All @@ -13,6 +12,7 @@ import Animated, {

import { useAppDispatch } from '../../../redux/hooks';
import { toggleDevMenuEnabled } from '../../../redux/SettingsSlice';
import { logEvent } from '../../Analytics';

const RotatingIcon: React.FunctionComponent = ({ }) => {
const dispatch = useAppDispatch();
Expand Down Expand Up @@ -48,7 +48,7 @@ const RotatingIcon: React.FunctionComponent = ({ }) => {
rotationCount.value = rotationCount.value + 1;
rotation.value = withTiming((rotationCount.value * 90), { duration: 1000, easing: Easing.elastic(1) });

await analytics().logEvent('app_icon');
await logEvent('app_icon');
}}>
<Animated.View style={[animatedStyles]}>
<Image source={require('../../../assets/icon.png')}
Expand Down
8 changes: 5 additions & 3 deletions src/components/Buttons/AppInfoButton.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import analytics from '@react-native-firebase/analytics';
import { render, fireEvent, waitFor } from '@testing-library/react-native';
import { fireEvent, render, waitFor } from '@testing-library/react-native';

import { useNavigationMock } from '../../../test/test-helpers';
import { logEvent } from '../../Analytics';

import AppInfoButton from './AppInfoButton';

jest.mock('../../Analytics');

describe('AppInfoButton', () => {
const navigation = useNavigationMock();

Expand All @@ -22,7 +24,7 @@ describe('AppInfoButton', () => {
fireEvent.press(button);

await waitFor(() => {
expect(analytics().logEvent).toHaveBeenCalledWith('app_info');
expect(logEvent).toHaveBeenCalledWith('app_info');
});
});
});
4 changes: 2 additions & 2 deletions src/components/Buttons/AppInfoButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
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 { Icon } from 'react-native-elements/dist/icons/Icon';

import { logEvent } from '../../Analytics';
import { systemBlue } from '../../constants';

import HeaderButton from './HeaderButton';
Expand All @@ -17,7 +17,7 @@ const AppInfoButton: React.FunctionComponent<Props> = ({ navigation }) => {
return (
<HeaderButton accessibilityLabel='App Info' onPress={async () => {
navigation.navigate('AppInfo');
await analytics().logEvent('app_info');
await logEvent('app_info');
}}>
<Icon name="gear"
type="font-awesome"
Expand Down
4 changes: 2 additions & 2 deletions src/components/Buttons/BackButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
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 { Icon } from 'react-native-elements/dist/icons/Icon';

import { logEvent } from '../../Analytics';
import { systemBlue } from '../../constants';

import HeaderButton from './HeaderButton';
Expand All @@ -17,7 +17,7 @@ const BackButton: React.FunctionComponent<Props> = ({ navigation }) => {
return (
<HeaderButton accessibilityLabel='Home' onPress={async () => {
navigation.goBack();
await analytics().logEvent('menu');
await logEvent('menu');
}}>
<Icon name="bars"
type="font-awesome-5"
Expand Down
8 changes: 5 additions & 3 deletions src/components/Buttons/CheckButton.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import analytics from '@react-native-firebase/analytics';
import { render, fireEvent, waitFor } from '@testing-library/react-native';
import { fireEvent, render, waitFor } from '@testing-library/react-native';

import { useNavigationMock } from '../../../test/test-helpers';
import { logEvent } from '../../Analytics';

import CheckButton from './CheckButton';

jest.mock('../../Analytics');

describe('CheckButton', () => {
const navigation = useNavigationMock();

Expand Down Expand Up @@ -33,7 +35,7 @@ describe('CheckButton', () => {
fireEvent.press(button);

await waitFor(() => {
expect(analytics().logEvent).toHaveBeenCalledWith('save_game');
expect(logEvent).toHaveBeenCalledWith('save_game');
});
});
});
4 changes: 2 additions & 2 deletions src/components/Buttons/CheckButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';

import analytics from '@react-native-firebase/analytics';
import { ParamListBase, RouteProp } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { Text } from 'react-native';

import { logEvent } from '../../Analytics';
import { systemBlue } from '../../constants';

import HeaderButton from './HeaderButton';
Expand All @@ -23,7 +23,7 @@ const CheckButton: React.FunctionComponent<Props> = ({ navigation, route }) => {

return (
<HeaderButton accessibilityLabel='Save Game' onPress={async () => {
await analytics().logEvent('save_game');
await logEvent('save_game');
if (route?.params?.source === 'list_screen') {
navigation.navigate('List');
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/components/Buttons/FullscreenButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';

import analytics from '@react-native-firebase/analytics';
import { Icon } from 'react-native-elements/dist/icons/Icon';

import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import { toggleHomeFullscreen } from '../../../redux/SettingsSlice';
import { logEvent } from '../../Analytics';
import { systemBlue } from '../../constants';

import HeaderButton from './HeaderButton';
Expand All @@ -15,7 +15,7 @@ const FullscreenButton: React.FunctionComponent = ({ }) => {

const expandHandler = async () => {
dispatch(toggleHomeFullscreen());
await analytics().logEvent('fullscreen');
await logEvent('fullscreen');
};

return (
Expand Down
6 changes: 3 additions & 3 deletions src/components/Buttons/HomeButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
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';
Expand All @@ -10,6 +9,7 @@ import { Icon } from 'react-native-elements/dist/icons/Icon';
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import { selectLastStoreReviewPrompt } from '../../../redux/selectors';
import { setLastStoreReviewPrompt } from '../../../redux/SettingsSlice';
import { logEvent } from '../../Analytics';
import { systemBlue } from '../../constants';

import HeaderButton from './HeaderButton';
Expand All @@ -30,7 +30,7 @@ const HomeButton: React.FunctionComponent<Props> = ({ navigation }) => {
if (gameCount < 3) { return; }
if (daysSinceLastPrompt < 90) { return; }

await analytics().logEvent('review_prompt');
await logEvent('review_prompt');

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

Expand All @@ -49,7 +49,7 @@ const HomeButton: React.FunctionComponent<Props> = ({ navigation }) => {
return (
<HeaderButton accessibilityLabel='Home' onPress={async () => {
navigation.navigate('List');
await analytics().logEvent('menu');
await logEvent('menu');

storePrompt();
}}>
Expand Down
4 changes: 2 additions & 2 deletions src/components/GameListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useCallback } from 'react';

import analytics from '@react-native-firebase/analytics';
import { ParamListBase } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import * as Haptics from 'expo-haptics';
Expand All @@ -12,6 +11,7 @@ import Animated, { FadeInUp, SlideOutLeft } from 'react-native-reanimated';
import { selectGameById } from '../../redux/GamesSlice';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import { setCurrentGameId } from '../../redux/SettingsSlice';
import { logEvent } from '../Analytics';

import GameListItemPlayerName from './GameListItemPlayerName';
import AbstractPopupMenu from './PopupMenu/AbstractPopupMenu';
Expand Down Expand Up @@ -45,7 +45,7 @@ const GameListItem: React.FunctionComponent<Props> = ({ navigation, gameId, inde
setCurrentGameCallback();
navigation.navigate('Game');

await analytics().logEvent('select_game', {
await logEvent('select_game', {
index: index,
game_id: gameId,
player_count: playerIds.length,
Expand Down
4 changes: 2 additions & 2 deletions src/components/Headers/EditPlayerHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';

import { getAnalytics } from '@react-native-firebase/analytics';
import { ParamListBase, RouteProp } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { StyleSheet, Text } from 'react-native';

import { logEvent } from '../../Analytics';
import { systemBlue } from '../../constants';
import HeaderButton from '../Buttons/HeaderButton';

Expand All @@ -28,7 +28,7 @@ const EditPlayerHeader: React.FunctionComponent<EditPlayerScreenProps> = ({ navi
headerLeft={
<HeaderButton accessibilityLabel='EditPlayerBack' onPress={async () => {
navigation.goBack();
await getAnalytics().logEvent('edit_player_back');
await logEvent('edit_player_back');
}}>
<Text style={{ color: systemBlue, fontSize: 20 }}>Back</Text>
</HeaderButton>
Expand Down
6 changes: 3 additions & 3 deletions src/components/Headers/GameHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
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 Haptics from 'expo-haptics';
Expand All @@ -10,6 +9,7 @@ import { Icon } from 'react-native-elements/dist/icons/Icon';

import { roundNext, roundPrevious, selectGameById } from '../../../redux/GamesSlice';
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import { logEvent } from '../../Analytics';
import { systemBlue } from '../../constants';
import AddendButton from '../Buttons/AddendButton';
import FullscreenButton from '../Buttons/FullscreenButton';
Expand Down Expand Up @@ -92,7 +92,7 @@ const GameHeader: React.FunctionComponent<Props> = ({ navigation }) => {
}

dispatch(roundNext(currentGame.id));
analytics().logEvent('round_change', {
logEvent('round_change', {
game_id: currentGameId,
source: 'next button',
round: roundCurrent,
Expand All @@ -105,7 +105,7 @@ const GameHeader: React.FunctionComponent<Props> = ({ navigation }) => {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);

dispatch(roundPrevious(currentGame.id));
analytics().logEvent('round_change', {
logEvent('round_change', {
game_id: currentGameId,
source: 'previous button',
round: roundCurrent,
Expand Down
4 changes: 2 additions & 2 deletions src/components/Interactions/HalfTap/HalfTileTouchSurface.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useState } from 'react';

import analytics from '@react-native-firebase/analytics';
import * as Haptics from 'expo-haptics';
import { StyleSheet, TouchableHighlight, View } from 'react-native';

import { useAppDispatch, useAppSelector } from '../../../../redux/hooks';
import { playerRoundScoreIncrement } from '../../../../redux/PlayersSlice';
import { selectCurrentGame } from '../../../../redux/selectors';
import { logEvent } from '../../../Analytics';
import { ScoreParticle } from '../../PlayerTiles/AdditionTile/ScoreParticle';

type ScoreParticleProps = {
Expand Down Expand Up @@ -55,7 +55,7 @@ export const HalfTileTouchSurface: React.FunctionComponent<Props> = (
addParticle(addend);
}
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
analytics().logEvent('score_change', {
logEvent('score_change', {
player_index: playerIndex,
game_id: currentGameId,
addend: addend,
Expand Down
4 changes: 2 additions & 2 deletions src/components/PlayerListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
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 { Alert, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
Expand All @@ -10,6 +9,7 @@ import { makeSelectPlayerColors, selectGameById, updateGame } from '../../redux/
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import { removePlayer, selectPlayerById } from '../../redux/PlayersSlice';
import { selectCurrentGame } from '../../redux/selectors';
import { logEvent } from '../Analytics';

interface Props {
playerId: string;
Expand Down Expand Up @@ -62,7 +62,7 @@ const PlayerListItem: React.FunctionComponent<Props> = ({
const deleteHandler = async () => {
removePlayerHandler();

await analytics().logEvent('remove_player', {
await logEvent('remove_player', {
game_id: currentGameId,
player_index: index,
});
Expand Down
Loading

0 comments on commit a8a19c2

Please sign in to comment.