Skip to content

Commit

Permalink
✨ Applying Redux in the screen of get top artists.
Browse files Browse the repository at this point in the history
  • Loading branch information
krrskl committed Jul 3, 2020
1 parent 7fa7c0f commit 76a79aa
Show file tree
Hide file tree
Showing 14 changed files with 345 additions and 56 deletions.
37 changes: 15 additions & 22 deletions app/components/Artist-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import React, {Component} from 'react';
import {ListItem, Text} from 'react-native-elements';
import {Artist} from 'app/core/models/Artist.model';
import NumberFormat from 'react-number-format';
import {Navigation} from 'react-native-navigation';
import {connect} from 'react-redux';
import {goToArtistDetails} from './../core/store/effects/artist.effects';
interface ArtistItemProps {
artist: Artist;
goToArtistDetails: any;
}

export default class ArtistItemComponent extends Component<ArtistItemProps> {
class ArtistItemComponent extends Component<ArtistItemProps> {
constructor(props: any) {
super(props);
}
Expand All @@ -28,30 +30,21 @@ export default class ArtistItemComponent extends Component<ArtistItemProps> {
}
leftAvatar={{source: {uri: artist.image[0]['#text']}}}
onPress={() => {
this.viewDetails(artist);
this.props.goToArtistDetails(artist);
}}
bottomDivider
chevron
/>
);
}

viewDetails(artist: Artist) {
Navigation.push('ArtistScreen', {
component: {
name: 'ArtistDetailsScreen',
id: 'ArtistDetailsScreen',
passProps: {
artist,
},
options: {
topBar: {
title: {
text: `Detalles de ${this.props.artist.name}`,
},
},
},
},
});
}
}

const mapDispatchToProps = (dispatch: any) => {
return {
goToArtistDetails: (artist: Artist) => {
return dispatch(goToArtistDetails(artist));
},
};
};

export default connect(null, mapDispatchToProps)(ArtistItemComponent);
10 changes: 5 additions & 5 deletions app/core/models/Artist-response.model.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ export interface ArtistResponse {

export interface Topartists {
artist: Artist[];
'@attr': Attr;
'@attr': ArtistAttr;
}

export interface Attr {
country: string;
export interface ArtistAttr {
country?: string;
page: string;
perPage: string;
perPage?: string;
totalPages: string;
total: string;
total?: string;
}
6 changes: 4 additions & 2 deletions app/core/navigation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ const store = configureStore();
export function registerScreens(): void {
Navigation.registerComponent('HomeScreen', () => HomeScreen);
Navigation.registerComponentWithRedux(
'ArtistScreen',
'ArtistsScreen',
() => ArtistScreen,
Provider,
store,
);
Navigation.registerComponent(
Navigation.registerComponentWithRedux(
'ArtistDetailsScreen',
() => ArtistDetailsScreen,
Provider,
store,
);
Navigation.registerComponentWithRedux(
'TracksScreen',
Expand Down
4 changes: 3 additions & 1 deletion app/core/services/artist-service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import {BaseService} from './base-api';
export class ArtistService extends BaseService {
private method: string = 'geo.gettopartists';

public getAllTopArtist(): Promise<any> {
public getAllTopArtists(limit: number = 10, page: number = 1): Promise<any> {
const params = {
country: 'colombia',
method: this.method,
limit,
page,
};
return super.get('/', params);
}
Expand Down
37 changes: 37 additions & 0 deletions app/core/store/actions/artist.actions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {Artist} from '../../models/Artist.model';
import {ArtistAttr} from '../../models/Artist-response.model';

const ArtistActionTypes = {
GET_ARTISTS: '[ARTISTS] Get tracks',
GET_ARTISTS_SUCCESS: '[ARTISTS] Get tracks success',
GET_ARTISTS_FAILURE: '[ARTISTS] Get tracks failure',

SET_ARTIST: '[ARTISTS] Set track',

NEXT_PAGE: '[ARTISTS] Next page',
PREV_PAGE: '[ARTISTS] Prev page',
};

export const getArtists = () => {
return {type: ArtistActionTypes.GET_ARTISTS};
};

export const getArtistsSuccess = (tracks: Artist[], paginator: ArtistAttr) => {
return {type: ArtistActionTypes.GET_ARTISTS_SUCCESS, tracks, paginator};
};

export const getArtistsFailure = (error: string) => {
return {type: ArtistActionTypes.GET_ARTISTS_FAILURE, error};
};

export const setArtist = (track: Artist) => {
return {type: ArtistActionTypes.SET_ARTIST, track};
};

export const nextPage = (page: number) => {
return {type: ArtistActionTypes.NEXT_PAGE, page};
};

export const prevPage = (page: number) => {
return {type: ArtistActionTypes.PREV_PAGE, page};
};
3 changes: 2 additions & 1 deletion app/core/store/actions/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as TrackActions from './track.actions';
import * as ArtistActions from './artist.actions';

export {TrackActions};
export {TrackActions, ArtistActions};
68 changes: 68 additions & 0 deletions app/core/store/effects/artist.effects.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {ArtistActions} from '../actions';
import {ArtistService} from '../../services/artist-service';
import {ArtistResponse} from '../../models/Artist-response.model';
import {Artist} from '../../models/Artist.model';
import {Navigation} from 'react-native-navigation';

const artistService = new ArtistService();

export const fetchArtists = () => {
return (dispatch: any, getState: any) => {
dispatch({type: ArtistActions.getArtists});

const {page, limit} = getState().artistsScreenStore.paginator;

artistService.getAllTopArtists(limit, page).then((resp) => {
const data: ArtistResponse = resp.data;
dispatch({
type: ArtistActions.getArtistsSuccess,
artists: data.topartists.artist,
paginator: data.topartists['@attr'],
});
});
};
};

export const fetchNextPage = () => {
return (dispatch: any, getState: any) => {
let {page, totalPages} = getState().artistsScreenStore.paginator;

if (page < totalPages) {
page = parseInt(`${page}`, 10) + 1;

dispatch({type: ArtistActions.nextPage, page});
dispatch(fetchArtists());
}
};
};

export const fetchPrevPage = () => {
return (dispatch: any, getState: any) => {
let {page} = getState().artistsScreenStore.paginator;
if (page > 1) {
page = parseInt(`${page}`, 10) - 1;

dispatch({type: ArtistActions.nextPage, page});
dispatch(fetchArtists());
}
};
};

export const goToArtistDetails = (artist: Artist) => {
return (dispatch: any) => {
dispatch({type: ArtistActions.setArtist, artist});
Navigation.push('ArtistsScreen', {
component: {
name: 'ArtistDetailsScreen',
id: 'ArtistDetailsScreen',
options: {
topBar: {
title: {
text: `Detalles de ${artist.name}`,
},
},
},
},
});
};
};
65 changes: 65 additions & 0 deletions app/core/store/reducers/artist.reducer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import {Artist} from '../../models/Artist.model';
import {ArtistActions} from '../actions';
import {ArtistAttr} from '../../models/Artist-response.model';

export interface ArtistState {
artists: Artist[];
artist: Artist | null;
loading: boolean;
error: string;
limit: number;
paginator: ArtistAttr;
}

const initialState: ArtistState = {
artists: [],
artist: null,
loading: false,
error: '',
limit: 10,
paginator: {page: '1', totalPages: '0'},
};

export default function artistReducer(
state: ArtistState = initialState,
action: any,
) {
switch (action.type) {
case ArtistActions.getArtists:
return {
...state,
loading: true,
};

case ArtistActions.getArtistsSuccess:
const {artists, paginator} = action;
return {
...state,
artists: [...artists],
paginator,
loading: false,
};

case ArtistActions.getArtistsFailure:
return {
...state,
loading: false,
erorr: action.error,
};

case ArtistActions.setArtist:
return {
...state,
artist: action.artist,
};

case ArtistActions.nextPage:
return {...state, paginator: {...state.paginator, page: action.page}};

case ArtistActions.prevPage:
return {...state, paginator: {...state.paginator, page: action.page}};

default:
return state;
}
}
6 changes: 5 additions & 1 deletion app/core/store/reducers/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import {combineReducers} from 'redux';
import trackReducer from './track.reducer';
import artistReducer from './artist.reducer';

const rootReducer = combineReducers({tracksScreenStore: trackReducer});
const rootReducer = combineReducers({
tracksScreenStore: trackReducer,
artistsScreenStore: artistReducer,
});

export default rootReducer;
15 changes: 11 additions & 4 deletions app/screens/Artist-details/ArtistDetailsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ import {Text, Badge, Card, Icon} from 'react-native-elements';
import {Artist} from '../../core/models/Artist.model';
import ArtistDetailsStyles from './styles';
import NumberFormat from 'react-number-format';
import {connect} from 'react-redux';

interface ArtistDetailsScreenProps {
artist: Artist | null;
}

export default class ArtistDetailsScreen extends Component<
ArtistDetailsScreenProps,
any
> {
class ArtistDetailsScreen extends Component<ArtistDetailsScreenProps, any> {
constructor(props: any) {
super(props);
}
Expand Down Expand Up @@ -70,3 +68,12 @@ export default class ArtistDetailsScreen extends Component<
);
}
}

const mapStateToProps = (state: any) => {
const {artistsScreenStore} = state;
return {
artist: artistsScreenStore.artist,
};
};

export default connect(mapStateToProps)(ArtistDetailsScreen);
Loading

0 comments on commit 76a79aa

Please sign in to comment.