diff --git a/src/Api/src/app.ts b/src/Api/src/app.ts index d3f8d36..41db4a0 100644 --- a/src/Api/src/app.ts +++ b/src/Api/src/app.ts @@ -50,6 +50,9 @@ class App { private initialiseControllers(controllers: Controller[]): void { controllers.forEach((controller: Controller) => { this.express.use('/api', controller.router); + this.express.get('/toto', (req, res) => { + res.send('Hello World!'); + }) }); } diff --git a/src/Api/src/controller/user-controller/userCtrl.ts b/src/Api/src/controller/user-controller/userCtrl.ts index 004e20e..9f5c740 100644 --- a/src/Api/src/controller/user-controller/userCtrl.ts +++ b/src/Api/src/controller/user-controller/userCtrl.ts @@ -161,8 +161,9 @@ class UserController implements Controller { ): Promise => { try { // the FladId should be created by the Userservice - const { name, email, password,idFlad, idSpotify } = req.body; - + const { name, email, password , idFlad, idSpotify } = req.body; + console.log(name, email, password, idFlad, idSpotify); + const token = await this.userService.register( name, email, diff --git a/src/Api/src/database/schema/LocationSchema.ts b/src/Api/src/database/schema/LocationSchema.ts index 795d45f..37d37b4 100644 --- a/src/Api/src/database/schema/LocationSchema.ts +++ b/src/Api/src/database/schema/LocationSchema.ts @@ -1,4 +1,4 @@ -import { Schema, model } from 'mongoose'; +import { Schema, model,Document } from 'mongoose'; const locationSchema = new Schema( diff --git a/src/Api/src/database/schema/User/UserValidation.ts b/src/Api/src/database/schema/User/UserValidation.ts index ec48660..e00e988 100644 --- a/src/Api/src/database/schema/User/UserValidation.ts +++ b/src/Api/src/database/schema/User/UserValidation.ts @@ -7,7 +7,8 @@ const register = Joi.object({ password: Joi.string().min(6).required(), // can add an field like confimPassword and cheked that the password is equal to the confirmPassword - + idSpotify: Joi.string(), + idFlad : Joi.string(), }); const login = Joi.object({ diff --git a/src/Api/src/service/UserService.ts b/src/Api/src/service/UserService.ts index 682a963..fa7128d 100644 --- a/src/Api/src/service/UserService.ts +++ b/src/Api/src/service/UserService.ts @@ -39,13 +39,14 @@ class UserService { email: string, password: string ): Promise { - try { // should maybe creat a method base on id and other information for better security // need to view with Emre const user = await this.user.findOne({ email }); + console.log(user?._id); // const user = await this.user.findById(idFlad); - if (!user) { + if (user === undefined || user === null) { + console.log("Could") throw new Error('Unable to find user with that email address'); } @@ -54,9 +55,7 @@ class UserService { } else { throw new Error('Wrong credentials given'); } - } catch (error) { - throw new Error('Unable to create user'); - } + } } diff --git a/src/FLAD/App.tsx b/src/FLAD/App.tsx index 2873efb..5e8131a 100644 --- a/src/FLAD/App.tsx +++ b/src/FLAD/App.tsx @@ -2,17 +2,18 @@ import Navigation from './navigation/Navigation'; import { StyleSheet,SafeAreaView } from 'react-native'; import { SafeAreaProvider } from 'react-native-safe-area-context'; import StartNavigation from './navigation/StartNavigation'; +import { Provider, useDispatch, useSelector } from 'react-redux'; +import store from './redux/store'; +import { useCallback, useEffect } from 'react'; +import * as SplashScreen from 'expo-splash-screen'; +import AuthNavigation from './navigation/AuthNavigation'; export default function App() { - + return ( - - - - // - // {/* */} - // - + + + ); } diff --git a/src/FLAD/assets/icons/Spotify_-_Animation_1.gif b/src/FLAD/assets/icons/Spotify_-_Animation_1.gif new file mode 100644 index 0000000..8df51f0 Binary files /dev/null and b/src/FLAD/assets/icons/Spotify_-_Animation_1.gif differ diff --git a/src/FLAD/assets/icons/icons/icon.ts b/src/FLAD/assets/icons/icons/icon.ts index 35b3a1f..670589c 100644 --- a/src/FLAD/assets/icons/icons/icon.ts +++ b/src/FLAD/assets/icons/icons/icon.ts @@ -1,6 +1,9 @@ const Icons = { discovery: require('./icon_discovery.png'), + like: require('./icon_like.png'), + dislike: require('./icon_dislike.png'), + // riveLike : require('./light_like.riv'), } diff --git a/src/FLAD/assets/lottie/Lottie.tsx b/src/FLAD/assets/lottie/Lottie.tsx new file mode 100644 index 0000000..30a1482 --- /dev/null +++ b/src/FLAD/assets/lottie/Lottie.tsx @@ -0,0 +1,6 @@ +const Lotties = { + likeAnimation: require('./spotify-like-interaction.json') + // riveLike : require('./light_like.riv'), +} + +export default Lotties; \ No newline at end of file diff --git a/src/FLAD/assets/lottie/spotify-like-interaction.json b/src/FLAD/assets/lottie/spotify-like-interaction.json new file mode 100644 index 0000000..9f4cb7e --- /dev/null +++ b/src/FLAD/assets/lottie/spotify-like-interaction.json @@ -0,0 +1 @@ +{"nm":"Like lottie","mn":"","layers":[{"ty":4,"nm":"Heart Outlines 3","mn":"","sr":1,"st":10,"op":149,"ip":20,"hd":false,"cl":"","ln":"","ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[204.026,184.705,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0},"i":{"x":0.833,"y":1},"s":[100,100,100],"t":20},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0,100],"t":29}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[399.737,393.085,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":1,"it":[{"ty":"sh","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[6.941,6.941],[36.832,-36.832],[-37.159,-37.16],[0,0],[-4.267,4.553],[0,0],[19.073,36.414],[44.334,-44.335]],"o":[[-6.941,6.941],[-37.494,-37.494],[-37.159,37.16],[0,0],[4.268,4.553],[0,0],[28.62,-29.507],[-31.636,-60.401],[0,0]],"v":[[12.834,-120.539],[-12.302,-120.539],[-146.867,-123.137],[-146.867,11.429],[-7.601,160.152],[8.162,160.152],[147.181,11.837],[164.953,-98.922],[12.849,-120.37]]},"ix":2}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[204.026,184.705],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]},{"ty":"fl","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0,0,0],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}}],"ind":1},{"ty":4,"nm":"Initial ring Outlines 2","mn":"","sr":1,"st":10,"op":149,"ip":12,"hd":false,"cl":"","ln":"","ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[280.077,280.077,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0},"i":{"x":0.667,"y":1},"s":[0,0,100],"t":20},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[150,150,100],"t":42}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[400,372,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":35},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":42}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[-141.427,0],[0,-141.428],[141.427,0],[0,141.427]],"o":[[141.427,0],[0,141.427],[-141.427,0],[0,-141.428]],"v":[[0,-256.077],[256.077,0.001],[0,256.077],[-256.077,0.001]]},"ix":2}},{"ty":"st","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":1,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"o":{"x":0.157,"y":0},"i":{"x":0.651,"y":0.816},"s":[48],"t":20},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[4],"t":31}],"ix":5},"d":[],"c":{"a":0,"k":[0.9725,0.0157,0.0157],"ix":3}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[280.077,280.077],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":2},{"ty":4,"nm":"Initial ring Outlines","mn":"","sr":1,"st":10,"op":149,"ip":12,"hd":false,"cl":"","ln":"","ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[280.077,280.077,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0},"i":{"x":0.667,"y":1},"s":[0,0,100],"t":20},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[120,120,100],"t":49}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[400,372,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":36},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":49}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[-141.427,0],[0,-141.428],[141.427,0],[0,141.427]],"o":[[141.427,0],[0,141.427],[-141.427,0],[0,-141.428]],"v":[[0,-256.077],[256.077,0.001],[0,256.077],[-256.077,0.001]]},"ix":2}},{"ty":"st","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":1,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"o":{"x":0.167,"y":0},"i":{"x":0.833,"y":1},"s":[64],"t":29},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[32],"t":46}],"ix":5},"d":[],"c":{"a":0,"k":[0.9725,0.0157,0.0157],"ix":3}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[280.077,280.077],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":3},{"ty":4,"nm":"Heart Outlines 2","mn":"","sr":1,"st":10,"op":149,"ip":20,"hd":false,"cl":"","ln":"","ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[204.026,184.705,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0},"i":{"x":0.833,"y":1},"s":[100,100,100],"t":20},{"o":{"x":0.167,"y":0},"i":{"x":0.833,"y":1},"s":[130,130,100],"t":26},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100,100],"t":34}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[399.737,393.085,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":1,"it":[{"ty":"sh","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[6.941,6.941],[36.832,-36.832],[-37.159,-37.16],[0,0],[-4.267,4.553],[0,0],[19.073,36.414],[44.334,-44.335]],"o":[[-6.941,6.941],[-37.494,-37.494],[-37.159,37.16],[0,0],[4.268,4.553],[0,0],[28.62,-29.507],[-31.636,-60.401],[0,0]],"v":[[12.834,-120.539],[-12.302,-120.539],[-146.867,-123.137],[-146.867,11.429],[-7.601,160.152],[8.162,160.152],[147.181,11.837],[164.953,-98.922],[12.849,-120.37]]},"ix":2}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[204.026,184.705],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]},{"ty":"fl","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.9725,0.0157,0.0157],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}}],"ind":4},{"ty":4,"nm":"Heart Outlines","mn":"","sr":1,"st":10,"op":68,"ip":0,"hd":false,"cl":"","ln":"","ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[204.026,184.705,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[399.737,393.085,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":30},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":40}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[6.941,6.941],[36.832,-36.832],[-37.159,-37.16],[0,0],[-4.267,4.553],[0,0],[19.073,36.414],[44.334,-44.335]],"o":[[-6.941,6.941],[-37.494,-37.494],[-37.159,37.16],[0,0],[4.268,4.553],[0,0],[28.62,-29.507],[-31.636,-60.401],[0,0]],"v":[[12.834,-120.539],[-12.302,-120.539],[-146.867,-123.137],[-146.867,11.429],[-7.601,160.152],[8.162,160.152],[147.181,11.837],[164.953,-98.922],[12.849,-120.37]]},"ix":2}},{"ty":"st","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":1,"lj":1,"ml":10,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":8,"ix":5},"d":[],"c":{"a":0,"k":[1,1,1],"ix":3}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[204.026,184.705],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":5},{"ty":4,"nm":"Small white Outlines 2","mn":"","sr":1,"st":1,"op":149,"ip":36,"hd":false,"cl":"","ln":"","ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[56.457,47.72,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[80,80,100],"t":36},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[110,110,100],"t":54}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[127.655,124.53,0],"t":36,"ti":[-10.333,10.333,0],"to":[10.333,-10.333,0]},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[189.655,62.53,0],"t":54}],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":43},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":54}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":4,"it":[{"ty":"sh","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[0.835,0.835],[11.836,-11.836],[-11.837,-11.836],[0,0],[-7.862,8.378],[0,0],[11.836,11.834],[11.827,-11.836]],"o":[[-11.837,-11.836],[-11.837,11.834],[0,0],[7.851,8.378],[0,0],[11.836,-11.836],[-11.837,-11.836],[-0.845,0.835]],"v":[[-1.515,-34.888],[-44.369,-35.633],[-44.369,7.224],[-14.505,39.091],[14.506,39.091],[44.37,7.224],[44.37,-35.633],[1.515,-34.888]]},"ix":2}},{"ty":"fl","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.7059,0.0157,0.0157],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[56.456,47.72],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":6,"parent":7},{"ty":4,"nm":"Small green Outlines 2","mn":"","sr":1,"st":1,"op":149,"ip":36,"hd":false,"cl":"","ln":"","ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[56.457,47.72,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[80,80,100],"t":36},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[110,110,100],"t":54}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[487.64,495.007,0],"t":36,"ti":[-5.667,4.667,0],"to":[1.667,3.333,0]},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[543.64,153.007,0],"t":54}],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":43},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":54}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":4,"it":[{"ty":"sh","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[0.835,0.836],[11.836,-11.836],[-11.827,-11.835],[0,0],[-7.851,8.378],[0,0],[11.837,11.834],[11.837,-11.836]],"o":[[-11.837,-11.836],[-11.827,11.834],[0,0],[7.851,8.378],[0,0],[11.837,-11.835],[-11.837,-11.836],[-0.835,0.836]],"v":[[-1.516,-34.888],[-44.38,-35.633],[-44.38,7.224],[-14.505,39.091],[14.495,39.091],[44.37,7.224],[44.37,-35.633],[1.505,-34.888]]},"ix":2}},{"ty":"fl","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[1,1,1],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[56.457,47.72],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":7},{"ty":4,"nm":"Small white Outlines","mn":"","sr":1,"st":-5,"op":149,"ip":30,"hd":false,"cl":"","ln":"","ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[56.457,47.72,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[80,80,100],"t":30},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[110,110,100],"t":40}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[127.655,124.53,0],"t":30,"ti":[-10.333,10.333,0],"to":[10.333,-10.333,0]},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[189.655,62.53,0],"t":50}],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":40},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":50}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":4,"it":[{"ty":"sh","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[0.835,0.835],[11.836,-11.836],[-11.837,-11.836],[0,0],[-7.862,8.378],[0,0],[11.836,11.834],[11.827,-11.836]],"o":[[-11.837,-11.836],[-11.837,11.834],[0,0],[7.851,8.378],[0,0],[11.836,-11.836],[-11.837,-11.836],[-0.845,0.835]],"v":[[-1.515,-34.888],[-44.369,-35.633],[-44.369,7.224],[-14.505,39.091],[14.506,39.091],[44.37,7.224],[44.37,-35.633],[1.515,-34.888]]},"ix":2}},{"ty":"fl","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[1,1,1],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[56.456,47.72],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":8,"parent":9},{"ty":4,"nm":"Small green Outlines","mn":"","sr":1,"st":-5,"op":149,"ip":30,"hd":false,"cl":"","ln":"","ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[56.457,47.72,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[80,80,100],"t":30},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[120,120,100],"t":40}],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[243.64,469.007,0],"t":30,"ti":[-5.667,4.667,0],"to":[1.667,3.333,0]},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[95.64,133.007,0],"t":50}],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":40},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0],"t":50}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":4,"it":[{"ty":"sh","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[0.835,0.836],[11.836,-11.836],[-11.827,-11.835],[0,0],[-7.851,8.378],[0,0],[11.837,11.834],[11.837,-11.836]],"o":[[-11.837,-11.836],[-11.827,11.834],[0,0],[7.851,8.378],[0,0],[11.837,-11.835],[-11.837,-11.836],[-0.835,0.836]],"v":[[-1.516,-34.888],[-44.38,-35.633],[-44.38,7.224],[-14.505,39.091],[14.495,39.091],[44.37,7.224],[44.37,-35.633],[1.505,-34.888]]},"ix":2}},{"ty":"fl","bm":0,"cl":"","ln":"","hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.7059,0.0157,0.0157],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[56.457,47.72],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":9}],"ddd":0,"h":800,"w":800,"meta":{"a":"","k":"","d":"","g":"LottieFiles AE 1.0.0","tc":"#000000"},"v":"4.8.0","fr":60,"op":55,"ip":0,"assets":[]} \ No newline at end of file diff --git a/src/FLAD/components/AnimatedParalax.tsx b/src/FLAD/components/AnimatedParalax.tsx new file mode 100644 index 0000000..4bb9c95 --- /dev/null +++ b/src/FLAD/components/AnimatedParalax.tsx @@ -0,0 +1,53 @@ +import { SharedElement } from "react-navigation-shared-element"; +import { NavigationProp, RouteProp } from "@react-navigation/native"; +import { View,Image,StyleSheet, Dimensions, useWindowDimensions } from "react-native"; +import Animated, { interpolate, SensorType, useAnimatedSensor, useAnimatedStyle, withTiming } from "react-native-reanimated"; + +interface SpotProps { + spot: { name: string, sourceUrl: string, index : number }; +} +const halfPi = Math.PI/2; + +const AnimatedParalax = ({}) => { + const {width, height} = useWindowDimensions(); + const sensor = useAnimatedSensor(SensorType.ROTATION); + const styleAniamatedImage = useAnimatedStyle(() => { + const {yaw, pitch, roll} = sensor.sensor.value; + const verticalAxis =interpolate( + pitch, + [-halfPi,halfPi], + [-25, 25] + ) + const horizontalAxis =interpolate( + roll, + [-halfPi*2,halfPi*2], + [-35, 35] + ) + return { + top : verticalAxis, + left : horizontalAxis, + }; + + }) + return ( + + + + + ); +}; + + +export default AnimatedParalax; \ No newline at end of file diff --git a/src/FLAD/components/Artist.tsx b/src/FLAD/components/Artist.tsx new file mode 100644 index 0000000..89ba68c --- /dev/null +++ b/src/FLAD/components/Artist.tsx @@ -0,0 +1,82 @@ +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 ArtistProps { + artist: Music; + onPress: () => void; + } +export const Artist = ({ artist, onPress }: ArtistProps) => { + const source = typeof artist.image === 'string' ? { uri: artist.image } : artist.image; + //@ts-ignore + const onSingleTapEvent = (event) => { + if (event.nativeEvent.state === State.ACTIVE) { + alert('Hey single tap!'); + } + }; + const doubleTapRef = useRef(null); + 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/Card.tsx b/src/FLAD/components/Card.tsx index 9ca470b..2623d4d 100644 --- a/src/FLAD/components/Card.tsx +++ b/src/FLAD/components/Card.tsx @@ -1,6 +1,6 @@ import { View, Text, Image , Dimensions, StyleSheet } from 'react-native' import React, { useRef, useState } from 'react' -import Animated,{ Extrapolate, interpolate, useAnimatedGestureHandler, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated'; +import Animated,{ Extrapolate, interpolate, runOnJS, useAnimatedGestureHandler, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated'; import { PanGestureHandler, PanGestureHandlerGestureEvent } from 'react-native-gesture-handler'; import * as Haptics from 'expo-haptics'; @@ -14,17 +14,18 @@ const SCREEN_WIDTH = Dimensions.get('window').width interface CardProps { title: string; image: any; + onSwipe: (direction: "left" | "right") => void; } type ContextType = { translateX: number; translateY: number; }; -const Card : React.FC = ({ title, image} : CardProps) => { +const Card = ({ title, image, onSwipe } : CardProps) => { const translateX = useSharedValue(0); const translateY = useSharedValue(0); - + const scale = useSharedValue(1); const onGestureEvent = useAnimatedGestureHandler< PanGestureHandlerGestureEvent, ContextType @@ -34,15 +35,20 @@ const Card : React.FC = ({ title, image} : CardProps) => { context.translateY = translateY.value; }, onActive : (event, context) => { - translateX.value = event.translationX + context.translateX -5; + translateX.value = event.translationX + context.translateX; translateY.value = event.translationY + context.translateY; + }, onEnd : (event, context) => { + console.log(translateX.value); + // translateX.value = withSpring(0); // translateY.value = withSpring(snapPoint(translateY.value,velocityY, snapPoints )) if (translateX.value > 160) { - // onSwipe("right"); + console.log("translateX2"); + runOnJS(onSwipe)("right"); } else if (translateX.value < -160) { + runOnJS(onSwipe)("left"); // onSwipe("left"); } else { translateX.value = withSpring(0); @@ -58,7 +64,7 @@ const Card : React.FC = ({ title, image} : CardProps) => { const opacityl = interpolate ( translateX.value, [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 4], - [0, 0, 1]); + [ 0,0, 1]); return { opacity : opacityl, }; @@ -77,7 +83,7 @@ const Card : React.FC = ({ title, image} : CardProps) => { const opacityl = interpolate ( translateX.value, [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 4], - [0.75, 1, 0.75]); + [0.35, 0, 0.35]); return { opacity : opacityl, @@ -92,6 +98,7 @@ const Card : React.FC = ({ title, image} : CardProps) => { opacity : opacityl, }; }); +const horizontalThreshold = SCREEN_WIDTH * 0.65; const rotateStyle = useAnimatedStyle(() => { const rot = interpolate @@ -106,7 +113,28 @@ const Card : React.FC = ({ title, image} : CardProps) => { }; }); - + const styleCardsNew = useAnimatedStyle(() => { + const factor = 1; + const rot = interpolate + ( translateX.value, + [0, factor * horizontalThreshold], + [0, 15], + ); + + return { + transform: [ + { scale: scale.value }, + { translateX: translateX.value }, + { translateY: translateY.value }, + { rotateZ: `${rot}deg` }, + ] + + }; + }); + + + // Calculate the distance of the card from its starting position + const rStyle = useAnimatedStyle(() => { return { @@ -124,10 +152,18 @@ const Card : React.FC = ({ title, image} : CardProps) => { return ( - + + + + + + <> = ({ title, image} : CardProps) => { = ({ title, image} : CardProps) => { @@ -164,8 +205,9 @@ const Card : React.FC = ({ title, image} : CardProps) => { /> - - + + + ); @@ -176,17 +218,21 @@ const styles = StyleSheet.create({ card : { justifyContent : 'center', alignItems : 'center', - }, image : { borderRadius : 24, - resizeMode: 'cover', - height: 529, - width: 312, - backgroundColor: 'black', + resizeMode: 'stretch', + height: 362, + width: 362, +}, +container: { + flex: 1, + width: '100%', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', } }) - - export default Card; +export default Card; diff --git a/src/FLAD/components/FladLoadingScreen.tsx b/src/FLAD/components/FladLoadingScreen.tsx new file mode 100644 index 0000000..3bdeda1 --- /dev/null +++ b/src/FLAD/components/FladLoadingScreen.tsx @@ -0,0 +1,114 @@ +import { View, Text, Image , Dimensions, StyleSheet } from 'react-native' +import React, { useEffect, useRef, useState } from 'react' +import Animated,{ Extrapolate, interpolate, runOnJS, useAnimatedGestureHandler, useAnimatedStyle, useSharedValue, withRepeat, withSpring, withTiming } from 'react-native-reanimated'; + +import { PanGestureHandler, PanGestureHandlerGestureEvent } from 'react-native-gesture-handler'; +import * as Haptics from 'expo-haptics'; + +const {width : wWidht} = Dimensions.get("window"); +const SCREEN_HEIGHT = Dimensions.get('window').height +const SCREEN_WIDTH = Dimensions.get('window').width +// const width = wWidht *0.75; +// const height = wWidht * (465/264); +// const borderRadius = 24; + + const size= 100 +const FladLoading = () => { + + const progresse = useSharedValue(1); + + + useEffect(() => { + // withTiming, withSpring + progresse.value =withRepeat( withTiming(0.01,{duration : 750}), -1,true); + }, [progresse]); + + const breatheStyle = useAnimatedStyle(() => { + const borderRange = interpolate + ( progresse.value, + [0, 1], + [(0*size) / 2,(1*size)/2], + ); + return { + justifyContent : 'center', + alignItems : 'center', + width : size, + height : size, + shadowColor : "#DA1D1D", + shadowOffset : {width : 0, height : 0}, + shadowOpacity : 1, + shadowRadius :borderRange, + }; + }); + const breatheStyle2 = useAnimatedStyle(() => { + const borderRange = interpolate + ( progresse.value, + [0, 1], + [(0*size) / 2,(1*size)/2], + ); + return { + + borderRadius : borderRange, + + }; + }); + + const breatheStyleSquare = useAnimatedStyle(() => { + const borderRange = interpolate + ( progresse.value, + [0, 1], + [(size+20),(size)], + ); + return { + + width : borderRange, + height : borderRange, + borderRadius : borderRange/2, + borderWidth : size/10, + borderColor : "#F80404", + shadowColor : "#F40C1C", + shadowOffset : {width : 0, height : 0}, + shadowOpacity : 1, + shadowRadius :10, + }; + }); + + + + return ( + + + + + + {/* + */} + + {/* */} + + + ); + }; + + +const styles = StyleSheet.create({ + card : { + justifyContent : 'center', + alignItems : 'center', + }, + image : { + borderRadius : 24, + resizeMode: 'stretch', + +}, +container: { + flex: 1, + width: '100%', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', +} +}) + +export default FladLoading; + diff --git a/src/FLAD/components/Genre.tsx b/src/FLAD/components/Genre.tsx new file mode 100644 index 0000000..d1fdcb2 --- /dev/null +++ b/src/FLAD/components/Genre.tsx @@ -0,0 +1,83 @@ +import { useState } from "react"; +import { FlatList, ScrollView } from "react-native"; +import Music from "../Model/Music"; +import { Artist } from "./Artist"; +import { StyleSheet } from "react-native"; + +export const ArtistLayout = () => { + 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"), + ] + const [artists, setArtists] = useState(MUSIC_LIST); + const [selectedArtists, setSelectedArtists] = useState ([]); + + return ( + + {artists.map((artist, i) => ( + { + // artists.splice(i, 1); + // // 2 implementation + const tmppArtist = new Music("Kratos", "PNL", "https://upload.wikimedia.org/wikipedia/en/a/a0/PNL_-_Dans_la_l%C3%A9gende.png"); + + // const existingObjIndex = selectedArtists.findIndex(obj => obj.title === tmppArtist.title); + // if (existingObjIndex === -1) { + // selectedArtists.push(tmppArtist); + // } else { + // selectedArtists.splice(existingObjIndex, 1); + // } + // setSelectedArtists([...selectedArtists]); + // 1 implementation + // setSelectedArtists(selectedArtists.findIndex(obj => obj.title === tmppArtist.title) === -1 + // ? [...selectedArtists, tmppArtist] + // : selectedArtists.filter(obj => obj.title !== tmppArtist.title)) + // 3 implementations + // use the selectedProps of the Artist Component + // then when we need to finish + // onPress{ () => setSelectedArtists([...selectedArtists,artists.filter(artist => artist.selected)])} + + artists.push(tmppArtist); + setArtists([...artists]); + }} + /> + ))} + {/* ( + { + artists.push(new Music("Kratos", "PNL", "https://upload.wikimedia.org/wikipedia/en/a/a0/PNL_-_Dans_la_l%C3%A9gende.png")); + setArtists([...artists]); + }}/> + )} + keyExtractor={(item: Music) => item.title } + // ListEmptyComponent = {} + /> */} + + + + ); + }; + + + + const styles = StyleSheet.create({ + container: { + flexDirection: "row", + flexWrap: "wrap", + + }, + }); \ No newline at end of file diff --git a/src/FLAD/components/Onboarding.tsx b/src/FLAD/components/Onboarding.tsx index 7dd4388..8c48acd 100644 --- a/src/FLAD/components/Onboarding.tsx +++ b/src/FLAD/components/Onboarding.tsx @@ -1,6 +1,6 @@ import React, { useState, useRef } from 'react'; -import { View, StyleSheet, Text, FlatList, Animated, TouchableOpacity, ImageBackground, Image } from 'react-native'; -import Modal from "react-native-modal"; +import { Modal, View, StyleSheet, Text, FlatList, Animated, TouchableOpacity, ImageBackground, Image } from 'react-native'; +// import Modal from "react-native-modal"; import {useNavigation} from "@react-navigation/native"; import normalize from '../components/Normalize'; @@ -53,11 +53,11 @@ export default function Onboarding() { onViewableItemsChanged={viewableItemsChanged} viewabilityConfig={viewConfig} ref={slidesRef} - /> + /> - + @@ -124,11 +124,10 @@ const styles = StyleSheet.create({ right: 10 }, modalContent: { - position: 'absolute', - top: '7%', - left: '-5%', - right: '-5%', - height: '100%', + + flex: 1, + justifyContent: 'center', + alignItems: 'center', }, modalView: { flex: 1, diff --git a/src/FLAD/data/data.ts b/src/FLAD/data/data.ts index 6dcc56d..85abaf4 100644 --- a/src/FLAD/data/data.ts +++ b/src/FLAD/data/data.ts @@ -1,12 +1,37 @@ export const cards = [{ name : "blue", - sourceUrl : "https://i.ebayimg.com/images/g/rY0AAOSw97djEo2C/s-l500.jpg", - index : 3 + sourceUrl : "https://th.bing.com/th/id/R.dbf87f0d8cbfd078ab6a589a5d921994?rik=1%2f6KliMpOAeh8A&pid=ImgRaw&r=0", + index : 4 }, { name : "her", sourceUrl : "https://i.ebayimg.com/images/g/rY0AAOSw97djEo2C/s-l500.jpg", + index : 9 +}, +{ + name : "gambino", + sourceUrl : "https://th.bing.com/th/id/R.0b2d1a59bfda9b1a49ecb561e08535a8?rik=Xyc35OZU%2f6VOVw&pid=ImgRaw&r=0", index : 3 -} +}, +{ + name : "PNL", + sourceUrl : "https://upload.wikimedia.org/wikipedia/en/a/a0/PNL_-_Dans_la_l%C3%A9gende.png", + index : 10 +}, +{ + name : "Freeze Raël", + sourceUrl : "https://intrld.com/wp-content/uploads/2020/08/freeze-corleone-la-menace-fanto%CC%82me.png", + index : 23 +}, +{ + name : "Sch", + sourceUrl : "https://images.genius.com/83b6c98680d38bde1571f6b4093244b5.1000x1000x1.jpg", + index : 44 +}, +{ + name : "Stratos", + sourceUrl : "https://images.genius.com/ddc9cadedd1d4cef0860aaa85af9cd46.705x705x1.png", + index : 89 +}, -] \ No newline at end of file +] diff --git a/src/FLAD/fladConfig.tsx b/src/FLAD/fladConfig.tsx new file mode 100644 index 0000000..0c6f028 --- /dev/null +++ b/src/FLAD/fladConfig.tsx @@ -0,0 +1 @@ +export const API_URL = "https://flad-api-production.up.railway.app" diff --git a/src/FLAD/navigation/AuthNavigation.tsx b/src/FLAD/navigation/AuthNavigation.tsx new file mode 100644 index 0000000..a0b4377 --- /dev/null +++ b/src/FLAD/navigation/AuthNavigation.tsx @@ -0,0 +1,67 @@ +import Navigation from './Navigation'; +import { StyleSheet,SafeAreaView } from 'react-native'; +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 * as SplashScreen from 'expo-splash-screen'; +import { View } from 'react-native'; +import { getRefreshToken } from '../redux/thunk/authThunk'; + +SplashScreen.preventAutoHideAsync(); + +export default function AuthNavigation() { + //@ts-ignore + const appIsReady : 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 dispatch = useDispatch(); + + useEffect(() => { + async function prepare() { + console.log(appIsReady, "1 AuthNav") + + //@ts-ignore + await dispatch(getRefreshToken()) + await SplashScreen.hideAsync(); + } + prepare(); + }, [dispatch]); + + const onStackRootView = useCallback(async () => { + if (appIsReady) { + await SplashScreen.hideAsync(); + } + }, [appIsReady]); + + if (appIsReady == false) { + console.log(appIsReady, "T9 AuthNav") + return null; + } + console.log(appIsReady, "k9 AuthNav") + // console.log(userToken, "k9 AuthNav") + return ( + <> + {isLogin ? ( + /* {userToken != null ? ( */ + + + + + ) : + + + + } + + ) + } + const styles = StyleSheet.create({ + mainSafeArea: { + flex: 1, + backgroundColor: "#141414", + } + }); \ No newline at end of file diff --git a/src/FLAD/navigation/FavoriteNavigation.tsx b/src/FLAD/navigation/FavoriteNavigation.tsx index 40fc83b..f60f3ae 100644 --- a/src/FLAD/navigation/FavoriteNavigation.tsx +++ b/src/FLAD/navigation/FavoriteNavigation.tsx @@ -1,6 +1,7 @@ import React, {Component} from 'react'; import FavoritePage from '../screens/favoritePage'; import { createStackNavigator } from '@react-navigation/stack'; +import { ArtistLayout } from '../components/Genre'; export default function MusicNavigation() { const Stack = createStackNavigator(); @@ -11,6 +12,11 @@ export default function MusicNavigation() { component={FavoritePage} options={{ headerShown: false }} /> + ) } \ No newline at end of file diff --git a/src/FLAD/navigation/Navigation.tsx b/src/FLAD/navigation/Navigation.tsx index 9243d9f..a712ef6 100644 --- a/src/FLAD/navigation/Navigation.tsx +++ b/src/FLAD/navigation/Navigation.tsx @@ -2,8 +2,12 @@ import React, {Component} from 'react'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { NavigationContainer } from '@react-navigation/native'; import FavoriteNavigation from './FavoriteNavigation'; + // @ts-ignore import FontAwesome from 'react-native-vector-icons/FontAwesome'; +import SpotNavigation from './SpotNavigation'; +import Login from '../screens/login'; +import FladLoading from '../components/FladLoadingScreen'; export default function Navigation() { const BottomTabNavigator = createBottomTabNavigator(); @@ -27,22 +31,26 @@ export default function Navigation() { tabBarLabelStyle: { bottom: 5 } }}> - , }}/> , }}/> - , }}/> - , diff --git a/src/FLAD/navigation/SpotNavigation.tsx b/src/FLAD/navigation/SpotNavigation.tsx new file mode 100644 index 0000000..158e177 --- /dev/null +++ b/src/FLAD/navigation/SpotNavigation.tsx @@ -0,0 +1,38 @@ +import React, {Component} from 'react'; +import FavoritePage from '../screens/favoritePage'; +import { createStackNavigator } from '@react-navigation/stack'; +import Spot from '../screens/spot' +import { createSharedElementStackNavigator } from "react-navigation-shared-element"; +import SpotDetailsPage from '../screens/SpotDetailsPage'; + + +export default function SpotNavigation() { + // const Stack = createSharedElementStackNavigator(); + const Stack = createStackNavigator(); + + return ( + + + + {/* { + return [route.params.spot.name] + }} + /> */} + + ) + } \ No newline at end of file diff --git a/src/FLAD/navigation/StartNavigation.tsx b/src/FLAD/navigation/StartNavigation.tsx index ee07e8c..6104df7 100644 --- a/src/FLAD/navigation/StartNavigation.tsx +++ b/src/FLAD/navigation/StartNavigation.tsx @@ -1,15 +1,40 @@ -import React, {Component} from 'react'; +import React, {Component, useCallback, useEffect} from 'react'; import LoginPage from '../screens/loginPage'; import InscriptionPage from '../screens/InscriptionPage'; import Onboarding from '../components/Onboarding'; import { createStackNavigator } from '@react-navigation/stack'; import { NavigationContainer } from '@react-navigation/native'; +import {useDispatch, useSelector} from 'react-redux'; +import * as SplashScreen from 'expo-splash-screen'; +import { getRefreshToken } from '../redux/thunk/authThunk'; +import { ArtistLayout } from '../components/Genre'; export default function StartNavigation() { + // //@ts-ignore + // const appIsReady : boolean = useSelector(state => state.userReducer.loading); + // const dispatch = useDispatch(); + + // useEffect(() => { + // async function prepare() { + // //@ts-ignore + // await dispatch(getRefreshToken()); + // } + // prepare(); + // }, [dispatch]); + + // const onStackRootView = useCallback(async () => { + // if (appIsReady) { + // await SplashScreen.hideAsync(); + // } + // }, [appIsReady]); + + // if (!appIsReady) { + // return null; + // } const Stack = createStackNavigator(); return ( - + { +// return { +// type: userTypes.LOGIN, +// playload : username, password +// }; +// } \ No newline at end of file diff --git a/src/FLAD/redux/actions/spotActions.tsx b/src/FLAD/redux/actions/spotActions.tsx new file mode 100644 index 0000000..3a64b9a --- /dev/null +++ b/src/FLAD/redux/actions/spotActions.tsx @@ -0,0 +1,8 @@ +import {spotTypes} from "../types/spotTypes"; + +export const setSpotList = (spotList: Spot[]) => { + return { + type: spotTypes.FETCH_SPOT, + payload: spotList, + }; + } \ No newline at end of file diff --git a/src/FLAD/redux/actions/userActions.tsx b/src/FLAD/redux/actions/userActions.tsx new file mode 100644 index 0000000..35d78f6 --- /dev/null +++ b/src/FLAD/redux/actions/userActions.tsx @@ -0,0 +1,39 @@ +import { userTypes } from "../types/userTypes"; + + +export interface Credentials { + email : string, + password : string +} +// export const setLoggedInState = loggedInState => ( +// { +// type: types.SET_LOGGED_IN_STATE, +// loggedInState, +// } +// ); +export const setLoginState = (cred : Credentials) => { + return { + type: userTypes.LOGIN, + playload : cred + }; +} + +export const restoreToken = (token : string) => { + return { + type: userTypes.RESTORE_TOKEN, + playload : token + }; +} +// export const UserLogin = (username: string, password: string) => { +// return { +// type: userTypes.LOGIN, +// playload : username, password +// }; +// } + + export const UserLogout = () => { + return { + type: userTypes.USER_LOGOUT, + }; + } + \ No newline at end of file diff --git a/src/FLAD/redux/reducers/appReducer.tsx b/src/FLAD/redux/reducers/appReducer.tsx new file mode 100644 index 0000000..85db729 --- /dev/null +++ b/src/FLAD/redux/reducers/appReducer.tsx @@ -0,0 +1,22 @@ +const initialState = { + spot: [], + favoriteMusic: [], + } + + const appReducer = (state = initialState, action : any) => { + switch (action.type) { + case ADD_FAVORITE_MUSICS: + return {...state, favoriteMusic: state.favoriteMusic.push(action.payload)}; + case REMOVE_FAVORITE_MUSICS: + return {...state, favoriteMusic: state.favoriteMusic}; + case FETCH_SPOT: + return {...state, spot: action.payload}; + case FETCH_DISCOVERIES: + + + default: + return state; + } + } + + 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 new file mode 100644 index 0000000..42effc8 --- /dev/null +++ b/src/FLAD/redux/reducers/spotifyAuthReducer.tsx @@ -0,0 +1,18 @@ + +Uri getApiUrlAuthorize() => _api.identification.urlAuthorize; + +String getApiRedirectUrl() => _api.identification.redirectUri; + +String getIdSpotify() => _currentUser.idSpotify; + +String getIdDafl() => _currentUser.idDafl; + + +case getCompleteMusic + +playTrack(String id) + + case addToPlaylist: + return {...state, spot: action.payload} + + case removeFromPlaylist: diff --git a/src/FLAD/redux/reducers/userReducer.tsx b/src/FLAD/redux/reducers/userReducer.tsx new file mode 100644 index 0000000..015cd9a --- /dev/null +++ b/src/FLAD/redux/reducers/userReducer.tsx @@ -0,0 +1,52 @@ +import { userTypes } from "../types/userTypes"; +const initialState = { + loading: false, + user: {}, // for user object + userFladToken: null, // for storing the JWT + userSpotifyToken : null, + error: null, + isLogedIn: false, + } + + const userReducer = (state = initialState, action : any) => { + switch (action.type) { + // just for the navigation and speciafly use + // and + case userTypes.RESTORE_TOKEN: + console.log(state.loading, "((((((((((((((((((((((((((((((((((((userRducer))))))))))))))))))))))))))))))))))))"); + + console.log(state.userFladToken, "userRducer"); + console.log(state.loading, "((((((((((((((((((((((((((((((((((((userRducer))))))))))))))))))))))))))))))))))))"); + + return { + ...state, + userFladToken : action.playload, + loading: true, + // isLogedIn: true, + }; + + case userTypes.LOGIN: + return { + ...state, + user :action.payload, + isLogedIn: true + }; + case userTypes.SIGNUP: + return { + ...state, + user :action.payload, + isLogedIn: true + }; + // case USER_SIGNUP: + // return {...state, nounours: action.payload}; + case userTypes.USER_LOGOUT: + return {...state, + user :null, + isLogedIn: false } + default: + return state; + } + } + export default userReducer + + \ No newline at end of file diff --git a/src/FLAD/redux/store.tsx b/src/FLAD/redux/store.tsx new file mode 100644 index 0000000..9595adf --- /dev/null +++ b/src/FLAD/redux/store.tsx @@ -0,0 +1,15 @@ +import {configureStore} from '@reduxjs/toolkit' +import appReducer from './reducers/appReducer'; +import userReducer from './reducers/userReducer'; + +// Reference here all your application reducers +const reducer = { + // appReducer: appReducer, + userReducer: userReducer +} + +const store = configureStore({ + reducer : reducer, +},); + +export default store; \ No newline at end of file diff --git a/src/FLAD/redux/thunk/authThunk.tsx b/src/FLAD/redux/thunk/authThunk.tsx new file mode 100644 index 0000000..c658329 --- /dev/null +++ b/src/FLAD/redux/thunk/authThunk.tsx @@ -0,0 +1,127 @@ +//Define your action creators that will be responsible for asynchronous operations + +import axios from "axios"; +import { json } from "express"; +import { useEffect } from "react"; +import { API_URL } from "../../fladConfig"; +import { Credentials, restoreToken, setLoginState } from "../actions/userActions"; +import * as SecureStore from 'expo-secure-store'; + +const key = 'userToken'; + +export const registerUser = ( resgisterCredential : any) => { + //@ts-ignore + return async dispatch => { + try { + const config = { + headers: { + 'Content-Type': 'application/json', + }, + } + const resp = await axios.post( + `${API_URL}/api/users/register`, + resgisterCredential, + config + ) + if (resp.data.msg === 'success') { // response success checking logic could differ + await SecureStore.setItemAsync(key, resp.data.token); + dispatch(setLoginState(resp.data.user) ); // our action is called here + } else { + console.log('Login Failed', 'Username or Password is incorrect'); + } + + } catch (error) { + console.log('Error---------', error); + } + } + } +export const userLogin = ( loginCredential : Credentials) => { +//@ts-ignore +return async dispatch => { + try { + console.log(loginCredential); + + const config = { + headers: { + 'Content-Type': 'application/json', + }, + } + // const resppp = await axios.get(`${API_URL}/toto`); + // console.log(resppp.data, "sddsd"); + + const resp = await axios.post( + "https://flad-api-production.up.railway.app/api/users/login", + loginCredential, + config + ) + console.log("====================================================================================") + console.log(resp.data) + console.log("====================================================================================") + if (resp.data.token) { + console.log(resp.data.token); + const token = resp.data.token; + await SecureStore.setItemAsync(key, token); + const headers = { + 'Authorization': 'Bearer ' + token}; + + const user = await axios.get( + "https://flad-api-production.up.railway.app/api/users", + {headers} + ) + // dispatch(setLoginState(resp.data.user) ); // our action is called here + + dispatch(setLoginState(user.data) ); // our action is called here + } else { + console.log('Login Failed', 'Username or Password is incorrect'); + } + + } catch (error) { + console.log('Error---------', error); + } +} +} + +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 =================="); + + if (userToken) { + console.log("==========key2 =================="); + console.log(userToken); + console.log("==========key =================="); + + dispatch(restoreToken(userToken) ); + + } else { + console.log("==========OOOOOORRRRRRRRHHHHHHHHHH =================="); + const empty = ""; + dispatch(restoreToken(empty) ); + + console.log("merddee"); + } + } catch (e) { + console.log('Error---------', e); + } + } +} + + // const logIn = (email, password) => { + // const action = (dispatch) => { + // if (email === user.email && password === user.password) { + // dispatch(setLoggedInState(true)); + // return true; + // } + // dispatch(setLoggedInState(false)); + // return false; + // }; + // return action; + // }; + // better + async function save(key : string, value : string) { + await SecureStore.setItemAsync(key, value); + } \ No newline at end of file diff --git a/src/FLAD/redux/thunk/spotThunk.tsx b/src/FLAD/redux/thunk/spotThunk.tsx new file mode 100644 index 0000000..cbc10bb --- /dev/null +++ b/src/FLAD/redux/thunk/spotThunk.tsx @@ -0,0 +1,29 @@ +//Define your action creators that will be responsible for asynchronous operations + +import { API_URL } from "../../fladConfig"; + + +export type CreateSpotReqBody = { + id : string; + name : string; + artist : string; + linkCover : string; + user : string; +} + +// export const getSpotList = () => { +// return async dispatch => { +// try { + +// const spotPromise = await fetch(`${API_URL}/spotify/spot`); +// const spotJson = await spotPromise.json(); +// const spotList: Spot[] = spotJson.map(spot => { + +// } ); + +// dispatch(setNounoursList(spotList)); +// } catch (error) { +// console.log('Error---------', error); +// } +// } +// } \ No newline at end of file diff --git a/src/FLAD/redux/types/musicTypes.tsx b/src/FLAD/redux/types/musicTypes.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/FLAD/redux/types/playlistTypes.tsx b/src/FLAD/redux/types/playlistTypes.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/FLAD/redux/types/spotTypes.tsx b/src/FLAD/redux/types/spotTypes.tsx new file mode 100644 index 0000000..9ac6c8f --- /dev/null +++ b/src/FLAD/redux/types/spotTypes.tsx @@ -0,0 +1,3 @@ +export const spotTypes = { + FETCH_SPOT : 'FETCH_NOUNOURS', + } \ No newline at end of file diff --git a/src/FLAD/redux/types/userTypes.tsx b/src/FLAD/redux/types/userTypes.tsx new file mode 100644 index 0000000..cdea161 --- /dev/null +++ b/src/FLAD/redux/types/userTypes.tsx @@ -0,0 +1,9 @@ + +export const userTypes = { + LOGIN: 'LOGIN', + SIGNUP: 'SIGNUP', + UPDATE_USER: 'UPDATE_USER', + UPDATE_PROFILE_PICTURE: 'UPDATE_PROFILE_PICTURE', + USER_LOGOUT : 'USER_LOGOUT', + RESTORE_TOKEN : "RESTORE_TOKEN" + } \ No newline at end of file diff --git a/src/FLAD/screens/InscriptionPage.tsx b/src/FLAD/screens/InscriptionPage.tsx index d466459..bae2a4a 100644 --- a/src/FLAD/screens/InscriptionPage.tsx +++ b/src/FLAD/screens/InscriptionPage.tsx @@ -1,8 +1,12 @@ -import React, {Component, useState } from 'react'; -import { View, Image, StyleSheet, Text, ImageBackground, Button, TextInput, TouchableWithoutFeedback, Keyboard, TouchableOpacity } from 'react-native'; +import React, {Component, useEffect, useState } from 'react'; +import { View, Image, StyleSheet, Text, ImageBackground, Button, TextInput, TouchableWithoutFeedback, Keyboard, TouchableOpacity, Platform } from 'react-native'; import {useNavigation} from "@react-navigation/native"; import normalize from '../components/Normalize'; - +import * as SecureStore from 'expo-secure-store'; +import * as AuthSession from 'expo-auth-session'; +import axios from 'axios'; +import * as WebBrowser from 'expo-web-browser'; +import { makeRedirectUri, useAuthRequest } from 'expo-auth-session'; // @ts-ignore const DismissKeyboard = ({ children }) => ( Keyboard.dismiss()}> @@ -10,6 +14,21 @@ const DismissKeyboard = ({ children }) => ( ) +export const MY_SECURE_AUTH_STATE_KEY = 'MySecureAuthStateKey'; + +WebBrowser.maybeCompleteAuthSession(); + +// Endpoint +const discovery = { +authorizationEndpoint: 'https://accounts.spotify.com/authorize', +tokenEndpoint: 'https://accounts.spotify.com/api/token', +}; +// save the spotifyToken +async function save(key : string, value : string) { +await SecureStore.setItemAsync(key, value); +} + + export default function InscriptionPage() { const [rememberMe, setRememberMe] = useState(false); const navigation = useNavigation(); @@ -17,6 +36,29 @@ export default function InscriptionPage() { const toggleRememberMe = () => { setRememberMe(!rememberMe); } +//spotify auth + const [request, response, promptAsync] = useAuthRequest( + { + responseType: AuthSession.ResponseType.Token, + clientId: '1f1e34e4b6ba48b388469dba80202b10', + scopes: ['user-read-private','user-read-email','user-read-playback-state','user-read-currently-playing','user-read-recently-played','playlist-modify-public','ugc-image-upload','user-modify-playback-state'], + redirectUri: makeRedirectUri({ + scheme: 'flad' + }), + }, + discovery + ); + useEffect(() => { + if (response && response.type === 'success') { + const auth = response.params.access_token; + const storageValue = JSON.stringify(auth); + + if (Platform.OS !== 'web') { + // Securely store the auth on your device + save(MY_SECURE_AUTH_STATE_KEY, storageValue); + } + } + }, [response]); return ( @@ -39,7 +81,9 @@ export default function InscriptionPage() { - + { + promptAsync(); + }} style={[styles.buttonSpotify, styles.shadow]}> Lier compte @@ -161,4 +205,4 @@ const styles = StyleSheet.create ({ borderRadius: 30, flexDirection: 'row' } -}) \ No newline at end of file +}) diff --git a/src/FLAD/screens/SpotDetailsPage.tsx b/src/FLAD/screens/SpotDetailsPage.tsx new file mode 100644 index 0000000..8987e0e --- /dev/null +++ b/src/FLAD/screens/SpotDetailsPage.tsx @@ -0,0 +1,76 @@ +import { SharedElement } from "react-navigation-shared-element"; +import { NavigationProp, RouteProp } from "@react-navigation/native"; +import { View,Text,Image,StyleSheet, Dimensions, useWindowDimensions } from "react-native"; +import Animated, { interpolate, SensorType, useAnimatedSensor, useAnimatedStyle, withSpring, withTiming } from "react-native-reanimated"; +import { BlurView } from 'expo-blur'; + +interface SpotProps { + spot: { name: string, sourceUrl: string, index : number }; +} +const halfPi = Math.PI/2; + +// const {width : wWidht} = Dimensions.get("window"); +//@ts-ignore +const SpotDetailsPage = ({ route }) => { + const {width, height} = useWindowDimensions(); + console.log("===================================="); + console.log(route); + + const spot : { name: string, sourceUrl: string, index : number } = route.params.spot; + console.log(spot); + const sensor = useAnimatedSensor(SensorType.ROTATION); + const styleAniamatedImage = useAnimatedStyle(() => { + const {yaw, pitch, roll} = sensor.sensor.value; + const verticalAxis =interpolate( + pitch, + [-halfPi,halfPi], + [-30, 30] + ) + const horizontalAxis =interpolate( + roll, + [-halfPi*2,halfPi*2], + [-30, 30] + ) + return { + top : withSpring( verticalAxis), + left : withSpring(horizontalAxis), + }; + + }) + return ( + + {/* */} + + + {/* + {props.character} + + */} + {/* */} + + + ); +}; + +export default SpotDetailsPage; \ No newline at end of file diff --git a/src/FLAD/screens/favoritePage.tsx b/src/FLAD/screens/favoritePage.tsx index 74cd16e..9a7b8b1 100644 --- a/src/FLAD/screens/favoritePage.tsx +++ b/src/FLAD/screens/favoritePage.tsx @@ -1,9 +1,13 @@ import React, {Component} from 'react'; -import { Animated, StyleSheet, Text, View, FlatList, ScrollView } from 'react-native'; +import { Animated, Image,StyleSheet, Text, View, FlatList, ScrollView, TouchableOpacity } from 'react-native'; import CardMusic from '../components/CardMusic'; +import normalize from '../components/Normalize'; import Music from '../Model/Music' +import {useNavigation} from "@react-navigation/native"; 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")), @@ -32,6 +36,11 @@ export default function favoritePage() { keyExtractor={(item: Music) => item.title } /> + navigation.navigate('Genre')}> + + ); @@ -57,5 +66,29 @@ const styles = StyleSheet.create({ fontSize: 18, color: '#787878', marginBottom: 20 + }, + button: { + marginTop: '10%', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + alignSelf: 'center', + backgroundColor: 'white', + width: normalize(100), + height: normalize(100), + borderRadius: 21 + }, + buttonImage: { + width: normalize(46), + height: normalize(46), + }, + shadow: { + shadowColor: '#000', + shadowOffset: { + width: 2, + height: 3, + }, + shadowOpacity: 0.50, + shadowRadius: 3.84, } }); diff --git a/src/FLAD/screens/login.tsx b/src/FLAD/screens/login.tsx index 6533a2a..1b6991d 100644 --- a/src/FLAD/screens/login.tsx +++ b/src/FLAD/screens/login.tsx @@ -10,6 +10,7 @@ import { cards as cardArray } from '../data/data' import FladButton from '../components/button/button'; import * as WebBrowser from 'expo-web-browser'; import { makeRedirectUri, useAuthRequest } from 'expo-auth-session'; +import { Buffer } from 'buffer'; const SCREEN_WIDTH = Dimensions.get('window').width @@ -26,6 +27,7 @@ interface Params { email: string; id: string; } + //generate random string export const MY_SECURE_AUTH_STATE_KEY = 'MySecureAuthStateKey'; @@ -36,8 +38,7 @@ const discovery = { authorizationEndpoint: 'https://accounts.spotify.com/authorize', tokenEndpoint: 'https://accounts.spotify.com/api/token', }; - - +// save the spotifyToken async function save(key : string, value : string) { await SecureStore.setItemAsync(key, value); } @@ -45,14 +46,18 @@ async function save(key : string, value : string) { export default function Login() { // const [advice, setAdvice] = useState("dd"); + // there we use implicit grant flow const [request, response, promptAsync] = useAuthRequest( { responseType: AuthSession.ResponseType.Token, clientId: '1f1e34e4b6ba48b388469dba80202b10', scopes: ['user-read-private','user-read-email','user-read-playback-state','user-read-currently-playing','user-read-recently-played','playlist-modify-public','ugc-image-upload','user-modify-playback-state'], + usePKCE: false, redirectUri: makeRedirectUri({ - scheme: 'flad' - }), + scheme: 'https://auth.expo.io/@anonymous/FLAD-7eafd441-fd6b-4fb6-924c-ec2b0ed5ce6d', + useProxy : true + }) + }, discovery ); @@ -68,22 +73,78 @@ export default function Login() { }; React.useEffect(() => { if (response && response.type === 'success') { + console.log(response); + console.log("========================code====================="); + + console.log(response.params.code) + console.log("============================================="); + + console.log("========================acess====================="); + console.log(response.params.access_token) + console.log("============================================="); + const auth = response.params.access_token; const storageValue = JSON.stringify(auth); if (Platform.OS !== 'web') { // Securely store the auth on your device - save(MY_SECURE_AUTH_STATE_KEY, storageValue); + // save(MY_SECURE_AUTH_STATE_KEY, storageValue); } } }, [response]); +const scopesArr = ['user-read-private','user-read-email','user-read-playback-state','user-read-currently-playing','user-read-recently-played','playlist-modify-public','ugc-image-upload','user-modify-playback-state']; +const scopes = scopesArr.join(' '); + //work so use this for my implementation + const getAuthorizationCode = async () => { + try { + const redirectUrl = "https://auth.expo.io/@anonymous/FLAD-7eafd441-fd6b-4fb6-924c-ec2b0ed5ce6d"; //this will be something like https://auth.expo.io/@your-username/your-app-slug + const result = await AuthSession.startAsync({ + authUrl: + 'https://accounts.spotify.com/authorize' + + '?response_type=code' + + '&client_id=' + + "1f1e34e4b6ba48b388469dba80202b10" + + (scopes ? '&scope=' + encodeURIComponent(scopes) : '') + + '&redirect_uri=' + + encodeURIComponent(redirectUrl), + }) + console.log(result); + } catch (err) { + console.error(err) + } + } + const getTokens = async () => { + try { + const authorizationCode = await getAuthorizationCode() //we wrote this function above + const response = await fetch('https://accounts.spotify.com/api/token', { + method: 'POST', + headers: { + Authorization: 'Basic ' + (Buffer.from('1f1e34e4b6ba48b388469dba80202b10' + ':' + '779371c6d4994a68b8dd6e84b0873c82').toString('base64')), + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: `grant_type=authorization_code&code=${authorizationCode}&redirect_uri=https://auth.expo.io/@anonymous/FLAD-7eafd441-fd6b-4fb6-924c-ec2b0ed5ce6d`, + }); + const responseJson = await response.json(); + // destructure the response and rename the properties to be in camelCase to satisfy my linter ;) + const { + access_token: accessToken, + refresh_token: refreshToken, + expires_in: expiresIn, + } = responseJson; + + console.log(responseJson); + } catch (err) { + console.error(err); + } + } return ( Hello flad test logIn */} - - - ))} + {cards.map((card, index) => ( + + + {hapti(card)}} > + {/* */} + {onSwipe(index, direction)}} + /> + {/* */} + + + )) + } + - - {/* */} - + + + + + + + + + + + + + + + + ) + : ( + + + + + + Vous avez explorer toutes les spot autour de vous. + {"\n"}Continuer dans discoverie pour découvrir de nouvelles music basées dur vos gouts musicaux. + + + ) + } + ); }; @@ -205,7 +272,32 @@ export default function Spot() { flex: 1, alignItems: 'center', justifyContent: 'center', + alignContent : 'center', + flexDirection : 'column', backgroundColor : '#000' - } + }, + lottie : { + width : '100%', + }, + button : { + setOpacityTo: 0.8, + alignItems : 'center', + borderRadius : 100, + justifyContent : 'center', + width: 61, + height: 61, + + backgroundColor: '#24243A', + opacity : 0.8, + shadowRadius : 2, + + }, + gradient : { + position : "absolute", + top : 0, + left : 0, + right : 0, + height : 209, + }, })