localStorage #14

Merged
emre.kartal merged 6 commits from localStorage into master 2 years ago

@ -82,7 +82,7 @@ Tout d'abord, il faut fournir votre *adresse e-mail* et votre *nom Spotify* aux
<div align = center>
<img src="doc/Images/Real_RegisterPage.JPG" width="250" >
<img src="doc/Images/Real_RegisterPage.png" width="250" >
</div>
@ -117,19 +117,25 @@ Notre environnement de travail se base sur plusieurs outils et langages :👇
La composition pour le projet se voit réaliser par deux élèves de l'IUT d'Aubière:
<br>
Emre KARTAL : emre.kartal@etu.uca.fr
<br>
David D'ALMEIDA : david.d_almeida@etu.uca.fr
- Emre KARTAL : emre.kartal@etu.uca.fr
- David D'ALMEIDA : david.d_almeida@etu.uca.fr
<div align="center">
<a href = "https://codefirst.iut.uca.fr/git/emre.kartal">
<img src="https://codefirst.iut.uca.fr/git/avatars/402cf312e853192f42c0135a888725c2?size=870" width="50" >
</a>
<a href = "https://codefirst.iut.uca.fr/git/david.d_almeida">
<img src="https://codefirst.iut.uca.fr/git/avatars/0f8eaaad1e26d3de644ca522eccaea7c?size=870" width="50" >
</a>
</div>
<div align = center>
© PM2 (Projet inspiré par nos très chers développeurs de la Dafl Team (S.O les Dafl dev))
</div>
<hr>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a><br />Ce(tte) œuvre est mise à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Licence Creative Commons Attribution - Pas d&#39;Utilisation Commerciale - Pas de Modification 4.0 International</a>.
<hr>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

@ -17,7 +17,7 @@ type CustomCardMusic = { //Props
export default function CardMusic(CBP: CustomCardMusic) {
const isDark = useSelector(state => state.userReducer.dark);
const style = isDark ? GraphicalCharterLight : GraphicalCharterDark;
const style = isDark ? GraphicalCharterDark : GraphicalCharterLight;
const currentMusic = useSelector(state => state.appReducer.currentMusic);
const source = typeof CBP.image === 'string' ? { uri: CBP.image } : CBP.image;

@ -1,5 +1,5 @@
import Navigation from './Navigation';
import { StyleSheet, SafeAreaView } from 'react-native';
import { StyleSheet, SafeAreaView, AsyncStorage } from 'react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import StartNavigation from './StartNavigation';
import { Provider, useDispatch, useSelector } from 'react-redux';
@ -7,7 +7,7 @@ import store from '../redux/store';
import { useCallback, useEffect, useState } from 'react';
import * as SplashScreen from 'expo-splash-screen';
import { View } from 'react-native';
import { getRefreshToken } from '../redux/thunk/authThunk';
import { ChangeMode, getRefreshToken } from '../redux/thunk/authThunk';
import * as Location from 'expo-location';
// const LOCATION_TASK_NAME = 'flad-background-location-task';
@ -60,9 +60,6 @@ export default function AuthNavigation() {
// };
// }, []);
useEffect(() => {
async function prepare() {
//@ts-ignore
await dispatch(getRefreshToken())
@ -70,6 +67,21 @@ export default function AuthNavigation() {
await SplashScreen.hideAsync();
} // await SplashScreen.hideAsync();
}
async function ChangeDarkMode() {
try {
const currentValue = await AsyncStorage.getItem('dark');
if (currentValue !== null) {
const newValue = JSON.stringify(JSON.parse(currentValue));
dispatch(ChangeMode(JSON.parse(newValue)))
}
} catch (error) {
console.log(`Une erreur s'est produite lors de la mise à jour de la valeur booléenne pour la clé 'dark': `, error);
}
}
useEffect(() => {
ChangeDarkMode();
prepare();
}, [appIsReady, tokenProcesed]);

@ -21,7 +21,7 @@ import SpotifyService from '../services/spotify/spotify.service';
export default function Navigation() {
const isDark = useSelector(state => state.userReducer.dark);
const style = isDark ? GraphicalCharterLight : GraphicalCharterDark;
const style = isDark ? GraphicalCharterDark : GraphicalCharterLight;
const BottomTabNavigator = createBottomTabNavigator();
const MyTheme = {
dark: false,

@ -9,6 +9,7 @@
"web": "expo start --web"
},
"dependencies": {
"@react-native-async-storage/async-storage": "^1.17.11",
"@react-navigation/bottom-tabs": "^6.5.4",
"@react-navigation/native": "^6.1.4",
"@react-navigation/native-stack": "^6.9.8",

@ -19,10 +19,11 @@ export interface CredentialsRegister {
// loggedInState,
// }
// );
export const setLoginState = (cred : Credentials) => {
export const setLoginState = (userJson: any) => {
const user = new User(userJson.data.idFlad,userJson.data.idSpotify,userJson.data.email,new Date(),userJson.data.name, require('../../assets/images/jul.png'));
return {
type: userTypes.LOGIN,
playload : cred
playload: user
};
}
@ -45,8 +46,21 @@ export const userSignUp = (user : User) => {
};
}
export const userChangeMode = () => {
export const userChangeMode = (value: boolean) => {
return {
type: userTypes.CHANGE_MODE,
playload: value
};
}
export const ChangeErrorLogin = () => {
return {
type: userTypes.CHANGE_ERROR_LOGIN,
};
}
export const ChangeErrorSignup = () => {
return {
type: userTypes.CHANGE_ERROR_SIGNUP,
};
}

@ -1,3 +1,4 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { User } from "../../Model/User";
import { userTypes } from "../types/userTypes";
const initialState = {
@ -7,7 +8,9 @@ const initialState = {
userSpotifyToken: null,
error: null,
isLogedIn: false,
dark: false,
failedLogin: false,
failedSignup: false,
dark: null
}
const userReducer = (state = initialState, action: any) => {
@ -24,25 +27,38 @@ const userReducer = (state = initialState, action: any) => {
isLogedIn: resp,
};
case userTypes.LOGIN:
AsyncStorage.setItem('dark', JSON.stringify(false)).then(() => {
console.log('La nouvelle clé et sa valeur ont été créées dans le localstorage');
});
console.log("++++++++++++++++++++++++++++++++++++++userRducer+++++++++++++++++++++++++++++3");
console.log(action.playload, "LOOGGIIINN");
console.log("++++++++++++++++++++++++++++++++++++++userRducer+++++++++++++++++++++++++++++3");
return {
...state,
user: action.playload,
isLogedIn: true
failedLogin: false,
isLogedIn: true,
dark: false
};
case userTypes.SIGNUP:
AsyncStorage.setItem('dark', JSON.stringify(false)).then(() => {
console.log('La nouvelle clé et sa valeur ont été créées dans le localstorage');
});
console.log("++++++++++++++++++++++++++++++++++++++userRducer+++++++++++++++++++++++++++++3");
console.log(action.playload, "LOOGGIIINN");
console.log(action.playload, "SIGNNNNNUUUUPPPPPPP");
console.log("++++++++++++++++++++++++++++++++++++++userRducer+++++++++++++++++++++++++++++3");
return {
...state,
user: action.playload,
isLogedIn: true
failedSignup: false,
isLogedIn: true,
dark: false
};
case userTypes.USER_LOGOUT:
AsyncStorage.removeItem('dark').then(() => {
console.log('La clé a été supprimée du localstorage');
});
return {
...state,
user: null,
@ -53,8 +69,12 @@ const userReducer = (state = initialState, action: any) => {
...state,
userSpotifyToken: action.playload,
};
case userTypes.CHANGE_ERROR_LOGIN:
return { ...state, failedLogin: true }
case userTypes.CHANGE_ERROR_SIGNUP:
return { ...state, failedSignup: true }
case userTypes.CHANGE_MODE:
return { ...state, dark: !state.dark }
return { ...state, dark: action.playload }
default:
return state;
}

@ -4,10 +4,11 @@ import axios from "axios";
import { json } from "express";
import { useEffect } from "react";
import { API_URL } from "../../fladConfig";
import { Credentials, CredentialsRegister, restoreToken, setLoginState, UserLogout, userChangeMode, userSignUp } from "../actions/userActions";
import { Credentials, CredentialsRegister, restoreToken, setLoginState, UserLogout, userChangeMode, userSignUp, ChangeErrorLogin, ChangeErrorSignup } from "../actions/userActions";
import * as SecureStore from 'expo-secure-store';
import { User } from "../../Model/User";
import { UserFactory } from "../../Model/factory/UserFactory";
import * as ImagePicker from 'expo-image-picker';
const key = 'userToken';
@ -33,7 +34,8 @@ export const registerUser = ( resgisterCredential : CredentialsRegister) => {
const token = resp.data.token;
// await SecureStore.setItemAsync(key, token);
const headers = {
'Authorization': 'Bearer ' + token};
'Authorization': 'Bearer ' + token
};
const user = await axios.get(
"https://flad-api-production.up.railway.app/api/users",
{ headers }
@ -55,6 +57,7 @@ export const registerUser = ( resgisterCredential : CredentialsRegister) => {
} catch (error) {
console.log('Error---------', error);
dispatch(ChangeErrorSignup())
}
}
}
@ -95,12 +98,14 @@ export const userLogin = (loginCredential: Credentials) => {
)
// dispatch(setLoginState(resp.data.user) ); // our action is called here
console.log(user.data);
dispatch(setLoginState(user.data)); // our action is called here
} else {
console.log('Login Failed', 'Username or Password is incorrect');
}
} catch (error) {
dispatch(ChangeErrorLogin())
console.log('Error---------', error);
}
}
@ -146,13 +151,20 @@ export const DeleteToken = () => {
}
}
export const ChangeMode = () => {
export const ChangeMode = (value: boolean) => {
//@ts-ignore
return async dispatch => {
dispatch(userChangeMode());
await SecureStore.deleteItemAsync(key);
dispatch(userChangeMode(value));
}
}
export const ChangeImageUserCurrent = (value: ImagePicker) => {
//@ts-ignore
return async dispatch => {
dispatch(userChangeImage(value));
}
}
// const logIn = (email, password) => {
// const action = (dispatch) => {

@ -6,5 +6,7 @@ export const userTypes = {
UPDATE_PROFILE_PICTURE: 'UPDATE_PROFILE_PICTURE',
USER_LOGOUT: 'USER_LOGOUT',
RESTORE_TOKEN: "RESTORE_TOKEN",
CHANGE_MODE: "CHANGE_MODE"
CHANGE_MODE: "CHANGE_MODE",
CHANGE_ERROR_LOGIN: "CHANGE_ERROR_LOGIN",
CHANGE_ERROR_SIGNUP: "CHANGE_ERROR_SIGNUP"
}

@ -12,14 +12,14 @@ import { GraphicalCharterDark } from '../assets/GraphicalCharterDark';
import { GraphicalCharterLight } from '../assets/GraphicalCharterLight';
export default function favoritePage() {
const dispatch = useDispatch();
//Dark Mode
const isDark = useSelector(state => state.userReducer.dark);
const style = isDark ? GraphicalCharterLight : GraphicalCharterDark;
const style = isDark ? GraphicalCharterDark : GraphicalCharterLight;
const navigation = useNavigation();
//@ts-ignore
const favoritesMusic = useSelector(state => state.appReducer.favoriteMusic);
const dispatch = useDispatch();
const images = [
{ id: 1, source: require('../assets/images/FLADYLove.png') },
{ id: 2, source: require('../assets/images/FLADYStar.png') },

@ -3,7 +3,7 @@ import { View, Image, StyleSheet, Text, ImageBackground, TextInput, TouchableWit
import { useNavigation } from "@react-navigation/native";
import normalize from '../components/Normalize';
import { userLogin } from '../redux/thunk/authThunk';
import { useDispatch } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { Audio } from 'expo-av';
import { Credentials } from '../redux/actions/userActions';
@ -19,6 +19,8 @@ export default function loginPage() {
const [rememberMe, setRememberMe] = useState(false);
const navigation = useNavigation();
const failedLogin = useSelector(state => state.userReducer.failedLogin);
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
async function playSound() {
@ -56,14 +58,19 @@ export default function loginPage() {
</Text>
<Image source={require("../assets/icons/Logo_White_Flad.png")} style={styles.imageLogo} />
<Text style={styles.text}>SE CONNECTER</Text>
<View>
<TextInput placeholder="Username"
{failedLogin && (
<Text style={styles.textError}>Email ou mot de passe incorrect!</Text>
)}
<View style={{ marginTop: 7 }}>
<TextInput placeholder="Email"
placeholderTextColor="#B8B4B8"
value={username}
onChangeText={setUsername} style={[styles.input, styles.shadow]} />
<Image source={require('../assets/icons/icons/User.png')} style={styles.iconUser} />
</View>
<View>
<TextInput placeholder="Password"
placeholderTextColor="#B8B4B8"
value={password}
onChangeText={setPassword}
secureTextEntry style={[styles.input, styles.shadow]} />
@ -118,6 +125,12 @@ const styles = StyleSheet.create({
height: normalize(100),
borderRadius: 21
},
textError: {
fontSize: 15,
alignSelf: "center",
color: "red",
fontWeight: 'bold'
},
buttonImage: {
width: normalize(46),
height: normalize(46),
@ -152,7 +165,7 @@ const styles = StyleSheet.create({
fontSize: normalize(29),
alignSelf: 'center',
color: 'white',
marginBottom: 15
marginBottom: 8
},
shadow: {
shadowColor: 'black',

@ -7,7 +7,7 @@ import * as AuthSession from 'expo-auth-session';
import * as WebBrowser from 'expo-web-browser';
import { makeRedirectUri, useAuthRequest } from 'expo-auth-session';
import { registerUser } from '../redux/thunk/authThunk';
import { useDispatch } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { Audio } from 'expo-av';
import { CredentialsRegister } from '../redux/actions/userActions';
import { Buffer } from 'buffer';
@ -41,6 +41,8 @@ export default function InscriptionPage() {
const navigation = useNavigation();
const [spotifyToken, setSpotifyToken] = useState('');
const [spotifyID, setSpotifyIds] = useState('')
const failedSignup = useSelector(state => state.userReducer.failedSignup);
async function playSound() {
console.log('Loading Sound');
const { sound } = await Audio.Sound.createAsync(
@ -238,20 +240,26 @@ export default function InscriptionPage() {
</Text>
<Image source={require("../assets/icons/Logo_White_Flad.png")} style={styles.imageLogo} />
<Text style={styles.text}>S'INSCRIRE</Text>
<View>
{failedSignup && (
<Text style={styles.textError}>Email ou mot de passe incorrect!</Text>
)}
<View style={{ marginTop: 7 }}>
<TextInput style={[styles.input, styles.shadow]} placeholder="Username"
placeholderTextColor="#B8B4B8"
value={username}
onChangeText={setUsername} />
<Image source={require('../assets/icons/icons/User.png')} style={styles.iconUser} />
</View>
<View>
<TextInput style={[styles.input, styles.shadow]} placeholder="Email"
placeholderTextColor="#B8B4B8"
value={email}
onChangeText={setEmail} />
<Image source={require('../assets/icons/icons/lock.png')} style={styles.iconLock} />
</View>
<View>
<TextInput style={[styles.input, styles.shadow]} placeholder="Password"
placeholderTextColor="#B8B4B8"
value={password} secureTextEntry={true}
onChangeText={setPassword} />
<Image source={require('../assets/icons/icons/lock.png')} style={styles.iconLock} />
@ -307,6 +315,12 @@ const styles = StyleSheet.create({
height: normalize(100),
borderRadius: 21
},
textError: {
fontSize: 15,
alignSelf: "center",
color: "red",
fontWeight: 'bold'
},
buttonImage: {
width: normalize(46),
height: normalize(46),
@ -324,7 +338,7 @@ const styles = StyleSheet.create({
fontSize: normalize(29),
alignSelf: 'center',
color: 'white',
marginBottom: 15
marginBottom: 8
},
textIntoButton: {
fontWeight: 'bold',

@ -1,4 +1,5 @@
import React, { useEffect, useRef, useState } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { View, StyleSheet, Text, Image, TouchableWithoutFeedback, Keyboard, TouchableOpacity, SafeAreaView } from 'react-native';
import { Svg, Path } from 'react-native-svg';
import { useNavigation } from "@react-navigation/native";
@ -33,10 +34,20 @@ export default function Setting() {
//Dark Mode
const isDark = useSelector(state => state.userReducer.dark);
const style = isDark ? GraphicalCharterLight : GraphicalCharterDark;
const ChangeDarkMode = () => {
dispatch(ChangeMode())
const style = isDark ? GraphicalCharterDark : GraphicalCharterLight;
async function ChangeDarkMode() {
try {
const currentValue = await AsyncStorage.getItem('dark');
if (currentValue !== null) {
const newValue = JSON.stringify(!JSON.parse(currentValue));
await AsyncStorage.setItem('dark', newValue);
dispatch(ChangeMode(JSON.parse(newValue)))
}
} catch (error) {
console.log(`Une erreur s'est produite lors de la mise à jour de la valeur booléenne pour la clé 'dark': `, error);
}
}
//Notification
@ -87,7 +98,7 @@ export default function Setting() {
},
inputSearch: {
placeholderTextColor: 'red',
color: 'white',
color: style.Text,
width: normalize(350),
},
profil: {
@ -319,7 +330,7 @@ export default function Setting() {
</View>
<View style={styles.musicActually}>
<CardMusic image={currentMusic.image} title={currentMusic.title} description="PNL" />
<CardMusic image="{currentMusic.image}" title="{currentMusic.title}" description="PNL" />
<Image source={require("../assets/images/FladyShadow.png")} style={styles.mascot} />
</View>

@ -1,16 +1,17 @@
import React, { useState, useRef } from 'react';
import React, { useState, useRef, useEffect } from 'react';
import { View, Text, StyleSheet, TouchableWithoutFeedback, Keyboard, ScrollView, Image } from 'react-native';
import { TextInput, TouchableOpacity } from 'react-native-gesture-handler';
import { Svg, Path } from 'react-native-svg';
import Modal from "react-native-modal";
import { useNavigation } from "@react-navigation/native";
import { useSelector } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import normalize from '../components/Normalize';
import * as ImagePicker from 'expo-image-picker';
import { SafeAreaView } from 'react-native-safe-area-context';
import { GraphicalCharterDark } from '../assets/GraphicalCharterDark';
import { GraphicalCharterLight } from '../assets/GraphicalCharterLight';
import AsyncStorage from '@react-native-async-storage/async-storage';
// @ts-ignore
const DismissKeyboard = ({ children }) => (
@ -22,14 +23,20 @@ const DismissKeyboard = ({ children }) => (
export default function SettingProfil() {
//Dark Mode
const dispatch = useDispatch();
const isDark = useSelector(state => state.userReducer.dark);
const style = isDark ? GraphicalCharterLight : GraphicalCharterDark;
const UserCurrent = useSelector(state => state.userReducer.user);
const style = isDark ? GraphicalCharterDark : GraphicalCharterLight;
const [image, setImage] = useState(null);
const navigation = useNavigation();
const [currentIndex, setCurrentIndex] = useState(0);
const [isModalVisible, setIsModalVisible] = React.useState(false);
useEffect(() => {
console.log(UserCurrent.image);
});
const handleModal = () => setIsModalVisible(() => !isModalVisible);
// @ts-ignore
const viewableItemsChanged = useRef(({ viewableItems }) => {
@ -44,11 +51,7 @@ export default function SettingProfil() {
aspect: [4, 3],
quality: 1,
});
console.log(result);
if (!result.canceled) {
setImage(result.assets[0].uri);
}
};
@ -172,12 +175,12 @@ export default function SettingProfil() {
textInputId: {
marginLeft: 50,
width: '57%',
color: 'white',
color: style.Text,
fontSize: normalize(18),
},
textInputMail: {
marginLeft: 100,
color: 'white',
color: style.Text,
width: '57%',
fontSize: normalize(18)
},
@ -278,7 +281,7 @@ export default function SettingProfil() {
<View style={styles.profilHead}>
<Text style={styles.title}>Profil</Text>
<View style={styles.imageWrapper}>
{image && <Image source={{ uri: image }} style={styles.imageProfil} />}
<Image source={{ uri: UserCurrent.image }} style={styles.imageProfil} />
</View>
<View style={styles.editButton}>
<TouchableOpacity onPress={pickImage} >
@ -291,11 +294,11 @@ export default function SettingProfil() {
<View style={styles.body}>
<View style={styles.optionId}>
<Text style={styles.textOption}>Identifiant</Text>
<TextInput placeholderTextColor='#828288' placeholder='Flady' style={styles.textInputId} />
<TextInput placeholderTextColor='#828288' placeholder={UserCurrent.name} style={styles.textInputId} />
</View>
<View style={styles.optionMail}>
<Text style={styles.textOption}>Mail</Text>
<TextInput placeholderTextColor='#828288' placeholder='emre.kartal@etu.uca.fr' style={styles.textInputMail} />
<TextInput placeholderTextColor='#828288' placeholder={UserCurrent.email} style={styles.textInputMail} />
</View>
</View>

Loading…
Cancel
Save