diff --git a/src/Api/src/controller/spotify-controller/spotifyCtrl.ts b/src/Api/src/controller/spotify-controller/spotifyCtrl.ts
index a26f33b..204c815 100644
--- a/src/Api/src/controller/spotify-controller/spotifyCtrl.ts
+++ b/src/Api/src/controller/spotify-controller/spotifyCtrl.ts
@@ -22,7 +22,7 @@ class SpotifyController implements Controller {
this.router.get(`${this.path}/exchange`,this.login);
this.router.get(`${this.path}/callback`,this.getAccessToken);
// this.router.post(`${this.path}/refresh`,this.getRefreshToken);
- this.router.get(`${this.path}/play/:musicId`, this.getMusic);
+ // this.router.get(`${this.path}/play/:musicId`, this.getMusic);
this.router.get(`${this.path}/spot`, this.getSpot);
}
@@ -137,10 +137,6 @@ class SpotifyController implements Controller {
}
- public getMusic(){
-
- return null;
- }
public getSpot = async (
req: Request,
diff --git a/src/Api/src/controller/user-controller/userCtrl.ts b/src/Api/src/controller/user-controller/userCtrl.ts
index 9f5c740..2479abb 100644
--- a/src/Api/src/controller/user-controller/userCtrl.ts
+++ b/src/Api/src/controller/user-controller/userCtrl.ts
@@ -219,8 +219,9 @@ class UserController implements Controller {
console.log('Impossible de convertir la chaîne en nombre');
}
//}
+ const currentMusicId = req.body.currentMusicId;
const userId = req.user.idFlad;
- const data = await this.locationService.getNearUser(userId,latitude,longitude);
+ const data = await this.locationService.getNearUser(userId,latitude,longitude, currentMusicId);
console.log(data);
res.status(201).send(data);
diff --git a/src/Api/src/database/schema/LocationSchema.ts b/src/Api/src/database/schema/LocationSchema.ts
index 37d37b4..b055d2b 100644
--- a/src/Api/src/database/schema/LocationSchema.ts
+++ b/src/Api/src/database/schema/LocationSchema.ts
@@ -18,6 +18,9 @@ const locationSchema = new Schema(
type: Number,
required: true,
},
+ currentMusicId : {
+ type: String,
+ }
},
diff --git a/src/Api/src/model/locationModel.ts b/src/Api/src/model/locationModel.ts
index 99fb3ca..37341b1 100644
--- a/src/Api/src/model/locationModel.ts
+++ b/src/Api/src/model/locationModel.ts
@@ -32,10 +32,12 @@ export class UserLocation {
uuid: string;
latitude : number;
longitude: number;
- constructor(uuid: string, latitude: number, longitude: number){
+ currentMusicId : string;
+ constructor(uuid: string, latitude: number, longitude: number, currentMusicId : string) {
this.uuid = uuid;
this.latitude = latitude;
this.longitude = longitude;
+ this.currentMusicId = currentMusicId;
}
}
diff --git a/src/Api/src/service/LocationService.ts b/src/Api/src/service/LocationService.ts
index 077c0a5..6b09c4a 100644
--- a/src/Api/src/service/LocationService.ts
+++ b/src/Api/src/service/LocationService.ts
@@ -6,11 +6,11 @@ import LocationSchema from "../database/schema/LocationSchema";
class LocationService {
private locationCollection = LocationSchema;
// private API_KEY : string = "AIzaSyBFCEAtmhZ8jvw84UTQvX3Aqpr66GVqB_A";
- public async getNearUser(idFlad : string, latitude : number, longitude : number)
+ public async getNearUser(idFlad : string, latitude : number, longitude : number, currentMusicId: string)
{
await this.locationCollection.findOneAndUpdate(
{ idFlad },
- { idFlad, latitude, longitude },
+ { idFlad, latitude, longitude, currentMusicId },
{ upsert: true }
);
@@ -22,18 +22,18 @@ class LocationService {
let dbUsersList:UserLocation[] = [];
snapshot.forEach(doc => {
- dbUsersList.push(new UserLocation(doc.idFlad,doc.latitude,doc.longitude));
+ dbUsersList.push(new UserLocation(doc.idFlad,doc.latitude,doc.longitude, doc.currentMusicId));
console.log(doc.idFlad, '=>', doc);
});
// missing the curent music
- let listUser: string[] = [];
+ let listUser: {userid: string, music : string}[] = [];
dbUsersList.forEach(user => {
console.log(user);
const dist = this.distanceBetween(latitude , longitude , user.latitude, user.longitude);
console.log(user.uuid,dist);
if (dist <= 100) {
- listUser.push(user.uuid);
+ listUser.push({userid : user.uuid, music : user.currentMusicId});
}
});
diff --git a/src/FLAD/Model/Music.tsx b/src/FLAD/Model/Music.tsx
index cc20984..d2b1715 100644
--- a/src/FLAD/Model/Music.tsx
+++ b/src/FLAD/Model/Music.tsx
@@ -1,14 +1,14 @@
-export default class Music {
- private id : string;
- private name : string;
- private artist : string;
- private linkCover : string; // Image.source
+// export default class Music {
+// private id : string;
+// private name : string;
+// private artist : string;
+// private linkCover : string; // Image.source
- constructor(id : string, name : string, artist : string, linkCover : string){
- this.id = id;
- this.name = name;
- this.artist = artist;
- this.linkCover = linkCover;
- }
+// constructor(id : string, name : string, artist : string, linkCover : string){
+// this.id = id;
+// this.name = name;
+// this.artist = artist;
+// this.linkCover = linkCover;
+// }
-}
+// }
diff --git a/src/FLAD/Model/Spot.tsx b/src/FLAD/Model/Spot.tsx
index 46a6f9d..6212dca 100644
--- a/src/FLAD/Model/Spot.tsx
+++ b/src/FLAD/Model/Spot.tsx
@@ -2,7 +2,7 @@ import Music from "./Music";
export class Spot {
private _userId : string;
- public _music : Music;
+ private _music : Music;
constructor(userId : string, music : Music){
this._userId = userId;
this._music = music;
@@ -10,8 +10,13 @@ export class Spot {
get userSpotifyId(): string {
return this._userId;
}
- get idSpotify(): Music {
- return this._music;
- }
-
+ set userSpotifyId(value: string) {
+ this._userId = value;
+ }
+ get music(): Music {
+ return this._music;
+ }
+ set music(value: Music) {
+ this._music = value;
+ }
}
\ No newline at end of file
diff --git a/src/FLAD/Model/factory/MusicFactory.ts b/src/FLAD/Model/factory/MusicFactory.ts
index 1e813c2..e1d9973 100644
--- a/src/FLAD/Model/factory/MusicFactory.ts
+++ b/src/FLAD/Model/factory/MusicFactory.ts
@@ -5,7 +5,9 @@ export default class MusicFactory {
const music = new Music(
jsonMusic.id,
jsonMusic.name,
- jsonMusic.album.images[0].url
+ "",
+ jsonMusic.album.images[0].url,
+ jsonMusic.preview_url
);
return music;
}
diff --git a/src/FLAD/app.json b/src/FLAD/app.json
index 1cdc675..8db8416 100644
--- a/src/FLAD/app.json
+++ b/src/FLAD/app.json
@@ -7,7 +7,7 @@
"icon": "./assets/icons/icon.png",
"userInterfaceStyle": "light",
"splash": {
- "image": "./assets/images/RedFlady.png",
+ "image": "./assets/icons/splash.png",
"resizeMode": "contain",
"backgroundColor": "#1d2129"
},
diff --git a/src/FLAD/components/Card.tsx b/src/FLAD/components/Card.tsx
index 40c8002..1e70aa7 100644
--- a/src/FLAD/components/Card.tsx
+++ b/src/FLAD/components/Card.tsx
@@ -11,7 +11,7 @@ const SCREEN_WIDTH = Dimensions.get('window').width
interface CardProps {
title: string;
image: any;
- onSwipe: (direction: "left" | "right") => void;
+ onSwipe: (direction: "left" | "right" | "down") => void;
}
type ContextType = {
translateX: number;
@@ -47,7 +47,12 @@ const Card = ({ title, image, onSwipe } : CardProps) => {
} else if (translateX.value < -160) {
runOnJS(onSwipe)("left");
// onSwipe("left");
- } else {
+ }else if (translateY.value > 250) {
+ runOnJS(onSwipe)("down");
+ // onSwipe("left");
+ }
+
+ else {
translateX.value = withSpring(0);
translateY.value = withSpring(0);
}
diff --git a/src/FLAD/components/CardMusic.tsx b/src/FLAD/components/CardMusic.tsx
index 7cf3393..89b1602 100644
--- a/src/FLAD/components/CardMusic.tsx
+++ b/src/FLAD/components/CardMusic.tsx
@@ -1,24 +1,33 @@
import React from 'react';
import { StyleSheet, Text, View , Image } from 'react-native';
+import { SharedElement } from 'react-navigation-shared-element';
+import { useSelector } from 'react-redux';
import normalize from '../components/Normalize';
type CustomCardMusic = { //Props
- image: ImageSource;
+ image: string;
title: string;
description: string;
+ id : string;
}
+
export default function CardMusic(CBP: CustomCardMusic) {
+
+const currentMusic = useSelector(state => state.appReducer.currentMusic);
+
const source = typeof CBP.image === 'string' ? { uri: CBP.image } : CBP.image;
return (
+
- {CBP.title}
- {CBP.description}
+ {/* currentMusic.id === CBP.id && styles.currentMusic */}
+ {CBP.title}
+ {CBP.description}
);
@@ -59,5 +68,8 @@ const styles = StyleSheet.create({
description: {
color: 'white',
fontSize: normalize(18)
+ },
+ currentMusic: {
+ color: 'red'
}
});
\ No newline at end of file
diff --git a/src/FLAD/components/CurrentMusic.tsx b/src/FLAD/components/CurrentMusic.tsx
new file mode 100644
index 0000000..09e2ac3
--- /dev/null
+++ b/src/FLAD/components/CurrentMusic.tsx
@@ -0,0 +1,145 @@
+// import React, { useEffect, useRef } from 'react';
+// import { StyleSheet, Text, View , Image } from 'react-native';
+// import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
+// import { SharedElement } from 'react-navigation-shared-element';
+// import { useSelector } from 'react-redux';
+
+// import normalize from '../components/Normalize';
+// import SpotifyService from '../services/spotify/spotify.service';
+
+
+
+// export default function CurrentMusic() {
+// const animatedStyle = useAnimatedStyle(() => {
+// return {
+// transform: [
+// { scale: withTiming(139.929, { duration: 1000 }) }
+// ]
+// }
+// });
+// const centerX = useSharedValue(0);
+// const centerY = useSharedValue(0);
+// const scale = useSharedValue(0);
+// const width = useSharedValue(0);
+// const height = useSharedValue(0);
+// const rippleOpacity = useSharedValue(1);
+// const rStyle = useAnimatedStyle(() => {
+// const circleRadius = Math.sqrt(width.value ** 2 + height.value ** 2);
+
+// const translateX = centerX.value - circleRadius;
+// const translateY = centerY.value - circleRadius;
+
+// return {
+// width: circleRadius * 2,
+// height: circleRadius * 2,
+// borderRadius: circleRadius,
+// opacity: rippleOpacity.value,
+// backgroundColor: 'rgba(0,0,0,0.2)',
+// position: 'absolute',
+// top: 0,
+// left: 0,
+// transform: [
+// { translateX },
+// { translateY },
+// {
+// scale: scale.value,
+// },
+// ],
+// };
+// });
+
+// useEffect(() => {
+// // withTiming, withSpring
+// rippleOpacity.value = 1;
+// scale.value = withTiming(1, { duration: 1000 });
+// }, [rippleOpacity,scale]);
+// return (
+
+//
+//
+//
+//
+//
+// );
+// }
+
+
+import React, { useEffect, useRef } from 'react';
+import { StyleSheet, Text, View , Image } from 'react-native';
+import Animated, { useAnimatedStyle, useDerivedValue, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';
+import { SharedElement } from 'react-navigation-shared-element';
+import { useSelector } from 'react-redux';
+
+import normalize from '../components/Normalize';
+import SpotifyService from '../services/spotify/spotify.service';
+
+
+
+export default function CurrentMusic() {
+ const transition = useDerivedValue(() => {
+ return withSpring(value.value);
+ });
+
+
+ return (
+
+
+
+
+
+
+ );
+}
+
diff --git a/src/FLAD/components/HorizontalFlatList.tsx b/src/FLAD/components/HorizontalFlatList.tsx
new file mode 100644
index 0000000..e14d26d
--- /dev/null
+++ b/src/FLAD/components/HorizontalFlatList.tsx
@@ -0,0 +1,52 @@
+import { View, StyleSheet, Dimensions,Text, Image, Pressable, TouchableWithoutFeedback, TouchableOpacity, TouchableHighlight, FlatList } from "react-native";
+import Animated, {
+ Layout,
+ Transition,
+ ZoomIn,
+ ZoomOut,
+ } from "react-native-reanimated";
+
+const { width } = Dimensions.get("window");
+const SIZE = width / 3;
+import { Feather as Icon } from "@expo/vector-icons";
+import Music from "../Model/Music";
+import { State, TapGestureHandler } from "react-native-gesture-handler";
+import { useRef, useState } from "react";
+
+
+interface HorizontalFlatListProps {
+ // React.ReactNode;
+ renderCell: (image: string, titre : string) => React.ReactElement
+ title : string;
+ data : any[];
+ }
+export const HorizontalFlatList = ({ title, data, renderCell}: HorizontalFlatListProps) => {
+
+
+ return (
+
+ {title}
+ item.id}
+ renderItem={({item}) =>{
+ return renderCell(item.image, image.titre);
+ }}
+ />
+ );
+ };
+ const styles = StyleSheet.create({
+ similarSection: {
+ paddingTop: 30
+ },
+ similarTitle: {
+ color: "#2998FD",
+ paddingLeft: 35,
+ fontSize: 17,
+ fontWeight: "600",
+ paddingBottom: 20
+ }
+
+ });
\ No newline at end of file
diff --git a/src/FLAD/components/SelectedCard.tsx b/src/FLAD/components/SelectedCard.tsx
new file mode 100644
index 0000000..8a05ce5
--- /dev/null
+++ b/src/FLAD/components/SelectedCard.tsx
@@ -0,0 +1,74 @@
+import { View, StyleSheet, Dimensions, Image, Pressable, TouchableWithoutFeedback, TouchableOpacity, TouchableHighlight } from "react-native";
+import Animated, {
+ Layout,
+ Transition,
+ ZoomIn,
+ ZoomOut,
+ } from "react-native-reanimated";
+
+const { width } = Dimensions.get("window");
+const SIZE = width / 3;
+import { Feather as Icon } from "@expo/vector-icons";
+import Music from "../Model/Music";
+import { State, TapGestureHandler } from "react-native-gesture-handler";
+import { useRef, useState } from "react";
+
+
+interface SelectedCardProps {
+ artist: Music;
+ onPress: () => void;
+ // cheepPosition: string ;(direction: "left" | "right" | "down")
+ }
+export const SelectedCard = ({ artist, onPress }: SelectedCardProps) => {
+ const [selected,setSeleted] = useState(false);
+ const onS = () => {
+ setSeleted(!selected);
+ onPress();
+ };
+
+ return (
+
+
+
+
+ { selected && (
+
+
+
+ )}
+
+
+
+
+ );
+ };
+ const styles = StyleSheet.create({
+ container: {
+ width: SIZE,
+ height: SIZE,
+ padding: 8,
+ },
+ card: {
+ flex: 1,
+ padding: 8,
+ alignItems: "flex-end",
+ },
+ image: {
+ borderRadius: 8,
+ ...StyleSheet.absoluteFillObject,
+ width: undefined,
+ height: undefined,
+ },
+ cheked : {
+ backgroundColor : "white",
+ borderRadius : 100,
+ alignItems : "center",
+
+
+ }
+ });
\ No newline at end of file
diff --git a/src/FLAD/components/littleCard.tsx b/src/FLAD/components/littleCard.tsx
new file mode 100644
index 0000000..362cd47
--- /dev/null
+++ b/src/FLAD/components/littleCard.tsx
@@ -0,0 +1,29 @@
+import {TouchableOpacity, ScrollView, View, Text, StyleSheet, Image, SafeAreaView, FlatList, Animated} from 'react-native';
+
+
+export default function littleCard ({image,titre}){
+ return (
+
+
+ {titre}
+
+
+ )
+}
+const styles = StyleSheet.create({
+
+ similarContainer: {
+ width: 90,
+ marginHorizontal: 7
+ },
+ similarTitleFilm: {
+ color: "#DADADA",
+ paddingTop: 5,
+ fontWeight: "300"
+ },
+ similarPoster: {
+ height: 130,
+ width: 90,
+ borderRadius: 8
+ }
+})
diff --git a/src/FLAD/data/data.ts b/src/FLAD/data/data.ts
index 4b92177..96fe6e1 100644
--- a/src/FLAD/data/data.ts
+++ b/src/FLAD/data/data.ts
@@ -1,6 +1,8 @@
-export const cards = [{
- musicName : "Je bibi",
- name : "Kaaris",
+import Music from "../Model/Music";
+import { Spot } from "../Model/Spot";
+
+export const cards= [{
+ name : "blue",
sourceUrl : "https://th.bing.com/th/id/R.dbf87f0d8cbfd078ab6a589a5d921994?rik=1%2f6KliMpOAeh8A&pid=ImgRaw&r=0",
index : 4
},
@@ -42,3 +44,43 @@ export const cards = [{
},
]
+
+const spotArray: Spot[] = [
+ new Spot("1", new Music("1", "Title 1", "Bio 1", "Image 1", "TrackPreviewUrl 1")),
+ new Spot("2", new Music("2", "Title 2", "Bio 2", "Image 2", "TrackPreviewUrl 2")),
+ new Spot("3", new Music("3", "Title 3", "Bio 3", "Image 3", "TrackPreviewUrl 3")),
+ new Spot("4", new Music("4", "Title 4", "Bio 4", "Image 4", "TrackPreviewUrl 4")),
+ new Spot("5", new Music("5", "Title 5", "Bio 5", "Image 5", "TrackPreviewUrl 5")),
+];
+export const spotArray2: Spot[] = [
+ new Spot("1", new Music("6KNw3UKRp3QRsO7Cf4ASVE",
+ "MOLLY - A COLORS SHOW",
+ "Tame Impala",
+ "https://i.scdn.co/image/ab67616d0000b2734299eb40408fc73ce8bf490a",
+ "https://p.scdn.co/mp3-preview/4faf99856f15e03a09d50b91006efd3205606866?cid=774b29d4f13844c495f206cafdad9c86")
+ ),
+ new Spot("2", new Music("5yHoANSze7sGzhn9MUarH3",
+ "Passat",
+ "Silk Sonic, Bruno Mars, Anderson .Paak",
+ "https://i.scdn.co/image/ab67616d0000b273e9df9b5a7df491536c51c922",
+ "https://p.scdn.co/mp3-preview/0bb7472026a00790950fc231fe61963ef7cc867b?cid=774b29d4f13844c495f206cafdad9c86")
+ ),
+ new Spot("3", new Music("7suNqxRED5CrwyZSzYC0nT",
+ "Extendo",
+ "Kali Uchis",
+ "https://i.scdn.co/image/ab67616d0000b273b856464c40a062d1723a21f2",
+ "https://p.scdn.co/mp3-preview/5398121f6295965e3c7cad8a6dca5667ba7f4713?cid=774b29d4f13844c495f206cafdad9c86")
+ ),
+ new Spot("4", new Music("07JqNLmPUJSlcouGQoJlzq",
+ "Addiction",
+ "Harry Styles",
+ "https://i.scdn.co/image/ab67616d0000b2739297f238f237431d56c67460",
+ "https://p.scdn.co/mp3-preview/33d12e9e5a3dd3394b1649d515912260b01579dd?cid=774b29d4f13844c495f206cafdad9c86")
+ ),
+ new Spot("5", new Music("5Ylp75kdffyJSwISRPqEiL",
+ "La Vidéo",
+ "Harry Styles",
+ "https://i.scdn.co/image/ab67616d0000b2738900d48677696015bf325b8b",
+ "https://p.scdn.co/mp3-preview/4fff3f8d76a422f42cea39f001836a3d54937fc4?cid=774b29d4f13844c495f206cafdad9c86")
+ )
+];
diff --git a/src/FLAD/model/Music.ts b/src/FLAD/model/Music.ts
index db657b8..2d21e6a 100644
--- a/src/FLAD/model/Music.ts
+++ b/src/FLAD/model/Music.ts
@@ -1,12 +1,16 @@
export default class Music {
+ private _id : string;
private _title: string;
private _bio: string;
- private _image: ImageSource;
+ private _image: string;
+ private _trackPreviewUrl : string;
- constructor(title: string, bio: string, image: ImageSource) {
+ constructor(id : string,title: string, bio: string, image: string, trackPreviewUrl: string) {
this._title = title;
this._bio = bio;
this._image = image;
+ this._id = id;
+ this._trackPreviewUrl = trackPreviewUrl;
}
get title(): string {
@@ -25,11 +29,27 @@ export default class Music {
this._bio = value;
}
- get image(): ImageSource {
+ get image(): string {
return this._image;
}
- set image(value: ImageSource) {
+ set image(value: string) {
this._image = value;
}
+
+ get id(): string {
+ return this._id;
+ }
+
+ set id(value: string) {
+ this._id = value;
+ }
+
+ get trackPreviewUrl(): string {
+ return this._trackPreviewUrl;
+ }
+
+ set trackPreviewUrl(value: string) {
+ this._trackPreviewUrl = value;
+ }
}
diff --git a/src/FLAD/navigation/FavoriteNavigation.tsx b/src/FLAD/navigation/FavoriteNavigation.tsx
index a2f92d0..4b76015 100644
--- a/src/FLAD/navigation/FavoriteNavigation.tsx
+++ b/src/FLAD/navigation/FavoriteNavigation.tsx
@@ -2,20 +2,28 @@ import React from 'react';
import Favorite from '../screens/Favorite';
import { createStackNavigator } from '@react-navigation/stack';
import { ArtistLayout } from '../components/Genre';
+import MusicDetail from '../screens/MusicDetail';
+import InfoScreen from '../screens/testPage';
+import { createSharedElementStackNavigator } from 'react-navigation-shared-element';
+import CurrentMusic from '../components/CurrentMusic';
+const Stack = createSharedElementStackNavigator();
export default function MusicNavigation() {
- const Stack = createStackNavigator();
return (
-
+
+ {return [route.params.music.id]}}
/>
)
diff --git a/src/FLAD/navigation/Navigation.tsx b/src/FLAD/navigation/Navigation.tsx
index 90987fa..eba9bb6 100644
--- a/src/FLAD/navigation/Navigation.tsx
+++ b/src/FLAD/navigation/Navigation.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useEffect } from 'react';
import { View, StyleSheet, Platform } from 'react-native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { NavigationContainer } from '@react-navigation/native';
@@ -11,6 +11,9 @@ import FontAwesome from 'react-native-vector-icons/FontAwesome';
import SpotNavigation from './SpotNavigation';
import Login from '../screens/login';
import FladLoading from '../components/FladLoadingScreen';
+import { useDispatch, useSelector } from 'react-redux';
+import { getFavoritesMusic } from '../redux/actions/appActions';
+// import { fetchFavoritesMusic } from '../redux/thunk/spotThunk';
export default function Navigation() {
const BottomTabNavigator = createBottomTabNavigator();
@@ -23,6 +26,15 @@ export default function Navigation() {
text: 'rgb(138, 138, 138)',
}
};
+ //@ts-ignore
+ const favoritesMusicLength : number = useSelector(state => state.appReducer.favoriteMusic.length);
+ // const dispatch = useDispatch();
+ // useEffect(() => {
+ // const loadFavoritesMusics = async () => {
+ // await dispatch(fetchFavoritesMusic());
+ // };
+ // loadFavoritesMusics();
+ // }, [dispatch]);
return (
// @ts-ignore
@@ -45,8 +57,8 @@ export default function Navigation() {
,
diff --git a/src/FLAD/navigation/SpotNavigation.tsx b/src/FLAD/navigation/SpotNavigation.tsx
index 158e177..595c106 100644
--- a/src/FLAD/navigation/SpotNavigation.tsx
+++ b/src/FLAD/navigation/SpotNavigation.tsx
@@ -1,5 +1,5 @@
import React, {Component} from 'react';
-import FavoritePage from '../screens/favoritePage';
+import FavoritePage from '../screens/favorite';
import { createStackNavigator } from '@react-navigation/stack';
import Spot from '../screens/spot'
import { createSharedElementStackNavigator } from "react-navigation-shared-element";
@@ -22,10 +22,10 @@ export default function SpotNavigation() {
name="Spots"
component={Spot}
/>
-
+ /> */}
{/* {
+ return {
+ type: favoritesTypes.GET_FAVORITE_MUSICS,
+ playload: favoritesMusic,
+ };
+}
+export const addFavoritesMusic = (favoritesMusic: Music) => {
+ return {
+ type: favoritesTypes.ADD_FAVORITE_MUSICS ,
+ playload: favoritesMusic,
+ };
+}
diff --git a/src/FLAD/redux/reducers/appReducer.tsx b/src/FLAD/redux/reducers/appReducer.tsx
index c08cc64..2d6bc04 100644
--- a/src/FLAD/redux/reducers/appReducer.tsx
+++ b/src/FLAD/redux/reducers/appReducer.tsx
@@ -4,18 +4,30 @@ import { discoveriesTypes } from "../types/discoverieTypes";
import { favoritesTypes } from "../types/favoritesTypes";
import { spotifyTypes } from "../types/spotifyTypes";
import { spotTypes } from "../types/spotTypes";
-
+let tmpMusic: Music[] = [
+ // new Music("La pharmacie", "Jul",require("../assets/images/jul.png")),
+ // new Music("Deux frères", "PNL", require("../assets/images/pnl.png")),
+ new Music("6npyDB4mn8MO1A1h666FTk","Bambina", "PNL", "https://upload.wikimedia.org/wikipedia/en/a/a0/PNL_-_Dans_la_l%C3%A9gende.png","https://p.scdn.co/mp3-preview/d38052978a79adced2187cd8b6497bb10bedc452?cid=774b29d4f13844c495f206cafdad9c86"),
+ // new Music("0qwxx9ouUc5kGmMWHglDpq","Stratos", "Kekra", "https://images.genius.com/ddc9cadedd1d4cef0860aaa85af9cd46.705x705x1.png",""),
+ new Music("03o8WSqd2K5rkGvn9IsLy2","Autobahn", "Sch", "https://images.genius.com/83b6c98680d38bde1571f6b4093244b5.1000x1000x1.jpg","https://p.scdn.co/mp3-preview/c55f95de81b8c3d0df04148da1b03bd38db56e8f?cid=774b29d4f13844c495f206cafdad9c86"),
+ new Music("6DPrYPPGYK218iVIZDix3i","Freeze Raël", "Freeze Corleone", "https://intrld.com/wp-content/uploads/2020/08/freeze-corleone-la-menace-fanto%CC%82me.png","https://p.scdn.co/mp3-preview/a9f9cb19ac1fe6db0d06b67decf8edbb25895a33?cid=774b29d4f13844c495f206cafdad9c86"),
+ // new Music("Blanka", "PNL", require("../assets/images/pnl.png")),
+ new Music("5GFHFEASZeJF0gyWuDDjGE","Kratos", "PNL", "https://upload.wikimedia.org/wikipedia/en/a/a0/PNL_-_Dans_la_l%C3%A9gende.png","https://p.scdn.co/mp3-preview/9e854f4905c1228482e390169eb76d8520076b8f?cid=774b29d4f13844c495f206cafdad9c86"),
+ ] ;
const initialState = {
spot: [] as Spot[],
- favoriteMusic: [] as Music [],
+ favoriteMusic: tmpMusic,
userCurrentMusic : null
}
+
const appReducer = (state = initialState, action : any) => {
switch (action.type) {
+ case favoritesTypes.GET_FAVORITE_MUSICS:
+ return {...state, favoriteMusic: action.playload};
case favoritesTypes.ADD_FAVORITE_MUSICS:
- return {...state, favoriteMusic: state.favoriteMusic.push(action.payload)};
- case favoritesTypes.REMOVE_FAVORITE_MUSICS:
+ return {...state, favoriteMusic: [action.playload, ...state.favoriteMusic]};
+ case favoritesTypes.REMOVE_FAVORITE_MUSICS:
return {...state, favoriteMusic: state.favoriteMusic};
case spotTypes.FETCH_SPOT:
return {...state, spot: action.payload};
diff --git a/src/FLAD/redux/store.tsx b/src/FLAD/redux/store.tsx
index 9595adf..79b0b19 100644
--- a/src/FLAD/redux/store.tsx
+++ b/src/FLAD/redux/store.tsx
@@ -4,7 +4,7 @@ import userReducer from './reducers/userReducer';
// Reference here all your application reducers
const reducer = {
- // appReducer: appReducer,
+ appReducer: appReducer,
userReducer: userReducer
}
diff --git a/src/FLAD/redux/thunk/spotThunk.tsx b/src/FLAD/redux/thunk/spotThunk.tsx
index 907a329..051d19d 100644
--- a/src/FLAD/redux/thunk/spotThunk.tsx
+++ b/src/FLAD/redux/thunk/spotThunk.tsx
@@ -8,6 +8,8 @@ import { Spot } from "../../Model/Spot";
import SpotifyService from "../../services/spotify/spotify.service";
import * as Location from 'expo-location';
import { setSpotList, setUserCurrentMusic } from "../actions/spotActions";
+import Music from "../../Model/Music";
+import { getFavoritesMusic } from "../actions/appActions";
const key = 'userToken';
export type CreateSpotReqBody = {
@@ -91,6 +93,46 @@ export const getCurrentUserMusic = (resuestHandler : SpotifyService)=> {
}
}
}
+export const searchMusic = async (resuestHandler : SpotifyService,search: string) => {
+ //
+ return async (dispatch) => {
+ // const fetchAll = async () => {
+ // const data = await fetch(`https://kanjialive-api.p.rapidapi.com/api/public/search/${search}`, options)
+ // .then(response => response.json());
+
+ // const fetchPromises = data.map(it =>
+ // fetch(`https://kanjialive-api.p.rapidapi.com/api/public/kanji/${it.kanji.character}`, options)
+ // .then(detail => detail.json())
+ // );
+
+ // const kanjis = await Promise.all(fetchPromises)
+ // .then(details => details.map(detail_data => KanjiMapper.ApiJsonToKanji(detail_data)));
+
+ // return kanjis;
+ // };
+
+ return resuestHandler.searchMusic(search).then(musics => dispatch((musics))).catch(err => console.log("something goes wrong while searching : " + err));
+
+
+ };
+}
+// export const fetchFavoritesMusic = () => {
+// //@ts-ignore
+// return async dispatch => {
+// const MovieList: Music[] = [
+// // new Music("La pharmacie", "Jul",require("../assets/images/jul.png")),
+// // new Music("Deux frères", "PNL", require("../assets/images/pnl.png")),
+// new Music("Bambina", "PNL", "https://upload.wikimedia.org/wikipedia/en/a/a0/PNL_-_Dans_la_l%C3%A9gende.png"),
+// new Music("Stratos", "Kekra", "https://images.genius.com/ddc9cadedd1d4cef0860aaa85af9cd46.705x705x1.png"),
+// new Music("Autobahn", "Sch", "https://images.genius.com/83b6c98680d38bde1571f6b4093244b5.1000x1000x1.jpg"),
+// new Music("Freeze Raël", "Freeze Corleone", "https://intrld.com/wp-content/uploads/2020/08/freeze-corleone-la-menace-fanto%CC%82me.png"),
+// // new Music("Blanka", "PNL", require("../assets/images/pnl.png")),
+// new Music("Kratos", "PNL", "https://upload.wikimedia.org/wikipedia/en/a/a0/PNL_-_Dans_la_l%C3%A9gende.png"),
+// ] ;
+// dispatch(getFavoritesMusic(MovieList));
+// }
+// }
+
// export const getSpotList = () => {
// return async dispatch => {
// try {
diff --git a/src/FLAD/redux/types/favoritesTypes.tsx b/src/FLAD/redux/types/favoritesTypes.tsx
index 3634534..e9c066d 100644
--- a/src/FLAD/redux/types/favoritesTypes.tsx
+++ b/src/FLAD/redux/types/favoritesTypes.tsx
@@ -1,6 +1,7 @@
export const favoritesTypes = {
+ GET_FAVORITE_MUSICS : 'GET_FAVORITE_MUSICS',
ADD_FAVORITE_MUSICS : 'ADD_FAVORITE_MUSICS',
REMOVE_FAVORITE_MUSICS : 'REMOVE_FAVORITE_MUSICS',
}
\ No newline at end of file
diff --git a/src/FLAD/screens/Favorite.tsx b/src/FLAD/screens/Favorite.tsx
index bd6f8f8..d515231 100644
--- a/src/FLAD/screens/Favorite.tsx
+++ b/src/FLAD/screens/Favorite.tsx
@@ -1,29 +1,28 @@
-import React, { useState} from 'react';
-import { Image,StyleSheet, Text, View, FlatList, ScrollView, TouchableOpacity, SafeAreaView } from 'react-native';
+import React, { useEffect, useState} from 'react';
+import { Image,StyleSheet, Text, View, FlatList, ScrollView, TouchableOpacity, TouchableHighlight } from 'react-native';
import CardMusic from '../components/CardMusic';
import normalize from '../components/Normalize';
import Music from '../Model/Music'
import {useNavigation} from "@react-navigation/native";
+import { useDispatch, useSelector } from 'react-redux';
+import { getFavoritesMusic } from '../redux/actions/appActions';
+import { SharedElement } from 'react-navigation-shared-element';
export default function favoritePage() {
const navigation = useNavigation();
-
- const MUSIC_LIST : Music[] = [
- new Music("La pharmacie", "Jul",require("../assets/images/jul.png")),
- new Music("Deux frères", "PNL", require("../assets/images/pnl.png")),
- new Music("Bambina", "PNL", "https://upload.wikimedia.org/wikipedia/en/a/a0/PNL_-_Dans_la_l%C3%A9gende.png"),
- new Music("Stratos", "Kekra", "https://images.genius.com/ddc9cadedd1d4cef0860aaa85af9cd46.705x705x1.png"),
- new Music("Autobahn", "Sch", "https://images.genius.com/83b6c98680d38bde1571f6b4093244b5.1000x1000x1.jpg"),
- new Music("Freeze Raël", "Freeze Corleone", "https://intrld.com/wp-content/uploads/2020/08/freeze-corleone-la-menace-fanto%CC%82me.png"),
- new Music("Blanka", "PNL", require("../assets/images/pnl.png")),
- new Music("Kratos", "PNL", "https://upload.wikimedia.org/wikipedia/en/a/a0/PNL_-_Dans_la_l%C3%A9gende.png"),
- ]
+ //@ts-ignore
+ const favoritesMusic = useSelector(state => state.appReducer.favoriteMusic);
+ const dispatch = useDispatch();
+
+ const navigueToDetail = (music : any) => {
+ navigation.navigate("MusicDetail", {"music": music})
+ };
// to do
const [filteredDataSource, setFilteredDataSource] = useState([]);
const [search, setSearch] = useState('');
const searchMusic = (text: string) => {
if (text) {
- const newData = MUSIC_LIST.filter(function (item: Music) {
+ const newData = favoritesMusic.filter(function (item: Music) {
const search = item.title
? item.title.toUpperCase() : ''.toUpperCase();
const textsearch = text.toUpperCase();
@@ -40,9 +39,24 @@ export default function favoritePage() {
return (
-
- Favoris
- Retrouvez ici vos musiques favorites
+
+ Favoris
+ Retrouvez ici vos musiques favorites
+
+
+
+ (
+ {navigueToDetail(item)}}>
+
+
+
+
+
+ )}
+ keyExtractor={(item: Music) => item.title }
+ />
diff --git a/src/FLAD/screens/MusicDetail.tsx b/src/FLAD/screens/MusicDetail.tsx
new file mode 100644
index 0000000..dc77d51
--- /dev/null
+++ b/src/FLAD/screens/MusicDetail.tsx
@@ -0,0 +1,283 @@
+import { NavigationProp, RouteProp } from "@react-navigation/native";
+import { View,Text,Image,StyleSheet, Dimensions, useWindowDimensions, Button, TouchableOpacity } from "react-native";
+import Animated, { interpolate, SensorType, useAnimatedSensor, useAnimatedStyle, useDerivedValue, useSharedValue, Value, withSpring, withTiming } from "react-native-reanimated";
+import { BlurView } from 'expo-blur';
+import qs from "qs";
+import axios from "axios";
+import { Buffer } from 'buffer';
+import { Audio } from 'expo-av';
+import { useEffect, useState } from "react";
+import { State, TapGestureHandler } from "react-native-gesture-handler";
+import { RequestHandler } from "../services/spotify/spotifyRequestHandler/utils";
+import { FetchRequest } from "expo-auth-session/build/Fetch";
+import Music from "../Model/Music";
+import SpotifyService from "../services/spotify/spotify.service";
+import { SharedElement } from "react-navigation-shared-element";
+
+const halfPi = Math.PI/2;
+
+//@ts-ignore
+const MusicDetail = ({ route }) => {
+ const music : Music = route.params.music;
+ const [currentspot, setCurrentspot] = useState(music);
+ const [sound, setSound] = useState(null);
+
+ const [isPlaying, setIsPlaying] = useState(false);
+ const loader = useSharedValue(0);
+ useEffect(() => {
+ loader.value = isPlaying ? 1 : 0
+ }, [isPlaying,loader ]);
+
+ const transition = useDerivedValue(()=>{
+ return withTiming(loader.value, {duration : 1000})
+ }
+ )
+
+
+ // const styleAniamatedButton = useAnimatedStyle(() => {
+ // const verticalAxis =interpolate(
+ // transition.value,
+ // [0,1],
+ // [circumference, 0]
+ // )
+
+ // return {
+ // top : withSpring( verticalAxis),
+ // left : withSpring(horizontalAxis),
+ // };
+
+ // })
+
+
+ const playTrackPreview = async () => {
+ console.log("===============================================================================================================");
+
+ console.log('get in Sound');
+
+ const { sound } = await Audio.Sound.createAsync({uri :music.trackPreviewUrl});
+ //@ts-ignore
+ setSound(sound);
+ console.log('Playing Sound');
+ await sound.playAsync();
+ setIsPlaying(true);
+
+
+ // const soundObject = new Audio.Sound();
+ // try {
+ // await soundObject.loadAsync({ uri: trackPreviewUrl });
+ // await soundObject.playAsync();
+ // setIsPlaying(true);
+ // } catch (error) {
+ // console.log('Error loading sound:', error);
+ // }
+ };
+
+ const handlePlaySound = async () => {
+ if (sound === null) {
+ const { sound: newSound } = await Audio.Sound.createAsync(
+ { uri: music.trackPreviewUrl },
+ { shouldPlay: true }
+ );
+ setSound(newSound);
+ setIsPlaying(true);
+
+ } else {
+ setIsPlaying(true);
+ //@ts-ignore
+ await sound.playAsync();
+ }
+ };
+
+ const handleStopSound = async () => {
+ if (sound !== null) {
+ setIsPlaying(false);
+
+ //@ts-ignore
+ await sound.stopAsync();
+ }
+ else{
+ }
+ };
+ useEffect(() => {
+ return sound ? () => {
+ console.log('Unloading Sound');
+ //@ts-ignore
+ sound.unloadAsync();
+ }
+ : undefined;
+ }, [sound]);
+ // useEffect(() => {
+ // if(isPlaying){
+
+ // }
+ // })
+
+ const sensor = useAnimatedSensor(SensorType.ROTATION);
+ const styleAniamatedImage = useAnimatedStyle(() => {
+ const {yaw, pitch, roll} = sensor.sensor.value;
+ const verticalAxis =interpolate(
+ pitch,
+ [-halfPi*2,halfPi*2],
+ [-45, 45]
+ )
+ const horizontalAxis =interpolate(
+ roll,
+ [-halfPi*2,halfPi*2],
+ [-45, 45]
+ )
+ return {
+ top : withSpring( verticalAxis),
+ left : withSpring(horizontalAxis),
+ };
+
+ })
+ // const CLIENT_ID = "1f1e34e4b6ba48b388469dba80202b10";
+ // const CLIENT_SECRET = "779371c6d4994a68b8dd6e84b0873c82";
+ // const spotify = "BQA2IAFZ-7ta4-_4_Uqdcdrqi_peE6Hlf1jwxFqjXTbwes0z8xgVGx0rE3zv4cQlusd1ILJhRwkxzPsL1YakzSvCxaTI1P7kOzBrrMqlkDgk4vlFvzLjScB0hBLULbpZyn3ylgx4RyZBEWfmc24wZPQOsrJU58AYCveA52UxYVSIc_Frr7LZyRmwjzGB68MPZeBD"
+ // var authOptions = {
+ // method: 'GET',
+ // url: 'https://api.spotify.com/v1/me/player/currently-playing',
+
+ // headers: {
+ // 'Authorization': 'Bearer ' + spotify,
+ // 'Content-Type' : 'application/json',
+ // 'market' : 'FR',
+ // },
+ // json: true
+ // };
+
+ // var id = '0cFS3AMF9Lhj3CNoFvwjvY'
+ // const requestor = new RequestHandler()
+
+ // const getCurrentTrack = async () => {
+ // try {
+ // const opt : FetchRequest ={headers : Record}
+ // requestor.spotifyFetch(`tracks${id}`,)
+
+ // // var GetTrackOptions = {
+ // // method: 'GET',
+ // // url: 'https://api.spotify.com/v1/tracks/'+id,
+
+ // // headers: {
+ // // 'Authorization': 'Bearer ' + spotify,
+ // // 'Content-Type' : 'application/json',
+ // // 'market' : 'FR',
+ // // },
+ // // json: true
+ // // };
+ // // const resp = await axios(GetTrackOptions)
+ // // console.log("============");
+ // // console.log(resp.data.href);
+ // // console.log("================================"+resp.data.album.images[0].url+ "================================");
+ // // var tmp = currentspot;
+
+ // // tmp.sourceUrl = resp.data.album.images[0].url;
+ // // setCurrentspot(tmp);
+ // // await axios(authOptions).then(async (response) =>{
+ // // console.log(response.data.item.preview_url);
+ // // const id = response.data.item.id;
+ // // var GetTrackOptions = {
+ // // method: 'GET',
+ // // url: 'https://api.spotify.com/v1/tracks/'+id,
+
+ // // headers: {
+ // // 'Authorization': 'Bearer ' + spotify,
+ // // 'Content-Type' : 'application/json',
+ // // 'market' : 'FR',
+ // // },
+ // // json: true
+ // // };
+ // // console.log("============");
+ // // const music = await axios(GetTrackOptions);
+ // // console.log("================================"+music.data+ "================================");
+ // // currentspot.sourceUrl = music.data.images[0];
+ // // setCurrentspot(currentspot);
+ // // })
+
+ // // const response = await fetch('https://api.spotify.com/v1/me', {
+ // // method: 'GET',
+ // // headers: {
+ // // Authorization: 'Bearer ' + spotify,
+ // // 'Content-Type': 'application/json',
+ // // },
+ // // });
+ // // response.json()
+
+ // // destructure the response and rename the properties to be in camelCase to satisfy my linter ;)
+
+ // } catch (err) {
+ // console.error(err);
+ // }
+ // }
+ const animationState = new Value(State.UNDETERMINED);
+ const playMusic = async (id: string) => {
+ try {
+ const service = new SpotifyService("BQDWJTPvSloZPYDqLc1YWri2LEcognvqoM5bdoCWMuHR9In2FhaKq5tW3-VC5JET9dD9K-W4Rmm0IiyhtX-fSL3Tb8RTHMJUc5GKFq2jxWlH7QXxsiYZV8Fhw2qU1eCpSof1qkPsBd1R36GOgcBaXq2N6kLTP5UcfP-gzjz65x_fVRSxoP6znK2dkvL6saQ6WwzoEFopqpqo") ;
+ console.log("=====================================================)))))))))))))))"+id+"================================")
+ await service.playMusic(id);
+ }catch(error){}
+ }
+
+ return (
+
+ {/* */}
+
+
+
+
+ {/* Button */}
+
+
+
+ {/* */}
+
+
+
+
+ {isPlaying ? 'Playing...' : 'Play'}
+
+
+
+
+ {/* */}
+
+ {/* Button */}
+ {/* */}
+
+
+ );
+};
+
+export default MusicDetail;
\ No newline at end of file
diff --git a/src/FLAD/screens/spot.tsx b/src/FLAD/screens/spot.tsx
index 5d8b124..15f9434 100644
--- a/src/FLAD/screens/spot.tsx
+++ b/src/FLAD/screens/spot.tsx
@@ -6,7 +6,7 @@ import Animated from 'react-native-reanimated';
import Card from '../components/Card';
-import { cards as cardArray } from '../data/data'
+import { cards as cardArray, spotArray2 } from '../data/data'
import FladButton from '../components/button/button';
import axios from 'axios';
@@ -21,6 +21,9 @@ import Lotties from '../assets/lottie/Lottie';
import FladLoading from '../components/FladLoadingScreen';
import { SharedElement } from 'react-navigation-shared-element';
import { useNavigation } from '@react-navigation/native';
+import Music from '../Model/Music';
+import { addFavoritesMusic } from '../redux/actions/appActions';
+import { useDispatch } from 'react-redux';
interface SpotProps {
}
@@ -90,17 +93,30 @@ async function getValueFor(key:string) :Promise {
}
export default function Spot() {
- const [cards, setCards] = useState(cardArray);
+ const [cards, setCards] = useState(spotArray2);
const [currentCard, setcurrentCard] = useState(cards[cards.length - 1]);
- const onSwipe = (index: number, direction: 'left' | 'right') => {
+ const onSwipe = (index: number, direction: 'left' | 'right' | 'down') => {
+
if (direction === 'right') {
// Swiped right
+ console.log("====2==="+currentCard.music.title+"======2=========");
+ addLike(currentCard.music);
+ console.log('Swiped right');
} else if (direction === 'left') {
// Swiped left
+ console.log('Swiped left');
+ }
+ else if (direction === 'down') {
+ // Swiped down
+ console.log('Swiped down');
}
- // update the state of the cards state when it remove thisy
- setCards(cards.filter((_, i) => i !== index));
- setcurrentCard(cards[index-1]);
+ // update the state of the cards state when it remove this
+ setTimeout(() => {
+ setCards(cards.filter((_, i) => i !== index));
+ setcurrentCard(cards[index - 1]);
+ }, 3);
+ // setCards(cards.filter((_, i) => i !== index));
+ // setcurrentCard(cards[index-1]);
};
const likeButtonref = useRef(null);
@@ -110,26 +126,22 @@ export default function Spot() {
const onLike = useCallback( () => {
likeButtonref.current?.reset();
likeButtonref.current?.play(0,55);
+ likeButtonref.current?.play(55,0);
}, [])
+ const dispatch = useDispatch();
+ function addLike(music: Music) {
+ onLike();
+ console.log("====3==="+currentCard.music.title+"======3=========");
-// function addWatchLater(props: Movie) {
-// dispatch(addMovieToWatchLater(props));
-// dispatch(removeMovieTrending(props));
-// if (displayIndex == trendingMovies.length - 1) {
-// setdisplayIndex(0);
-// swiper.swipeLeft();
-// }
-// }
+ dispatch(addFavoritesMusic(music))
+ // dispatch(addFavoriteMusic(props));
+ // if (displayIndex == trendingMovies.length - 1) {
+ // setdisplayIndex(0);
+ // swiper.swipeLeft();
+ // }
+}
-// function addFavourite(props: Movie) {
-// dispatch(addMovieToFavourite(props));
-// dispatch(removeMovieTrending(props));
-// if (displayIndex == trendingMovies.length - 1) {
-// setdisplayIndex(0);
-// swiper.swipeLeft();
-// }
-// }
// const hapti = (() => {
@@ -206,7 +218,7 @@ export default function Spot() {
alignItems: "center",
}}
source={{
- uri:currentCard.sourceUrl ,
+ uri:currentCard.music.image ,
}}
>
@@ -235,13 +247,13 @@ export default function Spot() {
{cards.map((card, index) => (
-
+
{hapti(card)}} >
{/* */}
{onSwipe(index, direction)}}
/>
{/* */}
@@ -260,7 +272,7 @@ export default function Spot() {
-
+
diff --git a/src/FLAD/screens/testPage.tsx b/src/FLAD/screens/testPage.tsx
new file mode 100644
index 0000000..519b46d
--- /dev/null
+++ b/src/FLAD/screens/testPage.tsx
@@ -0,0 +1,479 @@
+
+import * as React from 'react';
+import {TouchableOpacity, ScrollView, View, Text, StyleSheet, Image, SafeAreaView, FlatList, Animated} from 'react-native';
+import {useSafeAreaInsets} from "react-native-safe-area-context";
+import {LinearGradient} from 'expo-linear-gradient';
+import {useEffect, useState} from "react";
+import Ionicons from "@expo/vector-icons/Ionicons";
+import { SharedElement } from "react-navigation-shared-element";
+import { NavigationProp, RouteProp, useNavigation } from "@react-navigation/native";
+import { Dimensions, useWindowDimensions, Button } from "react-native";
+import { interpolate, SensorType, useAnimatedSensor, useAnimatedStyle, useDerivedValue, useSharedValue, Value, withSpring, withTiming } from "react-native-reanimated";
+import { BlurView } from 'expo-blur';
+import qs from "qs";
+import axios from "axios";
+import { Buffer } from 'buffer';
+import { Audio } from 'expo-av';
+import { State, TapGestureHandler } from "react-native-gesture-handler";
+import { RequestHandler } from "../services/spotify/spotifyRequestHandler/utils";
+import { FetchRequest } from "expo-auth-session/build/Fetch";
+import SpotifyService from "../services/spotify/spotify.service";
+import Music from '../Model/Music';
+import { HorizontalFlatList } from '../components/HorizontalFlatList';
+import littleCard from '../components/littleCard';
+const halfPi = Math.PI/2;
+// InfoScreen.sharedElement = (navigation : ReturnType)=>{
+// const music = navigation.getParam('music');
+// return [music.id];
+// }
+ // @ts-ignore
+export default function InfoScreen({route, navigation}) {
+
+ const item: Music = route.params.music;
+
+ const insets = useSafeAreaInsets();
+
+ const [similarMusics, setSimilarMusics] = useState([]);
+
+// parralax
+
+// parralax
+
+
+ const styles = StyleSheet.create({
+ background1: {
+ height: '100%',
+ width: '100%',
+ paddingTop: insets.top,
+ },
+ body: {
+ backgroundColor: "#0E0E0E"
+ },
+ backgroundSection: {
+ height: "100%",
+ width: "100%",
+ position: "absolute"
+ },
+ back_drop: {
+ height: "45%",
+ width: '100%',
+ position: "absolute",
+ },
+ gradientFade: {
+ height: "30%",
+ top: "25%"
+ },
+ backButton: {
+ position: "absolute",
+ top: 10,
+ left: 5
+ },
+ list: {
+ height: "100%"
+ },
+ section1: {
+ paddingHorizontal: 35
+ },
+ title: {
+ color: "white",
+ fontSize: 43,
+ fontWeight: "bold",
+ paddingBottom: 10,
+ paddingTop: "45%"
+ },
+ characteristics: {
+ flexDirection: "row",
+ width: "100%",
+ justifyContent: "flex-start"
+ },
+ stars: {
+ flexDirection: "row",
+ width: "100%",
+ justifyContent: "flex-start",
+ alignItems: "center",
+ paddingBottom: 30
+ },
+ starsLabel: {
+ color: "#FFC42D",
+ fontWeight: "bold",
+ paddingLeft: 10,
+ fontSize: 16
+ },
+ player: {
+ borderRadius: 10,
+ overflow: "hidden"
+ },
+ resume: {
+ color: "#B3B3B3",
+ paddingTop: 30,
+ fontSize: 17
+ },
+ creditSection: {
+ paddingTop: 30
+ },
+ creditTitle: {
+ color: "#2998FD",
+ paddingBottom: 20,
+ paddingLeft: 35,
+ fontSize: 17,
+ fontWeight: "600"
+ },
+ similarSection: {
+ paddingTop: 30
+ },
+ similarTitle: {
+ color: "#2998FD",
+ paddingLeft: 35,
+ fontSize: 17,
+ fontWeight: "600",
+ paddingBottom: 20
+ },
+ similarContainer: {
+ width: 90,
+ marginHorizontal: 7
+ },
+ similarPoster: {
+ height: 130,
+ width: 90,
+ borderRadius: 8
+ },
+ similarTitleFilm: {
+ color: "#DADADA",
+ paddingTop: 5,
+ fontWeight: "300"
+ },
+ reviewSection: {
+ paddingTop: 30
+ },
+ reviewTitle: {
+ color: "#2998FD",
+ paddingLeft: 35,
+ fontSize: 17,
+ fontWeight: "600",
+ paddingBottom: 10
+ },
+ reviewContainer: {
+ marginHorizontal: 7,
+ width: 300,
+ padding: 20,
+ backgroundColor: "#09090F",
+ marginVertical: 10,
+ borderRadius: 14,
+ borderWidth: 0.8,
+ borderColor: "rgba(223,223,223,0.14)"
+ },
+ reviewInfo: {
+ flexDirection: "row",
+ paddingBottom: 20
+ },
+ imageProfile: {
+ height: 50,
+ width: 50,
+ borderRadius: 100
+ },
+ infoContainer: {
+ paddingLeft: 10,
+ flexDirection: "row",
+ justifyContent: "space-between",
+ width: "80%",
+ alignItems: "center"
+ },
+ pseudo: {
+ color: "white",
+ paddingTop: 5,
+ fontWeight: "700",
+ fontSize: 16
+ },
+ date: {
+ color: "grey",
+ paddingTop: 5,
+ fontWeight: "500",
+ fontSize: 14
+ },
+ message: {
+ color: "#B3B3B3",
+ paddingTop: 5,
+ fontWeight: "400"
+ },
+ creditContainer: {
+ width: 90,
+ marginHorizontal: 7,
+ alignItems: "center"
+ },
+ bubble: {
+ justifyContent: "center"
+ },
+ photo: {
+ height: 90,
+ width: 90,
+ borderRadius: 200,
+ borderWidth: 3,
+ borderColor: "rgba(255,255,255,0.8)"
+ },
+ popularityDot: {
+ backgroundColor: "white",
+ borderRadius: 20,
+ padding: 2,
+ paddingHorizontal: 5,
+ justifyContent: "center",
+ alignItems: "center",
+ position: "absolute",
+ bottom: 0,
+ right: 0,
+ flexDirection: "row"
+ },
+ popularityLabel: {
+ color: "black",
+ fontWeight: "500",
+ paddingRight: 4
+ },
+ creditName: {
+ color: "#DADADA",
+ paddingTop: 5,
+ fontWeight: "300"
+ }
+ });
+
+
+ const getSimilarMusics = async () => {
+
+
+ const tmpMusic: Music[] = [
+ // new Music("La pharmacie", "Jul",require("../assets/images/jul.png")),
+ // new Music("Deux frères", "PNL", require("../assets/images/pnl.png")),
+ new Music("6npyDB4mn8MO1A1h666FTk","Bambina", "PNL", "https://upload.wikimedia.org/wikipedia/en/a/a0/PNL_-_Dans_la_l%C3%A9gende.png","https://p.scdn.co/mp3-preview/d38052978a79adced2187cd8b6497bb10bedc452?cid=774b29d4f13844c495f206cafdad9c86"),
+ // new Music("0qwxx9ouUc5kGmMWHglDpq","Stratos", "Kekra", "https://images.genius.com/ddc9cadedd1d4cef0860aaa85af9cd46.705x705x1.png",""),
+ new Music("03o8WSqd2K5rkGvn9IsLy2","Autobahn", "Sch", "https://images.genius.com/83b6c98680d38bde1571f6b4093244b5.1000x1000x1.jpg","https://p.scdn.co/mp3-preview/c55f95de81b8c3d0df04148da1b03bd38db56e8f?cid=774b29d4f13844c495f206cafdad9c86"),
+ new Music("6DPrYPPGYK218iVIZDix3i","Freeze Raël", "Freeze Corleone", "https://intrld.com/wp-content/uploads/2020/08/freeze-corleone-la-menace-fanto%CC%82me.png","https://p.scdn.co/mp3-preview/a9f9cb19ac1fe6db0d06b67decf8edbb25895a33?cid=774b29d4f13844c495f206cafdad9c86"),
+ // new Music("Blanka", "PNL", require("../assets/images/pnl.png")),
+ new Music("5GFHFEASZeJF0gyWuDDjGE","Kratos", "PNL", "https://upload.wikimedia.org/wikipedia/en/a/a0/PNL_-_Dans_la_l%C3%A9gende.png","https://p.scdn.co/mp3-preview/9e854f4905c1228482e390169eb76d8520076b8f?cid=774b29d4f13844c495f206cafdad9c86"),
+ ] ;
+ setSimilarMusics(tmpMusic);
+ }
+
+
+ useEffect(() => {
+ getSimilarMusics();
+ }, []);
+
+////////////////////////////////////////////////
+
+
+
+const {width, height} = useWindowDimensions();
+
+const [currentspot, setCurrentspot] = useState(item);
+const [sound, setSound] = useState(null);
+
+const [isPlaying, setIsPlaying] = useState(false);
+const loader = useSharedValue(0);
+useEffect(() => {
+ loader.value = isPlaying ? 1 : 0
+}, [isPlaying,loader ]);
+
+const transition = useDerivedValue(()=>{
+ return withTiming(loader.value, {duration : 1000})
+}
+)
+
+
+// const styleAniamatedButton = useAnimatedStyle(() => {
+// const verticalAxis =interpolate(
+// transition.value,
+// [0,1],
+// [circumference, 0]
+// )
+
+// return {
+// top : withSpring( verticalAxis),
+// left : withSpring(horizontalAxis),
+// };
+
+// })
+
+
+const trackPreviewUrl = 'https://p.scdn.co/mp3-preview/08ef3b9d6dbd6bab233f5e9ca564091902767f71?cid=774b29d4f13844c495f206cafdad9c86';
+const playTrackPreview = async () => {
+console.log("===============================================================================================================");
+
+ console.log('get in Sound');
+
+ const { sound } = await Audio.Sound.createAsync({uri :item.trackPreviewUrl});
+ //@ts-ignore
+ setSound(sound);
+ console.log('Playing Sound');
+ await sound.playAsync();
+ setIsPlaying(true);
+
+
+ // const soundObject = new Audio.Sound();
+ // try {
+ // await soundObject.loadAsync({ uri: trackPreviewUrl });
+ // await soundObject.playAsync();
+ // setIsPlaying(true);
+ // } catch (error) {
+ // console.log('Error loading sound:', error);
+ // }
+ };
+
+const handlePlaySound = async () => {
+if (sound === null) {
+ const { sound: newSound } = await Audio.Sound.createAsync(
+ { uri: item.trackPreviewUrl },
+ { shouldPlay: true }
+ );
+ setSound(newSound);
+
+} else {
+ //@ts-ignore
+ await sound.playAsync();
+}
+};
+
+const handleStopSound = async () => {
+if (sound !== null) {
+ //@ts-ignore
+ await sound.stopAsync();
+}
+else{
+ setIsPlaying(true);
+}
+};
+useEffect(() => {
+return sound ? () => {
+ console.log('Unloading Sound');
+ //@ts-ignore
+ sound.unloadAsync();
+ }
+ : undefined;
+}, [sound]);
+
+
+const sensor = useAnimatedSensor(SensorType.ROTATION);
+const styleAniamatedImage = useAnimatedStyle(() => {
+ const {yaw, pitch, roll} = sensor.sensor.value;
+ const verticalAxis =interpolate(
+ pitch,
+ [-halfPi*2,halfPi*2],
+ [-45, 45]
+ )
+ const horizontalAxis =interpolate(
+ roll,
+ [-halfPi*2,halfPi*2],
+ [-45, 45]
+ )
+ return {
+ top : withSpring( verticalAxis),
+ left : withSpring(horizontalAxis),
+ };
+
+})
+
+ const animationState = new Value(State.UNDETERMINED);
+ const playMusic = async (id: string) => {
+ try {
+ const service = new SpotifyService("BQC4k_OPQXENwmm2S8qLm9whlJT9IjeKsuG6kJNyVCSd88b0L-zOY84VqwvQxFsc9G3GvtPyUMezwxi8BBBloitzbhWX5tmTKTaLsJosGTnb7xivwNhRv0-LnNYbZWB24ZGAg0xPmDLn0yYmYlo7M_SMK5cCZdYQcZNXAuMYaI18GVXKoICBaKfCn4GcqBiRRgXyCVQnNGU4") ;
+ console.log("=====================================================)))))))))))))))"+id+"================================")
+ await service.playMusic(id);
+ }catch(error){}
+ }
+ return (
+
+
+
+
+
+
+
+
+
+ navigation.goBack()} style={{zIndex: 100}}>
+
+
+
+
+
+
+ {/* */}
+
+
+
+
+
+
+ {/* Button */}
+
+
+
+ {/* */}
+
+
+
+
+ {isPlaying ? 'Playing...' : 'Play'}
+
+
+
+
+
+
+
+
+
+ {similarMusics.length !== 0 && (
+
+
+
+
+ )}
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/FLAD/services/spotify/spotify.service.ts b/src/FLAD/services/spotify/spotify.service.ts
index 3e7ce5f..e188434 100644
--- a/src/FLAD/services/spotify/spotify.service.ts
+++ b/src/FLAD/services/spotify/spotify.service.ts
@@ -1,7 +1,7 @@
import axios from "axios";
import MusicFactory from "../../Model/factory/MusicFactory";
import Music from "../../Model/Music";
-import { RequestHandler } from "./spotifyRequestHandler/utils";
+import { FetchOptions, RequestHandler } from "./spotifyRequestHandler/utils";
export default class SpotifyService implements IspotifyService {
private readonly API_URL = "https://flad-api-production.up.railway.app/api/";
@@ -46,17 +46,116 @@ export default class SpotifyService implements IspotifyService {
return respMusic.data.items[0].track.id;
}
- public async playMusic(): Promise{
- var requestData :string = '/me/player/recently-played';
+ public async playMusic(idMusic : string): Promise{
+ var requestData :string = '/me/player/play';
+ const fetchOptions: FetchOptions = {
+ method: 'PUT',
+ body: {
+ uris: [`spotify:track:${idMusic}`],
+ position_ms: 0
+ }
+ };
+ const respMusic = await this.spotifyRequestHandler.spotifyFetch(requestData, fetchOptions,this.token);
+ console.log(respMusic.data);
+ // need to handle when
+ // if (respMusic.status != 200) {
+ // if (respMusic.status == 400 && respMusic.data.message =='need to use Spotify premium'){
+
+ // }
+ // }
+ // if(respMusic){
+ // console.log(respMusic);
+ // console.log(respMusic.data);
+
+ // }
+ return ;
+ }
+
+ public async searchMusic(text : string): Promise{
+ var requestData :string = '/search';
+ const fetchOptions: FetchOptions = {
+ params: {
+ q: text,
+ type: 'track'
+ }
+ };
+ const respMusic = await this.spotifyRequestHandler.spotifyFetch(requestData, fetchOptions,this.token);
+
+ if (respMusic.status != 200) {
+ }
+ const tracksData = respMusic?.data?.tracks?.items;
+ if (!tracksData || !Array.isArray(tracksData)) {
+ return [];
+ }
+ const tracks = tracksData.map((trackData: any) => {
+ // const { id, name, artists, album } = trackData;
+ return MusicFactory.mapFromSpotifyTrack(trackData)
+ // const artistNames = artists.map((artist: any) => artist.name).join(', ');
+ // const linkCover = album?.images[0]?.url || '';
+ // return new Music(id, name, artistNames, linkCover);
+ });
+ return tracks;
+ }
+ // tempo version
+ public async getMusicMoreDetails(idMusic : string): Promise{
+ var requestData :string = '/audio-features/' + idMusic;
const respMusic = await this.spotifyRequestHandler.spotifyFetch(requestData, undefined,this.token);
if (respMusic.status != 200) {
}
- if (respMusic.data.items.length <= 0) {
- return null;
- }
- return respMusic.data.items[0].track.id;
+
+ return respMusic.data.audio_features.tempo;
+ }
+
+ public async getRelatedArtist(idArtist : string): Promise{
+ var requestData :string = '/artists/' + idArtist + '/related-artists';
+ const respMusic = await this.spotifyRequestHandler.spotifyFetch(requestData, undefined,this.token);
+ if (respMusic.status != 200) {
+ }
+
+ return respMusic.data.audio_features.tempo;
+ }
+
+ public async getArtistTopTracks(idArtist : string): Promise{
+ var requestData :string = '/artists/' + idArtist + '/top-tracks';
+ const respMusic = await this.spotifyRequestHandler.spotifyFetch(requestData, undefined,this.token);
+ if (respMusic.status != 200) {
+ }
+
+ return respMusic.data.audio_features.tempo;
}
-
+
+
+ public async addItemToPlayList(playlistId : string, idMusic : string): Promise{
+ var requestData :string = '/playlists/' + playlistId + '/tracks';
+ const fetchOptions: FetchOptions = {
+ method: 'POST',
+ body: {
+ uris: [`spotify:track:${idMusic}`]
+ }
+ };
+ const respMusic = await this.spotifyRequestHandler.spotifyFetch(requestData, fetchOptions,this.token);
+ console.log(respMusic.data);
+ return ;
+ }
+
+ public async createPlayList(userId : string,name : string,description : string): Promise{
+ var requestData :string = '/users/' + encodeURIComponent(userId) + '/playlists';
+
+ const fetchOptions: FetchOptions = {
+ method: 'POST',
+ body: {
+ "public": false,
+ "name": name || "New Flad Playlist",
+ "description": description,
+ }
+ };
+ const respMusic = await this.spotifyRequestHandler.spotifyFetch(requestData, fetchOptions,this.token);
+ console.log(respMusic.data);
+ return ;
+ }
+
+
+
async getSpotifyCredentials() {
const res = await axios.get(this.API_URL)
// then verify error
diff --git a/src/FLAD/services/spotify/spotifyRequestHandler/utils.tsx b/src/FLAD/services/spotify/spotifyRequestHandler/utils.tsx
index 2addfb7..b7de8eb 100644
--- a/src/FLAD/services/spotify/spotifyRequestHandler/utils.tsx
+++ b/src/FLAD/services/spotify/spotifyRequestHandler/utils.tsx
@@ -20,6 +20,7 @@ export class RequestHandler{
}
public async spotifyFetch(url: string, options: FetchOptions = {}, token: string) {
+ console.log(options+ "sds=============");
const resp = await axios({
url: `https://api.spotify.com/${this.version}${url}`,
method: options.method || 'GET',
@@ -31,7 +32,7 @@ export class RequestHandler{
},
data: options.body
});
- console.log()
+ console.log(resp);
return resp;
// if (
// // @ts-ignore