diff --git a/front/API.ts b/front/API.ts index 2cdbd8f..844be9e 100644 --- a/front/API.ts +++ b/front/API.ts @@ -277,10 +277,10 @@ export default class API { }; } - public static getAllSongs(falseQuery: string, include?: SongInclude[]): Query { + public static getAllSongs(include?: SongInclude[]): Query { include ??= []; return { - key: ['songs', falseQuery, include], + key: ['songs', include], exec: () => API.fetch( { diff --git a/front/components/ScoreGraph.tsx b/front/components/ScoreGraph.tsx index f0b53ad..09e4bff 100644 --- a/front/components/ScoreGraph.tsx +++ b/front/components/ScoreGraph.tsx @@ -121,7 +121,7 @@ const Graph = ({ songId, since }: GraphProps) => { const ScoreGraph = () => { const layout = useWindowDimensions(); - const songs = useQuery(API.getAllSongs); + const songs = useQuery(API.getAllSongs()); const rangeOptions = [ { label: '3 derniers jours', value: '3days' }, { label: 'Dernière semaine', value: 'week' }, diff --git a/front/components/SearchBar.tsx b/front/components/SearchBar.tsx deleted file mode 100644 index 7613ddb..0000000 --- a/front/components/SearchBar.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import { Icon, Input, Button, Flex } from 'native-base'; -import React from 'react'; -import { MaterialIcons } from '@expo/vector-icons'; -import { translate } from '../i18n/i18n'; -import { SearchContext } from '../views/SearchView'; -import { debounce } from 'lodash'; - -export type Filter = 'artist' | 'song' | 'genre' | 'all' | 'favorites'; - -type FilterButton = { - name: string; - callback: () => void; - id: Filter; -}; - -const SearchBar = () => { - const { filter, updateFilter } = React.useContext(SearchContext); - const { stringQuery, updateStringQuery } = React.useContext(SearchContext); - const [barText, updateBarText] = React.useState(stringQuery); - - const debouncedUpdateStringQuery = debounce(updateStringQuery, 500); - - // there's a bug due to recursive feedback that erase the text as soon as you type this is a temporary "fix" - // will probably be fixed by removing the React.useContext - // React.useEffect(() => { - // updateBarText(stringQuery); - // }, [stringQuery]); - - const handleClearQuery = () => { - updateStringQuery(''); - updateBarText(''); - }; - - const handleChangeText = (text: string) => { - debouncedUpdateStringQuery(text); - updateBarText(text); - }; - - const filters: FilterButton[] = [ - { - name: translate('allFilter'), - callback: () => updateFilter('all'), - id: 'all', - }, - { - name: translate('favoriteFilter'), - callback: () => updateFilter('favorites'), - id: 'favorites', - }, - { - name: translate('artistFilter'), - callback: () => updateFilter('artist'), - id: 'artist', - }, - { - name: translate('songsFilter'), - callback: () => updateFilter('song'), - id: 'song', - }, - { - name: translate('genreFilter'), - callback: () => updateFilter('genre'), - id: 'genre', - }, - ]; - - return ( - - handleChangeText(text)} - variant={'rounded'} - value={barText} - rounded={'full'} - placeholder={translate('search')} - width={['100%', '50%']} //responsive array syntax with native-base - py={2} - px={2} - fontSize={'12'} - InputLeftElement={ - } - /> - } - InputRightElement={ - } - /> - } - /> - - - {filters.map((btn) => ( - - ))} - - - ); -}; - -export default SearchBar; diff --git a/front/components/SearchResult.tsx b/front/components/SearchResult.tsx deleted file mode 100644 index 46dab02..0000000 --- a/front/components/SearchResult.tsx +++ /dev/null @@ -1,277 +0,0 @@ -import React from 'react'; -import { - VStack, - Heading, - Box, - Card, - Flex, - useBreakpointValue, - Column, - ScrollView, -} from 'native-base'; -import { SafeAreaView } from 'react-native'; -import { SearchContext } from '../views/SearchView'; -import { useQuery } from '../Queries'; -import { Translate, translate } from '../i18n/i18n'; -import API from '../API'; -import LoadingComponent, { LoadingView } from './Loading'; -import ArtistCard from './ArtistCard'; -import GenreCard from './GenreCard'; -import SongCard from './SongCard'; -import CardGridCustom from './CardGridCustom'; -import SearchHistoryCard from './HistoryCard'; -import Song from '../models/Song'; -import { useNavigation } from '../Navigation'; -import SongRow from '../components/SongRow'; -import FavSongRow from './FavSongRow'; -import { useLikeSongMutation } from '../utils/likeSongMutation'; - -const swaToSongCardProps = (song: Song) => ({ - songId: song.id, - name: song.name, - artistName: song.artist!.name, - cover: song.cover, -}); - -const HomeSearchComponent = () => { - const { updateStringQuery } = React.useContext(SearchContext); - const { isLoading: isLoadingHistory, data: historyData = [] } = useQuery( - API.getSearchHistory(0, 12), - { enabled: true } - ); - const songSuggestions = useQuery(API.getSongSuggestions(['artist'])); - - return ( - - - {translate('lastSearched')} - {isLoadingHistory ? ( - - ) : ( - { - return { - ...h, - timestamp: h.timestamp.toLocaleString(), - onPress: () => { - updateStringQuery(h.query); - }, - }; - })} - cardComponent={SearchHistoryCard} - /> - )} - - - {translate('songsToGetBetter')} - {!songSuggestions.data ? ( - - ) : ( - - )} - - - ); -}; - -type SongsSearchComponentProps = { - maxRows?: number; -}; - -const SongsSearchComponent = (props: SongsSearchComponentProps) => { - const navigation = useNavigation(); - const { songData } = React.useContext(SearchContext); - const favoritesQuery = useQuery(API.getLikedSongs(['artist'])); - const { mutate } = useLikeSongMutation(); - - return ( - - - - {songData?.length ? ( - songData.slice(0, props.maxRows).map((comp, index) => ( - query?.songId == comp.id) - } - handleLike={async (state: boolean, songId: number) => - mutate({ songId: songId, like: state }) - } - onPress={() => { - API.createSearchHistoryEntry(comp.name, 'song'); - navigation.navigate('Play', { songId: comp.id }); - }} - /> - )) - ) : ( - - )} - - - ); -}; - -type ItemSearchComponentProps = { - maxItems?: number; -}; - -const ArtistSearchComponent = (props: ItemSearchComponentProps) => { - const { artistData } = React.useContext(SearchContext); - const navigation = useNavigation(); - - return ( - - - {artistData?.length ? ( - ({ - image: API.getArtistIllustration(artistData.id), - name: artistData.name, - id: artistData.id, - onPress: () => { - API.createSearchHistoryEntry(artistData.name, 'artist'); - navigation.navigate('Artist', { artistId: artistData.id }); - }, - }))} - cardComponent={ArtistCard} - /> - ) : ( - - )} - - ); -}; - -const GenreSearchComponent = (props: ItemSearchComponentProps) => { - const { genreData } = React.useContext(SearchContext); - const navigation = useNavigation(); - - return ( - - - {genreData?.length ? ( - ({ - image: API.getGenreIllustration(g.id), - name: g.name, - id: g.id, - onPress: () => { - API.createSearchHistoryEntry(g.name, 'genre'); - navigation.navigate('Genre', { genreId: g.id }); - }, - }))} - cardComponent={GenreCard} - /> - ) : ( - - )} - - ); -}; - -const FavoritesComponent = () => { - const navigation = useNavigation(); - const favoritesQuery = useQuery(API.getLikedSongs()); - - if (favoritesQuery.isError) { - navigation.navigate('Error'); - return <>; - } - if (!favoritesQuery.data) { - return ; - } - - return ( - - - - {favoritesQuery.data?.map((songData) => ( - { - API.createSearchHistoryEntry(songData.song.name, 'song'); //todo - navigation.navigate('Play', { songId: songData.song!.id }); - }} - /> - ))} - - - ); -}; - -const AllComponent = () => { - const screenSize = useBreakpointValue({ base: 'small', md: 'big' }); - const isMobileView = screenSize == 'small'; - - return ( - - - - - - - - - - - - - - - - ); -}; - -const FilterSwitch = () => { - const { filter } = React.useContext(SearchContext); - const [currentFilter, setCurrentFilter] = React.useState(filter); - - React.useEffect(() => { - setCurrentFilter(filter); - }, [filter]); - - switch (currentFilter) { - case 'all': - return ; - case 'song': - return ; - case 'artist': - return ; - case 'genre': - return ; - case 'favorites': - return ; - default: - return ( - `${e}: ${currentFilter}`} /> - ); - } -}; - -export const SearchResultComponent = () => { - const { stringQuery } = React.useContext(SearchContext); - const { filter } = React.useContext(SearchContext); - const shouldOutput = !!stringQuery.trim() || filter == 'favorites'; - - return shouldOutput ? ( - - - - ) : ( - - ); -}; diff --git a/front/views/SearchView.tsx b/front/views/SearchView.tsx deleted file mode 100644 index a06a9c8..0000000 --- a/front/views/SearchView.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import React, { useState } from 'react'; -import SearchBar from '../components/SearchBar'; -import Artist from '../models/Artist'; -import Song from '../models/Song'; -import Genre from '../models/Genre'; -import API from '../API'; -import { useQuery } from '../Queries'; -import { SearchResultComponent } from '../components/SearchResult'; -import { SafeAreaView } from 'react-native'; -import { Filter } from '../components/SearchBar'; -import { ScrollView } from 'native-base'; -import { RouteProps } from '../Navigation'; -import LikedSong from '../models/LikedSong'; -import ScaffoldCC from '../components/UI/ScaffoldCC'; - -interface SearchContextType { - filter: 'artist' | 'song' | 'genre' | 'all' | 'favorites'; - updateFilter: (newData: 'artist' | 'song' | 'genre' | 'all' | 'favorites') => void; - stringQuery: string; - updateStringQuery: (newData: string) => void; - songData: Song[]; - artistData: Artist[]; - genreData: Genre[]; - favoriteData: LikedSong[]; - isLoadingSong: boolean; - isLoadingArtist: boolean; - isLoadingGenre: boolean; - isLoadingFavorite: boolean; -} - -export const SearchContext = React.createContext({ - filter: 'all', - updateFilter: () => {}, - stringQuery: '', - updateStringQuery: () => {}, - songData: [], - artistData: [], - genreData: [], - favoriteData: [], - isLoadingSong: false, - isLoadingArtist: false, - isLoadingGenre: false, - isLoadingFavorite: false, -}); - -type SearchViewProps = { - query?: string; -}; - -const SearchView = (props: RouteProps) => { - const [filter, setFilter] = useState('all'); - const [stringQuery, setStringQuery] = useState(props?.query ?? ''); - - //flemme de corriger de toute facon c'est déprecié et bientot remplacé - const { isLoading: isLoadingSong, data: songData = [] } = useQuery( - API.searchSongs({ artist: undefined, genre: undefined, query: 'zeruigze' }), - { enabled: !!stringQuery } - ); - - const { isLoading: isLoadingArtist, data: artistData = [] } = useQuery( - API.searchArtists(stringQuery), - { enabled: !!stringQuery } - ); - - const { isLoading: isLoadingGenre, data: genreData = [] } = useQuery( - API.searchGenres(stringQuery), - { enabled: !!stringQuery } - ); - - const { isLoading: isLoadingFavorite, data: favoriteData = [] } = useQuery( - API.getLikedSongs(), - { enabled: true } - ); - - const updateFilter = (newData: Filter) => { - // called when the filter is changed - setFilter(newData); - }; - - const updateStringQuery = (newData: string) => { - // called when the stringQuery is updated - setStringQuery(newData); - }; - - return ( - - - - - - - - - - - ); -}; - -export default SearchView;