From 0a6b80c9fa33d5bf97be89c3d2f8c46165e39fa4 Mon Sep 17 00:00:00 2001 From: Justin Wyne <1986068+wyne@users.noreply.github.com> Date: Mon, 25 Dec 2023 11:57:34 -0500 Subject: [PATCH 1/7] Store Review dependencies --- package-lock.json | 27 +++++++++++++++++++++++++++ package.json | 4 +++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 052449bf..0e56375a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,11 +35,13 @@ "expo-device": "~5.4.0", "expo-haptics": "~12.4.0", "expo-image": "~1.3.2", + "expo-linking": "~5.0.2", "expo-screen-orientation": "~6.0.5", "expo-sensors": "~12.3.0", "expo-sharing": "~11.5.0", "expo-splash-screen": "~0.20.5", "expo-status-bar": "~1.6.0", + "expo-store-review": "~6.4.0", "expo-system-ui": "~2.4.0", "expo-updates": "~0.18.12", "firebase": "^9.17.1", @@ -8047,6 +8049,11 @@ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, + "node_modules/@types/qs": { + "version": "6.9.11", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", + "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" + }, "node_modules/@types/react": { "version": "18.2.45", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.45.tgz", @@ -11970,6 +11977,18 @@ "expo": "*" } }, + "node_modules/expo-linking": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-5.0.2.tgz", + "integrity": "sha512-SPQus0+tYGx9c69Uw4wmdo3rkKX8vRT1vyJz/mvkpSlZN986s0NmP/V0M5vDv5Zv2qZzVdqJyuITFe0Pg5aI+A==", + "dependencies": { + "@types/qs": "^6.9.7", + "expo-constants": "~14.4.2", + "invariant": "^2.2.4", + "qs": "^6.11.0", + "url-parse": "^1.5.9" + } + }, "node_modules/expo-manifests": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/expo-manifests/-/expo-manifests-0.7.2.tgz", @@ -12186,6 +12205,14 @@ "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.6.0.tgz", "integrity": "sha512-e//Oi2WPdomMlMDD3skE4+1ZarKCJ/suvcB4Jo/nO427niKug5oppcPNYO+csR6y3ZglGuypS+3pp/hJ+Xp6fQ==" }, + "node_modules/expo-store-review": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/expo-store-review/-/expo-store-review-6.4.0.tgz", + "integrity": "sha512-aD06KSOO9syeecaP9NfJO++FzmfQjg49HY7qeUQ9r826YqswW/FPAcnXY0RJLhfJTqeAPRSl/xzPLZA5vwdqLQ==", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-structured-headers": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/expo-structured-headers/-/expo-structured-headers-3.3.0.tgz", diff --git a/package.json b/package.json index 513429c9..4d69627d 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,9 @@ "react-redux": "^8.0.2", "redux-persist": "^6.0.0", "semver": "^7.5.4", - "typescript": "^5.1.6" + "typescript": "^5.1.6", + "expo-store-review": "~6.4.0", + "expo-linking": "~5.0.2" }, "devDependencies": { "@babel/core": "^7.19.3", From c4c693e9f9a80cd599da618ca04d5963afb4aa2b Mon Sep 17 00:00:00 2001 From: Justin Wyne <1986068+wyne@users.noreply.github.com> Date: Wed, 27 Mar 2024 01:25:33 -0700 Subject: [PATCH 2/7] Add store review prompt --- redux/SettingsSlice.ts | 8 +++++- redux/selectors.ts | 9 +++++++ redux/store.ts | 1 + src/components/Buttons/HomeButton.tsx | 36 +++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/redux/SettingsSlice.ts b/redux/SettingsSlice.ts index eb9cc287..6ac6318e 100644 --- a/redux/SettingsSlice.ts +++ b/redux/SettingsSlice.ts @@ -13,6 +13,7 @@ export interface SettingsState { onboarded: string | undefined; showPointParticles: boolean; interactionType: InteractionType; + lastStoreReviewPrompt: number; }; const initialState: SettingsState = { @@ -24,6 +25,7 @@ const initialState: SettingsState = { onboarded: undefined, showPointParticles: true, interactionType: InteractionType.SwipeVertical, + lastStoreReviewPrompt: 0, }; const settingsSlice = createSlice({ @@ -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) { + state.lastStoreReviewPrompt = action.payload; + }, } }); @@ -68,6 +73,7 @@ export const { setOnboardedVersion, toggleshowPointParticles, setInteractionType, + setLastStoreReviewPrompt, } = settingsSlice.actions; export default settingsSlice.reducer; diff --git a/redux/selectors.ts b/redux/selectors.ts index 1aef08a3..c017826f 100644 --- a/redux/selectors.ts +++ b/redux/selectors.ts @@ -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) => { @@ -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; diff --git a/redux/store.ts b/redux/store.ts index b3aadeea..24b8248f 100644 --- a/redux/store.ts +++ b/redux/store.ts @@ -19,6 +19,7 @@ const settingsPersistConfig = { 'onboarded', 'showPointParticles', 'interactionType', + 'lastStoreReviewPrompt', ], }; diff --git a/src/components/Buttons/HomeButton.tsx b/src/components/Buttons/HomeButton.tsx index 1c95e0a8..472ac205 100644 --- a/src/components/Buttons/HomeButton.tsx +++ b/src/components/Buttons/HomeButton.tsx @@ -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'; @@ -14,10 +19,41 @@ interface Props { } const HomeButton: React.FunctionComponent = ({ 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 ( { navigation.navigate("List"); await analytics().logEvent('menu'); + + storePrompt(); }}> Date: Wed, 27 Mar 2024 01:44:49 -0700 Subject: [PATCH 3/7] Better redux store typing --- redux/GamesSlice.ts | 21 +++++++++++-------- redux/store.ts | 7 ++++++- src/components/Boards/FlexboxBoard.tsx | 4 ++-- src/components/Boards/FlexboxTile.tsx | 6 ++---- src/components/EditGame.tsx | 7 ++++--- src/components/EditPlayer.tsx | 10 ++++----- .../Interactions/HalfTap/HalfTap.tsx | 6 ++---- .../HalfTap/HalfTileTouchSurface.tsx | 4 ++-- src/components/Interactions/Swipe/Swipe.tsx | 4 ++-- .../PlayerTiles/AdditionTile/AdditionTile.tsx | 5 ++--- src/components/ScoreLog/PlayerNameColumn.tsx | 10 +++++---- src/components/ScoreLog/RoundScoreColumn.tsx | 9 ++++---- src/components/ScoreLog/TotalScoreColumn.tsx | 7 +++---- src/components/Sheets/GameSheet.tsx | 7 ++++--- src/screens/GameScreen.tsx | 4 ++-- src/screens/SettingsScreen.tsx | 5 +++-- src/screens/ShareScreen.tsx | 5 +++-- 17 files changed, 65 insertions(+), 56 deletions(-) diff --git a/redux/GamesSlice.ts b/redux/GamesSlice.ts index 9d949cc2..96d490ec 100644 --- a/redux/GamesSlice.ts +++ b/redux/GamesSlice.ts @@ -2,7 +2,7 @@ import analytics from '@react-native-firebase/analytics'; import { createSlice, PayloadAction, createEntityAdapter, createAsyncThunk, createSelector } from '@reduxjs/toolkit'; import * as Crypto from 'expo-crypto'; -import { playerAdd, selectAllPlayers } from './PlayersSlice'; +import { ScoreState, playerAdd, selectAllPlayers } from './PlayersSlice'; import { setCurrentGameId } from './SettingsSlice'; import { RootState } from './store'; @@ -65,7 +65,7 @@ interface GamesSlice { export const asyncCreateGame = createAsyncThunk( 'games/create', async ( - { gameCount, playerCount }: { gameCount: number, playerCount: number }, + { gameCount, playerCount }: { gameCount: number, playerCount: number; }, { dispatch } ) => { const newGameId = Crypto.randomUUID(); @@ -105,14 +105,17 @@ export const asyncCreateGame = createAsyncThunk( export const selectSortedPlayers = createSelector( [ selectAllPlayers, - (state: RootState) => state.games.entities[state.settings.currentGameId] + (state: RootState) => state.settings.currentGameId ? state.games.entities[state.settings.currentGameId] : undefined ], - (players, currentGame) => players - .filter(player => currentGame?.playerIds.includes(player.id)) - .sort((a, b) => { - if (currentGame?.playerIds == undefined) return 0; - return currentGame.playerIds.indexOf(a.id) - currentGame.playerIds.indexOf(b.id); - }) + (players: ScoreState[], currentGame: GameState | undefined) => { + if (!currentGame) return []; + + return players.filter(player => currentGame.playerIds?.includes(player.id)) + .sort((a, b) => { + if (currentGame?.playerIds == undefined) return 0; + return currentGame.playerIds.indexOf(a.id) - currentGame.playerIds.indexOf(b.id); + }); + } ); export const { diff --git a/redux/store.ts b/redux/store.ts index 24b8248f..504acbf7 100644 --- a/redux/store.ts +++ b/redux/store.ts @@ -52,7 +52,12 @@ export const store = configureStore({ }); // Infer the `RootState` and `AppDispatch` types from the store itself -export type RootState = ReturnType; +export interface RootState { + settings: ReturnType; + games: ReturnType; + players: ReturnType; +} + // Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState} export type AppDispatch = typeof store.dispatch; diff --git a/src/components/Boards/FlexboxBoard.tsx b/src/components/Boards/FlexboxBoard.tsx index 56136e0d..5ffe3c1a 100644 --- a/src/components/Boards/FlexboxBoard.tsx +++ b/src/components/Boards/FlexboxBoard.tsx @@ -4,8 +4,8 @@ import { getContrastRatio } from 'colorsheet'; import { LayoutChangeEvent, StyleSheet } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; -import { selectGameById } from '../../../redux/GamesSlice'; import { useAppSelector } from '../../../redux/hooks'; +import { selectCurrentGame } from '../../../redux/selectors'; import { bottomSheetHeight } from '../../components/Sheets/GameSheet'; import FlexboxTile from './FlexboxTile'; @@ -22,7 +22,7 @@ const FlexboxBoard: React.FC = () => { const [rows, setRows] = useState(0); const [cols, setCols] = useState(0); const fullscreen = useAppSelector(state => state.settings.home_fullscreen); - const currentGame = useAppSelector(state => selectGameById(state, state.settings.currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); const [width, setWidth] = useState(null); const [height, setHeight] = useState(null); diff --git a/src/components/Boards/FlexboxTile.tsx b/src/components/Boards/FlexboxTile.tsx index 3b8df2bd..7158802b 100644 --- a/src/components/Boards/FlexboxTile.tsx +++ b/src/components/Boards/FlexboxTile.tsx @@ -3,9 +3,8 @@ import React from 'react'; import { DimensionValue, StyleSheet } from 'react-native'; import Animated, { Easing, FadeIn } from 'react-native-reanimated'; -import { selectGameById } from '../../../redux/GamesSlice'; import { useAppSelector } from '../../../redux/hooks'; -import { selectInteractionType } from '../../../redux/selectors'; +import { selectCurrentGame, selectInteractionType } from '../../../redux/selectors'; import { interactionComponents } from '../Interactions/InteractionComponents'; import { InteractionType } from '../Interactions/InteractionType'; import AdditionTile from '../PlayerTiles/AdditionTile/AdditionTile'; @@ -35,8 +34,7 @@ const FlexboxTile: React.FunctionComponent = ({ if (!(width > 0 && height > 0)) return null; if (Number.isNaN(width) || Number.isNaN(height)) return null; - const currentGameId = useAppSelector(state => state.settings.currentGameId); - const currentGame = useAppSelector(state => selectGameById(state, currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); if (typeof currentGame == 'undefined') return null; const widthPerc: DimensionValue = `${(100 / cols)}%`; diff --git a/src/components/EditGame.tsx b/src/components/EditGame.tsx index c51f28d8..f4271656 100644 --- a/src/components/EditGame.tsx +++ b/src/components/EditGame.tsx @@ -1,16 +1,17 @@ import React, { useState } from 'react'; -import { Text, View, StyleSheet, NativeSyntheticEvent, TextInputEndEditingEventData } from 'react-native'; +import { NativeSyntheticEvent, StyleSheet, Text, TextInputEndEditingEventData, View } from 'react-native'; import { Input } from 'react-native-elements'; -import { selectGameById, updateGame } from '../../redux/GamesSlice'; +import { updateGame } from '../../redux/GamesSlice'; import { useAppDispatch, useAppSelector } from '../../redux/hooks'; +import { selectCurrentGame } from '../../redux/selectors'; const UNTITLED = "Untitled"; const EditGame = ({ }) => { const dispatch = useAppDispatch(); - const currentGame = useAppSelector(state => selectGameById(state, state.settings.currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); if (typeof currentGame == 'undefined') return null; diff --git a/src/components/EditPlayer.tsx b/src/components/EditPlayer.tsx index 258ad0a4..0b93b796 100644 --- a/src/components/EditPlayer.tsx +++ b/src/components/EditPlayer.tsx @@ -1,16 +1,16 @@ import React from 'react'; import analytics from '@react-native-firebase/analytics'; -import { Text, View, StyleSheet, TouchableOpacity, NativeSyntheticEvent, TextInputEndEditingEventData, Alert } from 'react-native'; +import { Alert, NativeSyntheticEvent, StyleSheet, Text, TextInputEndEditingEventData, TouchableOpacity, View } from 'react-native'; import { Icon, Input } from 'react-native-elements'; import Animated from 'react-native-reanimated'; -import { selectGameById, updateGame } from '../../redux/GamesSlice'; +import { updateGame } from '../../redux/GamesSlice'; import { useAppDispatch, useAppSelector } from '../../redux/hooks'; -import { selectPlayerById , removePlayer, updatePlayer } from '../../redux/PlayersSlice'; +import { removePlayer, selectPlayerById, updatePlayer } from '../../redux/PlayersSlice'; +import { selectCurrentGame } from '../../redux/selectors'; import { palette } from '../constants'; - interface Props { playerId: string; index: number; @@ -20,7 +20,7 @@ interface Props { const EditPlayer: React.FunctionComponent = ({ playerId, index, setPlayerWasAdded, playerWasAdded }) => { const dispatch = useAppDispatch(); - const currentGame = useAppSelector(state => selectGameById(state, state.settings.currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); const player = useAppSelector(state => selectPlayerById(state, playerId)); if (typeof currentGame == 'undefined') return null; diff --git a/src/components/Interactions/HalfTap/HalfTap.tsx b/src/components/Interactions/HalfTap/HalfTap.tsx index 90025917..d343d79f 100644 --- a/src/components/Interactions/HalfTap/HalfTap.tsx +++ b/src/components/Interactions/HalfTap/HalfTap.tsx @@ -1,9 +1,8 @@ import React from 'react'; - -import { selectGameById } from '../../../../redux/GamesSlice'; import { useAppSelector } from '../../../../redux/hooks'; import { selectPlayerById } from '../../../../redux/PlayersSlice'; +import { selectCurrentGame } from '../../../../redux/selectors'; import { HalfTileTouchSurface } from './HalfTileTouchSurface'; @@ -20,8 +19,7 @@ const HalfTap: React.FC = ({ fontColor, playerId }) => { - const currentGameId = useAppSelector(state => state.settings.currentGameId); - const currentGame = useAppSelector(state => selectGameById(state, currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); if (typeof currentGame == 'undefined') return null; const player = useAppSelector(state => selectPlayerById(state, playerId)); diff --git a/src/components/Interactions/HalfTap/HalfTileTouchSurface.tsx b/src/components/Interactions/HalfTap/HalfTileTouchSurface.tsx index 6c95a676..9a232a77 100644 --- a/src/components/Interactions/HalfTap/HalfTileTouchSurface.tsx +++ b/src/components/Interactions/HalfTap/HalfTileTouchSurface.tsx @@ -4,9 +4,9 @@ import analytics from '@react-native-firebase/analytics'; import * as Haptics from 'expo-haptics'; import { StyleSheet, TouchableHighlight, View } from 'react-native'; -import { selectGameById } from '../../../../redux/GamesSlice'; import { useAppDispatch, useAppSelector } from '../../../../redux/hooks'; import { playerRoundScoreIncrement } from '../../../../redux/PlayersSlice'; +import { selectCurrentGame } from '../../../../redux/selectors'; import { ScoreParticle } from '../../PlayerTiles/AdditionTile/ScoreParticle'; type ScoreParticleProps = { @@ -33,7 +33,7 @@ export const HalfTileTouchSurface: React.FunctionComponent = ( const addendTwo = useAppSelector(state => state.settings.addendTwo); const currentGameId = useAppSelector(state => state.settings.currentGameId); - const currentGame = useAppSelector(state => selectGameById(state, currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); if (typeof currentGame == 'undefined') return null; const roundCurrent = currentGame.roundCurrent; diff --git a/src/components/Interactions/Swipe/Swipe.tsx b/src/components/Interactions/Swipe/Swipe.tsx index d8198cef..329406e7 100644 --- a/src/components/Interactions/Swipe/Swipe.tsx +++ b/src/components/Interactions/Swipe/Swipe.tsx @@ -6,9 +6,9 @@ import { Animated, StyleSheet, View } from 'react-native'; import { PanGestureHandler, PanGestureHandlerStateChangeEvent, State } from 'react-native-gesture-handler'; import { runOnJS, useAnimatedReaction, useSharedValue } from 'react-native-reanimated'; -import { selectGameById } from '../../../../redux/GamesSlice'; import { useAppDispatch, useAppSelector } from '../../../../redux/hooks'; import { playerRoundScoreIncrement } from '../../../../redux/PlayersSlice'; +import { selectCurrentGame } from '../../../../redux/selectors'; interface HalfTapProps { children: React.ReactNode; @@ -27,7 +27,7 @@ const SwipeVertical: React.FC = ({ //#region Selector setup const currentGameId = useAppSelector(state => state.settings.currentGameId); - const currentGame = useAppSelector(state => selectGameById(state, currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); if (typeof currentGame == 'undefined') return null; const roundCurrent = currentGame.roundCurrent; diff --git a/src/components/PlayerTiles/AdditionTile/AdditionTile.tsx b/src/components/PlayerTiles/AdditionTile/AdditionTile.tsx index 7881a1fb..7195abdd 100644 --- a/src/components/PlayerTiles/AdditionTile/AdditionTile.tsx +++ b/src/components/PlayerTiles/AdditionTile/AdditionTile.tsx @@ -3,9 +3,9 @@ import React from 'react'; import { StyleSheet } from 'react-native'; import Animated from 'react-native-reanimated'; -import { selectGameById } from '../../../../redux/GamesSlice'; import { useAppSelector } from '../../../../redux/hooks'; import { selectPlayerById } from '../../../../redux/PlayersSlice'; +import { selectCurrentGame } from '../../../../redux/selectors'; import { calculateFontSize } from './Helpers'; import ScoreAfter from './ScoreAfter'; @@ -26,8 +26,7 @@ const AdditionTile: React.FunctionComponent = ({ maxHeight, playerId, }) => { - const currentGameId = useAppSelector(state => state.settings.currentGameId); - const currentGame = useAppSelector(state => selectGameById(state, currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); if (typeof currentGame == 'undefined') return null; const roundCurrent = currentGame.roundCurrent; diff --git a/src/components/ScoreLog/PlayerNameColumn.tsx b/src/components/ScoreLog/PlayerNameColumn.tsx index af125472..011ea6a7 100644 --- a/src/components/ScoreLog/PlayerNameColumn.tsx +++ b/src/components/ScoreLog/PlayerNameColumn.tsx @@ -1,20 +1,22 @@ import React from 'react'; -import { Text, View, StyleSheet } from 'react-native'; +import { StyleSheet, Text, View } from 'react-native'; import { Icon } from 'react-native-elements/dist/icons/Icon'; -import { selectGameById, selectSortedPlayers } from '../../../redux/GamesSlice'; +import { selectSortedPlayers } from '../../../redux/GamesSlice'; import { useAppSelector } from '../../../redux/hooks'; +import { selectCurrentGame } from '../../../redux/selectors'; import { palette, systemBlue } from '../../constants'; const PlayerNameColumn: React.FunctionComponent = ({ }) => { - const currentGameId = useAppSelector(state => state.settings.currentGameId); - const currentGame = useAppSelector(state => selectGameById(state, currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); if (currentGame == undefined) return null; const players = useAppSelector(selectSortedPlayers); + if (players == undefined) return null; + return ( diff --git a/src/components/ScoreLog/RoundScoreColumn.tsx b/src/components/ScoreLog/RoundScoreColumn.tsx index b86feed0..b0ed0068 100644 --- a/src/components/ScoreLog/RoundScoreColumn.tsx +++ b/src/components/ScoreLog/RoundScoreColumn.tsx @@ -1,10 +1,11 @@ import React, { memo, useCallback } from 'react'; import analytics from '@react-native-firebase/analytics'; -import { Text, View , TouchableWithoutFeedback } from 'react-native'; +import { Text, TouchableWithoutFeedback, View } from 'react-native'; -import { selectGameById, updateGame } from '../../../redux/GamesSlice'; +import { updateGame } from '../../../redux/GamesSlice'; import { useAppDispatch, useAppSelector } from '../../../redux/hooks'; +import { selectCurrentGame } from '../../../redux/selectors'; import RoundScoreCell from './RoundScoreCell'; @@ -18,12 +19,12 @@ const RoundScoreColumn: React.FunctionComponent = ({ round, isCurrentRoun const dispatch = useAppDispatch(); const currentGameId = useAppSelector(state => state.settings.currentGameId); - const currentGame = useAppSelector(state => selectGameById(state, currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); if (typeof currentGame == 'undefined') return null; const onPressHandler = useCallback(async () => { - if (disabled) return; + if (disabled || !currentGameId) return; dispatch(updateGame({ id: currentGameId, diff --git a/src/components/ScoreLog/TotalScoreColumn.tsx b/src/components/ScoreLog/TotalScoreColumn.tsx index 8c8f5f6b..c0a6b49c 100644 --- a/src/components/ScoreLog/TotalScoreColumn.tsx +++ b/src/components/ScoreLog/TotalScoreColumn.tsx @@ -1,15 +1,14 @@ import React from 'react'; -import { Text, View, StyleSheet } from 'react-native'; +import { StyleSheet, Text, View } from 'react-native'; -import { selectGameById } from '../../../redux/GamesSlice'; import { useAppSelector } from '../../../redux/hooks'; +import { selectCurrentGame } from '../../../redux/selectors'; import TotalScoreCell from './TotalScoreCell'; const TotalScoreColumn = ({ }) => { - const currentGameId = useAppSelector(state => state.settings.currentGameId); - const currentGame = useAppSelector(state => selectGameById(state, currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); if (typeof currentGame == 'undefined') return null; diff --git a/src/components/Sheets/GameSheet.tsx b/src/components/Sheets/GameSheet.tsx index 1e0a2377..53037447 100644 --- a/src/components/Sheets/GameSheet.tsx +++ b/src/components/Sheets/GameSheet.tsx @@ -3,14 +3,15 @@ import React, { useCallback, useMemo, useState } from 'react'; import BottomSheet, { BottomSheetBackdrop, BottomSheetBackdropProps, BottomSheetScrollView } from '@gorhom/bottom-sheet'; import { ParamListBase, useIsFocused } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; -import { View, StyleSheet, Text, Alert, TouchableWithoutFeedback, Platform } from 'react-native'; +import { Alert, Platform, StyleSheet, Text, TouchableWithoutFeedback, View } from 'react-native'; import { Button } from 'react-native-elements'; import Animated, { Extrapolate, FadeIn, Layout, interpolate, useAnimatedStyle, useSharedValue } from 'react-native-reanimated'; import { SafeAreaView } from 'react-native-safe-area-context'; -import { selectGameById, selectSortedPlayers, updateGame } from '../../../redux/GamesSlice'; +import { selectSortedPlayers, updateGame } from '../../../redux/GamesSlice'; import { useAppDispatch, useAppSelector } from '../../../redux/hooks'; import { updatePlayer } from '../../../redux/PlayersSlice'; +import { selectCurrentGame } from '../../../redux/selectors'; import { systemBlue } from '../../constants'; import BigButton from '../BigButtons/BigButton'; import Rounds from '../Rounds'; @@ -34,7 +35,7 @@ const GameSheet: React.FunctionComponent = ({ navigation, containerHeight if (typeof currentGameId == 'undefined') return null; const fullscreen = useAppSelector(state => state.settings.home_fullscreen); - const currentGame = useAppSelector(state => selectGameById(state, state.settings.currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); if (currentGame == undefined) return null; diff --git a/src/screens/GameScreen.tsx b/src/screens/GameScreen.tsx index 0af7bc7d..0c846ab7 100644 --- a/src/screens/GameScreen.tsx +++ b/src/screens/GameScreen.tsx @@ -4,8 +4,8 @@ import { ParamListBase } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { LayoutChangeEvent, StyleSheet, View } from 'react-native'; -import { selectGameById } from '../../redux/GamesSlice'; import { useAppSelector } from '../../redux/hooks'; +import { selectCurrentGame } from '../../redux/selectors'; import FlexboxBoard from '../components/Boards/FlexboxBoard'; import AddendModal from '../components/Sheets/AddendModal'; import GameSheet from '../components/Sheets/GameSheet'; @@ -19,7 +19,7 @@ const ScoreBoardScreen: React.FunctionComponent = ({ navigation }) => { if (typeof currentGameId == 'undefined') return null; const fullscreen = useAppSelector(state => state.settings.home_fullscreen); - const currentGame = useAppSelector(state => selectGameById(state, state.settings.currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); if (currentGame == undefined) return null; diff --git a/src/screens/SettingsScreen.tsx b/src/screens/SettingsScreen.tsx index 06f3ca35..00b384b3 100644 --- a/src/screens/SettingsScreen.tsx +++ b/src/screens/SettingsScreen.tsx @@ -9,9 +9,10 @@ import { Button, Icon } from 'react-native-elements'; import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'; import Animated, { Layout } from 'react-native-reanimated'; -import { selectGameById, selectSortedPlayers, updateGame, } from '../../redux/GamesSlice'; +import { selectSortedPlayers, updateGame } from '../../redux/GamesSlice'; import { useAppDispatch, useAppSelector } from '../../redux/hooks'; import { playerAdd } from '../../redux/PlayersSlice'; +import { selectCurrentGame } from '../../redux/selectors'; import EditGame from '../components/EditGame'; import EditPlayer from '../components/EditPlayer'; import { systemBlue } from '../constants'; @@ -34,7 +35,7 @@ const SettingsScreen: React.FunctionComponent = ({ }) => { const currentGameId = useAppSelector(state => state.settings.currentGameId); if (typeof currentGameId == 'undefined') return null; - const currentGame = useAppSelector(state => selectGameById(state, state.settings.currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); const players = useAppSelector(selectSortedPlayers); const maxPlayers = 12; diff --git a/src/screens/ShareScreen.tsx b/src/screens/ShareScreen.tsx index 01aafeef..9944a0e1 100644 --- a/src/screens/ShareScreen.tsx +++ b/src/screens/ShareScreen.tsx @@ -4,13 +4,14 @@ import analytics from '@react-native-firebase/analytics'; import { ParamListBase } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import * as Sharing from 'expo-sharing'; -import { View, StyleSheet, ScrollView, Text } from 'react-native'; +import { ScrollView, StyleSheet, Text, View } from 'react-native'; import { Button, Icon } from 'react-native-elements'; import { SafeAreaView } from 'react-native-safe-area-context'; import { captureRef } from "react-native-view-shot"; import { selectGameById } from '../../redux/GamesSlice'; import { useAppSelector } from '../../redux/hooks'; +import { selectCurrentGame } from '../../redux/selectors'; import PlayerNameColumn from '../components/ScoreLog/PlayerNameColumn'; import RoundScoreColumn from '../components/ScoreLog/RoundScoreColumn'; import TotalScoreColumn from '../components/ScoreLog/TotalScoreColumn'; @@ -25,7 +26,7 @@ const ShareScreen: React.FunctionComponent = ({ navigation }) => { if (typeof currentGameId == 'undefined') return null; const roundTotal = useAppSelector(state => selectGameById(state, currentGameId)?.roundTotal || 0); - const currentGame = useAppSelector(state => selectGameById(state, state.settings.currentGameId)); + const currentGame = useAppSelector(selectCurrentGame); if (typeof currentGame == 'undefined') return null; const roundsScrollViewEl = useRef(null); From 0e056684a674a375434fd1ca8a7718c400e85618 Mon Sep 17 00:00:00 2001 From: Justin Wyne <1986068+wyne@users.noreply.github.com> Date: Wed, 27 Mar 2024 01:46:49 -0700 Subject: [PATCH 4/7] Analytics --- src/components/Buttons/HomeButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Buttons/HomeButton.tsx b/src/components/Buttons/HomeButton.tsx index 472ac205..4bf73483 100644 --- a/src/components/Buttons/HomeButton.tsx +++ b/src/components/Buttons/HomeButton.tsx @@ -33,7 +33,7 @@ const HomeButton: React.FunctionComponent = ({ navigation }) => { if (roundCurrent < 1) { return; } if (daysSinceLastPrompt < 180) { return; } - console.log("Prompt for review"); + await analytics().logEvent('review_prompt'); dispatch(setLastStoreReviewPrompt(Date.now())); From 5d0840abbffd7794a37f1dd22b852e5c4d48d876 Mon Sep 17 00:00:00 2001 From: Justin Wyne <1986068+wyne@users.noreply.github.com> Date: Wed, 27 Mar 2024 01:59:39 -0700 Subject: [PATCH 5/7] v2.5.1 build 75 --- app.config.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app.config.js b/app.config.js index ac93e091..a02759f1 100644 --- a/app.config.js +++ b/app.config.js @@ -59,7 +59,7 @@ switch (variant) { export default { name: name, slug: "scorepad", - version: "2.5.0", + version: "2.5.1", orientation: "default", icon: icon, assetBundlePatterns: ["assets/*"], @@ -68,7 +68,7 @@ export default { bundleIdentifier: packageName, supportsTablet: true, requireFullScreen: false, - buildNumber: "74", + buildNumber: "75", infoPlist: { RCTAsyncStorageExcludeFromBackup: false, }, @@ -82,7 +82,7 @@ export default { }, package: packageName, permissions: [], - versionCode: 74, + versionCode: 75, googleServicesFile: "./google-services.json", }, userInterfaceStyle: "dark", From a375a4c1f2be80defc52520ff05abb724ddc4576 Mon Sep 17 00:00:00 2001 From: Justin Wyne <1986068+wyne@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:17:00 -0700 Subject: [PATCH 6/7] Expo doctor dependencies --- .nvmrc | 2 +- eas.json | 4 + package-lock.json | 344 +++++++--------------------------------------- package.json | 10 +- 4 files changed, 58 insertions(+), 302 deletions(-) diff --git a/.nvmrc b/.nvmrc index 67a228a4..4a58985b 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18.18.0 \ No newline at end of file +18.18 diff --git a/eas.json b/eas.json index bcb9d342..94d02282 100644 --- a/eas.json +++ b/eas.json @@ -5,6 +5,7 @@ }, "build": { "development-simulator": { + "node": "18.18.2", "developmentClient": true, "distribution": "internal", "ios": { @@ -16,6 +17,7 @@ } }, "development": { + "node": "18.18.2", "developmentClient": true, "distribution": "internal", "ios": { @@ -27,6 +29,7 @@ } }, "preview": { + "node": "18.18.2", "distribution": "internal", "ios": { "resourceClass": "m-medium" @@ -38,6 +41,7 @@ } }, "production": { + "node": "18.18.2", "ios": { "resourceClass": "m-medium" }, diff --git a/package-lock.json b/package-lock.json index be7f9841..01fedfe5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,23 +24,23 @@ "@reduxjs/toolkit": "^1.9.3", "colorsheet": "^1.0.5", "dotenv": "^16.0.3", - "expo": "^50.0.13", + "expo": "~50.0.14", "expo-application": "~5.8.3", "expo-blur": "~12.9.2", "expo-build-properties": "~0.11.1", "expo-constants": "~15.4.5", "expo-crypto": "~12.8.1", - "expo-dev-client": "~3.3.10", + "expo-dev-client": "~3.3.11", "expo-device": "~5.9.3", "expo-haptics": "~12.8.1", "expo-image": "~1.10.6", - "expo-linking": "~5.0.2", + "expo-linking": "~6.2.2", "expo-screen-orientation": "~6.4.1", "expo-sensors": "~12.9.1", "expo-sharing": "~11.10.0", "expo-splash-screen": "~0.26.4", "expo-status-bar": "~1.11.1", - "expo-store-review": "~6.4.0", + "expo-store-review": "~6.8.3", "expo-system-ui": "~2.9.3", "expo-updates": "~0.24.12", "firebase": "^9.17.1", @@ -49,7 +49,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-moment": "^1.1.3", - "react-native": "0.73.5", + "react-native": "0.73.6", "react-native-animated-pagination-dots": "^0.1.73", "react-native-elements": "^3.4.2", "react-native-gesture-handler": "~2.14.0", @@ -8304,11 +8304,6 @@ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, - "node_modules/@types/qs": { - "version": "6.9.11", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", - "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" - }, "node_modules/@types/react": { "version": "18.2.45", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.45.tgz", @@ -9659,6 +9654,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -10719,6 +10715,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -11149,6 +11146,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -11160,6 +11158,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, "engines": { "node": ">= 0.4" } @@ -12004,9 +12003,9 @@ } }, "node_modules/expo": { - "version": "50.0.13", - "resolved": "https://registry.npmjs.org/expo/-/expo-50.0.13.tgz", - "integrity": "sha512-p0FYrhUJZe92YOwOXx6GZ/WaxF6YtsLXtWkql9pFIIocYBN6iQ3OMGsbQCRSu0ao8rlxsk7HgQDEWK4D+y9tAg==", + "version": "50.0.14", + "resolved": "https://registry.npmjs.org/expo/-/expo-50.0.14.tgz", + "integrity": "sha512-yLPdxCMVAbmeEIpzzyAuJ79wvr6ToDDtQmuLDMAgWtjqP8x3CGddXxUe07PpKEQgzwJabdHvCLP5Bv94wMFIjQ==", "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "0.17.8", @@ -12112,12 +12111,12 @@ } }, "node_modules/expo-dev-client": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-3.3.10.tgz", - "integrity": "sha512-UhZOJ+O90dRo7S/rmFmVIWwa/HxOqoQ4ySCqvWh87O3pFQuluPfVI9PdKicF4djYrNHZZmE8UXqBDN41hiYtAA==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-3.3.11.tgz", + "integrity": "sha512-9nhhbfbskfmjp/tlRS5KvDpCoW0BREJBxpu2GyjKu7nDB33W8fJLL0wXgNhP+QEb93r37o3uezKmUm2kibOvTw==", "dependencies": { - "expo-dev-launcher": "3.6.8", - "expo-dev-menu": "4.5.7", + "expo-dev-launcher": "3.6.9", + "expo-dev-menu": "4.5.8", "expo-dev-menu-interface": "1.7.2", "expo-manifests": "~0.13.0", "expo-updates-interface": "~0.15.1" @@ -12127,12 +12126,12 @@ } }, "node_modules/expo-dev-launcher": { - "version": "3.6.8", - "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-3.6.8.tgz", - "integrity": "sha512-lFyxRXpUk0z7V7BDd1tFg/M9eFPzo+WRq7kQBA4F8bFPX6drYuTjPqs/bEF/6A5S38oA1wcA34bY9TNgkiKf5w==", + "version": "3.6.9", + "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-3.6.9.tgz", + "integrity": "sha512-MBDMAqjCMVYt1Zv47u2dJTp4d8gCZMfM4GWAFhfQy3G6XzkUlFtewaQefAqy93FcYOv6BYdC9yZOLOb06tqTfA==", "dependencies": { "ajv": "8.11.0", - "expo-dev-menu": "4.5.7", + "expo-dev-menu": "4.5.8", "expo-manifests": "~0.13.0", "resolve-from": "^5.0.0", "semver": "^7.5.3" @@ -12162,9 +12161,9 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/expo-dev-menu": { - "version": "4.5.7", - "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-4.5.7.tgz", - "integrity": "sha512-yIAsiKIhxvAmzd6x25HTvANeengGg2Uax6JnKy7+YfxgynKtqmWUlGCyc9EECoQI4+ItxbfjU4fSTxTiQYGFug==", + "version": "4.5.8", + "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-4.5.8.tgz", + "integrity": "sha512-GXfI0CmYlqjOqyFjtplXO9PSoJQoy89+50lbUSNZykDsGyvzCPzl4txdQcdHHSglKYr7lWV7aeMVeehuSct60w==", "dependencies": { "expo-dev-menu-interface": "1.7.2", "semver": "^7.5.3" @@ -12249,249 +12248,14 @@ } }, "node_modules/expo-linking": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-5.0.2.tgz", - "integrity": "sha512-SPQus0+tYGx9c69Uw4wmdo3rkKX8vRT1vyJz/mvkpSlZN986s0NmP/V0M5vDv5Zv2qZzVdqJyuITFe0Pg5aI+A==", - "dependencies": { - "@types/qs": "^6.9.7", - "expo-constants": "~14.4.2", - "invariant": "^2.2.4", - "qs": "^6.11.0", - "url-parse": "^1.5.9" - } - }, - "node_modules/expo-linking/node_modules/@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/expo-linking/node_modules/@expo/config": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@expo/config/-/config-8.1.2.tgz", - "integrity": "sha512-4e7hzPj50mQIlsrzOH6XZ36O094mPfPTIDIH4yv49bWNMc7GFLTofB/lcT+QyxiLaJuC0Wlk9yOLB8DIqmtwug==", - "dependencies": { - "@babel/code-frame": "~7.10.4", - "@expo/config-plugins": "~7.2.0", - "@expo/config-types": "^49.0.0-alpha.1", - "@expo/json-file": "^8.2.37", - "getenv": "^1.0.0", - "glob": "7.1.6", - "require-from-string": "^2.0.2", - "resolve-from": "^5.0.0", - "semver": "7.5.3", - "slugify": "^1.3.4", - "sucrase": "^3.20.0" - } - }, - "node_modules/expo-linking/node_modules/@expo/config-plugins": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-7.2.5.tgz", - "integrity": "sha512-w+5ccu1IxBHgyQk9CPFKLZOk8yZQEyTjbJwOzESK1eR7QwosbcsLkN1c1WWUZYiCXwORu3UTwJYll4+X2xxJhQ==", - "dependencies": { - "@expo/config-types": "^49.0.0-alpha.1", - "@expo/json-file": "~8.2.37", - "@expo/plist": "^0.0.20", - "@expo/sdk-runtime-versions": "^1.0.0", - "@react-native/normalize-color": "^2.0.0", - "chalk": "^4.1.2", - "debug": "^4.3.1", - "find-up": "~5.0.0", - "getenv": "^1.0.0", - "glob": "7.1.6", - "resolve-from": "^5.0.0", - "semver": "^7.5.3", - "slash": "^3.0.0", - "xcode": "^3.0.1", - "xml2js": "0.6.0" - } - }, - "node_modules/expo-linking/node_modules/@expo/config-types": { - "version": "49.0.0", - "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-49.0.0.tgz", - "integrity": "sha512-8eyREVi+K2acnMBe/rTIu1dOfyR2+AMnTLHlut+YpMV9OZPdeKV0Bs9BxAewGqBA2slslbQ9N39IS2CuTKpXkA==" - }, - "node_modules/expo-linking/node_modules/@expo/json-file": { - "version": "8.2.37", - "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-8.2.37.tgz", - "integrity": "sha512-YaH6rVg11JoTS2P6LsW7ybS2CULjf40AbnAHw2F1eDPuheprNjARZMnyHFPkKv7GuxCy+B9GPcbOKgc4cgA80Q==", - "dependencies": { - "@babel/code-frame": "~7.10.4", - "json5": "^2.2.2", - "write-file-atomic": "^2.3.0" - } - }, - "node_modules/expo-linking/node_modules/@expo/plist": { - "version": "0.0.20", - "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.0.20.tgz", - "integrity": "sha512-UXQ4LXCfTZ580LDHGJ5q62jSTwJFFJ1GqBu8duQMThiHKWbMJ+gajJh6rsB6EJ3aLUr9wcauxneL5LVRFxwBEA==", - "dependencies": { - "@xmldom/xmldom": "~0.7.7", - "base64-js": "^1.2.3", - "xmlbuilder": "^14.0.0" - } - }, - "node_modules/expo-linking/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/expo-linking/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/expo-linking/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/expo-linking/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/expo-linking/node_modules/expo-constants": { - "version": "14.4.2", - "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-14.4.2.tgz", - "integrity": "sha512-nOB122DOAjk+KrJT69lFQAoYVQGQjFHSigCPVBzVdko9S1xGsfiOH9+X5dygTsZTIlVLpQJDdmZ7ONiv3i+26w==", - "dependencies": { - "@expo/config": "~8.1.0", - "uuid": "^3.3.2" - }, - "peerDependencies": { - "expo": "*" - } - }, - "node_modules/expo-linking/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/expo-linking/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/expo-linking/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/expo-linking/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/expo-linking/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/expo-linking/node_modules/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/expo-linking/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/expo-linking/node_modules/write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-6.2.2.tgz", + "integrity": "sha512-FEe6lP4f7xFT/vjoHRG+tt6EPVtkEGaWNK1smpaUevmNdyCJKqW0PDB8o8sfG6y7fly8ULe8qg3HhKh5J7aqUQ==", "dependencies": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "expo-constants": "~15.4.3", + "invariant": "^2.2.4" } }, - "node_modules/expo-linking/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/expo-manifests": { "version": "0.13.2", "resolved": "https://registry.npmjs.org/expo-manifests/-/expo-manifests-0.13.2.tgz", @@ -12712,9 +12476,9 @@ "integrity": "sha512-ddQEtCOgYHTLlFUe/yH67dDBIoct5VIULthyT3LRJbEwdpzAgueKsX2FYK02ldh440V87PWKCamh7R9evk1rrg==" }, "node_modules/expo-store-review": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/expo-store-review/-/expo-store-review-6.4.0.tgz", - "integrity": "sha512-aD06KSOO9syeecaP9NfJO++FzmfQjg49HY7qeUQ9r826YqswW/FPAcnXY0RJLhfJTqeAPRSl/xzPLZA5vwdqLQ==", + "version": "6.8.3", + "resolved": "https://registry.npmjs.org/expo-store-review/-/expo-store-review-6.8.3.tgz", + "integrity": "sha512-RuZ1P0AO9BT37FnVQgK93KtxGoriLfG0uH0HqYyWdN2GQAKHtm1Ucu6sfwrHkdXpOXs+xqbTd669k4D6HC/+0w==", "peerDependencies": { "expo": "*" } @@ -13368,6 +13132,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -13576,6 +13341,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -13637,6 +13403,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "dependencies": { "es-define-property": "^1.0.0" }, @@ -13648,6 +13415,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -13659,6 +13427,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -18473,6 +18242,7 @@ "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -19224,20 +18994,6 @@ "qrcode-terminal": "bin/qrcode-terminal.js" } }, - "node_modules/qs": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz", - "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/query-string": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", @@ -19258,7 +19014,8 @@ "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true }, "node_modules/queue": { "version": "6.0.2", @@ -19396,9 +19153,9 @@ } }, "node_modules/react-native": { - "version": "0.73.5", - "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.73.5.tgz", - "integrity": "sha512-iHgDArmF4CrhL0qTj+Rn+CBN5pZWUL9lUGl8ub+V9Hwu/vnzQQh8rTMVSwVd2sV6N76KjpE5a4TfIAHkpIHhKg==", + "version": "0.73.6", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.73.6.tgz", + "integrity": "sha512-oqmZe8D2/VolIzSPZw+oUd6j/bEmeRHwsLn1xLA5wllEYsZ5zNuMsDus235ONOnCRwexqof/J3aztyQswSmiaA==", "dependencies": { "@jest/create-cache-key-function": "^29.6.3", "@react-native-community/cli": "12.3.6", @@ -20320,7 +20077,8 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true }, "node_modules/reselect": { "version": "4.1.8", @@ -20718,6 +20476,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -20805,6 +20564,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -22111,6 +21871,7 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -22153,15 +21914,6 @@ "base64-arraybuffer": "^1.0.2" } }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", diff --git a/package.json b/package.json index c7b772d7..97ab0fba 100644 --- a/package.json +++ b/package.json @@ -27,13 +27,13 @@ "@reduxjs/toolkit": "^1.9.3", "colorsheet": "^1.0.5", "dotenv": "^16.0.3", - "expo": "^50.0.13", + "expo": "~50.0.14", "expo-application": "~5.8.3", "expo-blur": "~12.9.2", "expo-build-properties": "~0.11.1", "expo-constants": "~15.4.5", "expo-crypto": "~12.8.1", - "expo-dev-client": "~3.3.10", + "expo-dev-client": "~3.3.11", "expo-device": "~5.9.3", "expo-haptics": "~12.8.1", "expo-image": "~1.10.6", @@ -50,7 +50,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-moment": "^1.1.3", - "react-native": "0.73.5", + "react-native": "0.73.6", "react-native-animated-pagination-dots": "^0.1.73", "react-native-elements": "^3.4.2", "react-native-gesture-handler": "~2.14.0", @@ -74,8 +74,8 @@ "redux-persist": "^6.0.0", "semver": "^7.5.4", "typescript": "^5.1.6", - "expo-store-review": "~6.4.0", - "expo-linking": "~5.0.2" + "expo-store-review": "~6.8.3", + "expo-linking": "~6.2.2" }, "devDependencies": { "@babel/core": "^7.19.3", From 2d8cba0aabaf4b29009e3b85b08fae429d40b30a Mon Sep 17 00:00:00 2001 From: Justin Wyne <1986068+wyne@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:27:01 -0700 Subject: [PATCH 7/7] easignore --- .easignore | 2 ++ .gitignore | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 .easignore diff --git a/.easignore b/.easignore new file mode 100644 index 00000000..d986adfd --- /dev/null +++ b/.easignore @@ -0,0 +1,2 @@ +assets-src/ +assets-stores/ diff --git a/.gitignore b/.gitignore index 5eb80c4e..29ce2cd9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,8 @@ *.key *.mobileprovision *.orig.* - +*.ipa +*.apk # Ignore iOS and Android builds @@ -50,4 +51,4 @@ yarn-error.* # typescript *.tsbuildinfo -# @end expo-cli \ No newline at end of file +# @end expo-cli