diff --git a/Api/package.json b/Api/package.json index 8267a4f..bfcbf92 100644 --- a/Api/package.json +++ b/Api/package.json @@ -17,14 +17,17 @@ "@types/morgan": "^1.9.4", "nodemon": "^2.0.20", "ts-node": "^10.9.1", - "typescript": "^4.9.4" + "typescript": "^4.9.5" }, "dependencies": { "@types/crypto-js": "^4.1.1", + "@types/mongoose": "^5.11.97", "@types/request": "^2.48.8", "axios": "^1.2.6", "cors": "^2.8.5", "express-winston": "^4.2.0", + "mongodb": "^5.0.0", + "mongoose": "^6.9.0", "morgan": "^1.10.0", "swagger-ui-express": "^4.6.0", "winston": "^3.8.2" diff --git a/Api/src/controller/user-controller/userCtrl.ts b/Api/src/controller/user-controller/userCtrl.ts new file mode 100644 index 0000000..f7f5bc8 --- /dev/null +++ b/Api/src/controller/user-controller/userCtrl.ts @@ -0,0 +1,169 @@ +import { Router, Request, Response, NextFunction, RequestHandler } from 'express'; +import Controller from '../Icontroller'; +import HttpException from '../../middleware/exeption/httpExeption'; +import LocationService from '../../service/LocationService'; + + +class TaskController implements Controller { + public path = '/task'; + public router = Router(); + private userService = new UserService(); + private locationService = new LocationService(); + + constructor() { + this.initialiseRoutes(); + } + + private initialiseRoutes(): void { + //create + this.router.post(`${this.path}`,this.createUser); + + // // get One + this.router.get (`${this.path}/:userId`, this.getUserById); + // // get All + this.router.get (`${this.path}`, this.getAllUsers); + + //update One + this.router.put (`${this.path}/:userId`, this.updateUser); + + //Delete One + this.router.delete (`${this.path}/:userId`, this.deleteUser); + + } + + private createUser = async ( + req: Request, + res: Response, + next: NextFunction + ): Promise => { + try { + + console.log(req.body); + const reqBody:CreateTaskReqBody = Object.assign({}, req.body); + checkIfIsValidCreateTaskReqBody(reqBody); + await this.userService.createUserById(reqBody.fin + ); + + res.status(200).send({ status: "Success", msg: "Success add" }); + + + } catch (error) { + next(new HttpException(400, 'Cannot create post')); + } + }; + private readonly getUserById: RequestHandler = async ( + req: Request, + res: Response, + next: NextFunction + ): Promise => { + try { + const id = req.params.taskId; + const userId = req.params.userId; + + const data = await this.userService.getUserById(id, userId); + res.status(201).send(data); + + } + catch(error){ + next(new HttpException(400, 'Cannot create post')); + } + + } + private readonly getAllUsers: RequestHandler = async ( + req: Request, + res: Response, + next: NextFunction + ): Promise => { + try { + const userId = req.params.userId; + const tasks = await this.userService.getUsers(userId); + const responseList = tasks.map(task => new TaskResumedRes(task)); + res.status(201).send(responseList); + + } + catch(error){ + next(new HttpException(400, 'Cannot get user task')); + } + + } + + private deleteUser = async ( + req: Request, + res: Response, + next: NextFunction + ): Promise => { + try { + const id = req.params.taskId; + const userId = req.params.userId; + await this.userService.DeleteUser(id, userId); + return res.status(200).send({ status: "Success", msg: "Data Removed" }); + } catch (error) { + next(new HttpException(400, 'Cannot create post')); + } + }; + + private updateUser = async ( + req: Request, + res: Response, + next: NextFunction + ): Promise => { + try { + + const taskId = req.params.taskId; + const userId = req.params.userId; + const reqBody:CreateTaskReqBody = Object.assign({}, req.body); + + const updatedTask = await this.userService.UpdateTask( + // req.auth!.uid, + taskId, + userId, + // firebase.auth().currentUser.getIdToken() + reqBody.nom, + reqBody.description, + reqBody.logo, + reqBody.duration, + reqBody.done, + // reqBody.tags, + reqBody.repepat, + reqBody.deb, + reqBody.fin + ); + // res.send('Success add'); + // res.status(201).json({ task }); + res.status(204).send(`Update a new contact: ${updatedTask}`); + } catch (error) { + console.log(error); + next(new HttpException(403, 'Cannot create post')); + } + }; + + + + private getUserNext: RequestHandler = async ( + req: Request, + res: Response, + next: NextFunction + ): Promise => { + try { + const longitude = Number(req.body.longitude); + const latitude = Number(req.body.latitude); + //verify::val_int(){ + if (isNaN(longitude) || isNaN(latitude)) { + console.log('Impossible de convertir la chaîne en nombre'); + } + //} + const userId = req.body.userId; + const data = await this.locationService.getNearUser(userId,latitude,longitude); + console.log(data); + res.status(201).send(data); + + } + catch(error){ + next(new HttpException(400, 'Cannot create post')); + } + + } + +} + +export default TaskController; \ No newline at end of file diff --git a/Api/src/database/MongoDataBase.ts b/Api/src/database/MongoDataBase.ts new file mode 100644 index 0000000..1e9bd7d --- /dev/null +++ b/Api/src/database/MongoDataBase.ts @@ -0,0 +1,3 @@ +const uri = "mongodb+srv://fladDevDb:ZslYlNRWIOUU7i6o@fladcluster.b29tytu.mongodb.net/?retryWrites=true&w=majority" + +export default db = new MongoClient(uri); \ No newline at end of file diff --git a/Api/src/database/schema/NotificationSchema.ts b/Api/src/database/schema/NotificationSchema.ts new file mode 100644 index 0000000..7aa9525 --- /dev/null +++ b/Api/src/database/schema/NotificationSchema.ts @@ -0,0 +1,6 @@ +const notificationSchema = new mongoose.Schema({ + type: {type: String, required: true}, + content: {type: String, required: true} +}); + +export default {Annonce: mongoose.model("nofitication", notificationSchema)} \ No newline at end of file diff --git a/Api/src/database/schema/UserSchema.ts b/Api/src/database/schema/UserSchema.ts new file mode 100644 index 0000000..27153b8 --- /dev/null +++ b/Api/src/database/schema/UserSchema.ts @@ -0,0 +1,21 @@ + +const userSchema: Schema = new mongoose.Schema({ + pseudo: {type: String, index: { unique: true }}, + email: {type: String}, + idDafl: {type: String, index: { unique: true }}, + idSpotify: {type: String}, + password: {type: String}, + prenom: {type: String, default: ""}, + description: {type: String, default: ""}, + nom: {type: String, default: ""}, + ville: {type: String, default: ""}, + profilPic: {type: String}, + noteList: [], + notifications: [], + friends: {type: [String] }, + favoris: [], + conversations: {type: [String] } +}); +// fladDevDb +// ZslYlNRWIOUU7i6o +export const User: Model = model('User', userSchema); diff --git a/Api/src/model/IUser.ts b/Api/src/model/IUser.ts new file mode 100644 index 0000000..2084e48 --- /dev/null +++ b/Api/src/model/IUser.ts @@ -0,0 +1,5 @@ +export default interface IUser{ + name: string; + email: string; + avatar?: string; + } \ No newline at end of file diff --git a/Api/src/model/locationModel.ts b/Api/src/model/locationModel.ts new file mode 100644 index 0000000..99fb3ca --- /dev/null +++ b/Api/src/model/locationModel.ts @@ -0,0 +1,57 @@ +export interface Position { + /** + * Creation timestamp for coords + */ + timestamp: number; + /** + * The GPS coordinates along with the accuracy of the data + */ + coords: { + /** + * Latitude in decimal degrees + */ + latitude: number; + /** + * longitude in decimal degrees + */ + longitude: number; + }; +} +export class PlacePosition implements Position { + timestamp: number; + coords: { + latitude: number; + longitude: number; + }; + constructor(timestamp: number,latitude : number ,longitude: number){ + this.timestamp = timestamp; + this.coords = {latitude, longitude}; + } +} +export class UserLocation { + uuid: string; + latitude : number; + longitude: number; + constructor(uuid: string, latitude: number, longitude: number){ + this.uuid = uuid; + this.latitude = latitude; + this.longitude = longitude; + } +} + +export class Place{ +position: Position; +address: Address; +constructor(address: Address,position: Position){ + this.position = position; + this.address = address; +} +} + + +export type Address = { +street : string; +city : string; +state : string; +zip : string; +} \ No newline at end of file diff --git a/Api/src/service/LocationService.ts b/Api/src/service/LocationService.ts new file mode 100644 index 0000000..dd12d59 --- /dev/null +++ b/Api/src/service/LocationService.ts @@ -0,0 +1,136 @@ +// import db from '../database'; +import { Place, PlacePosition, Position, UserLocation } from '../model/locationModel'; +import axios from 'axios'; + +class LocationService { + private API_KEY : string = "AIzaSyBFCEAtmhZ8jvw84UTQvX3Aqpr66GVqB_A"; + public async getNearUser(uuid : string, latitude : number, longitude : number) + { + const UserCollectionref = db.collection('UserPosition'); + db.collection('UserPosition').doc(uuid).set({uuid : uuid, latitude : latitude, longitude : longitude}); + // const newPosition = { + // name: 'Los Angeles', + // state: 'CA', + // country: 'USA' + // }; + const snapshot = await UserCollectionref.where("uuid", "!=", uuid).get(); + if (snapshot.empty) { + console.log('No matching documents.'); + return; + } + + let dbUsersList:UserLocation[] = []; + snapshot.forEach(doc => { + dbUsersList.push(new UserLocation(doc.data().uuid,doc.data().latitude,doc.data().longitude)); + console.log(doc.id, '=>', doc.data()); + }); + + let listUser: string[] = []; //Set the listUser to an empty list + dbUsersList.forEach(user => { + console.log(user); + const dist = this.distanceBetween(latitude , longitude , user.latitude, user.longitude); //With the function meters, determinate the distance between the current user and the user who is in the actual row + console.log(user.uuid,dist); + if (dist <= 5) { //If the user in the actual row is less than 100 meters away of the current user + + listUser.push(user.uuid); //Add the username and the ID of the song that user who is in the actual row is listening + + } + }); + + + return listUser; //Return an array + // $listUser[] = ['user' => $userID, 'music' => $idMusic]; //Add the username and the ID of the song that user who is in the actual row is listening + + } + + public getCenter (points: Position[]) { + if (Array.isArray(points) === false || points.length === 0) { + return false; + } + + const numberOfPoints = points.length; + + const sum = points.reduce( + (acc, point) => { + const pointLat = this.toRad(point.coords.latitude); + const pointLon = this.toRad(point.coords.longitude); + return { + X: acc.X + Math.cos(pointLat) * Math.cos(pointLon), + Y: acc.Y + Math.cos(pointLat) * Math.sin(pointLon), + Z: acc.Z + Math.sin(pointLat), + }; + }, + { X: 0, Y: 0, Z: 0 } + ); + + const X = sum.X / numberOfPoints; + const Y = sum.Y / numberOfPoints; + const Z = sum.Z / numberOfPoints; + + return { + longitude: this.toDeg(Math.atan2(Y, X)), + latitude: this.toDeg(Math.atan2(Z, Math.sqrt(X * X + Y * Y))), + }; + }; + + public toRad = (value: number) => (value * Math.PI) / 180; + public toDeg = (value: number) => (value * 180) / Math.PI; + + // sa c'est un utils du coup mettre dans une calss utils + // resulta en km + private distanceBetween (lat1 : number, lon1 : number, lat2: number, lon2 : number) : number { + if ((lat1 == lat2) && (lon1 == lon2)) { + return 0; + } + else { + var radlat1 = Math.PI * lat1/180; + var radlat2 = Math.PI * lat2/180; + var theta = lon1-lon2; + var radtheta = Math.PI * theta/180; + var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta); + + if (dist > 1) { + dist = 1; + } + + dist = Math.acos(dist); + dist = dist * 180/Math.PI; + dist = dist * 60 * 1.1515; + dist = dist * 1.609344; + + return dist; + } + } + private distanceBetweenPosition(first : Position, second : Position) : number { + return this.distanceBetween (first.coords.latitude, first.coords.longitude, second.coords.latitude, second.coords.longitude) + } + + // give a array of position sorted by distance and return the first + private findNearest(main : Position, list : Position[]){ + this.orderByDistance(main, list)[0] + } + + //distanceFn: DistanceFn = getDistance est param sa serrait cool de lui passer un fonction + private orderByDistance (mainPos: Position,coords: Position[]){ + return coords + .slice() + .sort((a, b) => this.distanceBetweenPosition(mainPos, a) - this.distanceBetweenPosition(mainPos, b)); + }; + + // getCenter(coords) + + + + +} + + + +export default LocationService; + + + + + + + \ No newline at end of file diff --git a/Api/src/service/UserService.ts b/Api/src/service/UserService.ts new file mode 100644 index 0000000..e69de29 diff --git a/FLAD/Model/Manager.tsx b/FLAD/Model/Manager.tsx index e137aa1..ea92241 100644 --- a/FLAD/Model/Manager.tsx +++ b/FLAD/Model/Manager.tsx @@ -1,111 +1,111 @@ -// import { useState } from "react"; -// import SpotifyService from "../services/spotify/spotify.service"; +import { useState } from "react"; +import SpotifyService from "../services/spotify/spotify.service"; -// class Manager{ +class Manager{ -// // injection de dépences -// spotifyService = new SpotifyService(); -// userService = new userService(); + // injection de dépences + spotifyService = new SpotifyService(); + userService = new userService(); -// private currentUser = useState(null); + private currentUser = useState(null); -// constructor() { -// } + constructor() { + } -// // spotify methods -// apiAuthorization(url : string) { -// spotifyService.apiAuthorization(url); -// } + // spotify methods + apiAuthorization(url : string) { + spotifyService.apiAuthorization(url); + } -// getCompleteMusic = async (id : string) :Promise =>{ -// // Map info = await spotifyService.getTrackInfo(id); -// // return Music(id, info['name'], info['artist'], info['cover']); -// } + getCompleteMusic = async (id : string) :Promise =>{ + // Map info = await spotifyService.getTrackInfo(id); + // return Music(id, info['name'], info['artist'], info['cover']); + } -// removeFromPlaylist(id : string) { -// this.spotifyService.removeFromPlaylist(id); -// } + removeFromPlaylist(id : string) { + this.spotifyService.removeFromPlaylist(id); + } -// addToPlaylist(id : string) { -// this.spotifyService.addToPlaylist(id); -// } + addToPlaylist(id : string) { + this.spotifyService.addToPlaylist(id); + } -// playTrack(id : string) { -// this.spotifyService.playTrack(id); -// } -// //////////////////////////////////////////// + playTrack(id : string) { + this.spotifyService.playTrack(id); + } + //////////////////////////////////////////// -// // private readonly getTaskById: RequestHandler = async ( -// // req: Request, -// // res: Response, -// // next: NextFunction -// // ): Promise => { -// // try { -// // const id = req.params.taskId; -// // const userId = req.params.userId; + // private readonly getTaskById: RequestHandler = async ( + // req: Request, + // res: Response, + // next: NextFunction + // ): Promise => { + // try { + // const id = req.params.taskId; + // const userId = req.params.userId; -// // const data = await this.Taskservice.getTaskById(id, userId); -// // res.status(201).send(data); + // const data = await this.Taskservice.getTaskById(id, userId); + // res.status(201).send(data); -// // } -// // catch(error){ -// // next(new HttpException(400, 'Cannot create post')); -// // } + // } + // catch(error){ + // next(new HttpException(400, 'Cannot create post')); + // } -// // } + // } -// // private delete = async ( -// // req: Request, -// // res: Response, -// // next: NextFunction -// // ): Promise => { -// // try { -// // const id = req.params.taskId; -// // const userId = req.params.userId; -// // await this.Taskservice.DeleteTask(id, userId); -// // return res.status(200).send({ status: "Success", msg: "Data Removed" }); -// // } catch (error) { -// // next(new HttpException(400, 'Cannot create post')); -// // } -// // }; + // private delete = async ( + // req: Request, + // res: Response, + // next: NextFunction + // ): Promise => { + // try { + // const id = req.params.taskId; + // const userId = req.params.userId; + // await this.Taskservice.DeleteTask(id, userId); + // return res.status(200).send({ status: "Success", msg: "Data Removed" }); + // } catch (error) { + // next(new HttpException(400, 'Cannot create post')); + // } + // }; -// // private updateTask = async ( -// // req: Request, -// // res: Response, -// // next: NextFunction -// // ): Promise => { -// // try { + // private updateTask = async ( + // req: Request, + // res: Response, + // next: NextFunction + // ): Promise => { + // try { -// // const taskId = req.params.taskId; -// // const userId = req.params.userId; -// // const reqBody:CreateTaskReqBody = Object.assign({}, req.body); + // const taskId = req.params.taskId; + // const userId = req.params.userId; + // const reqBody:CreateTaskReqBody = Object.assign({}, req.body); -// // const updatedTask = await this.Taskservice.UpdateTask( -// // // req.auth!.uid, -// // taskId, -// // userId, -// // // firebase.auth().currentUser.getIdToken() -// // reqBody.nom, -// // reqBody.description, -// // reqBody.logo, -// // reqBody.duration, -// // reqBody.done, -// // // reqBody.tags, -// // reqBody.repepat, -// // reqBody.deb, -// // reqBody.fin -// // ); -// // // res.send('Success add'); -// // // res.status(201).json({ task }); -// // res.status(204).send(`Update a new contact: ${updatedTask}`); -// // } catch (error) { -// // console.log(error); -// // next(new HttpException(403, 'Cannot create post')); -// // } -// // }; + // const updatedTask = await this.Taskservice.UpdateTask( + // // req.auth!.uid, + // taskId, + // userId, + // // firebase.auth().currentUser.getIdToken() + // reqBody.nom, + // reqBody.description, + // reqBody.logo, + // reqBody.duration, + // reqBody.done, + // // reqBody.tags, + // reqBody.repepat, + // reqBody.deb, + // reqBody.fin + // ); + // // res.send('Success add'); + // // res.status(201).json({ task }); + // res.status(204).send(`Update a new contact: ${updatedTask}`); + // } catch (error) { + // console.log(error); + // next(new HttpException(403, 'Cannot create post')); + // } + // }; -// } +} -// export default Manager; \ No newline at end of file +export default Manager; \ No newline at end of file diff --git a/FLAD/package-lock.json b/FLAD/package-lock.json index c90b1db..c7086ae 100644 --- a/FLAD/package-lock.json +++ b/FLAD/package-lock.json @@ -16,6 +16,7 @@ "expo-cli": "^6.1.0", "expo-haptics": "~12.0.1", "expo-linear-gradient": "~12.0.1", + "expo-location": "~15.0.1", "expo-random": "~13.0.0", "expo-secure-store": "~12.0.0", "expo-status-bar": "~1.4.2", @@ -10116,6 +10117,14 @@ "url-parse": "^1.5.9" } }, + "node_modules/expo-location": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/expo-location/-/expo-location-15.0.1.tgz", + "integrity": "sha512-GOAP24m8fMahFcBT75H07f2+IQAOCOdNTzb8Ci/19NZ+Y/CY2lIvb55V8zu7Gn0+76FKPb7XC3ebQaq4ctn1QA==", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-modules-autolinking": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-1.0.2.tgz", @@ -31188,6 +31197,12 @@ "url-parse": "^1.5.9" } }, + "expo-location": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/expo-location/-/expo-location-15.0.1.tgz", + "integrity": "sha512-GOAP24m8fMahFcBT75H07f2+IQAOCOdNTzb8Ci/19NZ+Y/CY2lIvb55V8zu7Gn0+76FKPb7XC3ebQaq4ctn1QA==", + "requires": {} + }, "expo-modules-autolinking": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-1.0.2.tgz", diff --git a/FLAD/package.json b/FLAD/package.json index 7b56a2f..37af788 100644 --- a/FLAD/package.json +++ b/FLAD/package.json @@ -28,7 +28,8 @@ "react-native-screens": "~3.18.0", "react-native-web": "~0.18.9", "rive-react-native": "^3.0.41", - "expo-secure-store": "~12.0.0" + "expo-secure-store": "~12.0.0", + "expo-location": "~15.0.1" }, "devDependencies": { "@babel/core": "^7.12.9", diff --git a/FLAD/pages/login.tsx b/FLAD/pages/login.tsx index c140153..e3d2aaf 100644 --- a/FLAD/pages/login.tsx +++ b/FLAD/pages/login.tsx @@ -27,7 +27,7 @@ interface Params { id: string; } //generate random string - const MY_SECURE_AUTH_STATE_KEY = 'MySecureAuthStateKey'; + export const MY_SECURE_AUTH_STATE_KEY = 'MySecureAuthStateKey'; WebBrowser.maybeCompleteAuthSession(); @@ -42,6 +42,7 @@ async function save(key : string, value : string) { await SecureStore.setItemAsync(key, value); } + export default function Login() { // const [advice, setAdvice] = useState("dd"); const [request, response, promptAsync] = useAuthRequest( @@ -87,9 +88,9 @@ export default function Login() { /> ); - }; +}; - const styles = StyleSheet.create({ +const styles = StyleSheet.create({ centeredView: { justifyContent: 'center', alignItems: 'center', @@ -132,5 +133,5 @@ export default function Login() { justifyContent : 'center' } - }) +}) diff --git a/FLAD/pages/spot.tsx b/FLAD/pages/spot.tsx index e8cba9b..66f5752 100644 --- a/FLAD/pages/spot.tsx +++ b/FLAD/pages/spot.tsx @@ -1,5 +1,5 @@ import { View, Text, Image, Animated ,PanResponder, Dimensions, StyleSheet, ImageBackground, Button, Pressable } from 'react-native' -import React, { useCallback, useRef, useState, useTransition } from 'react' +import React, { useCallback, useEffect, useRef, useState, useTransition } from 'react' import { LinearGradient } from 'expo-linear-gradient'; import * as Haptics from 'expo-haptics'; @@ -7,10 +7,82 @@ import Card from '../components/Card'; import { cards as cardArray } from '../FakeData/data' import FladButton from '../components/button/button'; +import axios from 'axios'; + +import * as SecureStore from 'expo-secure-store'; +import { MY_SECURE_AUTH_STATE_KEY } from './login'; + +import * as Location from 'expo-location'; + interface SpotProps { } +type LocationData = { + latitude: number; + longitude: number; + timestamp: number; +} + +interface NearbyUser { + id: number; + name: string; + latitude: number; + longitude: number; +} + +async function getUserData(accessToken : string) { + axios.get("https://api.spotify.com/v1/me", + { + headers: { + 'Authorization': 'Bearer ' + accessToken, + "Content-Type" : "application/json" + }}) + .then(response => + { + if (response && response.statusText === 'success') { + console.log(response.data.message); + const userData = JSON.stringify(response.data); + const userId = response.data.id; + return {userId, userData} + } + }) + .catch(function (error) { + console.log(error); + }); + +}; +// async function sendUserLoc(accessToken : string) { +// axios.get("https://api.spotify.com/v1/me", +// { +// headers: { +// 'Authorization': 'Bearer ' + accessToken, +// "Content-Type" : "application/json" +// }}) +// .then(response => +// { +// if (response && response.statusText === 'success') { +// console.log(response.data.message); +// const userData = JSON.stringify(response.data); +// const userId = response.data.id;} + +// }) +// .catch(function (error) { +// console.log(error); +// }); +// }; + +async function getValueFor(key:string) :Promise { + let result = await SecureStore.getItemAsync(key); + if (result) { + alert("🔐 Here's your value 🔐 \n" + result); + } else { + + alert('No values stored under that key.'); + } + return result; +} + export default function Spot() { const [cards, setCards] = useState(cardArray); const [currentCard, setcurrentCard] = useState(cards[cards.length - 1]); @@ -26,12 +98,57 @@ export default function Spot() { setcurrentCard(cards[cards.length -1]); }; - const hapti = (() => { - + const hapti = (() => { + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy) + getValueFor(MY_SECURE_AUTH_STATE_KEY) + .then(key => { (key != null) ? getUserData(key) :console.log("error key is nullll") } ) ; // Haptics.NotificationFeedbackType.Success - Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy) - }); + }); + +//////////////////////////////////////////////////////////////// + const [locationData, setLocationData] = useState(); + const [prevLocationData, setPrevLocationData] = useState(); + const [nearbyUsers, setNearbyUsers] = useState([]); + const [currentMusic, setCurrentMusic] = useState(""); + + async function getLocation() { + var { status } = await Location.requestForegroundPermissionsAsync(); + if (status !== 'granted') { + console.log('Permission to access location was denied'); + return; + } + let currentLocation = await Location.getCurrentPositionAsync({}); + setLocationData({ + latitude: currentLocation.coords.latitude, + longitude: currentLocation.coords.longitude, + timestamp: currentLocation.timestamp + }); + }; + async function sendLocationToServer() { + getLocation(); + if (!locationData) return; + if (prevLocationData && locationData.latitude === prevLocationData.latitude && locationData.longitude === prevLocationData.longitude) { + return; + } + try { + const response = await axios.post( + 'http://localhost/api/users/david/nextToMe', + locationData + ); + + if (response.status !== 200) { + throw new Error('Failed to send location to server'); + } + + setPrevLocationData(locationData); + setNearbyUsers(response.data); + } catch (error) { + console.error(error); + } + }; + + setInterval(sendLocationToServer, 30000) return ( @@ -87,7 +204,7 @@ export default function Spot() { ); - }; +}; const styles = StyleSheet.create({ spot : { flex: 1,