master
gorky1234 2 years ago
parent b59f0d961c
commit c041f6f4dd

@ -0,0 +1,54 @@
import AsyncStorage from "@react-native-async-storage/async-storage";
import {Artist} from "../Model/Artist";
export const storeLikeArtists = async (artistsList) => {
try {
const jsonArtistsList = JSON.stringify(artistsList);
await AsyncStorage.setItem('likeArtists', jsonArtistsList);
} catch (e) {
console.log("An error occurred while storing artists list", e);
}
};
export const getLikeArtist = async () => {
try {
const jsonArtistsList = await AsyncStorage.getItem('likeArtists');
const artistsList = jsonArtistsList !== null ? JSON.parse(jsonArtistsList) : [];
console.log("get")
artistsList.map(artist => console.log(artist, artist._id,artist._name,artist._image));
return artistsList.map(artist => new Artist(artist._id,artist._name,artist._image));
} catch (e) {
console.log("An error occurred while retrieving artists list", e);
return [];
}
}
export const getLikeArtistJson = async () => {
try {
const jsonArtistsList = await AsyncStorage.getItem('likeArtists');
return jsonArtistsList !== null ? JSON.parse(jsonArtistsList) : [];
} catch (e) {
console.log("An error occurred while retrieving artists list", e);
return [];
}
}
export const addLikeArtist = async (artist) => {
try {
const artistsList = await getLikeArtistJson();
artistsList.push(artist);
await storeLikeArtists(artistsList);
} catch (e) {
console.log("An error occurred while adding artist to the list", e);
}
};
export const removeArtist = async (artistId) => {
try {
let artistsList = await getLikeArtistJson();
artistsList = artistsList.filter(artist => artist.id !== artistId);
await storeLikeArtists(artistsList);
} catch (e) {
console.log("An error occurred while removing artist from the list", e);
}
}

@ -4,14 +4,11 @@ export class Artist {
private _id: number
private _name: string;
private _image: string;
private _bio: string;
private _listAlbum: Album[];
constructor(id: number, name: string, image: string,bio: string) {
constructor(id: number, name: string, image: string) {
this._id = id;
this._name = name;
this._image = image;
this._bio = bio;
}
get id(): number{
@ -33,19 +30,4 @@ export class Artist {
this._image = value;
}
get bio(): string {
return this._bio;
}
set bio(value: string) {
this._bio = value;
}
get listAlbum(): Album[] {
return this._listAlbum;
}
set listAlbum(value: Album[]) {
this._listAlbum = value;
}
}

@ -2,31 +2,43 @@
import React from 'react';
import {View, Image, Text, StyleSheet} from 'react-native';
const AlbumCard = ({ album }) => {
console.log(album);
const date = new Date(album.date);
const formattedDate = date.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
return (
<View style={styles.container}>
<Image source={{ uri: album.coverUrl }} style={styles.image}/>
<Text style={styles.name}>{album.name}</Text>
<View style={styles.containerText}>
<Text style={styles.name}>{album.name}</Text>
<Text>{formattedDate}</Text>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
margin: 10,
flexDirection: 'row',
alignItems: 'center',
margin: 10,
},
image: {
width: 50,
height: 50,
marginRight: 10,
containerText:{
flexDirection: 'column',
alignItems: 'flex-start'
},
name: {
fontSize: 20,
fontWeight: 'bold',
},
image: {
width: 50,
height: 50,
marginRight: 10,
},
});
export default AlbumCard;

@ -5,20 +5,19 @@ import AlbumCard from "./AlbumCard";
const ArtistList = ({ALBUM_LIST}) => {
return (
<View style={styles.container}>
<FlatList
data={ALBUM_LIST}
renderItem={({ item }) => (
<AlbumCard album={item} />
<FlatList data={ALBUM_LIST} renderItem={({ item }) => (
<AlbumCard key={item.id} album={item} />
)}
keyExtractor={(item) => item.name}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
height: 400,
width: '100%',
height: '70%',
}
});

@ -1,17 +1,15 @@
// @ts-ignore
import React from 'react';
import {View, Image, Text, StyleSheet, TouchableNativeFeedback} from 'react-native';
import {View, Image, Text, StyleSheet, TouchableNativeFeedback, TouchableOpacity} from 'react-native';
const ArtistCard = ({ navigation, item }) => {
//console.log(item)
return (
<TouchableNativeFeedback onPress={() => { navigation.navigate("ArtistDetail",{"artist":item});}}>
<TouchableOpacity onPress={() => { console.log("ici");navigation.navigate("ArtistDetail",{"artist":item});console.log("non ici");}}>
<View style={styles.container}>
<Image source={{ uri: item.image }} style={styles.image}/>
<Text style={styles.name}>{item.name}</Text>
</View>
</TouchableNativeFeedback>
</TouchableOpacity>
);
};

@ -1,38 +1,55 @@
import React from "react";
import {FlatList, ScrollView} from "react-native";
import React, {useEffect, useState} from "react";
import {FlatList, Text, View} from "react-native";
import {useSelector} from 'react-redux';
import {useEffect} from 'react';
import ArtistCard from "./ArtistCard";
import {getLikeArtist} from './../../AsyncStorage/likeArtistStorage'
const ArtistList = ({ navigation, type }) => {
const [artistsList, setArtistsList] = useState([]);
const artists = useSelector((state) => {
if (type === "search") {
// @ts-ignore
return state.ReducerArtist.artistsSearch;
} else if (type === "liked") {
// @ts-ignore
return state.ReducerArtist.likedArtists;
}
return [];
});
const ArtistList = ({navigation, type}) => {
// @ts-ignore
let ARTISTS_LIST = useSelector((state) => state.ReducerArtist.artists);
if(type == "search") {
// @ts-ignore
ARTISTS_LIST = useSelector((state) => state.ReducerArtist.artistsSearch);
}
useEffect(() => {
if (type === "liked") {
async function fetchLikedArtists() {
const likedArtists = await getLikeArtist();
setArtistsList(likedArtists);
}
fetchLikedArtists();
}
}, [type]);
useEffect(() => {
console.log('ARTISTS_LIST has changed:', ARTISTS_LIST);
}, [ARTISTS_LIST]);
setArtistsList(artists);
}, [artists]);
console.log('artistsList',artistsList)
if(artistsList == undefined){
console.log("Loading")
return <Text>Loading...</Text>
}
console.log('pas Loading')
console.log("----")
console.log(ARTISTS_LIST)
return (
<ScrollView>
<View>
<FlatList
data={ARTISTS_LIST}
data={artistsList}
renderItem={({ item }) => (
<ArtistCard navigation={navigation} item={item} />
<ArtistCard key={item.id} navigation={navigation} item={item} />
)}
keyExtractor={(item) => item.name}
keyExtractor={(item) => item.id}
/>
</ScrollView>
</View>
);
};
export default ArtistList;

@ -1,40 +1,67 @@
// @ts-ignore
import React, {useEffect} from 'react';
import React, {useEffect, useState} from 'react';
import { View, Image, Text, StyleSheet } from 'react-native';
import {getAlbumByArtist, getArtistInfo} from "../../redux/actions/action";
import {useDispatch} from "react-redux";
import ArtistList from "../Album/AlbumList";
import AlbumList from "../Album/AlbumList";
import LikeButton from "./likeButton";
export default function ArtistPage({ route }) {
const [bio, setBio] = useState("");
const [albumList, setAlbumList] = useState("");
const artist = route.params.artist;
const dispatch = useDispatch();
useEffect(() => {
const load = async () => {
// @ts-ignore
await dispatch(getArtistInfo(artist));
const bio = await dispatch(getArtistInfo(artist));
if (bio) {
// @ts-ignore
setBio(bio);
}
// @ts-ignore
await dispatch(getAlbumByArtist(artist));
const albumList = await dispatch(getAlbumByArtist(artist));
if (albumList) {
console.log(albumList)
// @ts-ignore
setAlbumList(albumList)
}
};
load();
})
}, [artist, dispatch])
return (
<View style={styles.container}>
<Image source={{ uri: artist.image }} style={styles.image} />
<View style={styles.likeButtonContainer}>
<LikeButton artist={artist}/>
</View>
<Text style={styles.name}>{artist.name}</Text>
<Text style={styles.bio}>{artist.bio}</Text>
<Text style={styles.bio}>{bio}</Text>
<Text style={styles.titre}>Liste Album</Text>
<ArtistList ALBUM_LIST={artist.listAlbum}/>
<AlbumList ALBUM_LIST={albumList}/>
</View>
);
};
}
const styles = StyleSheet.create({
container: {
marginTop:10,
alignItems: 'center'
alignItems: 'center',
position: 'relative'
},
likeButtonContainer: {
position: 'absolute',
right: 10,
backgroundColor: 'white',
borderRadius: 20,
borderWidth: 2,
borderColor: 'black',
padding: 10,
margin: 10
},
image: {
width: 100,
@ -56,4 +83,4 @@ const styles = StyleSheet.create({
fontSize: 20,
fontWeight: "bold"
}
});
});

@ -0,0 +1,39 @@
import React, {useEffect, useState} from 'react';
import { TouchableOpacity, View } from 'react-native';
import {AntDesign} from "@expo/vector-icons";
import {addLikeArtist, getLikeArtist, removeArtist} from '../../AsyncStorage/likeArtistStorage';
const LikeButton = ({ artist }) => {
const [isLiked, setIsLiked] = useState(false);
const [likedArtists, setLikedArtists] = useState([]);
useEffect(() => {
const fetchLikedArtists = async () => {
const artists = await getLikeArtist();
setLikedArtists(artists);
setIsLiked(artists.some((a) => a._id === artist._id));
};
fetchLikedArtists();
}, [artist]);
const handleLike = () => {
setIsLiked(true);
addLikeArtist(artist);
};
const handleDislike = () => {
setIsLiked(false);
removeArtist(artist._id);
};
return (
<TouchableOpacity onPress={isLiked ? handleDislike : handleLike}>
<View>
<AntDesign name="heart" size={24} color={isLiked ? 'gold' : 'black'} />
</View>
</TouchableOpacity>
);
}
export default LikeButton;

@ -1,13 +1,13 @@
import React, {useState} from 'react';
import {View, Text, StyleSheet, TextInput} from 'react-native';
import React from 'react';
import {View, StyleSheet, Text} from 'react-native';
import ArtistList from "./Artist/ArtistList";
import SearchBar from "./SearchBar";
const HomePage = ({navigation}) => {
return (
<View style={styles.container}>
<ArtistList navigation={navigation}/>
<Text style={styles.titre}>Artiste favori</Text>
<ArtistList navigation={navigation} type={"liked"}/>
</View>
);
};
@ -22,6 +22,10 @@ const styles = StyleSheet.create({
fontWeight: 'bold',
textAlign: 'center',
},
titre: {
fontSize: 20,
fontWeight: "bold"
}
});
export default HomePage;

@ -5,7 +5,7 @@ import SettingsPage from "../SettingsPage";
import StackNavigationHomePage from "./StackNavigationHomePage";
import StackNavigationSearchPage from "./StackNavigationSearchPage";
export default function NavigationBar() {
function NavigationBar() {
const BottomTabNavigator = createBottomTabNavigator();
return (
<NavigationContainer >
@ -18,12 +18,9 @@ export default function NavigationBar() {
title: 'Search',
tabBarIcon: () => (<AntDesign name="search1" size={24} color="black" />)
}}/>
<BottomTabNavigator.Screen name="Settings" component={SettingsPage} options={{
title: 'Settings',
tabBarIcon: () => (<Ionicons name="settings-outline" size={24} color="black" />)
}}/>
</BottomTabNavigator.Navigator>
</NavigationContainer>
)
}
export default NavigationBar;

@ -7,11 +7,13 @@ import SearchPage from "../SearchPage";
const Stack = createStackNavigator();
export default function StackNavigationSearchPage() {
function StackNavigationSearchPage() {
return (
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Search" component={SearchPage}/>
<Stack.Screen name="ArtistDetail" component={ArtistePage}/>
<Stack.Screen name="Detail sur un artiste" component={ArtistePage}/>
</Stack.Navigator>
)
}
}
export default StackNavigationSearchPage;

@ -9,7 +9,6 @@ const SearchBar = () => {
const dispatch = useDispatch();
const handleSearch = () => {
console.log(searchText)
const loadArtist = async () => {
// @ts-ignore
await dispatch(searchArtists(searchText));

72
package-lock.json generated

@ -11,10 +11,12 @@
"@expo/ngrok": "^4.1.0",
"@expo/vector-icons": "^13.0.0",
"@extra-fs/promises": "^3.1.4",
"@react-native-async-storage/async-storage": "1.17.11",
"@react-navigation/bottom-tabs": "^6.5.7",
"@react-navigation/native": "^6.1.6",
"@react-navigation/stack": "^6.3.16",
"@reduxjs/toolkit": "^1.9.3",
"date-fns": "^2.29.3",
"expo": "^48.0.5",
"expo-cli": "^6.3.2",
"expo-status-bar": "~1.4.4",
@ -4036,6 +4038,17 @@
"node": ">=10"
}
},
"node_modules/@react-native-async-storage/async-storage": {
"version": "1.17.11",
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.11.tgz",
"integrity": "sha512-bzs45n5HNcDq6mxXnSsOHysZWn1SbbebNxldBXCQs8dSvF8Aor9KCdpm+TpnnGweK3R6diqsT8lFhX77VX0NFw==",
"dependencies": {
"merge-options": "^3.0.4"
},
"peerDependencies": {
"react-native": "^0.0.0-0 || 0.60 - 0.71 || 1000.0.0"
}
},
"node_modules/@react-native-community/cli": {
"version": "10.1.3",
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.1.3.tgz",
@ -8353,6 +8366,18 @@
"resolved": "https://registry.npmjs.org/dag-map/-/dag-map-1.0.2.tgz",
"integrity": "sha512-+LSAiGFwQ9dRnRdOeaj7g47ZFJcOUPukAP8J3A3fuZ1g9Y44BG+P1sgApjLXTQPOzC4+7S9Wr8kXsfpINM4jpw=="
},
"node_modules/date-fns": {
"version": "2.29.3",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
"integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==",
"engines": {
"node": ">=0.11"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/date-fns"
}
},
"node_modules/dateformat": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
@ -13286,6 +13311,25 @@
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
},
"node_modules/merge-options": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
"integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
"dependencies": {
"is-plain-obj": "^2.1.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/merge-options/node_modules/is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
"engines": {
"node": ">=8"
}
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@ -23634,6 +23678,14 @@
}
}
},
"@react-native-async-storage/async-storage": {
"version": "1.17.11",
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.11.tgz",
"integrity": "sha512-bzs45n5HNcDq6mxXnSsOHysZWn1SbbebNxldBXCQs8dSvF8Aor9KCdpm+TpnnGweK3R6diqsT8lFhX77VX0NFw==",
"requires": {
"merge-options": "^3.0.4"
}
},
"@react-native-community/cli": {
"version": "10.1.3",
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.1.3.tgz",
@ -26962,6 +27014,11 @@
"resolved": "https://registry.npmjs.org/dag-map/-/dag-map-1.0.2.tgz",
"integrity": "sha512-+LSAiGFwQ9dRnRdOeaj7g47ZFJcOUPukAP8J3A3fuZ1g9Y44BG+P1sgApjLXTQPOzC4+7S9Wr8kXsfpINM4jpw=="
},
"date-fns": {
"version": "2.29.3",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
"integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA=="
},
"dateformat": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
@ -30803,6 +30860,21 @@
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
},
"merge-options": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
"integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
"requires": {
"is-plain-obj": "^2.1.0"
},
"dependencies": {
"is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="
}
}
},
"merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",

@ -16,6 +16,7 @@
"@react-navigation/native": "^6.1.6",
"@react-navigation/stack": "^6.3.16",
"@reduxjs/toolkit": "^1.9.3",
"date-fns": "^2.29.3",
"expo": "^48.0.5",
"expo-cli": "^6.3.2",
"expo-status-bar": "~1.4.4",
@ -27,7 +28,8 @@
"react-native-safe-area-context": "4.5.0",
"react-native-web": "~0.18.11",
"react-redux": "^8.0.5",
"redux": "^4.2.1"
"redux": "^4.2.1",
"@react-native-async-storage/async-storage": "1.17.11"
},
"devDependencies": {
"@babel/core": "^7.12.9",

@ -1,9 +1,9 @@
import {FETCH_ARTISTE_SEARCH,ACCESS_TOKEN} from '../constants';
import {FETCH_ARTISTE_SEARCH, ACCESS_TOKEN} from '../constants';
import {Artist} from "../../Model/Artist";
import {Album} from "../../Model/Album";
export const setArtistList = (artistList: Artist[]) => {
export const setArtistSearchList = (artistList: Artist[]) => {
return {
type: FETCH_ARTISTE_SEARCH,
payload: artistList,
@ -11,7 +11,6 @@ export const setArtistList = (artistList: Artist[]) => {
}
export const searchArtists = (recherche) => {
console.log("getArtistList");
return async dispatch => {
try{
const response = await fetch(`https://genius.com/api/search/artists?page=1&q=${encodeURIComponent(recherche)}`);
@ -21,69 +20,56 @@ export const searchArtists = (recherche) => {
}
const artistListJson = await response.json();
console.log(artistListJson);
console.log("ici")
const artistList: Artist[] = artistListJson.response.sections[0].hits.map(hit =>
new Artist(hit.result.id, hit.result.name, hit.result.image_url,"")
);
dispatch(setArtistList(artistList));
} catch (error) {
dispatch(setArtistSearchList(artistList));
} catch (error) {
console.error('Error:', error);
}
}
}
export const getArtistInfo = (artist) => {
console.log(artist._id)
return async dispatch => {
try{
const response = await fetch(`https://api.genius.com/artists/${artist._id}`, {
headers: {
'Authorization': `Bearer ${ACCESS_TOKEN}`,
'Content-Type': 'application/json'
return async (dispatch) => {
try {
const response = await fetch(
`https://api.genius.com/artists/${artist.id}`,
{
headers: {
Authorization: `Bearer ${ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
}
})
);
if (!response.ok) {
console.log(response);
throw new Error('[getArtistInfo] Network response was not ok');
throw new Error("[getArtistInfo] Network response was not ok");
}
const artistInfoJson = await response.json();
artist.bio = artistInfoJson.response.artist.description.dom.children[0].children[0];
} catch (error) {
console.error('Error:', error);
}
}
}
export const getSongByArtist = (artist) => {
return async dispatch => {
try{
const response = await fetch(`https://api.genius.com/artists/${artist.id}/songs`, {
headers: {
'Authorization': `Bearer ${ACCESS_TOKEN}`,
'Content-Type': 'application/json'
var bio = "";
artistInfoJson.response.artist.description.dom.children[0].children.map(
(b) => {
if (typeof b === "object") {
bio += b.children[0];
} else {
bio += b;
}
}
})
if (!response.ok) {
console.log(response);
throw new Error('[getSongByArtist] Network response was not ok');
}
const artistSongsJson = await response.json();
console.log(artistSongsJson);
artistSongsJson.response.songs.map((hit: any) => console.log(hit));
);
return bio; // Return the JSON object
} catch (error) {
console.error('Error:', error);
console.error("Error:", error);
}
}
}
};
};
export const getAlbumByArtist = (artist) => {
return async dispatch => {
@ -96,6 +82,7 @@ export const getAlbumByArtist = (artist) => {
}
const artistAlbumJson = await response.json();
const albumList: Album[] = artistAlbumJson.response.albums.map((album: any) =>
new Album(album.id,
album.name,
@ -104,9 +91,8 @@ export const getAlbumByArtist = (artist) => {
Date(album.release_date_components.day, album.release_date_components.month, album.release_date_components.year)
)
);
artist.listAlbum = albumList;
console.log(artist.listAlbum);
return albumList;
} catch (error) {
console.error('Error:', error);
}

@ -1,5 +1,2 @@
export const FETCH_ARTISTE = 'FETCH_ARTISTE';
export const FETCH_ARTISTE_SEARCH = 'FETCH_ARTISTE_SEARCH';
export const ACCESS_TOKEN = 'M0GAzZXbwqfifGOTxfB7lLmEWlRNadkFGV99E9SQCgirIX58kbcvEFYhu2WajbGH';

@ -1,19 +1,15 @@
import {FETCH_ARTISTE, FETCH_ARTISTE_SEARCH} from '../constants';
import { FETCH_ARTISTE_SEARCH} from '../constants';
const initialState = {
artists: [],
artistsSearch: []
}
export default function ReducerArtist(state = initialState, action){
switch (action.type) {
case FETCH_ARTISTE:
// @ts-ignore
return {...state, artists: action.payload};
case FETCH_ARTISTE_SEARCH:
return {...state, artistsSearch: action.payload};
default:
console.log("nothing")
return state;
}
}
Loading…
Cancel
Save