diff --git a/src/FLAD/App.tsx b/src/FLAD/App.tsx index b26e99f..4169edb 100644 --- a/src/FLAD/App.tsx +++ b/src/FLAD/App.tsx @@ -2,6 +2,9 @@ import { StyleSheet } from 'react-native'; import { Provider } from 'react-redux'; import store from './redux/store'; import AuthNavigation from './navigation/AuthNavigation'; +import * as SplashScreen from 'expo-splash-screen'; + +SplashScreen.preventAutoHideAsync(); export default function App() { diff --git a/src/FLAD/Model/Artist.tsx b/src/FLAD/Model/Artist.tsx new file mode 100644 index 0000000..32e4151 --- /dev/null +++ b/src/FLAD/Model/Artist.tsx @@ -0,0 +1,12 @@ +export default class Artist { + private id : string; + private name : string; + private url : string; // Image.source + + constructor(id : string, name : string, url : string){ + this.id = id; + this.name = name; + this.url = url; + } + +} \ No newline at end of file diff --git a/src/FLAD/Model/factory/MusicFactory.ts b/src/FLAD/Model/factory/MusicFactory.ts index e1d9973..e26238b 100644 --- a/src/FLAD/Model/factory/MusicFactory.ts +++ b/src/FLAD/Model/factory/MusicFactory.ts @@ -11,4 +11,14 @@ export default class MusicFactory { ); return music; } + static mapFromSpotifyTrackSmpified(jsonMusic :any ): Music { + const music = new Music( + jsonMusic.id, + jsonMusic.name, + "", + jsonMusic.album.images[0].url, + jsonMusic.preview_url + ); + return music; + } } \ No newline at end of file diff --git a/src/FLAD/app.json b/src/FLAD/app.json index 8db8416..2ada30e 100644 --- a/src/FLAD/app.json +++ b/src/FLAD/app.json @@ -39,7 +39,7 @@ [ "expo-location", { - "locationAlwaysAndWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location." + "locationAlwaysAndWhenInUsePermission": "Allow Flad to use your location." } ] ] diff --git a/src/FLAD/assets/icons/icons/Vector.png b/src/FLAD/assets/icons/icons/Vector.png new file mode 100644 index 0000000..34364fb Binary files /dev/null and b/src/FLAD/assets/icons/icons/Vector.png differ diff --git a/src/FLAD/assets/icons/icons/icon.ts b/src/FLAD/assets/icons/icons/icon.ts index 670589c..c34f7bc 100644 --- a/src/FLAD/assets/icons/icons/icon.ts +++ b/src/FLAD/assets/icons/icons/icon.ts @@ -3,6 +3,8 @@ const Icons = { discovery: require('./icon_discovery.png'), like: require('./icon_like.png'), dislike: require('./icon_dislike.png'), + bookmark : require('./icon_bookmark.svg'), + share : require('./Vector.png'), // riveLike : require('./light_like.riv'), } diff --git a/src/FLAD/assets/icons/icons/icon_bookmark.svg b/src/FLAD/assets/icons/icons/icon_bookmark.svg new file mode 100644 index 0000000..694cf08 --- /dev/null +++ b/src/FLAD/assets/icons/icons/icon_bookmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/FLAD/components/ArtistChip.tsx b/src/FLAD/components/ArtistChip.tsx new file mode 100644 index 0000000..5a7eb2f --- /dev/null +++ b/src/FLAD/components/ArtistChip.tsx @@ -0,0 +1,50 @@ +import { useCallback, useState } from 'react'; +import { View, StyleSheet ,Text,Image, Pressable, Linking, Alert} from 'react-native' + +interface ArtistChipProps { + backgroundColor : string; + artist : Artist; +} + +const ArtistChip = ({artist} : ArtistChipProps) => { + const handlePress = useCallback(async () => { + // Checking if the link is supported for links with custom URL scheme. + const supported = await Linking.canOpenURL(artist.url); + + if (supported) { + // Opening the link with some app, if the URL scheme is "http" the web link should be opened + // by some browser in the mobile + await Linking.openURL(artist.url); + } else { + Alert.alert(`Don't know how to open this URL: ${artist.url}`); + } + }, [artist.url]); + + return ( + + + + + + + + ii + + + + ); + }; + +const styles = StyleSheet.create({ + input : { + justifyContent : 'center', + alignItems : 'center', + placeholder : "placeholde" + }, +}) + +export default HalfCirlce; \ No newline at end of file diff --git a/src/FLAD/components/Genre.tsx b/src/FLAD/components/Genre.tsx index d1fdcb2..22f231d 100644 --- a/src/FLAD/components/Genre.tsx +++ b/src/FLAD/components/Genre.tsx @@ -78,6 +78,5 @@ export const ArtistLayout = () => { container: { flexDirection: "row", flexWrap: "wrap", - }, }); \ No newline at end of file diff --git a/src/FLAD/components/HorizontalFlatList.tsx b/src/FLAD/components/HorizontalFlatList.tsx index e14d26d..f701e38 100644 --- a/src/FLAD/components/HorizontalFlatList.tsx +++ b/src/FLAD/components/HorizontalFlatList.tsx @@ -12,15 +12,16 @@ 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"; +import { RenderCellProps } from "./littleCard"; interface HorizontalFlatListProps { // React.ReactNode; - renderCell: (image: string, titre : string) => React.ReactElement + children:(props: RenderCellProps) => React.ReactElement title : string; data : any[]; } -export const HorizontalFlatList = ({ title, data, renderCell}: HorizontalFlatListProps) => { +export const HorizontalFlatList = ({ title, data, children : RenderCell }: HorizontalFlatListProps) => { return ( @@ -31,22 +32,19 @@ export const HorizontalFlatList = ({ title, data, renderCell}: HorizontalFlatLis data={data} horizontal={true} keyExtractor={item => item.id} - renderItem={({item}) =>{ - return renderCell(item.image, image.titre); - }} - /> + renderItem={({ item }) => RenderCell(item)}/> ); }; const styles = StyleSheet.create({ similarSection: { - paddingTop: 30 + paddingTop: 16 }, similarTitle: { - color: "#2998FD", - paddingLeft: 35, - fontSize: 17, + color: "#FFF", + paddingLeft: 8, + fontSize: 24, fontWeight: "600", - paddingBottom: 20 + paddingBottom: 16 } }); \ No newline at end of file diff --git a/src/FLAD/components/littleCard.tsx b/src/FLAD/components/littleCard.tsx index 362cd47..0b0e0d3 100644 --- a/src/FLAD/components/littleCard.tsx +++ b/src/FLAD/components/littleCard.tsx @@ -1,19 +1,23 @@ import {TouchableOpacity, ScrollView, View, Text, StyleSheet, Image, SafeAreaView, FlatList, Animated} from 'react-native'; - -export default function littleCard ({image,titre}){ +export interface RenderCellProps { + image: string; + title: string; + } +export const LittleCard = (props : RenderCellProps)=>{ + console.log('==============='+ props.image + props.title+ '==ok============'); return ( - - {titre} + + {props.title} ) } + const styles = StyleSheet.create({ similarContainer: { - width: 90, marginHorizontal: 7 }, similarTitleFilm: { @@ -22,8 +26,8 @@ const styles = StyleSheet.create({ fontWeight: "300" }, similarPoster: { - height: 130, - width: 90, - borderRadius: 8 + height: 160, + width: 160, + borderRadius: 16 } }) diff --git a/src/FLAD/data/data.ts b/src/FLAD/data/data.ts index 96fe6e1..bc3ee42 100644 --- a/src/FLAD/data/data.ts +++ b/src/FLAD/data/data.ts @@ -82,5 +82,24 @@ export const spotArray2: Spot[] = [ "Harry Styles", "https://i.scdn.co/image/ab67616d0000b2738900d48677696015bf325b8b", "https://p.scdn.co/mp3-preview/4fff3f8d76a422f42cea39f001836a3d54937fc4?cid=774b29d4f13844c495f206cafdad9c86") + ), + new Spot("6", new Music("30d0q6kt1BIfwAQUCAfxVQ", + "Calme toi", + "Kerchack", + "https://i.scdn.co/image/ab67616d0000b273b4f73fb5c5ea299c7ebfbf60", + "https://p.scdn.co/mp3-preview/5de1103b9528c1e47e03d32b0aa5dbfe797191a2?cid=774b29d4f13844c495f206cafdad9c86") + ), + new Spot("7", new Music("7IXQrRgmHxWYWitSlyFY7z", + "Peur (feat. Ziak)", + "Ziak", + "https://i.scdn.co/image/ab67616d0000b273b533a3a5625bc6ce1be56a2e", + "https://p.scdn.co/mp3-preview/2c613f31b11375980aba80a5b535bf87ddb6211b?cid=774b29d4f13844c495f206cafdad9c86") + ), + new Spot("8", new Music("7wBoSW48q4ZFe8qSdozqqi", + "Blue", + "Kerchack", + "https://i.scdn.co/image/ab67616d0000b273cc4e66af40292c9d92146909", + "https://p.scdn.co/mp3-preview/401b51374dd3f2a15466a0b415a9ac7d2114a54b?cid=774b29d4f13844c495f206cafdad9c86") ) + ]; diff --git a/src/FLAD/navigation/AuthNavigation.tsx b/src/FLAD/navigation/AuthNavigation.tsx index daf8c95..ee8d9ee 100644 --- a/src/FLAD/navigation/AuthNavigation.tsx +++ b/src/FLAD/navigation/AuthNavigation.tsx @@ -4,56 +4,128 @@ import { SafeAreaProvider } from 'react-native-safe-area-context'; import StartNavigation from './StartNavigation'; import { Provider, useDispatch, useSelector } from 'react-redux'; import store from '../redux/store'; -import { useCallback, useEffect } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import * as SplashScreen from 'expo-splash-screen'; import { View } from 'react-native'; import { getRefreshToken } from '../redux/thunk/authThunk'; +import * as Location from 'expo-location'; -SplashScreen.preventAutoHideAsync(); +// const LOCATION_TASK_NAME = 'flad-background-location-task'; export default function AuthNavigation() { //@ts-ignore - const appIsReady : boolean = useSelector(state => state.userReducer.loading); + const tokenProcesed : boolean = useSelector(state => state.userReducer.loading); //@ts-ignore const isLogin : boolean = useSelector(state => state.userReducer.isLogedIn); // const userToken : string = useSelector(state => state.userReducer.userFladToken); - + const [appIsReady, setAppIsReady] = useState(false); const dispatch = useDispatch(); + const [location, setLocation] = useState({}); + const [errorMsg, setErrorMsg] = useState(''); + + +// // seems background task but not optimized +// TaskManager.defineTask(LOCATION_TASK_NAME, async ({ data, error }) => { +// if (error) { +// console.log(error); +// return; +// } +// if (data) { +// const { locations } = data; +// // send location updates to server +// console.log(locations); +// } +// }); + // const startLocationUpdates = async () => { + // try { + // await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, { + // accuracy: Location.Accuracy.Balanced, + // timeInterval: 5000, // send location updates every 5 seconds + // foregroundService: { + // notificationTitle: 'Location tracking', + // notificationBody: 'Location tracking is active.', + // }, + // }); + // } catch (error) { + // console.log(error); + // } + // }; + // useEffect(() => { + // startLocationUpdates(); + // return () => { + // Location.stopLocationUpdatesAsync(LOCATION_TASK_NAME); + // }; + // }, []); + + + useEffect(() => { async function prepare() { - console.log(appIsReady, "1 AuthNav") - //@ts-ignore await dispatch(getRefreshToken()) - await SplashScreen.hideAsync(); + if (tokenProcesed && appIsReady ) { + await SplashScreen.hideAsync(); + } // await SplashScreen.hideAsync(); } prepare(); - }, [dispatch]); + }, [appIsReady,tokenProcesed]); - const onStackRootView = useCallback(async () => { - if (appIsReady) { - await SplashScreen.hideAsync(); - } - }, [appIsReady]); - - if (appIsReady == false) { - console.log(appIsReady, "T9 AuthNav") + // const onStackRootView = useCallback(async () => { + + // }, [appIsReady]); + // useEffect(() => { + // const sendLocationUpdate = async () => { + // try { + // let { status } = await Location.requestForegroundPermissionsAsync(); + // console.log('Sending location update ================================###############'); + // if (status === 'granted') { + // console.log(appIsReady) + // if (true) {// should app is ready + // // see deeper the documentation + // // const [status, requestPermission] = Location.useBackgroundPermissions(); + // const locationresp = await Location.getCurrentPositionAsync({}); + // setLocation(locationresp); + // // send location to server + // console.log(locationresp); + // if(locationresp !=location ){ + + // } + // console.log(location); + // } + // } + // else{ + // console.log(`Sending location update with error ${status} ================================###############`); + // setErrorMsg('Permission to access location was denied'); + // return; + // } + // } catch (error) { + // console.log(error); + // } + // }; + // const interval = setInterval(sendLocationUpdate, 5000); // send location updates every 5 seconds + // return () => { + // clearInterval(interval); + // }; + // }, []); + if (tokenProcesed == false) { return null; } - console.log(appIsReady, "k9 AuthNav") + // console.log(userToken, "k9 AuthNav") return ( <> {isLogin ? ( /* {userToken != null ? ( */ - + // should set the reference to the function in Navigation to realy perform an on ready + // test purpose + setAppIsReady(true)}> ) : - - + setAppIsReady(true)}> + } diff --git a/src/FLAD/redux/actions/spotActions.tsx b/src/FLAD/redux/actions/spotActions.tsx index 41fbfa3..331b6bd 100644 --- a/src/FLAD/redux/actions/spotActions.tsx +++ b/src/FLAD/redux/actions/spotActions.tsx @@ -1,5 +1,6 @@ import Music from "../../Model/Music"; import { Spot } from "../../Model/Spot"; +import { spotifyTypes } from "../types/spotifyTypes"; import {spotTypes} from "../types/spotTypes"; export const setSpotList = (spotList: Spot[]) => { @@ -11,7 +12,7 @@ export const setSpotList = (spotList: Spot[]) => { export const setUserCurrentMusic = (currentMusic: Music) => { return { - type: spotTypes.FETCH_SPOT, + type: spotifyTypes.GET_USER_CURRENT_MUSIC, playload: currentMusic, }; } \ No newline at end of file diff --git a/src/FLAD/redux/actions/userActions.tsx b/src/FLAD/redux/actions/userActions.tsx index f470e84..2d43cc5 100644 --- a/src/FLAD/redux/actions/userActions.tsx +++ b/src/FLAD/redux/actions/userActions.tsx @@ -1,3 +1,4 @@ +import { User } from "../../Model/User"; import { userTypes } from "../types/userTypes"; @@ -31,12 +32,12 @@ export const restoreToken = (token : string) => { playload : token }; } -// export const UserLogin = (username: string, password: string) => { -// return { -// type: userTypes.LOGIN, -// playload : username, password -// }; -// } +export const userSignUp = (user : User) => { + return { + type: userTypes.LOGIN, + playload : user + }; + } export const UserLogout = () => { return { diff --git a/src/FLAD/redux/reducers/appReducer.tsx b/src/FLAD/redux/reducers/appReducer.tsx index 2d6bc04..1be550f 100644 --- a/src/FLAD/redux/reducers/appReducer.tsx +++ b/src/FLAD/redux/reducers/appReducer.tsx @@ -5,24 +5,18 @@ 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: tmpMusic, - userCurrentMusic : null - } + spot: [] as Spot[], + favoriteMusic: tmpMusic, + userCurrentMusic : null +} - - const appReducer = (state = initialState, action : any) => { - switch (action.type) { +const appReducer = (state = initialState, action : any) => { + switch (action.type) { case favoritesTypes.GET_FAVORITE_MUSICS: return {...state, favoriteMusic: action.playload}; case favoritesTypes.ADD_FAVORITE_MUSICS: @@ -37,7 +31,7 @@ const initialState = { return {...state, userCurrentMusic: action.payload}; default: return state; - } } +} - export default appReducer \ No newline at end of file +export default appReducer \ No newline at end of file diff --git a/src/FLAD/redux/reducers/spotifyAuthReducer.tsx b/src/FLAD/redux/reducers/spotifyAuthReducer.tsx index 42effc8..dc241e7 100644 --- a/src/FLAD/redux/reducers/spotifyAuthReducer.tsx +++ b/src/FLAD/redux/reducers/spotifyAuthReducer.tsx @@ -5,7 +5,7 @@ String getApiRedirectUrl() => _api.identification.redirectUri; String getIdSpotify() => _currentUser.idSpotify; -String getIdDafl() => _currentUser.idDafl; +String getIdFlad() => _currentUser.idFlad; case getCompleteMusic diff --git a/src/FLAD/redux/reducers/userReducer.tsx b/src/FLAD/redux/reducers/userReducer.tsx index 421f706..64b2212 100644 --- a/src/FLAD/redux/reducers/userReducer.tsx +++ b/src/FLAD/redux/reducers/userReducer.tsx @@ -3,7 +3,7 @@ import { userTypes } from "../types/userTypes"; const initialState = { loading: false, user: User, // for user object - userFladToken: null, // for storing the JWT + userFladToken: "", // for storing the JWT userSpotifyToken : null, error: null, isLogedIn: false, @@ -14,11 +14,13 @@ const initialState = { // just for the navigation and speciafly use // and case userTypes.RESTORE_TOKEN: + const resp = (action.playload == "" ? false : true) + console.log(resp, "si il ya le tokennen ou passssssssssss") return { ...state, userFladToken : action.playload, loading: true, - // isLogedIn: true, + isLogedIn: resp, }; case userTypes.LOGIN: console.log("++++++++++++++++++++++++++++++++++++++userRducer+++++++++++++++++++++++++++++3"); @@ -39,12 +41,15 @@ const initialState = { user :action.playload, isLogedIn: true }; - // case USER_SIGNUP: - // return {...state, nounours: action.payload}; case userTypes.USER_LOGOUT: return {...state, user :null, isLogedIn: false } + case userTypes.SAVE_SPOTIFY: + return { + ...state, + userSpotifyToken : action.playload, + }; default: return state; } diff --git a/src/FLAD/redux/thunk/authThunk.tsx b/src/FLAD/redux/thunk/authThunk.tsx index df93371..1e51f32 100644 --- a/src/FLAD/redux/thunk/authThunk.tsx +++ b/src/FLAD/redux/thunk/authThunk.tsx @@ -4,7 +4,7 @@ import axios from "axios"; import { json } from "express"; import { useEffect } from "react"; import { API_URL } from "../../fladConfig"; -import { Credentials, CredentialsRegister, restoreToken, setLoginState } from "../actions/userActions"; +import { Credentials, CredentialsRegister, restoreToken, setLoginState, userSignUp } from "../actions/userActions"; import * as SecureStore from 'expo-secure-store'; import { User } from "../../Model/User"; import { UserFactory } from "../../Model/factory/UserFactory"; @@ -38,7 +38,7 @@ export const registerUser = ( resgisterCredential : CredentialsRegister) => { "https://flad-api-production.up.railway.app/api/users", {headers} ) - dispatch(setLoginState( UserFactory.JsonToModel(user.data) )); // our action is called here + dispatch(userSignUp( UserFactory.JsonToModel(user.data) )); // our action is called here // console.log(user.data); // dispatch(setLoginState(user.data) ); // our action is called here } else { @@ -108,15 +108,13 @@ export const getRefreshToken = () => { //@ts-ignore return async dispatch => { try { - let userToken : string | null = await SecureStore.getItemAsync(key); - console.log("==========key =================="); - console.log(userToken); - console.log("==========key =================="); + let userToken : string | null = await SecureStore.getItemAsync('key'); if (userToken) { console.log("==========key2 =================="); console.log(userToken); console.log("==========key =================="); + console.log("==========on devrais être laaaa =================="); dispatch(restoreToken(userToken) ); diff --git a/src/FLAD/redux/types/userTypes.tsx b/src/FLAD/redux/types/userTypes.tsx index cdea161..081682f 100644 --- a/src/FLAD/redux/types/userTypes.tsx +++ b/src/FLAD/redux/types/userTypes.tsx @@ -2,6 +2,7 @@ export const userTypes = { LOGIN: 'LOGIN', SIGNUP: 'SIGNUP', + SAVE_SPOTIFY :'SAVE_SPOTIFY', UPDATE_USER: 'UPDATE_USER', UPDATE_PROFILE_PICTURE: 'UPDATE_PROFILE_PICTURE', USER_LOGOUT : 'USER_LOGOUT', diff --git a/src/FLAD/screens/MusicDetail.tsx b/src/FLAD/screens/MusicDetail.tsx index 6bd9abd..6fad95e 100644 --- a/src/FLAD/screens/MusicDetail.tsx +++ b/src/FLAD/screens/MusicDetail.tsx @@ -1,5 +1,5 @@ -import { NavigationProp, RouteProp } from "@react-navigation/native"; -import { View,Text,Image,StyleSheet, Dimensions, useWindowDimensions, Button, TouchableOpacity } from "react-native"; +import { NavigationProp, RouteProp, useNavigation } from "@react-navigation/native"; +import { View,Text,Image,StyleSheet, Dimensions, useWindowDimensions, Button, TouchableOpacity, ScrollView, Pressable } 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"; @@ -14,215 +14,143 @@ import Music from "../Model/Music"; import SpotifyService from "../services/spotify/spotify.service"; import { SharedElement } from "react-navigation-shared-element"; import { SafeAreaView } from "react-native-safe-area-context"; +import { LinearGradient } from "expo-linear-gradient"; +import Icons from "../assets/icons/icons/icon"; +import FontAwesome from 'react-native-vector-icons/FontAwesome'; +import { Feather as Icon } from "@expo/vector-icons"; +import { HorizontalFlatList } from "../components/HorizontalFlatList"; +import { LittleCard } from "../components/littleCard"; +import normalize from "../components/Normalize"; +import { Circle } from "react-native-svg"; +import { AntDesign } from '@expo/vector-icons'; +import * as SecureStore from 'expo-secure-store'; 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 [currentspot, setCurrentSpot] = useState(music); + const [simularMusic, setSimularMusic] = useState([]); const [isPlaying, setIsPlaying] = useState(false); - const loader = useSharedValue(0); - useEffect(() => { - loader.value = isPlaying ? 1 : 0 - }, [isPlaying,loader ]); + const [sound, setSound] = useState(null); + + const navigator = useNavigation(); + + const [testtoken, setTesttoken] = useState('') - const transition = useDerivedValue(()=>{ - return withTiming(loader.value, {duration : 1000}) + const sheet = async () => { + SecureStore.getItemAsync('MySecureAuthStateKey').then(result => { setTesttoken(result)}); + } - ) + + useEffect(() => { + sheet(); + getSimilarTrack(); + }, [testtoken]); - // const styleAniamatedButton = useAnimatedStyle(() => { - // const verticalAxis =interpolate( - // transition.value, - // [0,1], - // [circumference, 0] - // ) - - // return { - // top : withSpring( verticalAxis), - // left : withSpring(horizontalAxis), - // }; + // const getSimilarTrack = async () => { + // const service = new SpotifyService(testtoken); + // const simularMusic = await service.getSimilarTrack(currentspot.id, 5, 'FR'); + // console.log("suggesstd", simularMusic) + // setSimularMusic(simularMusic); - // }) - - - 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 getSimilarTrack = async () => { + try { + const service = new SpotifyService(testtoken); + const simularMusic = await service.getSimilarTrack(currentspot.id, 5, 'FR'); + console.log("suggesstd", simularMusic); + setSimularMusic(simularMusic); + } catch (error) { + console.error('Error ================ in getSimilarTrack', error); + // Handle the error here. + } } - }; - - const handleStopSound = async () => { - if (sound !== null) { - setIsPlaying(false); - //@ts-ignore - await sound.stopAsync(); - } - else{ - } - }; - useEffect(() => { - return sound ? () => { - console.log('Unloading Sound'); + 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 - sound.unloadAsync(); + await sound.playAsync(); } - : 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){} - } + 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]); + + 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), + }; + + }) return ( - - - + + + + + {/* */} + + + + + + + + + + {/* */} @@ -233,53 +161,66 @@ const MusicDetail = ({ route }) => { style={[ { - width: 370, - height: 370, + // width: 370, + // width: 400, + width: 392, + height: 392, borderRadius : 24, resizeMode: 'stretch', },styleAniamatedImage ]} /> -