Add:
continuous-integration/drone/push Build is failing Details

Possibilité de changer de skin avec uniqument les skins de l'utilisateur
Possibilité d'acheter des skins
Store: uniquement les skins que l'utilisateur n'a pas et se met à jours
Persistance
Thomas Chazot 2 years ago
parent 560c33ee1b
commit 82adcd6756

@ -5,7 +5,7 @@ import LoaderUserApi from './src/services/userServices/loaderUserApi'
import ManagerUser from './src/services/userServices/ManagerUser' import ManagerUser from './src/services/userServices/ManagerUser'
import FakeSaverUser from './src/services/userServices/fakeSaverUser' import FakeSaverUser from './src/services/userServices/fakeSaverUser'
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useUserStore } from './userContext'; import { useUserStore } from './src/context/userContext';
export const MANAGER_USER = new ManagerUser(new LoaderUserApi, new FakeSaverUser); export const MANAGER_USER = new ManagerUser(new LoaderUserApi, new FakeSaverUser);
@ -32,10 +32,6 @@ export const MANAGER_USER = new ManagerUser(new LoaderUserApi, new FakeSaverUser
resetUser(); resetUser();
}, []); }, []);
const handleUserChange = useCallback(async () => {
MANAGER_USER.getCurrentUser()?.setCurrentCoins(MANAGER_USER.getCurrentUser()?.getCurrentCoins()+100);
setUser(MANAGER_USER.getCurrentUser());
}, []);
const test = useCallback(async () => { const test = useCallback(async () => {

@ -1,4 +1,4 @@
import { FC, ReactNode } from "react" import { FC, ReactNode, useCallback } from "react"
import { Pressable, Image, View} from "react-native" import { Pressable, Image, View} from "react-native"
import React from "react" import React from "react"
@ -6,6 +6,9 @@ import React from "react"
Importing the correct stylesheet Importing the correct stylesheet
*/ */
import styles from './style/BotBar.style'; import styles from './style/BotBar.style';
import { useStoreStore } from "../context/storeContext";
import { MANAGER_USER } from "../../App";
import tabSkinApp from "../constSkin";
/* /*
Images that are required to create a bottom bar Images that are required to create a bottom bar
@ -35,6 +38,26 @@ export const BotBar :
FC<{nav: any, state?: String}> = FC<{nav: any, state?: String}> =
({nav, state}) => ({nav, state}) =>
{ {
const setTabSkin = useStoreStore((state) => state.setTabSkin);
const handleStoreChange = useCallback(async () => {
let tabSkinStore=[...tabSkinApp];
let tmp=MANAGER_USER.getCurrentUser()?.getTabSkin();
if (tmp!=undefined){
tmp.forEach(skin => {
for (let i=0; i<tabSkinStore.length; i++){
if(skin.isEqual(tabSkinStore[i])){
tabSkinStore.splice(i,1);
}
}
});
setTabSkin(tabSkinStore);
}
}, []);
/* /*
By default, all the images are the white ones By default, all the images are the white ones
*/ */
@ -78,7 +101,7 @@ FC<{nav: any, state?: String}> =
source={imgMid} source={imgMid}
/> />
</Pressable> </Pressable>
<Pressable onPress={() => nav.navigate('StoreTab')}> <Pressable onPress={() => {handleStoreChange(); nav.navigate('StoreTab')}}>
<Image <Image
style={styles.icon} style={styles.icon}
source={imgRight} source={imgRight}

@ -1,4 +1,4 @@
import { FC, ReactNode } from "react" import { FC, ReactNode, useCallback } from "react"
import { Pressable, Image, ImageStyle, Text, View, Alert, ImageSourcePropType, TextStyle } from "react-native" import { Pressable, Image, ImageStyle, Text, View, Alert, ImageSourcePropType, TextStyle } from "react-native"
import React from "react" import React from "react"
import { Skin } from "../core/skin" import { Skin } from "../core/skin"
@ -11,7 +11,12 @@ import { useDispatch, useSelector } from "react-redux"
import { loginUser } from "../redux/features/currentUserSlice" import { loginUser } from "../redux/features/currentUserSlice"
import { RootState } from "../redux/store" import { RootState } from "../redux/store"
import { MANAGER_USER } from "../../App" import { MANAGER_USER } from "../../App"
import { useUserStore } from "../../userContext" import { useUserStore } from "../context/userContext"
import { ManagerCoinsUser } from "../core/User/userCoinsModifier"
import ManagerUser from "../services/userServices/ManagerUser"
import UserSkinModifier from "../core/User/userSkinModifier"
import { useStoreStore } from "../context/storeContext"
import tabSkinApp from "../constSkin"
@ -28,17 +33,65 @@ FC<{nav : any, skin: Skin, state: String}> =
({nav, skin, state}) => ({nav, skin, state}) =>
{ {
console.log(nav); const navigation = nav;
const dispatch=useDispatch(); const dispatch=useDispatch();
const setUser = useUserStore((state) => state.setUser); const setUser = useUserStore((state) => state.setUser);
function changerSkin(skin:Skin) { const setTabSkin = useStoreStore((state) => state.setTabSkin);
MANAGER_USER.getCurrentUser()?.setCurrentSkin(skin);
setUser(MANAGER_USER.getCurrentUser());
MANAGER_USER.getsaverUser().updateUser(MANAGER_USER.getCurrentUser()); async function changerSkin(skin:Skin) {
const m=new UserSkinModifier();
const tmp = MANAGER_USER.getCurrentUser();
if (tmp!=null){
await m.changeCurrentSkin(tmp, skin);
setUser(tmp);
MANAGER_USER.setCurrentUser(tmp);
}
}
const handleStoreChange = useCallback(async () => {
let tabSkinStore=[...tabSkinApp];
let tmp=MANAGER_USER.getCurrentUser()?.getTabSkin();
if (tmp!=undefined){
tmp.forEach(skin => {
for (let i=0; i<tabSkinStore.length; i++){
if(skin.isEqual(tabSkinStore[i])){
tabSkinStore.splice(i,1);
}
}
});
setTabSkin(tabSkinStore);
}
}, []);
async function buySkin(skin:Skin) {
const mSkin=new UserSkinModifier();
const mCoins= new ManagerCoinsUser();
const tmp = MANAGER_USER.getCurrentUser();
if (tmp!=null){
await mCoins.removeCoins(tmp,skin.getSkinCost()).then(async (res) => {
if(res==true){
await mSkin.addSkin(tmp, skin);
setUser(tmp);
MANAGER_USER.setCurrentUser(tmp);
Alert.alert("Achat du skin");
handleStoreChange();
}
else{
Alert.alert("Pas assez d'argent pour acheter le skin");
}
});
}
} }
/* The display of this component depends of the screen from where it has been called: /* The display of this component depends of the screen from where it has been called:
@ -56,7 +109,7 @@ FC<{nav : any, skin: Skin, state: String}> =
case 'shop': case 'shop':
return( return(
<Pressable onPress={() => Alert.alert("Achat du skin")} style={styles.imageWrapper}> <Pressable onPress={() => buySkin(skin)} style={styles.imageWrapper}>
<Text style={styles.nomSkin}>{skin.getSkinName()}</Text> <Text style={styles.nomSkin}>{skin.getSkinName()}</Text>
<Image <Image
style={styles.imageSkin} style={styles.imageSkin}
@ -67,7 +120,7 @@ FC<{nav : any, skin: Skin, state: String}> =
) )
case 'liste': case 'liste':
return( return(
<Pressable onPress={() => {changerSkin(skin); nav.navigate('ProfileTab', {screen: 'Profile'})}} style={styles.imageWrapper}> <Pressable onPress={() => {changerSkin(skin); navigation.goBack()}} style={styles.imageWrapper}>
<Text style={styles.nomSkin}>{skin.getSkinName()}</Text> <Text style={styles.nomSkin}>{skin.getSkinName()}</Text>
<Image <Image
style={styles.imageSkin} style={styles.imageSkin}
@ -77,7 +130,7 @@ FC<{nav : any, skin: Skin, state: String}> =
) )
case 'profile': case 'profile':
return( return(
<Pressable onPress={() => Alert.alert("Achat du skin")} style={styles.imageWrapperProfil}> <Pressable onPress={() => Alert.alert("cool")} style={styles.imageWrapperProfil}>
<Text style={styles.nomSkin}>{skin.getSkinName()}</Text> <Text style={styles.nomSkin}>{skin.getSkinName()}</Text>
<Image <Image
style={styles.imageSkin} style={styles.imageSkin}

@ -12,7 +12,7 @@ import styles from './style/TopBar.style';
import { useSelector } from "react-redux" import { useSelector } from "react-redux"
import { RootState } from "../redux/store" import { RootState } from "../redux/store"
import { MANAGER_USER } from "../../App" import { MANAGER_USER } from "../../App"
import { useUserStore } from "../../userContext" import { useUserStore } from "../context/userContext"
/* /*
Images required Images required
@ -31,7 +31,6 @@ export const TopBar :
FC<{nav: any, state?: string}> = FC<{nav: any, state?: string}> =
({nav, state}) => ({nav, state}) =>
{ {
/* The display of this component depends of the screen from where it has been called: /* The display of this component depends of the screen from where it has been called:
* From the Settings (icon) : Name of the page + cross button * From the Settings (icon) : Name of the page + cross button

@ -0,0 +1,22 @@
import React from "react";
import create from "zustand";
import { MANAGER_USER } from "../../App";
import tabSkinApp from "../constSkin";
import { Skin } from "../core/Skin";
import { User } from "../core/User/user";
// Define store types
interface StoreState {
tabSkin: Skin[];
setTabSkin: (tabSkin: Skin[]) => void;
resetTabSkin: () => void;
}
// Define store data and methods
export const useStoreStore = create<StoreState>()((set, get) => ({
tabSkin: tabSkinApp,
setTabSkin: (tabSkin) => set((state) => ({ tabSkin: tabSkin })),
resetTabSkin: () => set((state) => ({ tabSkin: tabSkinApp })),
}));

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import create from "zustand"; import create from "zustand";
import { User } from "./src/core/User/user"; import { User } from "../core/User/user";
// Define store types // Define store types

@ -30,7 +30,7 @@ export class User{
this.currentCoins=currentCoins; this.currentCoins=currentCoins;
this.totalCoins=totalCoins; this.totalCoins=totalCoins;
this.currentSkin=currentSkin; this.currentSkin=currentSkin;
this.tabSkin=[]; this.tabSkin=tabSkin;
} }

@ -11,9 +11,13 @@ export class ManagerCoinsUser{
await MANAGER_USER.getsaverUser().updateUser(u); await MANAGER_USER.getsaverUser().updateUser(u);
} }
async removeCoins(u:User, coins:number){ async removeCoins(u:User, coins:number): Promise<boolean>{
u.setCurrentCoins(u.getCurrentCoins()-coins); if (u.getCurrentCoins()>=coins){
await MANAGER_USER.getsaverUser().updateUser(u); u.setCurrentCoins(u.getCurrentCoins()-coins);
await MANAGER_USER.getsaverUser().updateUser(u);
return true;
}
return false;
} }
async changeCurrentCoins(u:User, coins:number){ async changeCurrentCoins(u:User, coins:number){

@ -48,4 +48,8 @@ export class Skin{
setSkinCost(cost:number){ setSkinCost(cost:number){
this.cost=cost; this.cost=cost;
} }
isEqual(s:Skin){
return this.id==s.id;
}
} }

@ -9,7 +9,7 @@ import { SkinComponent } from '../components/Skin';
import { ButtonGreySmall } from '../components/ButtonGreySmall'; import { ButtonGreySmall } from '../components/ButtonGreySmall';
import { ScreenIndicator } from '../components/ScreenIndicator'; import { ScreenIndicator } from '../components/ScreenIndicator';
import { MANAGER_USER } from '../../App'; import { MANAGER_USER } from '../../App';
import { useUserStore } from '../../userContext'; import { useUserStore } from '../context/userContext';
const coin = require('../../assets/Icons/Coin.png') const coin = require('../../assets/Icons/Coin.png')
@ -35,8 +35,8 @@ function Profile(props: { navigation: any; }) {
<Text style={styles.coinText}>{useUserStore().user?.getCurrentCoins()}</Text> <Text style={styles.coinText}>{useUserStore().user?.getCurrentCoins()}</Text>
</View> </View>
<View style={styles.skinView}> <View style={styles.skinView}>
<SkinComponent skin={useUserStore().user?.getCurrentSkin()} state='profile' /> <SkinComponent skin={useUserStore().user?.getCurrentSkin()} state='profile' nav={navigation}/>
<ButtonGreySmall onPress={() => navigation.navigate('SkinList')} title='Changer de skin' state='Profile'/> <ButtonGreySmall onPress={() => {navigation.navigate('SkinList');}} title='Changer de skin' state='Profile'/>
</View> </View>
</View> </View>
<View style={styles.infoView}> <View style={styles.infoView}>

@ -11,8 +11,9 @@ import Dialog from "react-native-dialog"
import RNPickerSelect from "react-native-picker-select"; import RNPickerSelect from "react-native-picker-select";
import { PickerGreySmall } from '../components/PickerGreySmall'; import { PickerGreySmall } from '../components/PickerGreySmall';
import { MANAGER_USER } from '../../App'; import { MANAGER_USER } from '../../App';
import { useUserStore } from '../../userContext'; import { useUserStore } from '../context/userContext';
import DialogInput from 'react-native-dialog-input'; import DialogInput from 'react-native-dialog-input';
import UserModificationManager from '../core/User/userModificationManager';
function Settings(props: { navigation: any; }) { function Settings(props: { navigation: any; }) {
const { navigation } = props const { navigation } = props
@ -27,16 +28,24 @@ function Settings(props: { navigation: any; }) {
const [selectedNationality, setSelectedNationality] = useState(""); const [selectedNationality, setSelectedNationality] = useState("");
function changeUsername(username:string){ async function changeUsername(username:string){
MANAGER_USER.getCurrentUser()?.setUsername(username); const m = new UserModificationManager();
setUser(MANAGER_USER.getCurrentUser()); let tmp=MANAGER_USER.getCurrentUser();
MANAGER_USER.getsaverUser().updateUser(MANAGER_USER.getCurrentUser()); if (tmp!=null){
await m.changeUsername(tmp, username);
setUser(tmp);
MANAGER_USER.setCurrentUser(tmp);
}
} }
function changePassword(password:string){ async function changePassword(password:string){
MANAGER_USER.getCurrentUser()?.setPassword(password); const m = new UserModificationManager();
setUser(MANAGER_USER.getCurrentUser()); let tmp=MANAGER_USER.getCurrentUser();
MANAGER_USER.getsaverUser().updateUser(MANAGER_USER.getCurrentUser()); if (tmp!=null){
await m.changePassword(tmp, password);
setUser(tmp);
MANAGER_USER.setCurrentUser(tmp);
}
} }
const dispatch=useDispatch(); const dispatch=useDispatch();

@ -10,7 +10,7 @@ import { RootState } from '../redux/store';
import { updateIncorrectCredentials } from '../redux/features/credentialErrorsSlice'; import { updateIncorrectCredentials } from '../redux/features/credentialErrorsSlice';
import Dialog from "react-native-dialog"; import Dialog from "react-native-dialog";
import { MANAGER_USER } from '../../App'; import { MANAGER_USER } from '../../App';
import { useUserStore } from '../../userContext'; import { useUserStore } from '../context/userContext';
@ -35,8 +35,8 @@ function SignIn(props: { navigation: any; }) {
const us =await MANAGER_USER.getLoaderUser().loadByUsernamePassword(pseudo, password).then((res) => { const us =await MANAGER_USER.getLoaderUser().loadByUsernamePassword(pseudo, password).then((res) => {
if (res!=null){ if (res!=null){
MANAGER_USER.setCurrentUser(res); MANAGER_USER.setCurrentUser(res);
navigation.navigate('HomeTab');
setUser(MANAGER_USER.getCurrentUser()); setUser(MANAGER_USER.getCurrentUser());
navigation.navigate('HomeTab');
} }
else{ else{
console.log("wesh c'est null"); console.log("wesh c'est null");

@ -8,6 +8,7 @@ import { FlatList } from 'react-native-gesture-handler';
import { SkinComponent } from '../components/Skin'; import { SkinComponent } from '../components/Skin';
import tabSkinApp from '../constSkin'; import tabSkinApp from '../constSkin';
import { ScreenIndicator } from '../components/ScreenIndicator'; import { ScreenIndicator } from '../components/ScreenIndicator';
import { MANAGER_USER } from '../../App';
@ -22,11 +23,11 @@ function SkinList(props: { navigation: any; }) {
<View style={stylesScreen.bodyStart}> <View style={stylesScreen.bodyStart}>
<ScreenIndicator title='Mes Skins'/> <ScreenIndicator title='Mes Skins'/>
<FlatList <FlatList
data={tabSkinApp} data={MANAGER_USER.getCurrentUser()?.getTabSkin()}
numColumns={2} numColumns={2}
columnWrapperStyle={{ flex: 1, justifyContent: "space-around"}} columnWrapperStyle={{ flex: 1, justifyContent: "space-around"}}
keyExtractor={item =>item.getSkinName()} keyExtractor={item =>item.getSkinName()}
renderItem={({item}) => <SkinComponent skin={item} state='liste'/>} /> renderItem={({item}) => <SkinComponent skin={item} state='liste' nav={navigation}/>} />
</View> </View>
<BotBar <BotBar
nav={navigation} nav={navigation}

@ -1,19 +1,24 @@
import { StatusBar } from 'expo-status-bar' import { StatusBar } from 'expo-status-bar'
import { View } from 'react-native' import { View } from 'react-native'
import React from 'react'; import React, { useCallback } from 'react';
import stylesScreen from './style/screens.style'; import stylesScreen from './style/screens.style';
import { TopBar } from '../components/TopBar'; import { TopBar } from '../components/TopBar';
import { BotBar } from '../components/BotBar'; import { BotBar } from '../components/BotBar';
import { FlatList } from 'react-native-gesture-handler'; import { FlatList } from 'react-native-gesture-handler';
import { SkinComponent } from '../components/Skin'; import { SkinComponent } from '../components/Skin';
import { ScreenIndicator } from '../components/ScreenIndicator'; import { ScreenIndicator } from '../components/ScreenIndicator';
import { useSelector } from 'react-redux';
import { RootState } from '../redux/store';
import tabSkinApp from '../constSkin';
import { MANAGER_USER } from '../../App'; import { MANAGER_USER } from '../../App';
import { useUserStore } from '../../userContext'; import { useUserStore } from '../context/userContext';
import { useStoreStore } from '../context/storeContext';
function Store(props: { navigation: any; }) {
const { navigation } = props
function Store(props: { navigation: any; }) {
const { navigation } = props
return ( return (
<View style={stylesScreen.container}> <View style={stylesScreen.container}>
<TopBar <TopBar
@ -22,11 +27,11 @@ function Store(props: { navigation: any; }) {
<View style={stylesScreen.bodyStart}> <View style={stylesScreen.bodyStart}>
<ScreenIndicator title='Store'/> <ScreenIndicator title='Store'/>
<FlatList <FlatList
data={useUserStore().user?.getTabSkin()} data={useStoreStore().tabSkin}
numColumns={2} numColumns={2}
columnWrapperStyle={{ flex: 1, justifyContent: "space-around"}} columnWrapperStyle={{ flex: 1, justifyContent: "space-around"}}
keyExtractor={item =>item.getSkinName()} keyExtractor={item =>item.getSkinName()}
renderItem={({item}) => <SkinComponent skin={item} state='shop'/>} /> renderItem={({item}) => <SkinComponent skin={item} state='shop' nav={navigation}/>} />
</View> </View>
<BotBar <BotBar
nav={navigation} nav={navigation}

@ -102,7 +102,8 @@ export default class LoaderUserApi implements ILoaderUser{
} }
}) })
.then(function (response: any) { .then(function (response: any) {
user=new User("U0001", username, password, "ouioui", "homme", new Date(2022,12,12), 12222, 123324, 12, new Skin("S0001", "Bob",require('bob_party/assets/BobsSkins/BobClassic.png'), 0), [new Skin("S0001", "Bob",require('bob_party/assets/BobsSkins/BobClassic.png'), 0)]); const tabTest=[new Skin("S0001", "Bob",require('bob_party/assets/BobsSkins/BobClassic.png'), 0), new Skin("S0002", "Bob Blue",require('bob_party/assets/BobsSkins/BobBlue.png'), 100)];
user=new User("U0001", username, password, "ouioui", "homme", new Date(2022,12,12), 200, 123324, 12, new Skin("S0001", "Bob",require('bob_party/assets/BobsSkins/BobClassic.png'), 0), tabTest);
}); });
return user; return user;
} }

Loading…
Cancel
Save