From b3908be97577a9db5d72f4304898c7cc063eb8a2 Mon Sep 17 00:00:00 2001 From: "Corentin \"Koroh\" RICHARD" Date: Wed, 8 Mar 2023 10:33:51 +0100 Subject: [PATCH 01/12] update --- package.json | 1 + yarn.lock | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/package.json b/package.json index 6978a11..eab23c4 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "web": "expo start --web" }, "dependencies": { + "@react-native-async-storage/async-storage": "1.17.11", "@react-navigation/bottom-tabs": "^6.5.5", "@react-navigation/native": "^6.1.4", "@react-navigation/native-stack": "^6.9.10", diff --git a/yarn.lock b/yarn.lock index 0fc84ef..df7abcd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1523,6 +1523,13 @@ mkdirp "^1.0.4" rimraf "^3.0.2" +"@react-native-async-storage/async-storage@1.17.11": + version "1.17.11" + resolved "https://registry.yarnpkg.com/@react-native-async-storage/async-storage/-/async-storage-1.17.11.tgz#7ec329c1b9f610e344602e806b04d7c928a2341d" + integrity sha512-bzs45n5HNcDq6mxXnSsOHysZWn1SbbebNxldBXCQs8dSvF8Aor9KCdpm+TpnnGweK3R6diqsT8lFhX77VX0NFw== + dependencies: + merge-options "^3.0.4" + "@react-native-community/cli-clean@^9.2.1": version "9.2.1" resolved "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-9.2.1.tgz" @@ -3957,6 +3964,11 @@ is-path-inside@^3.0.2: resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" @@ -4421,6 +4433,13 @@ memory-cache@~0.2.0: resolved "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz" integrity sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA== +merge-options@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/merge-options/-/merge-options-3.0.4.tgz#84709c2aa2a4b24c1981f66c179fe5565cc6dbb7" + integrity sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ== + dependencies: + is-plain-obj "^2.1.0" + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" From 98bc1dc9a5d9643cb74ef31f96cff0d128a946cd Mon Sep 17 00:00:00 2001 From: "Corentin \"Koroh\" RICHARD" Date: Wed, 8 Mar 2023 21:27:20 +0100 Subject: [PATCH 02/12] Adding onPress action --- data/ApiDataManager.tsx | 14 ------------ data/stub.ts | 13 ------------ screens/ListScreen.tsx | 46 +++++++++++++++++++++++----------------- service/AsyncStorage.tsx | 1 + 4 files changed, 28 insertions(+), 46 deletions(-) delete mode 100644 data/ApiDataManager.tsx delete mode 100644 data/stub.ts diff --git a/data/ApiDataManager.tsx b/data/ApiDataManager.tsx deleted file mode 100644 index a08be79..0000000 --- a/data/ApiDataManager.tsx +++ /dev/null @@ -1,14 +0,0 @@ - -// export class ApiDataManager{ - - -// public async getCards() : Promise { - - -// const CardPromise = await fetch('https://omgvamp-hearthstone-v1.p.rapidapi.com/cards') - -// const CardListJson = await CardPromise.json(); -// const CardList: String[] = Array.of(CardListJson); -// return CardList; -// } -// } diff --git a/data/stub.ts b/data/stub.ts deleted file mode 100644 index f700882..0000000 --- a/data/stub.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Card } from "../models/Card" - -export class StubLib { - - public getCards(): Card[] { - const NOUNOURS_LIST : Card[] = [ - - - ] - return NOUNOURS_LIST - } -} - diff --git a/screens/ListScreen.tsx b/screens/ListScreen.tsx index 33d6fce..860c5f4 100644 --- a/screens/ListScreen.tsx +++ b/screens/ListScreen.tsx @@ -1,33 +1,36 @@ - -import { StyleSheet, Text, View, Button, TouchableHighlight } from 'react-native'; +import { StyleSheet, Text, View, Button, TouchableHighlight, ImageBackground } from 'react-native'; import { StatusBar } from 'expo-status-bar'; import React, { useState, useEffect } from "react"; import { FlatList } from 'react-native-gesture-handler'; import {useDispatch, useSelector} from 'react-redux'; - +import { FontAwesome } from '@expo/vector-icons'; import { ThunkAction } from 'redux-thunk'; //? possiblement à supprimer import { getAllCards } from "../redux/actions/actionSelection" - -import { StubLib } from '../data/stub'; import { Card } from '../models/Card'; import { Image } from 'react-native'; import { ImageURISource } from 'react-native'; //@ts-ignore -const Item = ({url}) => ( - // - // {title} - // - - - +const Item = ({url}) => { // a mettre dans components et definir une props pour passer le param + + const HandleAddFav = () => { + console.log('addfavorite'); + } + return( + + + + + + + + -); + ); +} //@ts-ignore export default function ListScreen({navigation}){ @@ -114,10 +117,15 @@ const styles = StyleSheet.create({ justifyContent: 'center', }, item: { - borderRadius : 15, - backgroundColor: '#efefef', - padding: 20, - margin : 10, + + }, + favoriteButton: { + position: 'absolute', + top: 10, + right: 10, + backgroundColor: 'transparent', + borderRadius: 50, + padding: 10, }, title: { fontStyle: "italic", diff --git a/service/AsyncStorage.tsx b/service/AsyncStorage.tsx index 84ec2a6..c7c237b 100644 --- a/service/AsyncStorage.tsx +++ b/service/AsyncStorage.tsx @@ -1,6 +1,7 @@ import { Card } from "../models/Card"; import AsyncStorage from "@react-native-async-storage/async-storage"; + export class AsyncStorageCard{ static AddCardStorage(name : string, cards : Card[]){ From 565cf8fec16eb9cf6194ced1491cc3dd7f90e609 Mon Sep 17 00:00:00 2001 From: "Corentin \"Koroh\" RICHARD" Date: Fri, 17 Mar 2023 09:01:31 +0100 Subject: [PATCH 03/12] Adding asynStorage methods --- models/Card.tsx | 11 +++++++++- screens/ListScreen.tsx | 27 +++++++++++++---------- service/AsyncStorage.tsx | 46 ++++++++++++++++++++++++++++++---------- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/models/Card.tsx b/models/Card.tsx index d85f1f0..655bd73 100644 --- a/models/Card.tsx +++ b/models/Card.tsx @@ -5,7 +5,7 @@ import {Classe} from "./Classe"; export class Card { - constructor(id: number,name :string, img : string, imgGold : string){//,set : CardSet,type : Type,clas : Classe,rarity : string,cost : number,attack : number, health : number, desc : string,flavor : string,artist : string,collectible : boolean,elite : boolean,race : string, cropImg :string) { + constructor(id: number,name :string, img : string, imgGold : string,fav : boolean = true){//,set : CardSet,type : Type,clas : Classe,rarity : string,cost : number,attack : number, health : number, desc : string,flavor : string,artist : string,collectible : boolean,elite : boolean,race : string, cropImg :string ) { this._id=id this._name=name //this._set=set @@ -22,6 +22,7 @@ export class Card { this._img = img this._imgGold = imgGold // this._cropImg = cropImg + this._fav = fav } @@ -155,4 +156,12 @@ export class Card { // set cropImg(value: string) { // this._cropImg = value; // } + + private _fav : boolean + get fav(): boolean{ + return this._fav; + } + set fav(value : boolean){ + this._fav = value; + } } \ No newline at end of file diff --git a/screens/ListScreen.tsx b/screens/ListScreen.tsx index 15a84cf..22c6699 100644 --- a/screens/ListScreen.tsx +++ b/screens/ListScreen.tsx @@ -1,5 +1,5 @@ -import { StyleSheet, Text, View, Button, TouchableHighlight, TextInput } from 'react-native'; +import { StyleSheet, Text, View, Button, TouchableHighlight, TextInput, ImageBackground } from 'react-native'; import { StatusBar } from 'expo-status-bar'; import React, { useState, useEffect } from "react"; import { FlatList } from 'react-native-gesture-handler'; @@ -20,16 +20,16 @@ import { ImageURISource } from 'react-native'; //@ts-ignore -const Item = ({url}) => { // a mettre dans components et definir une props pour passer le param +const Item = ({url,item}) => { // a mettre dans components et definir une props pour passer le param const HandleAddFav = () => { - console.log('addfavorite'); + item.fav = !item.fav } return( - + @@ -45,7 +45,6 @@ export default function ListScreen({navigation}){ // // Initialize the binding content with the application initial state - //@ts-ignore const nList = useSelector(state => state.appReducer.cards); // Create a const that will hold the react-redux events dispatcher @@ -65,9 +64,7 @@ export default function ListScreen({navigation}){ - //* Stub - // const {getCards} = new StubLib(); - // const list: Card[] = getCards(); + // const req = fetch('https://omgvamp-hearthstone-v1.p.rapidapi.com/cards') //https://us.api.blizzard.com/hearthstone/cards/678?locale=en_US @@ -93,7 +90,7 @@ export default function ListScreen({navigation}){ data={filteredList} renderItem={({item}) => navigation.navigate("ListFav")}> - + } keyExtractor={(item: Card) => item.id.toString()} @@ -127,11 +124,19 @@ const styles = StyleSheet.create({ item: { }, - favoriteButton: { + favoriteButtonNonFav: { + position: 'absolute', + top: 10, + right: 10, + backgroundColor: 'red', + borderRadius: 50, + padding: 10, + }, + favoriteButtonFav: { position: 'absolute', top: 10, right: 10, - backgroundColor: 'transparent', + backgroundColor: 'red', borderRadius: 50, padding: 10, }, diff --git a/service/AsyncStorage.tsx b/service/AsyncStorage.tsx index c7c237b..ff6e412 100644 --- a/service/AsyncStorage.tsx +++ b/service/AsyncStorage.tsx @@ -2,17 +2,41 @@ import { Card } from "../models/Card"; import AsyncStorage from "@react-native-async-storage/async-storage"; -export class AsyncStorageCard{ +export default class Storage { - static AddCardStorage(name : string, cards : Card[]){ - const storeFavoriteNounours = async (cards : Card[]) => { - try { - const jsonCard = JSON.stringify(cards) - await AsyncStorage.setItem(name, jsonCard); - } catch (e) { - console.log("An error occurred", e); - } + static async getItem(key: string): Promise { + try { + const value = await AsyncStorage.getItem(key); + if (value !== null) { + return JSON.parse(value); } + } catch (e) { + console.error(`AsyncStorage getItem error: ${e}`); + } + return null; } - -} \ No newline at end of file + + static async setItem(key: string, value: any): Promise { + try { + await AsyncStorage.setItem(key, JSON.stringify(value)); + } catch (e) { + console.error(`AsyncStorage setItem error: ${e}`); + } + } + + static async removeItem(key: string): Promise { + try { + await AsyncStorage.removeItem(key); + } catch (e) { + console.error(`AsyncStorage removeItem error: ${e}`); + } + } + + static async clear(): Promise { + try { + await AsyncStorage.clear(); + } catch (e) { + console.error(`AsyncStorage clear error: ${e}`); + } + } +} From 88a6612e770ae42f446611bfea891341cd65a1f9 Mon Sep 17 00:00:00 2001 From: "Corentin \"Koroh\" RICHARD" Date: Fri, 7 Apr 2023 09:27:19 +0200 Subject: [PATCH 04/12] favorite update --- components/ListItemComponent.tsx | 62 ++++++++++--- props/favprops.tsx | 8 ++ redux/actions/actionSelection.tsx | 6 +- redux/actions/action_setFavList.tsx | 6 +- redux/constants.tsx | 3 +- redux/reducers/appReducer.tsx | 18 +++- screens/ListFav.tsx | 136 +++++++++++----------------- screens/ListScreen.tsx | 73 ++------------- service/AsyncStorage.tsx | 2 +- 9 files changed, 144 insertions(+), 170 deletions(-) create mode 100644 props/favprops.tsx diff --git a/components/ListItemComponent.tsx b/components/ListItemComponent.tsx index e9b4d7d..037b2cc 100644 --- a/components/ListItemComponent.tsx +++ b/components/ListItemComponent.tsx @@ -1,17 +1,53 @@ -import { View } from 'react-native'; -import { Image } from 'react-native'; +import { useDispatch } from "react-redux"; +import { Card } from "../models/Card"; +import { setFavList } from "../redux/actions/action_setFavList"; +import { ImageBackground, TouchableHighlight, View } from "react-native"; +import React, { useEffect } from "react"; +import {CardProps} from "../props/favprops" +import { FontAwesome } from '@expo/vector-icons'; +import { StyleSheet} from 'react-native'; +export default function Item(props: CardProps){ // a mettre dans components et definir une props pour passer le param + + const {route} = props; + const item: Card = route.card; + const bool: boolean = route.bool; + const dispatch = useDispatch() -type ItemProps = { - url : string //Image URL -} + const HandleAddFav = (props : CardProps) => { + console.log("add new card") + dispatch(setFavList(props)); + } + return( -export function ListItemComponent(props : ItemProps){ - return ( - - - - ) + /* dispatch , */ + + + HandleAddFav(props)} > + + + + + + ); } +const styles = StyleSheet.create({ +item: { + + }, + favoriteButtonNonFav: { + position: 'absolute', + top: 10, + right: 10, + backgroundColor: 'red', + borderRadius: 50, + padding: 10, + }, + favoriteButtonFav: { + position: 'absolute', + top: 10, + right: 10, + backgroundColor: 'red', + borderRadius: 50, + padding: 10, + },}); \ No newline at end of file diff --git a/props/favprops.tsx b/props/favprops.tsx new file mode 100644 index 0000000..2662592 --- /dev/null +++ b/props/favprops.tsx @@ -0,0 +1,8 @@ +import { Card } from "../models/Card"; + +export interface CardProps{ + route : { + card: Card; + bool: boolean; + } +} \ No newline at end of file diff --git a/redux/actions/actionSelection.tsx b/redux/actions/actionSelection.tsx index 533a5d9..3b2cf3f 100644 --- a/redux/actions/actionSelection.tsx +++ b/redux/actions/actionSelection.tsx @@ -25,7 +25,7 @@ import { Card } from "../../models/Card"; // constructor(cardId : String, name : String, manaCost : number, attack : number, health : number, desc : String){ // this.cardId = cardId; // this.name = name; -// this.manaCost = manaCost; +// this.manaCost = manaCost;ADD_FAVORITE_DATA, FETCH_DATA, // this.attack = attack; // this.health = health; // this.desc = desc; @@ -50,7 +50,7 @@ export const getAllCards = () => { // 'content-length':'9505', // 'content-type':'application/json; charset=utf-8', // 'etag':'W/"74bb-QMT8DIj6saBS1wT4u5WWcEmZAdw"' - // } + // }ADD_FAVORITE_DATA, FETCH_DATA, //! Actualisation de l'API (16/03) : headers: { @@ -61,7 +61,7 @@ export const getAllCards = () => { //'pageSize':'100' }; //! Actualisation de l'API (16/03) : - const CardsPromise = await fetch('https://us.api.blizzard.com/hearthstone/cards?locale=en_US&access_token=EU1AbKy9Q7sOUjQYC5AFF1O1JPuoAgCNxk', options); + const CardsPromise = await fetch('https://us.api.blizzard.com/hearthstone/cards?locale=en_US&access_token=EUe6p4N9uLm8BbsHyYVZXIa4DDBP2hMR05', options); //const CardsPromise = await fetch('https://us.api.blizzard.com/hearthstone/cards?locale=en_US&access_token=EURTWhjBC2SRb4Ez42BT1kx8R2NcJc07kL', options); //console.log("FETCH") //console.log(CardsPromise) diff --git a/redux/actions/action_setFavList.tsx b/redux/actions/action_setFavList.tsx index 960fe9d..8707ffa 100644 --- a/redux/actions/action_setFavList.tsx +++ b/redux/actions/action_setFavList.tsx @@ -1,8 +1,10 @@ +import { Card } from '../../models/Card'; +import { CardProps } from '../../props/favprops'; import {ADD_FAVORITE_DATA, FETCH_DATA} from '../constants'; -export const setFavList = (List: String[]) => { +export const setFavList = (props : CardProps) => { return { type: ADD_FAVORITE_DATA, - payload: List, + payload: props, }; } \ No newline at end of file diff --git a/redux/constants.tsx b/redux/constants.tsx index ff6ccf4..ec2bb60 100644 --- a/redux/constants.tsx +++ b/redux/constants.tsx @@ -4,4 +4,5 @@ export const FETCH_DATA = "FETCH_DATA" export const ADD_FAVORITE_DATA = "ADD_FAVORITE_DATA" -export const DISPLAY_ALL_CARD = "DISPLAY_ALL_CARD" \ No newline at end of file +export const DISPLAY_ALL_CARD = "DISPLAY_ALL_CARD" + diff --git a/redux/reducers/appReducer.tsx b/redux/reducers/appReducer.tsx index 0af429d..82cac37 100644 --- a/redux/reducers/appReducer.tsx +++ b/redux/reducers/appReducer.tsx @@ -1,10 +1,9 @@ +import { CardProps } from '../../props/favprops' import {FETCH_DATA, ADD_FAVORITE_DATA} from '../constants' const initialState = { cards: [], - favoriteCards: [], - // cards: ["C_ace", "C_K", "C_Q", "C_J"], - // favoriteCards: [ "C_ace", "C_K"], + favoriteCards: [] } @@ -12,8 +11,17 @@ const initialState = { export default appReducer = (state = initialState, action) => { switch (action.type) { case ADD_FAVORITE_DATA: - // @ts-ignore - return {...state, favoriteCards: state.favoriteCards.push(action.payload)}; + const a : CardProps = action.payload + if(a.route.bool ==false){ + //@ts-ignore + const tab = state.favoriteCards.concat([a.route.card]) + console.log(state.favoriteCards) + return {...state, favoriteCards : tab}; + } + else{ + const tab = state.favoriteCards.filter((item) => item!= a.route.card) + return {...state, favoriteCards : tab }; + } case FETCH_DATA: // @ts-ignore return {...state, cards: action.payload}; diff --git a/screens/ListFav.tsx b/screens/ListFav.tsx index 61bb8fe..9ff355c 100644 --- a/screens/ListFav.tsx +++ b/screens/ListFav.tsx @@ -1,91 +1,64 @@ -import { StyleSheet, Text, View, Button, FlatList } from 'react-native'; -import { StatusBar } from 'expo-status-bar'; -import React, { useState } from "react"; - -import {setFavList } from '../redux/actions/action_setFavList'; -//redux +import { StyleSheet, Text, View, Button, TouchableHighlight, TextInput, ImageBackground } from 'react-native'; +import { StatusBar } from 'expo-status-bar'; +import React, { useState, useEffect } from "react"; +import { FlatList } from 'react-native-gesture-handler'; import {useDispatch, useSelector} from 'react-redux'; -import {useEffect} from 'react'; +import { FontAwesome } from '@expo/vector-icons'; +import { ThunkAction } from 'redux-thunk'; -export const Cardslist = [ - { - id: '1', - title: "premier élément", - }, - { - id: '2', - title: "second élément", - }, - { - id: '3', - title: "élément", - }, - { - id: '4', - title: "barman douteux", - }, - { - id: '10', - title: "dernier élément", - } -]; - +//? possiblement à supprimer +import { getAllCards } from "../redux/actions/actionSelection" +import { Card } from '../models/Card'; +import { Image } from 'react-native'; +import { ImageURISource } from 'react-native'; +import Item from '../components/ListItemComponent'; +//* Icons +// import { BiSearchAlt } from 'react-icons'; -//@ts-ignore -const Item = ({title}) => ( - - {title} - -); - - - -//TODO -// export const getFavList = () => { -// //In order to use await your callback must be asynchronous using async keyword. -// return async dispatch => { -// //Then perform your asynchronous operations. -// try { -// //Have it first fetch data from our starwars url. -// //const nounoursPromise = await fetch('https://iut-weather-api.azurewebsites.net/nounours'); -// //Then use the json method to get json data from api/ -// //const nounoursListJson = await nounoursPromise.json(); -// //const nounoursList: Nounours[] = nounoursListJson.map(elt => new Nounours(elt["name"], elt["age"], elt["nbPoils"], elt["image"])); - -// dispatch(setFavList(Array{id,title})); -// } catch (error) { -// console.log('Error---------', error); -// //You can dispatch to another action if you want to display an error message in the application -// //dispatch(fetchDataRejected(error)) -// } -// } -// } +//* Components +//@ts-ignore +export default function ListScreen({navigation}){ + //@ts-ignore + let nList = useSelector(state => state.appReducer.favoriteCards); + console.log(nList) + const [searchValue, setSearchValue] = useState(''); -export default function Main(){ - const [count, setCount] = useState(0); - return ( - Maman, J4AI UNE LISTE DE FAVORIS ! ! - - {count} -