diff --git a/package.json b/package.json index e502489..e8991b5 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "jest": { "preset": "jest-expo", "transformIgnorePatterns": [ - "node_modules/(?!((jest-)?react-native|@react-native(-community)?|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg|react-native-svg-charts|d3-path)/)" + "node_modules/(?!((jest-)?react-native|@react-native(-community)?|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg|react-native-svg-charts|d3-path|expo-constants|expo-modules-core)/)" ] }, "dependencies": { diff --git a/src/component/headers/back-header.tsx b/src/component/headers/back-header.tsx index 9eac67e..22b0cd8 100644 --- a/src/component/headers/back-header.tsx +++ b/src/component/headers/back-header.tsx @@ -1,10 +1,10 @@ -// BackHeader.tsx +import { NavigationProp } from "@react-navigation/native"; import React from "react"; import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { shadows } from "../../styles"; type BackHeaderProps = { - navigation: any; // You can replace 'any' with the appropriate type for your navigation prop + navigation: NavigationProp; // TODO: #135 should use a RootStackParamList title: string; }; @@ -14,6 +14,8 @@ const BackHeader: React.FC = ({ navigation, title }) => { navigation.goBack()} + accessibilityLabel="Go back" + accessibilityRole="button" > {`< ${title}`} diff --git a/src/component/image/image-with-fallback.tsx b/src/component/image/image-with-fallback.tsx index 2f7a414..57aac20 100644 --- a/src/component/image/image-with-fallback.tsx +++ b/src/component/image/image-with-fallback.tsx @@ -1,35 +1,34 @@ -import React, { useState } from "react"; -import { Image } from "react-native"; +import React, { memo, useState } from "react"; +import { Image, ImageStyle, StyleProp } from "react-native"; type ImageWithFallbackProps = { source: { uri: string }; - fallbackSource?: { uri: string }; - style?: object; + fallbackSource: { uri: string }; + style?: StyleProp; }; /** * A React component that displays an image with a fallback option. * If the primary image fails to load, it will display a fallback image instead. * - * @param {ImageWithFallbackProps} props - The props for the component. - * @param {Object} props.source - The source of the primary image. It should be an object with a `uri` property. - * @param {Object} [props.fallbackSource] - Optional. The source of the fallback image. It should be an object with a `uri` property. - * @param {Object} [props.style] - Optional. The style to apply to the image. It can be any valid React Native style object. + * @param {Object} source - The source of the primary image. + * @param {Object} fallbackSource - The source of the fallback image. Should be an asset rather than loaded from an endpoint. + * @param {StyleProp} style - Optional. The style to apply to the image. It can be any valid React Native style object. * @returns {React.ReactElement} A React element representing the image with fallback. */ -const ImageWithFallback: React.FC = ({ - source, - fallbackSource, - style, -}: ImageWithFallbackProps): React.ReactElement => { - const [imageSource, setImageSource] = useState(source); +const ImageWithFallback: React.FC = memo( + ({ source, fallbackSource, style }) => { + const [imageSource, setImageSource] = useState(source); - const handleError = () => { - if (fallbackSource) { - setImageSource(fallbackSource); - } - }; + const handleError = () => { + if (fallbackSource) { + setImageSource(fallbackSource); + } + }; - return ; -}; + return ; + }, +); + +ImageWithFallback.displayName = "ImageWithFallback"; export default ImageWithFallback; diff --git a/src/component/modals/slide-modal.tsx b/src/component/modals/slide-modal.tsx deleted file mode 100644 index 2074fd9..0000000 --- a/src/component/modals/slide-modal.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import React from "react"; -import { ScrollView, View } from "react-native"; -import Modal from "react-native-modal"; - -import { modal } from "../../styles"; - -interface SlideModalInterface { - modalVisible: boolean; - setModalVisible: Function; - children: React.ReactNode; -} - -/** - * SlideModal Component - * - * A modal component that slides down from the bottom of the screen and can be dismissed by swiping down or tapping the backdrop. - * - * @param {Object} props - Props for SlideModal component. - * @param {boolean} props.modalVisible - State variable that controls the visibility of the modal. - * @param {Function} props.setModalVisible - State setter function to update the visibility of the modal. - * @param {React.ReactNode} props.children - The content to be rendered inside the modal. - * - * @component - * @example - * const [modalVisible, setModalVisible] = useState(false); - * - * return ( - * - * Modal Content - * - * ); - */ -export default function SlideModal({ - modalVisible, - setModalVisible, - children, -}: SlideModalInterface): React.JSX.Element { - return ( - setModalVisible(false)} - onSwipeComplete={() => setModalVisible(false)} - swipeDirection="down" - style={modal.noMargin} - propagateSwipe - > - - - - {children} - - - - ); -} diff --git a/src/component/session-card/session-card-footer.tsx b/src/component/session-card/session-card-footer.tsx deleted file mode 100644 index fc51f24..0000000 --- a/src/component/session-card/session-card-footer.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from "react"; -import { StyleSheet, Text, View } from "react-native"; - -const SessionCardFooter = ({ sessionName, lastPlayed }) => { - return ( - - {sessionName} - {lastPlayed} - - ); -}; - -const styles = StyleSheet.create({ - sessionName: { - fontSize: 18, - paddingTop: 5, - marginHorizontal: 16, - }, - sessionDatetime: { - fontSize: 10, - color: "#A3A3A3", - marginHorizontal: 16, - }, -}); - -export default SessionCardFooter; diff --git a/src/component/session-card/session-card-header.tsx b/src/component/session-card/session-card-header.tsx deleted file mode 100644 index 1949b27..0000000 --- a/src/component/session-card/session-card-header.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from "react"; -import { Image, StyleSheet, Text, View } from "react-native"; - -const SessionCardHeader = ({ - playerName, - location, - gameType, - locationIconURL, - profileImageURL, -}) => { - return ( - - - - {playerName} - - - {location} - - {gameType} - - - ); -}; - -const styles = StyleSheet.create({ - headerContainer: { - flexDirection: "row", - alignItems: "center", - marginHorizontal: 16, - }, - - headerProfileImage: { - width: 60, - height: 60, - resizeMode: "contain", - }, - - headerText: { - flexDirection: "column", - padding: 10, - }, - playerName: { - fontSize: 24, - fontWeight: "bold", - }, - locationContainer: { - flexDirection: "row", - alignItems: "center", - }, - locationText: { - fontSize: 13, - }, - gameType: { - fontSize: 13, - }, - icon: { - width: 18, - height: 18, - resizeMode: "contain", - }, -}); - -export default SessionCardHeader; diff --git a/src/component/session-card/session-card-stat.tsx b/src/component/session-card/session-card-stat.tsx deleted file mode 100644 index 9c1b52c..0000000 --- a/src/component/session-card/session-card-stat.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from "react"; -import { StyleSheet, Text, View } from "react-native"; - -const SessionCardStat = ({ sessionStat, displayName }) => { - return ( - - {displayName} - {sessionStat} - - ); -}; - -const styles = StyleSheet.create({ - statItem: { - fontSize: 10, - textAlign: "center", - color: "#666", - }, - statValue: { - fontSize: 22, - fontWeight: "400", - }, -}); - -export default SessionCardStat; diff --git a/src/component/session-card/session-card-stats-row-container.tsx b/src/component/session-card/session-card-stats-row-container.tsx deleted file mode 100644 index 0c54a8f..0000000 --- a/src/component/session-card/session-card-stats-row-container.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from "react"; -import { StyleSheet, View } from "react-native"; -import SessionCardStat from "./session-card-stat"; - -const SessionCardStatsRowContainer = ({ - makePercent, - medianRun, - duration, - shotPacing, -}) => { - const stats = [ - { displayName: "Make Percent", sessionStat: makePercent }, - { displayName: "Median Run", sessionStat: medianRun }, - { displayName: "Time Played", sessionStat: duration }, - { displayName: "Shot Pacing", sessionStat: shotPacing }, - ]; - - return ( - - {stats.map((stat, index) => ( - - - {index < stats.length - 1 && } - - ))} - - ); -}; - -const styles = StyleSheet.create({ - statsContainer: { - flexDirection: "row", - justifyContent: "space-between", - alignItems: "center", - margin: 16, - }, - verticalSpacer: { - width: 1, - backgroundColor: "#A3A3A3", - height: "100%", - marginHorizontal: 12, - }, -}); - -export default SessionCardStatsRowContainer; diff --git a/src/component/session-card/session-card.tsx b/src/component/session-card/session-card.tsx deleted file mode 100644 index 566ecca..0000000 --- a/src/component/session-card/session-card.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React from "react"; -import { Image, StyleSheet, View } from "react-native"; -import SessionCardFooter from "./session-card-footer"; -import SessionCardHeader from "./session-card-header"; -import SessionCardStatsRowContainer from "./session-card-stats-row-container"; - -const SessionCard = ({ - playerName, - location, - gameType, - makePercent, - medianRun, - duration, - shotPacing, - sessionName, - lastPlayed, - imageURL, - profileImageURL, - locationIconURL, -}) => { - return ( - - - - - - - ); -}; - -const styles = StyleSheet.create({ - card: { - backgroundColor: "white", - borderRadius: 8, - borderWidth: 1, - borderColor: "#ddd", - shadowColor: "#000", - shadowOffset: { - width: 0, - height: 2, - }, - shadowOpacity: 0.25, - shadowRadius: 3.84, - elevation: 5, - margin: 10, - overflow: "hidden", - }, - image: { - width: "100%", - height: "50%", - }, -}); - -export default SessionCard; diff --git a/src/component/video-details/video-stat-list.tsx b/src/component/video-details/video-stat-list.tsx index 313772b..d7d1df2 100644 --- a/src/component/video-details/video-stat-list.tsx +++ b/src/component/video-details/video-stat-list.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { StyleSheet, Text, View } from "react-native"; +import { StyleProp, StyleSheet, Text, View, ViewStyle } from "react-native"; import { borders } from "../../styles"; type StatItem = { @@ -9,14 +9,14 @@ type StatItem = { type StatListProps = { items: StatItem[]; - style?: object; + style?: StyleProp; }; const StatList: React.FC = ({ items, style }) => { return ( {items.map((item, index) => ( - + {item.title} {item.value} @@ -27,7 +27,6 @@ const StatList: React.FC = ({ items, style }) => { const styles = StyleSheet.create({ container: { - flexDirection: "column", flex: 1, padding: 5, }, diff --git a/src/screens/video-stack/video-details.tsx b/src/screens/video-stack/video-details.tsx index 70cc226..1067313 100644 --- a/src/screens/video-stack/video-details.tsx +++ b/src/screens/video-stack/video-details.tsx @@ -101,14 +101,15 @@ const styles = StyleSheet.create({ flexDirection: "row", justifyContent: "space-between", paddingLeft: 45, - paddingVertical: 42, + paddingTop: 42, + paddingBottom: 38, }, statColumn: { flex: 1, padding: 5, }, horizontalDivider: { - width: "95%", + width: "92%", alignSelf: "center", ...borders.dottedBottomBorder, }, diff --git a/src/styles.ts b/src/styles.ts index 049ad18..d1aef1e 100644 --- a/src/styles.ts +++ b/src/styles.ts @@ -6,7 +6,7 @@ let STATUS_BAR_HEIGHT: number; Platform.OS === "android" ? (STATUS_BAR_HEIGHT = 24) - : (STATUS_BAR_HEIGHT = Constants.statusBarHeight | 24); + : (STATUS_BAR_HEIGHT = Constants.statusBarHeight || 24); // GLOBALLY STYLED export const globalInputStyles = StyleSheet.create({