fix - input & profile flatlist

This commit is contained in:
Victor
2025-09-17 16:24:06 +02:00
parent 3acfea7551
commit f40d5c8051
2 changed files with 129 additions and 138 deletions
+47 -47
View File
@@ -166,57 +166,57 @@ const Input = ({
}} }}
/> />
) : */} ) : */}
( {type !== 'countryPicker' && (
<TextInput <TextInput
ref={inputRef} ref={inputRef}
placeholder={placeholder} placeholder={placeholder}
placeholderTextColor={Palette.gray} placeholderTextColor={Palette.gray}
value={value} value={value}
onChangeText={setValue} onChangeText={setValue}
multiline={type === 'textarea'} multiline={type === 'textarea'}
editable={type !== 'countryPicker'} editable={type !== 'countryPicker'}
onFocus={() => setIsFocused(true)} onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)} onBlur={() => setIsFocused(false)}
style={{ style={{
width: '100%', width: '100%',
...(isRoundedRectangle ...(isRoundedRectangle
? {
height: '100%',
flex: 1,
textAlignVertical: type === 'textarea' ? 'top' : 'center',
}
: { textAlign: 'center' }),
fontSize: 14,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
...(isWeb
? {
lineHeight: 'auto',
}
: {}),
...textInputStyle,
}}
{...(type === 'password'
? { ? {
height: '100%', secureTextEntry: !showPassword,
flex: 1, autoCapitalize: 'none',
textAlignVertical: type === 'textarea' ? 'top' : 'center', autoCompleteType: 'password',
textContentType: 'password',
} }
: { textAlign: 'center' }), : {})}
fontSize: 14, {...(type === 'email'
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
...(isWeb
? { ? {
lineHeight: 'auto', keyboardType: 'email-address',
autoCapitalize: 'none',
autoCompleteType: 'email',
textContentType: 'emailAddress',
} }
: {}), : {})}
...textInputStyle, keyboardType={isNumeric ? 'numeric' : 'default'}
}} keyboardAppearance='dark'
{...(type === 'password' inputAccessoryViewID={inputAccessoryViewID}
? { {...textInputProps}
secureTextEntry: !showPassword, />
autoCapitalize: 'none',
autoCompleteType: 'password',
textContentType: 'password',
}
: {})}
{...(type === 'email'
? {
keyboardType: 'email-address',
autoCapitalize: 'none',
autoCompleteType: 'email',
textContentType: 'emailAddress',
}
: {})}
keyboardType={isNumeric ? 'numeric' : 'default'}
keyboardAppearance='dark'
inputAccessoryViewID={inputAccessoryViewID}
{...textInputProps}
/>
)} )}
{type === 'password' ? ( {type === 'password' ? (
<Pressable onPress={() => setShowPassword(!showPassword)}> <Pressable onPress={() => setShowPassword(!showPassword)}>
+82 -91
View File
@@ -1,7 +1,7 @@
import { useRoute } from "@react-navigation/native"; import { useRoute } from '@react-navigation/native';
import { BlurView } from "expo-blur"; import { BlurView } from 'expo-blur';
import { Image as ExpoImage } from "expo-image"; import { Image as ExpoImage } from 'expo-image';
import React, { useEffect, useMemo, useState } from "react"; import React, { useEffect, useMemo, useState } from 'react';
import { import {
FlatList, FlatList,
Image, Image,
@@ -11,27 +11,27 @@ import {
StyleSheet, StyleSheet,
Text, Text,
View, View,
} from "react-native"; } from 'react-native';
import { SheetManager } from "react-native-actions-sheet"; import { SheetManager } from 'react-native-actions-sheet';
import { responsiveHeight } from "react-native-responsive-dimensions"; import { responsiveHeight } from 'react-native-responsive-dimensions';
import { useGlobal } from "reactn"; import { useGlobal } from 'reactn';
import { background, icons, img } from "../../assets"; import { background, icons, img } from '../../assets';
import BorderGradient from "../../components/BorderGradient/BorderGradient"; import BorderGradient from '../../components/BorderGradient/BorderGradient';
import MoreMenu from "../../components/MoreMenu"; import MoreMenu from '../../components/MoreMenu';
import { projectsRef, usersRef } from "../../config/firebase"; import { projectsRef, usersRef } from '../../config/firebase';
import useDataFromRef from "../../hooks/useDataFromRef"; import useDataFromRef from '../../hooks/useDataFromRef';
import Page from "../../layouts/Page"; import Page from '../../layouts/Page';
import { Routes } from "../../navigation"; import { Routes } from '../../navigation';
import { navigate, push } from "../../navigation/NavigationService"; import { navigate, push } from '../../navigation/NavigationService';
import { useUser } from "../../providers/UserDataProvider"; import { useUser } from '../../providers/UserDataProvider';
import { Palette } from "../../styles"; import { Palette } from '../../styles';
import { FONT_FAMILY } from "../../styles/Fonts"; import { FONT_FAMILY } from '../../styles/Fonts';
import Style, { gutters, size } from "../../styles/Style"; import Style, { gutters, size } from '../../styles/Style';
import MusicCard from "../Library/components/MusicCard"; import MusicCard from '../Library/components/MusicCard';
const Profile = () => { const Profile = () => {
const { params } = useRoute(); const { params } = useRoute();
const [selected, setSelected] = useState("Chansons"); const [selected, setSelected] = useState('Chansons');
const { const {
userProjects: selfProjects, userProjects: selfProjects,
userPlaybacks: selfPlaybacks, userPlaybacks: selfPlaybacks,
@@ -41,10 +41,10 @@ const Profile = () => {
followUser, followUser,
unfollowUser, unfollowUser,
} = useUser(); } = useUser();
const [currentUID] = useGlobal("currentUID"); const [currentUID] = useGlobal('currentUID');
const targetUserId = params?.userId || currentUID || null; const targetUserId = params?.userId || currentUID || null;
const isSelf = !!currentUID && targetUserId === currentUID; const isSelf = !!currentUID && targetUserId === currentUID;
const [, setTooltip] = useGlobal("_tooltip"); const [, setTooltip] = useGlobal('_tooltip');
const [userData, setUserData] = useState(null); const [userData, setUserData] = useState(null);
const [isFollowing, setIsFollowing] = useState(false); const [isFollowing, setIsFollowing] = useState(false);
const [followers, setFollowers] = useState(0); const [followers, setFollowers] = useState(0);
@@ -65,7 +65,7 @@ const Profile = () => {
setFollowers( setFollowers(
Array.isArray(currentUserData?.followedBy) Array.isArray(currentUserData?.followedBy)
? currentUserData.followedBy.length ? currentUserData.followedBy.length
: 0, : 0
); );
return; return;
} }
@@ -82,7 +82,7 @@ const Profile = () => {
const followingQueryRef = useMemo(() => { const followingQueryRef = useMemo(() => {
try { try {
return targetUserId return targetUserId
? usersRef.where("followedBy", "array-contains", targetUserId) ? usersRef.where('followedBy', 'array-contains', targetUserId)
: null; : null;
} catch (e) { } catch (e) {
return null; return null;
@@ -113,7 +113,7 @@ const Profile = () => {
// Composant factorisé pour afficher la liste de musiques // Composant factorisé pour afficher la liste de musiques
const MusicListSection = ({ data, emptyText }) => ( const MusicListSection = ({ data, emptyText }) => (
<ScrollView style={{ flex: 1 }}> <ScrollView style={{ flex: 1, marginBottom: 70 }}>
{Array.isArray(data) && data.length > 0 ? ( {Array.isArray(data) && data.length > 0 ? (
<FlatList <FlatList
data={data} data={data}
@@ -124,10 +124,10 @@ const Profile = () => {
keyExtractor={(item) => item.id} keyExtractor={(item) => item.id}
renderItem={({ item }) => ( renderItem={({ item }) => (
<MusicCard <MusicCard
title={item?.title || "Sans titre"} title={item?.title || 'Sans titre'}
subtitle={ subtitle={
(isSelf ? currentUserData?.userName : userData?.userName) || (isSelf ? currentUserData?.userName : userData?.userName) ||
"MusicLand" 'MusicLand'
} }
imageUri={item?.coverUrl || null} imageUri={item?.coverUrl || null}
projectId={item?.id} projectId={item?.id}
@@ -156,25 +156,25 @@ const Profile = () => {
isSelf isSelf
? [ ? [
{ {
label: "Supprimer", label: 'Supprimer',
onPress: () => onPress: () =>
SheetManager.show("Delete", { SheetManager.show('Delete', {
payload: { payload: {
title: "Supprimer le projet", title: 'Supprimer le projet',
message: message:
"Cette action supprimera définitivement ce projet.", 'Cette action supprimera définitivement ce projet.',
onConfirm: async () => { onConfirm: async () => {
try { try {
if (!selectedProjectId) return; if (!selectedProjectId) return;
await projectsRef.doc(selectedProjectId).delete(); await projectsRef.doc(selectedProjectId).delete();
setTooltip({ setTooltip({
type: "success", type: 'success',
text: "Projet supprimé", text: 'Projet supprimé',
}); });
} catch (e) { } catch (e) {
setTooltip({ setTooltip({
type: "error", type: 'error',
text: e?.message || "Suppression impossible", text: e?.message || 'Suppression impossible',
}); });
} }
}, },
@@ -196,8 +196,7 @@ const Profile = () => {
color: Palette.white, color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular, fontFamily: FONT_FAMILY.InterRegular,
opacity: 0.8, opacity: 0.8,
}} }}>
>
{text} {text}
</Text> </Text>
</View> </View>
@@ -208,8 +207,8 @@ const Profile = () => {
try { try {
if (!targetUserId || isSelf) return null; if (!targetUserId || isSelf) return null;
return projectsRef return projectsRef
.where("userId", "==", targetUserId) .where('userId', '==', targetUserId)
.orderBy("updatedAt", "desc"); .orderBy('updatedAt', 'desc');
} catch (e) { } catch (e) {
return null; return null;
} }
@@ -229,24 +228,23 @@ const Profile = () => {
return ( return (
<Page <Page
backgroundImg={background.profileBG} backgroundImg={background.profileBG}
headerType="NAVIGATE" headerType='NAVIGATE'
hideBackButton={params?.noBack} hideBackButton={params?.noBack}
contentContainerStyle={{ contentContainerStyle={{
paddingBottom: gutters * 2, paddingBottom: gutters * 2,
}} }}
containerStyle={{ containerStyle={{
backgroundColor: "#0000004D", backgroundColor: '#0000004D',
}} }}
rightComponent={() => rightComponent={() =>
isSelf ? ( isSelf ? (
<Pressable onPress={() => SheetManager.show("ProfileSettings")}> <Pressable onPress={() => SheetManager.show('ProfileSettings')}>
<Image source={icons.more} style={{ ...size({ size: 24 }) }} /> <Image source={icons.more} style={{ ...size({ size: 24 }) }} />
</Pressable> </Pressable>
) : null ) : null
} }>
>
<View style={{ flex: 1, marginTop: responsiveHeight(2), gap: 20 }}> <View style={{ flex: 1, marginTop: responsiveHeight(2), gap: 20 }}>
<View style={{ borderRadius: 20, overflow: "hidden" }}> <View style={{ borderRadius: 20, overflow: 'hidden' }}>
<BlurView <BlurView
intensity={20} intensity={20}
style={{ style={{
@@ -258,7 +256,7 @@ const Profile = () => {
// Platform.OS !== "ios" ? "dimezisBlurView" : "none" // Platform.OS !== "ios" ? "dimezisBlurView" : "none"
// } // }
> >
<View style={{ alignItems: "center" }}> <View style={{ alignItems: 'center' }}>
<ExpoImage <ExpoImage
source={ source={
( (
@@ -273,9 +271,9 @@ const Profile = () => {
} }
: img.profile : img.profile
} }
cachePolicy="memory-disk" cachePolicy='memory-disk'
priority="high" priority='high'
contentFit="cover" contentFit='cover'
transition={100} transition={100}
style={{ style={{
...size({ size: 108 }), ...size({ size: 108 }),
@@ -287,14 +285,13 @@ const Profile = () => {
fontSize: 22, fontSize: 22,
color: Palette.white, color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold, fontFamily: FONT_FAMILY.InterSemiBold,
}} }}>
>
{(isSelf ? currentUserData?.userName : userData?.userName) || {(isSelf ? currentUserData?.userName : userData?.userName) ||
"Profil"} 'Profil'}
</Text> </Text>
</View> </View>
<View style={{ ...Style.containerRow, gap: 10, marginTop: 10 }}> <View style={{ ...Style.containerRow, gap: 10, marginTop: 10 }}>
<View style={{ flex: 1, alignItems: "center" }}> <View style={{ flex: 1, alignItems: 'center' }}>
<Text style={styles.value}> <Text style={styles.value}>
{Array.isArray(displayedProjects) {Array.isArray(displayedProjects)
? displayedProjects.length ? displayedProjects.length
@@ -303,14 +300,13 @@ const Profile = () => {
<Text style={styles.label}>projets</Text> <Text style={styles.label}>projets</Text>
</View> </View>
<Pressable <Pressable
style={{ flex: 1, alignItems: "center" }} style={{ flex: 1, alignItems: 'center' }}
onPress={() => onPress={() =>
push(Routes.Follows, { push(Routes.Follows, {
selected: "Abonnés", selected: 'Abonnés',
...(isSelf ? {} : { userId: targetUserId }), ...(isSelf ? {} : { userId: targetUserId }),
}) })
} }>
>
<Text style={styles.value}> <Text style={styles.value}>
{isSelf {isSelf
? currentUserData?.followedBy?.length || 0 ? currentUserData?.followedBy?.length || 0
@@ -319,14 +315,13 @@ const Profile = () => {
<Text style={styles.label}>abonnés</Text> <Text style={styles.label}>abonnés</Text>
</Pressable> </Pressable>
<Pressable <Pressable
style={{ flex: 1, alignItems: "center" }} style={{ flex: 1, alignItems: 'center' }}
onPress={() => onPress={() =>
push(Routes.Follows, { push(Routes.Follows, {
selected: "Abonnements", selected: 'Abonnements',
...(isSelf ? {} : { userId: targetUserId }), ...(isSelf ? {} : { userId: targetUserId }),
}) })
} }>
>
<Text style={styles.value}> <Text style={styles.value}>
{isSelf ? followingCount : following} {isSelf ? followingCount : following}
</Text> </Text>
@@ -339,23 +334,21 @@ const Profile = () => {
style={{ style={{
height: 36, height: 36,
borderRadius: 100, borderRadius: 100,
overflow: "hidden", overflow: 'hidden',
backgroundColor: "#FFFFFF22", backgroundColor: '#FFFFFF22',
alignItems: "center", alignItems: 'center',
justifyContent: "center", justifyContent: 'center',
width: "80%", width: '80%',
alignSelf: "center", alignSelf: 'center',
marginTop: 18, marginTop: 18,
}} }}>
>
<Text <Text
style={{ style={{
fontSize: 12, fontSize: 12,
color: Palette.white, color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold, fontFamily: FONT_FAMILY.InterSemiBold,
}} }}>
> {isFollowing ? 'Ne plus suivre' : 'Suivre'}
{isFollowing ? "Ne plus suivre" : "Suivre"}
</Text> </Text>
</View> </View>
</Pressable> </Pressable>
@@ -366,20 +359,18 @@ const Profile = () => {
style={{ style={{
...Style.containerRow, ...Style.containerRow,
gap: 6, gap: 6,
}} }}>
>
{/*{["Chansons", "Playbacks", "Clips"].map((item, index) => (*/} {/*{["Chansons", "Playbacks", "Clips"].map((item, index) => (*/}
{["Chansons", "Playbacks"].map((item, index) => ( {['Chansons', 'Playbacks'].map((item, index) => (
<Pressable <Pressable
key={index} key={index}
onPress={() => onPressMenu(item)} onPress={() => onPressMenu(item)}
style={{ flex: 1 }} style={{ flex: 1 }}>
>
<BorderGradient <BorderGradient
gradientProps={{ gradientProps={{
colors: colors:
selected === item selected === item
? ["#FFFFFF00", "#FFFFFF"] ? ['#FFFFFF00', '#FFFFFF']
: [Palette.tran, Palette.tran], : [Palette.tran, Palette.tran],
locations: [0, 1], locations: [0, 1],
start: { x: 0, y: 0 }, start: { x: 0, y: 0 },
@@ -401,22 +392,22 @@ const Profile = () => {
</Pressable> </Pressable>
))} ))}
</View> </View>
{selected === "Playbacks" && ( {selected === 'Playbacks' && (
<MusicListSection <MusicListSection
data={displayedPlaybacks} data={displayedPlaybacks}
emptyText="Aucun playback pour le moment" emptyText='Aucun playback pour le moment'
/> />
)} )}
{selected === "Chansons" && ( {selected === 'Chansons' && (
<MusicListSection <MusicListSection
data={displayedProjects} data={displayedProjects}
emptyText="Aucune chanson pour le moment" emptyText='Aucune chanson pour le moment'
/> />
)} )}
{selected === "Clips" && ( {selected === 'Clips' && (
<View style={{ flex: 1 }}> <View style={{ flex: 1 }}>
<EmptyText text={"Aucun clip pour le moment"} /> <EmptyText text={'Aucun clip pour le moment'} />
</View> </View>
)} )}
</View> </View>
@@ -446,20 +437,20 @@ const styles = StyleSheet.create({
borderWidth: 1, borderWidth: 1,
borderRadius: 10, borderRadius: 10,
height: 33, height: 33,
position: "absolute", position: 'absolute',
zIndex: 1, zIndex: 1,
width: "100%", width: '100%',
}, },
blurContainer: { blurContainer: {
height: 33, height: 33,
zIndex: -1, zIndex: -1,
borderRadius: 10, borderRadius: 10,
overflow: "hidden", overflow: 'hidden',
backgroundColor: Palette.glass, backgroundColor: Palette.glass,
}, },
blurView: { blurView: {
width: "100%", width: '100%',
height: "100%", height: '100%',
paddingHorizontal: 10, paddingHorizontal: 10,
...Style.containerCenter, ...Style.containerCenter,
}, },