Browse Source

feat: adaptiveStyle | style fixes

Oleksandr Honcharov 1 year ago
parent
commit
50cdc9a5bc

+ 1 - 0
package.json

@@ -40,6 +40,7 @@
     "react": "18.2.0",
     "react-native": "0.72.6",
     "react-native-calendar-picker": "^7.1.4",
+    "react-native-device-detection": "^0.2.1",
     "react-native-gesture-handler": "~2.12.0",
     "react-native-keyboard-aware-scroll-view": "^0.9.5",
     "react-native-maps": "1.7.1",

+ 1 - 1
src/screens/InAppScreens/ProfileScreen/navigation-opts.ts

@@ -1,7 +1,7 @@
 import { Colors } from '../../../theme';
 import { Dimensions, PixelRatio } from 'react-native';
 
-const widthPercentageToDP = (widthPercent: number) => {
+export const widthPercentageToDP = (widthPercent: number) => {
   const screenWidth = Dimensions.get('window').width;
   return PixelRatio.roundToNearestPixel((screenWidth * widthPercent) / 100);
 };

+ 56 - 63
src/screens/InAppScreens/TravellersScreen/Components/Profile.tsx

@@ -4,14 +4,14 @@ import { Image } from 'expo-image';
 import { useNavigation } from '@react-navigation/native';
 import * as FileSystem from 'expo-file-system';
 
-import { styles } from './styles';
+import { ProfileStyles, ScoreStyles, TBTStyles } from './styles';
 
 import { getOnlineStatus } from 'src/storage';
 import { AvatarWithInitials } from 'src/components';
 
 import { API_HOST } from '../../../../constants';
 import { getFontSize } from '../../../../utils';
-import { Colors } from '../../../../theme';
+import { adaptiveStyle } from '../../../../theme';
 
 import TickIcon from '../../../../../assets/icons/tick.svg';
 import UNIcon from '../../../../../assets/icons/un_icon.svg';
@@ -50,7 +50,6 @@ export const Profile: FC<Props> = ({
   index,
   score,
   active_score,
-  tbt_score,
   tbt_rank,
   badge_tbt,
   badge_1281,
@@ -60,7 +59,7 @@ export const Profile: FC<Props> = ({
 }) => {
   const navigation = useNavigation();
 
-  const scoreNames = ['NM', 'DARE', 'UN', 'UN+', 'TCC', 'DEEP', 'YES', 'SLOW', 'WHS', 'KYE', 'TBT'];
+  const scoreNames = ['NM', 'DARE', 'UN', 'UN+', 'TCC', 'DEEP', 'YES', 'SLOW', 'WHS', 'KYE'];
   const isOnline = getOnlineStatus();
 
   const avatarBaseUri = isOnline
@@ -81,21 +80,16 @@ export const Profile: FC<Props> = ({
     ];
 
     const Rank = ({ color }: { color: string }) => (
-      <View style={[styles.badge, { backgroundColor: color }]}>
+      <View style={adaptiveStyle([ProfileStyles.badge, { backgroundColor: color }], {})}>
         <TBTIcon />
       </View>
     );
 
     return tbt_rank && tbt_rank >= 1 ? (
-      <View
-        style={{
-          display: 'flex',
-          marginTop: 10
-        }}
-      >
-        <View style={{ display: 'flex', alignItems: 'center' }}>
+      <View style={adaptiveStyle(TBTStyles.badgeRoot, {})}>
+        <View style={adaptiveStyle(TBTStyles.badgeWrapper, {})}>
           {badge_tbt ? <Rank color={colors[tbt_rank - 1]} /> : null}
-          <Text style={[styles.titleText, { flex: 0 }]}>TBT # {tbt_rank}</Text>
+          <Text style={adaptiveStyle([ScoreStyles.scoreNameText], {})}>TBT # {tbt_rank}</Text>
         </View>
       </View>
     ) : null;
@@ -103,9 +97,9 @@ export const Profile: FC<Props> = ({
 
   const EmptyScore: FC<{ scoreName: string }> = ({ scoreName }) => {
     return (
-      <View style={styles.scoreWrapper}>
-        <Text style={[styles.scoreHeaderText, { flex: 0 }]}>-</Text>
-        <Text style={[styles.scoreNameText, { flex: 0 }]}>{scoreName}</Text>
+      <View style={adaptiveStyle(ScoreStyles.scoreWrapper, {})}>
+        <Text style={adaptiveStyle([ScoreStyles.scoreHeaderText], {})}>-</Text>
+        <Text style={adaptiveStyle([ScoreStyles.scoreNameText], {})}>{scoreName}</Text>
       </View>
     );
   };
@@ -117,52 +111,53 @@ export const Profile: FC<Props> = ({
           navigation.navigate(...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId }] as never))
         }
       >
-        <View style={{ alignItems: 'center', flexDirection: 'row', gap: 10, marginBottom: 5 }}>
+        <View style={adaptiveStyle(ProfileStyles.profileRoot, {})}>
           <View style={{ paddingLeft: 20 }}>
-            <View style={{ marginRight: 5 }}>
-              <Text style={styles.rankText}>{index + 1}</Text>
+            {index + 1 < 100 ? (
+              <View>
+                <Text style={adaptiveStyle(ScoreStyles.rankText, {})}>{index + 1}</Text>
+              </View>
+            ) : null}
+            <View style={{ marginLeft: 5 }}>
+              {avatar ? (
+                <Image
+                  style={adaptiveStyle(ProfileStyles.profileAvatar, {})}
+                  source={{ uri: avatarBaseUri + avatar }}
+                />
+              ) : (
+                <AvatarWithInitials
+                  text={`${first_name[0] ?? ''}${last_name[0] ?? ''}`}
+                  flag={flagBaseUri + homebase_flag}
+                  size={48}
+                />
+              )}
             </View>
-            {avatar ? (
-              <Image
-                style={{ borderRadius: 24, width: 48, height: 48 }}
-                source={{ uri: avatarBaseUri + avatar }}
-              />
-            ) : (
-              <AvatarWithInitials
-                text={`${first_name[0] ?? ''}${last_name[0] ?? ''}`}
-                flag={flagBaseUri + homebase_flag}
-                size={48}
-              />
-            )}
           </View>
-          <View style={{ gap: 5, width: '75%' }}>
-            <Text style={[styles.headerText, { fontSize: getFontSize(14), flex: 0 }]}>
+          <View style={adaptiveStyle(ProfileStyles.profileDataRoot, {})}>
+            <Text
+              style={adaptiveStyle(
+                [ProfileStyles.profileFirstLastName, { fontSize: getFontSize(14), flex: 0 }],
+                {}
+              )}
+            >
               {first_name ?? ''} {last_name ?? ''}
             </Text>
-            <View
-              style={{ display: 'flex', justifyContent: 'space-between', flexDirection: 'row' }}
-            >
-              <View
-                style={{
-                  display: 'flex',
-                  flexDirection: 'row',
-                  gap: 10,
-                  alignItems: 'center'
-                }}
-              >
-                <Text
-                  style={{ color: Colors.DARK_BLUE, fontWeight: '600', fontSize: getFontSize(12) }}
-                >
+            <View style={adaptiveStyle(ProfileStyles.profileDataContainer, {})}>
+              <View style={adaptiveStyle(ProfileStyles.profileDataWrapper, {})}>
+                <Text style={adaptiveStyle(ProfileStyles.profileAge, {})}>
                   Age: {date_of_birth ?? ''}
                 </Text>
-                <Image source={{ uri: flagBaseUri + homebase_flag }} style={styles.countryFlag} />
+                <Image
+                  source={{ uri: flagBaseUri + homebase_flag }}
+                  style={adaptiveStyle(ProfileStyles.countryFlag, {})}
+                />
                 {homebase2_flag && homebase2_flag !== homebase_flag ? (
                   <Image
                     source={{ uri: flagBaseUri + homebase2_flag }}
-                    style={[styles.countryFlag, { marginLeft: -15 }]}
+                    style={adaptiveStyle([ProfileStyles.countryFlag, { marginLeft: -15 }], {})}
                   />
                 ) : null}
-                <View style={{ display: 'flex', flexDirection: 'row', gap: 3, marginLeft: 10 }}>
+                <View style={adaptiveStyle(ProfileStyles.badgesWrapper, {})}>
                   {auth ? <TickIcon /> : null}
                   {badge_un ? <UNIcon /> : null}
                   {badge_1281 ? <NMIcon /> : null}
@@ -172,36 +167,34 @@ export const Profile: FC<Props> = ({
           </View>
         </View>
       </TouchableOpacity>
-      <View style={styles.rankingWrapper}>
-        <View style={styles.nmWrapper}>
-          <Text style={{ fontSize: 20, color: Colors.DARK_BLUE, fontWeight: '700' }}>
+      <View style={adaptiveStyle(ScoreStyles.rankingWrapper, {})}>
+        <View style={adaptiveStyle(ScoreStyles.nmWrapper, {})}>
+          <Text style={adaptiveStyle(ScoreStyles.activeScoreRanking, {})}>
             {score[active_score]}
           </Text>
-          <Text style={{ fontSize: 14, color: Colors.DARK_BLUE, fontWeight: '500' }}>
+          <Text style={adaptiveStyle(ScoreStyles.activeScoreName, {})}>
             {scoreNames[active_score]}
           </Text>
+          <TBRanking />
         </View>
 
-        <View style={styles.rankingScoresWrapper}>
+        <View style={adaptiveStyle(ScoreStyles.rankingScoresWrapper, {})}>
           {score.map((number, index) => {
             if (scoreNames[index] === 'SLOW' && number >= 4500)
               return <EmptyScore scoreName={scoreNames[index]} />;
             if (scoreNames[index] === 'YES' && number >= 10000)
               return <EmptyScore scoreName={scoreNames[index]} />;
             if (!number) return <EmptyScore scoreName={scoreNames[index]} />;
-            if (index === active_score) return;
             return (
-              <View style={styles.scoreWrapper}>
-                <Text style={[styles.scoreHeaderText, { flex: 0 }]}>{number}</Text>
-                <Text style={[styles.scoreNameText, { flex: 0 }]}>{scoreNames[index]}</Text>
+              <View style={adaptiveStyle(ScoreStyles.scoreWrapper, {})}>
+                <Text style={adaptiveStyle([ScoreStyles.scoreHeaderText], {})}>{number}</Text>
+                <Text style={adaptiveStyle([ScoreStyles.scoreNameText], {})}>
+                  {scoreNames[index]}
+                </Text>
               </View>
             );
           })}
         </View>
-
-        <View style={{ marginRight: 15, marginLeft: 15 }}>
-          <TBRanking />
-        </View>
       </View>
     </View>
   );

+ 86 - 41
src/screens/InAppScreens/TravellersScreen/Components/styles.ts

@@ -1,72 +1,113 @@
 import { Colors } from '../../../../theme';
 import { StyleSheet } from 'react-native';
 import { getFontSize } from '../../../../utils';
+import { widthPercentageToDP } from '../../ProfileScreen/navigation-opts';
 
-export const styles = StyleSheet.create({
-  rankText: {
-    fontSize: 18,
-    color: Colors.DARK_BLUE,
-    fontWeight: '700',
-    position: 'absolute',
-    left: -20,
-    top: 10
+export const ProfileStyles = StyleSheet.create({
+  badge: {
+    width: 36,
+    height: 14,
+    borderRadius: 7,
+    display: 'flex',
+    justifyContent: 'center',
+    alignItems: 'center'
   },
-  countryFlag: {
-    width: 20,
-    height: 20,
-    borderRadius: 20 / 2,
-    borderWidth: 0.5,
-    borderColor: 'gray'
+  badgesWrapper: {
+    display: 'flex',
+    flexDirection: 'row',
+    gap: 3,
+    marginLeft: 10
+  },
+  profileRoot: {
+    alignItems: 'center',
+    flexDirection: 'row',
+    gap: 10,
+    marginBottom: 5
+  },
+  profileAvatar: {
+    borderRadius: 24,
+    width: 48,
+    height: 48
   },
-  headerText: {
+  profileFirstLastName: {
     flex: 1,
     fontFamily: 'redhat-700',
     color: Colors.DARK_BLUE,
     fontSize: getFontSize(12)
   },
-  titleText: {
-    flex: 1,
+  profileDataRoot: {
+    gap: 5,
+    width: '75%'
+  },
+  profileDataContainer: {
+    display: 'flex',
+    justifyContent: 'space-between',
+    flexDirection: 'row'
+  },
+  profileDataWrapper: {
+    display: 'flex',
+    flexDirection: 'row',
+    gap: 10,
+    alignItems: 'center'
+  },
+  profileAge: {
     color: Colors.DARK_BLUE,
     fontWeight: '600',
-    fontSize: getFontSize(11)
+    fontSize: getFontSize(12)
   },
+  countryFlag: {
+    width: 20,
+    height: 20,
+    borderRadius: 20 / 2,
+    borderWidth: 0.5,
+    borderColor: 'gray'
+  }
+});
+
+export const ScoreStyles = StyleSheet.create({
   scoreWrapper: {
     display: 'flex',
     alignItems: 'center',
     justifyContent: 'center',
     flexDirection: 'column',
+    flexBasis: '18%',
     marginBottom: 10,
     width: 40
   },
   scoreHeaderText: {
-    flex: 1,
     fontFamily: 'redhat-700',
     color: Colors.DARK_BLUE,
     fontSize: getFontSize(12),
     textAlign: 'center'
   },
   scoreNameText: {
-    flex: 1,
     color: Colors.DARK_BLUE,
     fontWeight: '600',
     fontSize: getFontSize(11),
     textAlign: 'center'
   },
-  badge: {
-    width: 36,
-    height: 14,
-    borderRadius: 7,
+  rankText: {
+    fontSize: 18,
+    color: Colors.DARK_BLUE,
+    fontWeight: '700',
+    position: 'absolute',
+    left: -20,
+    top: 10
+  },
+  nmWrapper: {
+    paddingTop: 17,
+    paddingBottom: 17,
     display: 'flex',
     justifyContent: 'center',
-    alignItems: 'center'
+    alignItems: 'center',
+    marginLeft: widthPercentageToDP(6)
   },
-  seriesWrapper: {
+  rankingWrapper: {
     display: 'flex',
     flexDirection: 'row',
     justifyContent: 'center',
     alignItems: 'center',
-    flexWrap: 'wrap',
-    columnGap: 20,
+    marginBottom: 15,
     flex: 1
   },
   rankingScoresWrapper: {
@@ -78,22 +119,26 @@ export const styles = StyleSheet.create({
     columnGap: 5,
     flex: 1
   },
-  nmWrapper: {
-    paddingTop: 17,
-    paddingBottom: 17,
+  activeScoreRanking: {
+    fontSize: 20,
+    color: Colors.DARK_BLUE,
+    fontWeight: '700'
+  },
+  activeScoreName: {
+    fontSize: 14,
+    color: Colors.DARK_BLUE,
+    fontWeight: '500'
+  }
+});
+
+export const TBTStyles = StyleSheet.create({
+  badgeRoot: {
     display: 'flex',
-    justifyContent: 'center',
-    alignItems: 'center',
-    marginLeft: 15,
-    marginRight: 20
+    marginTop: 10
   },
-  rankingWrapper: {
+  badgeWrapper: {
     display: 'flex',
-    flexDirection: 'row',
-    justifyContent: 'center',
-    alignItems: 'center',
-    marginBottom: 15,
-    flex: 1
+    alignItems: 'center'
   }
 });
 

+ 1 - 2
src/screens/InAppScreens/TravellersScreen/MasterRankingScreen/index.tsx

@@ -242,8 +242,7 @@ const MasterRankingScreen = () => {
               item.score_yes,
               item.score_slow,
               item.score_whs,
-              item.score_kye,
-              item.rank_tbt
+              item.score_kye
             ]}
             tbt_score={item.score_tbt}
             active_score={confirmedValueRanking.value - 1}

+ 12 - 1
src/theme.ts

@@ -1,3 +1,7 @@
+import { CSSProperties } from 'react';
+import Device from 'react-native-device-detection';
+import { StyleProp } from 'react-native';
+
 export enum Colors {
   ORANGE = '#ED9334',
   DARK_BLUE = '#0F3F4F',
@@ -5,5 +9,12 @@ export enum Colors {
   DARK_LIGHT = '#E5E5E5',
   RED = '#EF5B5B',
   LIGHT_GRAY = '#C8C8C8',
-  TEXT_GRAY = '#3E6471',
+  TEXT_GRAY = '#3E6471'
+}
+
+export function adaptiveStyle(
+  phoneStyle: CSSProperties | CSSProperties[],
+  tabletStyle: CSSProperties | CSSProperties[]
+): StyleProp<any> {
+  return Device.isTablet ? tabletStyle : phoneStyle;
 }