feat: filter by lang

This commit is contained in:
2026-08-11 13:19:25 +02:00
parent c8656d6273
commit 0165e8b44d
8 changed files with 139 additions and 29 deletions
+89 -21
View File
@@ -1,13 +1,5 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import {
FlatList,
Image,
Platform,
ScrollView,
StyleSheet,
Text,
View,
} from 'react-native'
import { FlatList, Image, Platform, ScrollView, StyleSheet, Text, View } from 'react-native'
import { BlurView } from 'expo-blur'
import { responsiveHeight } from 'react-native-responsive-dimensions'
import { background, icons } from '../../assets'
@@ -29,6 +21,30 @@ import SongCard from './components/SongCard'
import ClubCard from '../Home/components/ClubCard'
const allowedPremiumLevels = new Set(['starter', 'pro', 'premium'])
const languageOptions = [
{ value: 'all', label: 'Toutes' },
{ value: 'fr', label: 'Français' },
{ value: 'en', label: 'English' },
]
const StreamingLanguageFilter = ({ selectedLanguage, onSelectLanguage }) => (
<View style={styles.languageFilter}>
<Text style={styles.languageFilterLabel}>Langue des musiques</Text>
<View style={styles.languageFilterButtons}>
{languageOptions.map((option) => (
<BorderGradientButton
key={option.value}
title={option.label}
onPress={() => onSelectLanguage(option.value)}
tint={selectedLanguage === option.value ? 'light' : 'dark'}
containerStyle={styles.languageFilterButton}
titleStyle={styles.languageFilterButtonText}
size="small"
/>
))}
</View>
</View>
)
const normalizePremiumLevel = (value) => {
if (typeof value !== 'string') {
@@ -48,13 +64,19 @@ const chunkArray = (items = [], size = 10) => {
const HitParade = () => {
const [selectedCategory, setSelectedCategory] = useState('Chansons')
const [selectedLanguage, setSelectedLanguage] = useState('all')
const navigateToMusicDetails = useNavigateToMusicDetails()
const allSongsRef = useMemo(() => {
const songsRef = projectsRef.where('hasSong', '==', true)
return selectedLanguage === 'all' ? songsRef : songsRef.where('lang', '==', selectedLanguage)
}, [selectedLanguage])
const { data: allSongs } = useDataFromRef({
ref: projectsRef.where('hasSong', '==', true),
ref: allSongsRef,
format: (docs) => docs.filter((item) => item?.hasPlayback !== true),
simpleRef: false,
listener: true,
condition: true,
refreshArray: [selectedLanguage],
})
const { data: topMonthSongs } = useDataFromRef({
@@ -62,7 +84,8 @@ const HitParade = () => {
format: (docs) => docs.filter((item) => item?.hasPlayback !== true),
simpleRef: false,
listener: false,
condition: true,
condition: selectedLanguage === 'all',
refreshArray: [selectedLanguage],
})
const { data: allTimeSongs } = useDataFromRef({
@@ -70,20 +93,31 @@ const HitParade = () => {
format: (docs) => docs.filter((item) => item?.hasPlayback !== true),
simpleRef: false,
listener: false,
condition: true,
condition: selectedLanguage === 'all',
refreshArray: [selectedLanguage],
})
const songsList = useMemo(() => (Array.isArray(allSongs) ? allSongs : []), [allSongs])
const topMonthList = useMemo(
() => (Array.isArray(topMonthSongs) ? topMonthSongs : []),
[topMonthSongs]
)
const topMonthList = useMemo(() => {
if (selectedLanguage === 'all') {
return Array.isArray(topMonthSongs) ? topMonthSongs : []
}
return [...songsList]
.filter((item) => typeof item?.monthViews === 'number' && item.monthViews > 0)
.sort((a, b) => b.monthViews - a.monthViews)
.slice(0, 20)
}, [selectedLanguage, songsList, topMonthSongs])
const allTimeList = useMemo(
() => (Array.isArray(allTimeSongs) ? allTimeSongs : []),
[allTimeSongs]
)
const allTimeList = useMemo(() => {
if (selectedLanguage === 'all') {
return Array.isArray(allTimeSongs) ? allTimeSongs : []
}
return [...songsList]
.filter((item) => typeof item?.views === 'number' && item.views > 0)
.sort((a, b) => b.views - a.views)
.slice(0, 20)
}, [allTimeSongs, selectedLanguage, songsList])
// === RENDUS PAR PLATEFORME ===
const renderSongsMobile = () => (
@@ -254,7 +288,12 @@ const HitParade = () => {
[setSearchSelected]
)
const musicResults = useMemo(() => (Array.isArray(musics) ? musics : []), [musics])
const musicResults = useMemo(() => {
const results = Array.isArray(musics) ? musics : []
return selectedLanguage === 'all'
? results
: results.filter((project) => project?.lang === selectedLanguage)
}, [musics, selectedLanguage])
const [creatorsById, setCreatorsById] = useState({})
@@ -632,6 +671,10 @@ const HitParade = () => {
style={{ alignSelf: 'center', height: 150, resizeMode: 'contain' }}
/> */}
<ClubCard />
<StreamingLanguageFilter
selectedLanguage={selectedLanguage}
onSelectLanguage={setSelectedLanguage}
/>
{isWeb && (
<View
@@ -724,3 +767,28 @@ const HitParade = () => {
}
export default HitParade
const styles = StyleSheet.create({
languageFilter: {
width: '100%',
maxWidth: 620,
alignSelf: 'center',
gap: 8,
},
languageFilterLabel: {
color: Palette.white,
fontSize: 13,
fontFamily: FONT_FAMILY.InterSemiBold,
textAlign: 'center',
},
languageFilterButtons: {
flexDirection: 'row',
gap: 10,
},
languageFilterButton: {
flex: 1,
},
languageFilterButtonText: {
fontSize: 13,
},
})
+1
View File
@@ -56,6 +56,7 @@ const Register = () => {
isLoading: socialLoading,
} = useSocialAuth({
onSuccess: afterSocialAuth,
preferredLanguage,
})
const isBusy = socialLoading
+17 -2
View File
@@ -29,7 +29,8 @@ const CreatingLyrics = ({ active, config, selections, onErrorRedirect }) => {
const [error, setError] = useState(null)
const hasShownErrorAlert = useRef(false)
const { setIsLoading } = useMinuit()
const { updateProjectData } = useUser()
const { selectedProject, updateProjectData } = useUser()
const projectLang = selectedProject?.lang === 'en' ? 'en' : 'fr'
const progressValue = Math.max(0, Math.min(100, Math.round(progress)))
// Reset when becomes active
@@ -74,6 +75,7 @@ const CreatingLyrics = ({ active, config, selections, onErrorRedirect }) => {
const sanitizedStructure = sanitizeStructureList(config?.structure, CUSTOM_SANITIZE_OPTIONS)
const callable = firebase.functions().httpsCallable('lyrics-generateLyrics')
const { data } = await callable({
lang: projectLang,
objective: config?.objective,
context: config?.context,
emotion: config?.emotion,
@@ -188,6 +190,7 @@ const CreatingLyrics = ({ active, config, selections, onErrorRedirect }) => {
}
await updateProjectData({
lang: projectLang,
title: result?.title || '',
lyrics: Array.isArray(result?.lyrics) ? result.lyrics : [],
description: result?.lyricsDescription,
@@ -206,7 +209,18 @@ const CreatingLyrics = ({ active, config, selections, onErrorRedirect }) => {
if (active && result && progress >= 100 && !saved && !error) {
autoSaveAndGo()
}
}, [active, result, progress, saved, error, setIsLoading, updateProjectData, config, selections])
}, [
active,
result,
progress,
saved,
error,
setIsLoading,
updateProjectData,
config,
selections,
projectLang,
])
useEffect(() => {
if (error && !hasShownErrorAlert.current) {
@@ -303,6 +317,7 @@ const CreatingLyrics = ({ active, config, selections, onErrorRedirect }) => {
await setIsLoading(true)
console.log('📄 [CreatingLyrics] Consultation manuelle du texte')
await updateProjectData({
lang: projectLang,
title: result?.title || '',
lyrics: Array.isArray(result?.lyrics) ? result.lyrics : [],
config: config || null,