final ftc commit : all look good

MqqtMessage
David D'ALMEIDA 2 years ago
parent 8e102f7966
commit f7e101eb94

@ -4,12 +4,11 @@ import AuthNavigation from './navigation/AuthNavigation';
import * as SplashScreen from 'expo-splash-screen';
SplashScreen.preventAutoHideAsync();
export default function App() {
return (
<Provider store={store}>
<AuthNavigation/>
</Provider>
);
}

@ -5,7 +5,7 @@ export default class MusicFactory {
const music = new Music(
jsonMusic.id,
jsonMusic.name,
"",
jsonMusic.artists[0].name,
jsonMusic.album.images[0].url,
jsonMusic.preview_url
);

@ -0,0 +1,7 @@
Object.defineProperty(exports, '__esModule', {value: true});
require('./mqttLib');
const storage = require('./storage');
function initialize() {
global.localStorage = storage;
}
exports.default = initialize;

File diff suppressed because it is too large Load Diff

@ -0,0 +1,10 @@
const storage = {
setItem: (key, item) => {
storage[key] = item;
},
getItem: key => storage[key],
removeItem: key => {
delete storage[key];
},
};
export default storage;

@ -8,8 +8,12 @@ import * as SplashScreen from 'expo-splash-screen';
import { ChangeMode, getRefreshToken } from '../redux/thunk/authThunk';
import * as Location from 'expo-location';
import SpotifyService from '../services/spotify/spotify.service';
import { getCurrentUserMusic } from '../redux/thunk/spotThunk';
import { getCurrentUserMusic, getSpotList } from '../redux/thunk/spotThunk';
import Music from '../Model/Music';
import axios from 'axios';
import qs from 'qs';
import * as SecureStore from 'expo-secure-store';
import { MY_SECURE_AUTH_STATE_KEY } from '../screens/Register';
export default function AuthNavigation() {
//@ts-ignore
@ -18,6 +22,8 @@ export default function AuthNavigation() {
const isLogin: boolean = useSelector(state => state.userReducer.isLogedIn);
//@ts-ignore
const currentMusic: Music = useSelector(state => state.appReducer.userCurrentMusic);
//@ts-ignore
const tokenSend: string = useSelector(state => state.userReducer.userFladToken);
const [appIsReady, setAppIsReady] = useState(false);
const dispatch = useDispatch();
@ -45,38 +51,68 @@ export default function AuthNavigation() {
console.log(`Une erreur s'est produite lors de la mise à jour de la valeur booléenne pour la clé 'dark': `, error);
}
}
const requestLocationPermission = async () => {
const { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
console.log('Permission to access location was denied');
} else {
console.log('Permission to access location was granted');
}
}
console.log(currentMusic + 'luuuuuuuiii')
useEffect(() => {
ChangeDarkMode();
prepare();
}, [appIsReady, tokenProcesed]);
useEffect(() => {
requestLocationPermission();
const sendLocationUpdate = async () => {
try {
let tmpKey: string = await SecureStore.getItemAsync(MY_SECURE_AUTH_STATE_KEY) ;
//@ts-ignore
await dispatch(getCurrentUserMusic(theService))
await dispatch(getCurrentUserMusic(new SpotifyService(tmpKey)))
let { status } = await Location.requestForegroundPermissionsAsync();
if (status == 'granted') {
console.log(appIsReady)
if (true) {// should app is ready
// should app is ready
const locationresp = await Location.getCurrentPositionAsync({});
setLocation(locationresp);
// send location to server
console.log(locationresp);
console.log(location);
if(currentMusic){
const body: Record<string, string | boolean | number | (string | boolean | number)[]> = {
longitude: locationresp.coords.longitude,
latitude: locationresp.coords.latitude,
currentMusic: currentMusic.id
}
console.log('===========================================================================================================')
console.log(body)
console.log('===========================================================================================================')
const resp = await axios({
url: 'https://flad-api-production.up.railway.app/api/users/nextTo?' + qs.stringify(body),
method: 'GET',
headers: {
Authorization: `Bearer ${tokenSend}`,
},
});
const datat: Record<string, string> = resp.data.listUser2;
//@ts-ignore
dispatch(getSpotList(datat, new SpotifyService(tmpKey)))
}
else{
return;
}
}
else {
//@ts-ignore
let {status} = Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
setErrorMsg('Permission to access location was denied');
return;
}
return;
}
} catch (error) {
console.log(error);
}
@ -85,21 +121,21 @@ export default function AuthNavigation() {
return () => {
clearInterval(interval);
};
}, []);
}, [appIsReady, tokenProcesed, currentMusic]);
if (tokenProcesed == false) {
return null;
}
return (
<SafeAreaProvider onLayout={() => setAppIsReady(true)}>
{isLogin ? (
<Navigation />
) :
<Navigation />
<StartNavigation/>
}
</SafeAreaProvider>
)
}
const theService = new SpotifyService('BQC0rAGJvxTt4-24P-nda6qP9iXYCql2eApnUAoEbZZkKemJ11cU3Nx-I_tKVX0FwEgFbIbSIuaVvxOapRVJq2z1Htyy3XQ5jIYNsrhrnp3KTCfppamAjxgDTf6khBrNGTxe6CNKBsMhc5IRnphey5Td2zJPvGMwnFFfMQdCtVAVsCNK7kPKlCAaf_kRMAoPn30Qk4RD45XmwtZIwQg7X0J4beGuHSiBf0MRjhsnFEW89GxVm8YuIVwgrDbF3izfPR0AlqS4IMJT5m4pEA72lYEwp1JnSDVsafILzmksaqG-11H3WAsWIENrOIu_j7qNgbvYwmUWXOrYmeWBkQ');

@ -1,6 +1,6 @@
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import SpotPage from '../screens/Spot'
import SpotPage from '../screens/spot'
import MusicDetail from '../screens/MusicDetail';

@ -49,7 +49,8 @@
"react-native-web": "~0.18.9",
"react-navigation-shared-element": "^3.1.3",
"react-redux": "^8.0.5",
"redux": "^4.2.1"
"redux": "^4.2.1",
"expo-linking": "~3.3.1"
},
"devDependencies": {
"@babel/core": "^7.12.9",

@ -9,6 +9,19 @@ export const setSpotList = (spotList: Spot[]) => {
payload: spotList,
};
}
export const removeFromSpotList = (spot: Spot) => {
return {
type: spotTypes.REMOVE_SPOT,
payload: spot
}
}
export const addSpotListMock = (spotList: Spot[]) => {
return {
type: spotTypes.ADD_SPOT_MOCK,
payload: spotList,
};
}
export const setUserCurrentMusic = (currentMusic: Music) => {
return {

@ -5,15 +5,9 @@ import { favoritesTypes } from "../types/favoritesTypes";
import { spotifyTypes } from "../types/spotifyTypes";
import { spotTypes } from "../types/spotTypes";
let tmpMusic: Music[] = [
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("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,
favoriteMusic: [] as Music[],
userCurrentMusic: null
}
@ -26,7 +20,13 @@ const appReducer = (state = initialState, action: any) => {
case favoritesTypes.REMOVE_FAVORITE_MUSICS:
return { ...state, favoriteMusic: state.favoriteMusic };
case spotTypes.FETCH_SPOT:
return { ...state, spot: action.payload };
const uniqueSpots = action.payload.filter((spot) => {
return !state.spot.some((s) => s.userSpotifyId === spot.userSpotifyId && s.music.id === spot.music.id);
});
const updatedSpotList = [...uniqueSpots, ...state.spot];
return { ...state, spot: updatedSpotList };
case spotTypes.REMOVE_SPOT:
return { ...state, spot: state.spot.filter((spot) => spot.userSpotifyId !== action.payload.userSpotifyId && spot.music.id !== action.payload.music.id) };
case discoveriesTypes.FETCH_DISCOVERIES:
return;
case spotifyTypes.GET_USER_CURRENT_MUSIC:

@ -10,13 +10,17 @@ export const registerUser = (resgisterCredential: CredentialsRegister) => {
//@ts-ignore
return async dispatch => {
try {
console.log("rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr")
console.log(resgisterCredential);
console.log("rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr")
const config = {
headers: {
'Content-Type': 'application/json',
},
}
const resp = await axios.post(
`${API_URL}/api/users/register`,
'https://flad-api-production.up.railway.app/api/users/register',
resgisterCredential,
config
)
@ -37,6 +41,7 @@ export const registerUser = (resgisterCredential: CredentialsRegister) => {
}
} catch (error) {
console.log('Login Failed'+ error.message + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
dispatch(ChangeErrorSignup())
}
}

@ -12,26 +12,16 @@ export type CreateSpotReqBody = {
linkCover: string;
user: string;
}
export const getSpotList = (resuestHandler: SpotifyService) => {
export const getSpotList = (spotsData : Record<string, string> , resuestHandler: SpotifyService) => {
console.log('oooooooooooooooooooooooooooostrat2oooooooooooooooooooooooooooooooooooo')
//@ts-ignore
return async dispatch => {
try {
//@ts-ignore
const userToken: string = await SecureStore.getItemAsync(key);
const headers = {
'Authorization': 'Bearer ' + userToken
};
const data = await axios.get(
"https://flad-api-production.up.railway.app/api/users/nextTo",
{ headers }
)
if (data.data.token) {
const spotsData: { [userId: string]: string } = {};
if (spotsData) {
for (const item of data.data) {
spotsData[item.user] = item.music;
}
const spots = await Promise.all(
Object.entries(spotsData).map(async ([userId, value]) => {
const completeMusic = await resuestHandler.getMusicById(value);
@ -64,6 +54,9 @@ export const getCurrentUserMusic = (resuestHandler: SpotifyService) => {
}
}
const completeMusic = await resuestHandler.getMusicById(currentTrackResponse);
if(!completeMusic){
return;
}
dispatch(setUserCurrentMusic(completeMusic));
}
catch (error) {

@ -1,3 +1,5 @@
export const spotTypes = {
FETCH_SPOT: 'FETCH_SPOT',
ADD_SPOT_MOCK: 'ADD_SPOT_MOCK',
REMOVE_SPOT: 'REMOVE_SPOT',
}

@ -18,20 +18,15 @@ const DismissKeyboard = ({ children }) => (
</TouchableWithoutFeedback>
)
export const MY_SECURE_AUTH_STATE_KEY = 'MySecureAuthStateKey';
export const MY_SECURE_AUTH_STATE_KEY = 'MySecureAuthStateKeySpotify';
export const MY_SECURE_AUTH_STATE_KEY_REFRESH = 'MySecureAuthStateKeySpotifyREFRESH';
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 [sound, setSound] = useState<Audio.Sound>();
const navigation = useNavigation();
@ -46,34 +41,10 @@ export default function InscriptionPage() {
setSound(sound);
await sound.playAsync();
}
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
//spotify auth
const [response] = 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]);
const dispatch = useDispatch();
@ -83,7 +54,7 @@ export default function InscriptionPage() {
password: password,
idSpotify: spotifyToken,
name: username,
idFlad: "3030"
idFlad: "9835698"
};
//@ts-ignore
dispatch(registerUser(credentials))
@ -91,19 +62,24 @@ export default function InscriptionPage() {
}
const getTokens2 = async () => {
try {
const response = await fetch('https://flad-api-production.up.railway.app/api/spotify/callback');
const responseJson = await response.json();
const redirectUri = AuthSession.makeRedirectUri();
const result = await AuthSession.startAsync({
authUrl: 'https://flad-api-production.up.railway.app/api/spotify/exchange?' + '&redirectUrl=' +
encodeURIComponent(redirectUri)
})
const {
access_token: accessToken,
} = responseJson;
await setSpotifyToken(accessToken);
console.log(spotifyToken);
access_token: access_token,
refresh_token: refresh_token,
} = result.params
save(MY_SECURE_AUTH_STATE_KEY, access_token);
setSpotifyToken(access_token)
save(MY_SECURE_AUTH_STATE_KEY_REFRESH, refresh_token);
} catch (err) {
console.error(err);
}
}
return (
<DismissKeyboard>
<View style={styles.container}>

@ -332,7 +332,7 @@ export default function Setting() {
</View>
<View style={styles.musicActually}>
<CardMusic image="{currentMusic.image}" title="{currentMusic.title}" description="PNL" id='1' />
<CardMusic image={currentMusic.image} title={currentMusic.title} description={currentMusic.bio} id='1' />
<Image source={require("../assets/images/FladyShadow.png")} style={styles.mascot} />
</View>

@ -6,8 +6,6 @@ import { makeRedirectUri, useAuthRequest } from 'expo-auth-session';
import { Buffer } from 'buffer';
import * as SecureStore from 'expo-secure-store';
export const MY_SECURE_AUTH_STATE_KEY = 'MySecureAuthStateKey'
WebBrowser.maybeCompleteAuthSession()
const discovery = {

@ -1,5 +1,5 @@
import { View, Text, Dimensions, StyleSheet, ImageBackground, Pressable, TouchableOpacity, SafeAreaView } from 'react-native'
import React, { useCallback, useRef, useState } from 'react'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { LinearGradient } from 'expo-linear-gradient';
import * as Haptics from 'expo-haptics';
import Animated from 'react-native-reanimated';
@ -13,30 +13,39 @@ import FladLoading from '../components/FladLoadingScreen';
import { useNavigation } from '@react-navigation/native';
import Music from '../Model/Music';
import { addFavoritesMusic } from '../redux/actions/appActions';
import { useDispatch } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { Spot } from '../Model/Spot';
import { removeFromSpotList, setSpotList } from '../redux/actions/spotActions';
export default function SpotPage() {
const [cards, setCards] = useState(spotArray2);
//@ts-ignore
const spotReducer = useSelector(state => state.appReducer.spot)
const [cards, setCards] = useState<Spot[]>(spotReducer);
const [currentCard, setcurrentCard] = useState(cards[cards.length - 1]);
useEffect(() => {
console.log(cards.length + "================================== cards");
console.log(spotReducer.length + "================================== spotReducer")
setCards(spotReducer);
// update the state of the cards state variable
setcurrentCard(spotReducer[spotReducer.length - 1]);
}, [spotReducer]);
const onSwipe = (index: number, direction: 'left' | 'right' | 'down') => {
if (direction === 'right') {
// Swiped right
addLike(currentCard.music);
addLike(currentCard);
} else if (direction === 'left') {
// Swiped left
console.log('Swiped left');
removeSpots(currentCard);
}
else if (direction === 'down') {
// Swiped down
addMockSpots();
console.log('Swiped down');
}
// update the state of the cards state when it remove this
setTimeout(() => {
setCards(cards.filter((_, i) => i !== index));
setcurrentCard(cards[index - 1]);
}, 3);
};
const likeButtonref = useRef<LottieView>(null);
@ -47,11 +56,22 @@ export default function SpotPage() {
}, [])
const dispatch = useDispatch();
function addLike(music: Music) {
function addLike(spot: Spot) {
onLike();
dispatch(addFavoritesMusic(music))
dispatch(addFavoritesMusic(spot.music))
dispatch(removeFromSpotList(spot));
}
function removeSpots(spot: Spot) {
dispatch(removeFromSpotList(spot));
}
function addMockSpots() {
//@ts-ignore
dispatch(setSpotList(spotArray2))
}
const navigator = useNavigation();
const { width: wWidht } = Dimensions.get("window");
@ -106,7 +126,6 @@ export default function SpotPage() {
{cards.map((card, index) => (
<View key={card.userSpotifyId} style={{ position: 'absolute' }} >
<Pressable onLongPress={() => { hapti(card) }} >
<Card
title={card.music.title}
@ -124,7 +143,7 @@ export default function SpotPage() {
<TouchableOpacity style={styles.button} onPress={onLike}>
<LottieView autoPlay={false} loop={false} ref={likeButtonref} source={Lotties.likeAnimation} style={styles.lottie} />
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={onLike}>
<TouchableOpacity style={styles.button} onPress={addMockSpots}>
<LottieView autoPlay={false} loop={false} ref={likeButtonref} source={Lotties.likeAnimation} style={styles.lottie} />
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={onLike}>

@ -0,0 +1,11 @@
// function onSubscribeHandler() {
// MqttClient.onSubscribe(subscribeTopic, onSubscribe);
// }
// function onPublishHandler() {
// MqttClient.onPublish(publishTopic, publishPayload);
// }
// function unSubscribeHandler() {
// MqttClient.unsubscribe(subscribeTopic);
// }

@ -1,4 +1,6 @@
import axios, { AxiosResponse } from "axios";
import { MY_SECURE_AUTH_STATE_KEY, MY_SECURE_AUTH_STATE_KEY_REFRESH } from "../../../screens/Register";
import * as SecureStore from 'expo-secure-store';
export type Methods = 'GET' | 'POST' | 'DELETE' | 'PUT' | 'PATCH';
@ -32,10 +34,45 @@ export class RequestHandler {
},
data: options.body
});
return resp;
}
catch(error : any){}
catch(error : any){
const errorMessage = error.response.data?.error?.message;
if (errorMessage === "Invalid access token" || errorMessage === "The access token expired" ) {
console.log('### Warning ! ### try refresh token Request Handler ' +error);
const newToken = await this.refreshToken();
console.log('### GOOD Warning ! ### new token Request Handler ' +newToken);
// Mettez à jour le token dans le store ou le reducer ici
return this.spotifyFetch(url, options, newToken);
}
else {
console.log('### Error ! ### while fetching Data in the SPotify Request Handler ' +error);
throw error;
}
}
}
private async refreshToken(): Promise<string> {
export class AuthHandler{}
// Faites une demande à votre API pour obtenir un nouveau token Spotify
let refreshToken = await SecureStore.getItemAsync(MY_SECURE_AUTH_STATE_KEY_REFRESH);
console.log('refresh token : ' + refreshToken);
const response = await axios.get(`https://flad-api-production.up.railway.app/api/spotify/refresh?refresh_token=${refreshToken}`);
// Renvoie le nouveau token
const {
access_token : access_token,
refresh_token: refresh_token,
} = response.data as SpotifyAuthResponse
console.log('new access token : ' + access_token);
console.log('new refresh token : ' + refresh_token);
await SecureStore.setItemAsync(MY_SECURE_AUTH_STATE_KEY, access_token);
return access_token;
}
}
interface SpotifyAuthResponse {
access_token: string;
refresh_token: string;
}

@ -1,13 +1,5 @@
import { AuthentificationService } from "../Auth/authentificationService.service";
export class UserService {
constructor(private auth: AuthentificationService) { }
getUserProfile() {
const user = this.auth.currentUser;
const userDocRef = doc(this.firestore, `User/${user.uid}`);
return docData(userDocRef);
}
}

@ -0,0 +1,80 @@
import initialize from '../lib';
initialize();
class MqttClient {
constructor() {
const clientId = 'ReactNativeMqtt';
this.client = new Paho.MQTT.Client('127.0.0.1', 9001, clientId);
this.client.onMessageArrived = this.onMessageArrived;
this.callbacks = {};
this.onSuccessHandler = undefined;
this.onConnectionLostHandler = undefined;
this.isConnected = false;
}
onConnect = (onSuccessHandler, onConnectionLostHandler) => {
this.onSuccessHandler = onSuccessHandler;
this.onConnectionLostHandler = onConnectionLostHandler;
this.client.onConnectionLost = () => {
this.isConnected = false;
onConnectionLostHandler();
};
this.client.connect({
timeout: 10,
onSuccess: () => {
this.isConnected = true;
onSuccessHandler();
},
useSSL: false,
onFailure: this.onError,
reconnect: true,
keepAliveInterval: 20,
cleanSession: true,
});
};
onError = ({errorMessage}) => {
console.log(errorMessage);
this.isConnected = false;
Alert.alert('Failed', 'Failed to connect to MQTT', [
{
text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: 'cancel',
},
{
text: 'Try Again',
onPress: () =>
this.onConnect(
this.onSuccessHandler,
this.onConnectionLostHandler,
),
},
]);
};
onMessageArrived = message => {
const {payloadString, topic} = message;
console.log('onMessageArrived:', payloadString);
this.callbacks[topic](payloadString);
};
onPublish = (topic, message) => {
this.client.publish(topic, message);
};
onSubscribe = (topic, callback) => {
this.callbacks[topic] = callback;
this.client.subscribe(topic);
};
unsubscribe = topic => {
delete this.callbacks[topic];
this.client.unsubscribe(topic);
};
}
let client = new MqttClient();
export {client as MqttClient};
Loading…
Cancel
Save