Front: Home Page: Use History
This commit is contained in:
10
front/API.ts
10
front/API.ts
@@ -342,12 +342,10 @@ export default class API {
|
||||
/**
|
||||
* Retrieve the authenticated user's play history
|
||||
*/
|
||||
public static async getUserPlayHistory(): Promise<Song[]> {
|
||||
const queryClient = new QueryClient();
|
||||
let songs = await queryClient.fetchQuery(["API", "allsongs"], API.getAllSongs);
|
||||
const shuffled = [...songs].sort(() => 0.5 - Math.random());
|
||||
|
||||
return shuffled.slice(0, 3);
|
||||
public static async getUserPlayHistory(): Promise<SongHistory[]> {
|
||||
return this.fetch({
|
||||
route: '/history'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,8 +20,8 @@ import useColorScheme from './hooks/colorScheme';
|
||||
const Stack = createNativeStackNavigator();
|
||||
|
||||
export const protectedRoutes = <>
|
||||
<Stack.Screen name="Play" component={PlayView} options={{ title: translate('play') }} />
|
||||
<Stack.Screen name="Home" component={HomeView} options={{ title: translate('welcome') }} />
|
||||
<Stack.Screen name="Play" component={PlayView} options={{ title: translate('play') }} />
|
||||
<Stack.Screen name="Settings" component={SetttingsNavigator} options={{ title: 'Settings' }} />
|
||||
<Stack.Screen name="Song" component={SongLobbyView} options={{ title: translate('play') }} />
|
||||
<Stack.Screen name="Score" component={ScoreView} options={{ title: translate('score') }} />
|
||||
|
||||
@@ -9,6 +9,7 @@ import CompetenciesTable from '../components/CompetenciesTable'
|
||||
import ProgressBar from "../components/ProgressBar";
|
||||
import Translate from "../components/Translate";
|
||||
import TextButton from "../components/TextButton";
|
||||
import Song from "../models/Song";
|
||||
|
||||
const HomeView = () => {
|
||||
const navigation = useNavigation();
|
||||
@@ -18,9 +19,20 @@ const HomeView = () => {
|
||||
const searchHistoryQuery = useQuery(['history', 'search'], () => API.getSearchHistory());
|
||||
const skillsQuery = useQuery(['skills'], () => API.getUserSkills());
|
||||
const nextStepQuery = useQuery(['user', 'recommendations'], () => API.getUserRecommendations());
|
||||
const artistsQueries = useQueries((playHistoryQuery.data?.concat(searchHistoryQuery.data ?? []).concat(nextStepQuery.data ?? []) ?? []).map((song) => (
|
||||
{ queryKey: ['artist', song.id], queryFn: () => API.getArtist(song.id) }
|
||||
)));
|
||||
const songHistory = useQueries(
|
||||
playHistoryQuery.data?.map(({ songID }) => ({
|
||||
queryKey: ['song', songID],
|
||||
queryFn: () => API.getSong(songID)
|
||||
})) ?? []
|
||||
);
|
||||
const artistsQueries = useQueries((songHistory
|
||||
.map((entry) => entry.data)
|
||||
.concat(nextStepQuery.data ?? [])
|
||||
.filter((s): s is Song => s !== undefined))
|
||||
.map((song) => (
|
||||
{ queryKey: ['artist', song.id], queryFn: () => API.getArtist(song.id) }
|
||||
))
|
||||
);
|
||||
|
||||
if (!userQuery.data || !skillsQuery.data || !searchHistoryQuery.data || !playHistoryQuery.data) {
|
||||
return <Center style={{ flexGrow: 1 }}>
|
||||
@@ -66,7 +78,11 @@ const HomeView = () => {
|
||||
<Box flex={{ md: 1 }}>
|
||||
<SongCardGrid
|
||||
heading={<Translate translationKey='recentlyPlayed'/>}
|
||||
songs={playHistoryQuery.data?.filter((song) => artistsQueries.find((artistQuery) => artistQuery.data?.id === song.artistId))
|
||||
songs={songHistory
|
||||
.filter((songQuery) => songQuery.data)
|
||||
.map(({ data }) => data)
|
||||
.filter((song, i, array) => array.map((s) => s.id).findIndex((id) => id == song.id) == i)
|
||||
.filter((song) => artistsQueries.find((artistQuery) => artistQuery.data?.id === song.artistId))
|
||||
.map((song) => ({
|
||||
albumCover: song.cover,
|
||||
songTitle: song.name,
|
||||
|
||||
@@ -1,42 +1,50 @@
|
||||
import { Card, Column, Image, Row, Text, useTheme, ScrollView, Center, VStack } from "native-base"
|
||||
import Translate from "../components/Translate";
|
||||
import SongCardGrid from "../components/SongCardGrid";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { useNavigation, useRoute } from "@react-navigation/native";
|
||||
import { CardBorderRadius } from "../components/Card";
|
||||
import TextButton from "../components/TextButton";
|
||||
import API from '../API';
|
||||
import { useQuery } from "react-query";
|
||||
import LoadingComponent from "../components/Loading";
|
||||
|
||||
const ScoreView = (/*{ songId }, { songId: number }*/) => {
|
||||
const ScoreView = () => {
|
||||
const theme = useTheme();
|
||||
const route = useRoute();
|
||||
const navigation = useNavigation();
|
||||
// const songQuery = useQuery(['song', props.songId], () => API.getSong(props.songId));
|
||||
// const songScoreQuery = useQuery(['song', props.songId, 'score', 'latest'], () => API.getLastSongPerformanceScore(props.songId));
|
||||
const { songId }: { songId: number } = route.params as any;
|
||||
const songQuery = useQuery(['song', songId], () => API.getSong(songId));
|
||||
const artistQuery = useQuery(['song', songId],
|
||||
() => API.getArtist(songQuery.data!.artistId),
|
||||
{ enabled: songQuery.data != undefined }
|
||||
);
|
||||
const songScoreQuery = useQuery(["score", songId], () => API.getUserPlayHistory()
|
||||
.then((history) => history.find((h) => h.songID == songId )!));
|
||||
// const perfoamnceRecommandationsQuery = useQuery(['song', props.songId, 'score', 'latest', 'recommendations'], () => API.getLastSongPerformanceScore(props.songId));
|
||||
const recommendations = useQuery(['song', 'recommendations'], () => API.getUserRecommendations());
|
||||
|
||||
if (!recommendations.data) {
|
||||
if (!recommendations.data || !songScoreQuery.data || !songQuery.data || (songQuery.data.artistId && !artistQuery.data)) {
|
||||
return <Center style={{ flexGrow: 1 }}>
|
||||
<LoadingComponent/>
|
||||
</Center>;
|
||||
}
|
||||
console.log(songScoreQuery.data);
|
||||
return <ScrollView p={8} contentContainerStyle={{ alignItems: 'center' }}>
|
||||
<VStack width={{ base: '100%', lg: '50%' }} textAlign='center'>
|
||||
<Text bold fontSize='lg'>Rolling in the Deep</Text>
|
||||
<Text bold>Adele - 3:45</Text>
|
||||
<Text bold fontSize='lg'>{songQuery.data.name}</Text>
|
||||
<Text bold>{artistQuery.data?.name}</Text>
|
||||
<Row style={{ justifyContent: 'center', display: 'flex' }}>
|
||||
<Card shadow={3} style={{ flex: 1 }}>
|
||||
<Image
|
||||
style={{ zIndex: 0, aspectRatio: 1, margin: 5, borderRadius: CardBorderRadius}}
|
||||
source={{ uri: 'https://imgs.search.brave.com/AinqAz0knOSOt0V3rcv7ps7aMVCo0QQfZ-1NTdwVjK0/rs:fit:1200:1200:1/g:ce/aHR0cDovLzEuYnAu/YmxvZ3Nwb3QuY29t/Ly0xTmZtZTdKbDVk/US9UaHd0Y3pieEVa/SS9BQUFBQUFBQUFP/TS9QdGx6ZWtWd2Zt/ay9zMTYwMC9BZGVs/ZSstKzIxKyUyNTI4/T2ZmaWNpYWwrQWxi/dW0rQ292ZXIlMjUy/OS5qcGc' }}
|
||||
source={{ uri: songQuery.data.cover }}
|
||||
/>
|
||||
</Card>
|
||||
<Card shadow={3} style={{ flex: 1 }}>
|
||||
<Column style={{ justifyContent: 'space-evenly', flexGrow: 1 }}>
|
||||
<Row style={{ alignItems: 'center' }}>
|
||||
{/*<Row style={{ alignItems: 'center' }}>
|
||||
<Text bold fontSize='xl'>
|
||||
80
|
||||
|
||||
</Text>
|
||||
<Translate translationKey='goodNotes' format={(t) => ' ' + t}/>
|
||||
</Row>
|
||||
@@ -45,15 +53,14 @@ const ScoreView = (/*{ songId }, { songId: number }*/) => {
|
||||
80
|
||||
</Text>
|
||||
<Translate translationKey='goodNotesInARow' format={(t) => ' ' + t}/>
|
||||
</Row>
|
||||
</Row>*/}
|
||||
<Row style={{ alignItems: 'center' }}>
|
||||
<Translate translationKey='precisionScore' format={(t) => t + ' : '}/>
|
||||
<Translate translationKey='score' format={(t) => t + ' : '}/>
|
||||
<Text bold fontSize='xl'>
|
||||
{"80" + "%"}
|
||||
{songScoreQuery.data.score + "pts"}
|
||||
</Text>
|
||||
</Row>
|
||||
</Column>
|
||||
{/* Precision */}
|
||||
</Card>
|
||||
</Row>
|
||||
<SongCardGrid
|
||||
@@ -74,7 +81,7 @@ const ScoreView = (/*{ songId }, { songId: number }*/) => {
|
||||
onPress={() => navigation.navigate('Home')}
|
||||
/>
|
||||
<TextButton
|
||||
onPress={() => navigation.navigate('Song', { songId: 1 })}
|
||||
onPress={() => navigation.navigate('Song', { songId })}
|
||||
translate={{ translationKey: 'playAgain' }}
|
||||
/>
|
||||
</Row>
|
||||
|
||||
@@ -14939,6 +14939,11 @@ react-shallow-renderer@^16.13.1, react-shallow-renderer@^16.15.0:
|
||||
object-assign "^4.1.1"
|
||||
react-is "^16.12.0 || ^17.0.0 || ^18.0.0"
|
||||
|
||||
react-sub-unsub@^2.1.6:
|
||||
version "2.1.11"
|
||||
resolved "https://registry.yarnpkg.com/react-sub-unsub/-/react-sub-unsub-2.1.11.tgz#173d0803e1d7b29611cb29d95f47ed7798e93642"
|
||||
integrity sha512-FNKy0uD5wSieRE+l5RXaS0bUu6cR8XAXLDwOJnvSDGBMHcWVb1dod8ZkXYjPKtKR74tjYCEpMWcEAWCOoWNXxQ==
|
||||
|
||||
react-test-renderer@17.0.2, react-test-renderer@~17.0.2:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-17.0.2.tgz#4cd4ae5ef1ad5670fc0ef776e8cc7e1231d9866c"
|
||||
@@ -14954,6 +14959,13 @@ react-timer-hook@^3.0.5:
|
||||
resolved "https://registry.yarnpkg.com/react-timer-hook/-/react-timer-hook-3.0.5.tgz#a8d930f99b180cd88da245965a26a17df3e7457b"
|
||||
integrity sha512-n+98SdmYvui2ne3KyWb3Ldu4k0NYQa3g/VzW6VEIfZJ8GAk/jJsIY700M8Nd2vNSTj05c7wKyQfJBqZ0x7zfiA==
|
||||
|
||||
react-use-precision-timer@^3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-use-precision-timer/-/react-use-precision-timer-3.3.1.tgz#8e49b6f58d507647925bf633a673a7cb0b2b924d"
|
||||
integrity sha512-PUCpFp48ftKoV2C+hz57mbqzqojE/Ol169Lyk2fFEIapsOH6tKIis8vZwmloedRe916qmJCOkXp+h9IB6QJY+A==
|
||||
dependencies:
|
||||
react-sub-unsub "^2.1.6"
|
||||
|
||||
react@18.1.0:
|
||||
version "18.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-18.1.0.tgz#6f8620382decb17fdc5cc223a115e2adbf104890"
|
||||
|
||||
Reference in New Issue
Block a user