Advertisement
BenjaminWade

headerprofille

Oct 11th, 2024
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
TypeScript 5.98 KB | Software | 0 0
  1. import React, { useState, useEffect } from 'react';
  2. import { Animated, Dimensions, StyleSheet, View, Text, Image } from 'react-native';
  3. import ButtonFollow from '@/components/FollowButton/followButton';
  4. import UserInformations from '@/components/userInformations/userInformations';
  5. import { useUserViewModel } from '../../context/user/viewModel';
  6. import { useVerifyFollowingViewModel } from '../../context/following/viewModel';
  7. import { IconButton } from 'native-base';
  8. import { MaterialIcons } from '@expo/vector-icons';
  9. import { router } from 'expo-router';
  10. import loadingGif from '@/../../assets/images/giffyBranco.gif';
  11. import defaultProfileImage from '@/assets/images/profileUser_black.jpg';
  12. import { Colors } from '@/constants/Colors';
  13. import { useToggleViewModel } from '@/context/toggleFollow/viewModel';
  14.  
  15. const { width, height } = Dimensions.get('window');
  16. const Header_Max_Height = height * 0.30;
  17. const Header_Min_Height = height * 0.10;
  18. const Scroll_Distance = Header_Max_Height - Header_Min_Height;
  19.  
  20. interface DynamicHeaderProps {
  21.   value: Animated.Value;
  22.   id?: number | null;
  23.   isOwnProfile: boolean;
  24.   profilePhoto: string;
  25. }
  26.  
  27. const DynamicHeader: React.FC<DynamicHeaderProps> = ({ value, id, isOwnProfile }) => {
  28.   const { userName, firstName, isLoading, profilePhoto } = useUserViewModel(id);
  29.  
  30.   const [isFollowing, setIsFollowing] = useState(false);
  31.  
  32.   const { isLoadingViewModel, isFollowing: followingStatus } = id !== null && !isOwnProfile ? useVerifyFollowingViewModel(id) : { isLoadingViewModel: false, isFollowing: false };
  33.  
  34.   const { toggleFollow } = id !== null && !isOwnProfile ? useToggleViewModel(id) : { toggleFollow: null };
  35.  
  36.   useEffect(() => {
  37.     if (!isOwnProfile && id != null) {
  38.       setIsFollowing(followingStatus);
  39.     }
  40.   }, [followingStatus, id, isOwnProfile]);
  41.  
  42.   const handleToggleFollow = async () => {
  43.     try {
  44.       if (id != null && toggleFollow) {
  45.         await toggleFollow();
  46.         setIsFollowing(!isFollowing);
  47.       }
  48.     } catch (error) {
  49.       console.error("Erro ao atualizar o status de seguir:", error);
  50.     }
  51.   };
  52.  
  53.   const animatedHeaderHeight = value.interpolate({
  54.     inputRange: [0, Scroll_Distance],
  55.     outputRange: [Header_Max_Height, Header_Min_Height],
  56.     extrapolate: 'clamp',
  57.   });
  58.  
  59.   const animatedHeaderColor = value.interpolate({
  60.     inputRange: [0, Scroll_Distance],
  61.     outputRange: ['#D8F38C', '#e3f6ae'],
  62.     extrapolate: 'clamp',
  63.   });
  64.  
  65.   const animatedProfileSize = value.interpolate({
  66.     inputRange: [0, Scroll_Distance],
  67.     outputRange: [width * 0.22, width * 0.10],
  68.     extrapolate: 'clamp',
  69.   });
  70.  
  71.   const animatedTitleSize = value.interpolate({
  72.     inputRange: [0, Scroll_Distance],
  73.     outputRange: [width * 0.06, width * 0.06],
  74.     extrapolate: 'clamp',
  75.   });
  76.  
  77.   const profileImageSource = profilePhoto ? { uri: profilePhoto } : defaultProfileImage;
  78.  
  79.   if (isLoading) {
  80.     return (
  81.       <View style={[styles.loadingContainer, StyleSheet.absoluteFillObject]}>
  82.         <Image source={loadingGif} style={styles.loadingImage} resizeMode="contain" />
  83.         <Text style={styles.loadingText}>LYRA</Text>
  84.       </View>
  85.     );
  86.   }
  87.  
  88.   return (
  89.     <Animated.View
  90.       style={[
  91.         styles.header,
  92.         {
  93.           height: animatedHeaderHeight,
  94.           backgroundColor: animatedHeaderColor,
  95.         },
  96.       ]}
  97.     >
  98.       <Animated.View style={styles.headerContent}>
  99.         <Animated.Image
  100.           source={profileImageSource}
  101.           style={[
  102.             styles.fotoPerfil,
  103.             {
  104.               width: animatedProfileSize,
  105.               height: animatedProfileSize,
  106.             },
  107.           ]}
  108.         />
  109.         <View style={styles.textContainer}>
  110.           <Animated.Text
  111.             style={[
  112.               styles.title,
  113.               {
  114.                 fontSize: animatedTitleSize,
  115.               },
  116.             ]}
  117.           >
  118.             {userName}
  119.           </Animated.Text>
  120.           <Animated.Text style={styles.nome}>{firstName}</Animated.Text>
  121.         </View>
  122.  
  123.         {!isOwnProfile && !isLoadingViewModel && (
  124.           <Animated.View style={styles.button}>
  125.             <ButtonFollow
  126.               title={followingStatus ? 'Seguindo' : 'Seguir'}
  127.               onPress={handleToggleFollow}
  128.               color={followingStatus ? Colors.primary : 'gray'}
  129.             />
  130.           </Animated.View>
  131.         )}
  132.  
  133.         {isOwnProfile && (
  134.           <View>
  135.             <IconButton
  136.               colorScheme={'light'}
  137.               _icon={{ as: MaterialIcons, name: 'menu', size: 10 }}
  138.               style={{ position: 'absolute', top: -height * 0.05, right: 3 }}
  139.               onPress={() => router.push('/editProfileAndConfigs')}
  140.             />
  141.           </View>
  142.         )}
  143.  
  144.         <UserInformations id={id} />
  145.       </Animated.View>
  146.     </Animated.View>
  147.   );
  148. };
  149.  
  150. export default DynamicHeader;
  151.  
  152. const styles = StyleSheet.create({
  153.   header: {
  154.     justifyContent: 'center',
  155.     alignItems: 'center',
  156.     width: '100%',
  157.     borderBottomLeftRadius: width * 0.10,
  158.     borderBottomRightRadius: width * 0.10,
  159.   },
  160.   headerContent: {
  161.     flexDirection: 'row',
  162.     alignItems: 'center',
  163.     justifyContent: 'space-between',
  164.     paddingHorizontal: '5%',
  165.     width: '100%',
  166.   },
  167.   loadingContainer: {
  168.     flex: 1,
  169.     justifyContent: 'center',
  170.     alignItems: 'center',
  171.     width: '100%',
  172.   },
  173.   title: {
  174.     color: 'black',
  175.     fontWeight: 'bold',
  176.     marginLeft: 10,
  177.   },
  178.   textContainer: {
  179.     flexDirection: 'column',
  180.     justifyContent: 'space-between',
  181.     alignItems: 'flex-start',
  182.     flex: 1,
  183.   },
  184.   fotoPerfil: {
  185.     aspectRatio: 1,
  186.     backgroundColor: 'pink',
  187.     borderRadius: 50,
  188.     marginRight: 10,
  189.   },
  190.   nome: {
  191.     color: '#333',
  192.     textAlign: 'left',
  193.   },
  194.   button: {
  195.     opacity: 1,
  196.     alignContent: 'center',
  197.     right: 40,
  198.   },
  199.   loadingText: {
  200.     color: '#ffffff',
  201.     marginTop: 10,
  202.     fontSize: 25,
  203.     fontWeight: 'bold',
  204.   },
  205.   loadingImage: {
  206.     width: 100,
  207.     height: 100,
  208.   },
  209. });
  210.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement