Skip to content

Commit 22add17

Browse files
authored
feat: Make the starred repositories list paged (#750)
* feat: Make the starred repositories list paged using the new api * Revert "feat: Make the starred repositories list paged using the new api" This reverts commit fdabf02. * feat: Make the starred repositories list paged using the new api * fix: remove leftovers * fix: make repo id always lowercase
1 parent 9b3421e commit 22add17

File tree

9 files changed

+93
-66
lines changed

9 files changed

+93
-66
lines changed

src/api/actions/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ import { createPaginationActionSet } from 'utils';
33
export const ACTIVITY_GET_EVENTS_RECEIVED = createPaginationActionSet(
44
'ACTIVITY_GET_EVENTS_RECEIVED'
55
);
6+
export const ACTIVITY_GET_STARRED_REPOS_FOR_USER = createPaginationActionSet(
7+
'ACTIVITY_GET_STARRED_REPOS_FOR_USER'
8+
);

src/api/client.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,5 +141,12 @@ export class Client {
141141
})
142142
);
143143
},
144+
getStarredReposForUser: async (userId, params) => {
145+
return this.call(`users/${userId}/starred`, params).then(response => ({
146+
response,
147+
nextPageUrl: this.getNextPageUrl(response),
148+
schema: Schemas.REPO_ARRAY,
149+
}));
150+
},
144151
};
145152
}

src/api/reducers/pagination.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,7 @@ const paginate = types => {
7878
// Updates the pagination data for different actions.
7979
export const pagination = combineReducers({
8080
ACTIVITY_GET_EVENTS_RECEIVED: paginate(Actions.ACTIVITY_GET_EVENTS_RECEIVED),
81+
ACTIVITY_GET_STARRED_REPOS_FOR_USER: paginate(
82+
Actions.ACTIVITY_GET_STARRED_REPOS_FOR_USER
83+
),
8184
});

src/api/schemas/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { eventSchema } from './events';
2+
import { repoSchema } from './repos';
23

34
export default {
45
EVENT: eventSchema,
56
EVENT_ARRAY: [eventSchema],
7+
REPO: repoSchema,
8+
REPO_ARRAY: [repoSchema],
69
};

src/api/schemas/repos.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { schema } from 'normalizr';
2+
3+
export const repoSchema = new schema.Entity(
4+
'repos',
5+
{},
6+
{
7+
idAttribute: repo => repo.full_name.toLowerCase(),
8+
}
9+
);

src/user/screens/starred-repository-list.screen.js

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,85 @@
11
import React, { Component } from 'react';
22
import { connect } from 'react-redux';
3-
import { bindActionCreators } from 'redux';
4-
import { FlatList } from 'react-native';
5-
6-
import { getStarredRepositories } from 'user';
3+
import { FlatList, View, ActivityIndicator } from 'react-native';
74

5+
import { RestClient } from 'api';
86
import {
97
ViewContainer,
108
RepositoryListItem,
119
LoadingRepositoryListItem,
1210
} from 'components';
1311

14-
const mapStateToProps = state => ({
15-
user: state.user.user,
16-
starredRepositories: state.user.starredRepositories,
17-
isPendingStarredRepositories: state.user.isPendingStarredRepositories,
18-
});
12+
const mapStateToProps = (state, ownProps) => {
13+
const {
14+
auth: { user },
15+
pagination: { ACTIVITY_GET_STARRED_REPOS_FOR_USER },
16+
entities: { repos },
17+
} = state;
18+
19+
const userId = ownProps.navigation.state.params.user.login;
20+
21+
const starredReposPagination = ACTIVITY_GET_STARRED_REPOS_FOR_USER[
22+
userId
23+
] || {
24+
ids: [],
25+
isFetching: true,
26+
};
27+
const starredRepos = starredReposPagination.ids.map(id => repos[id]);
28+
29+
return {
30+
user,
31+
starredReposPagination,
32+
starredRepos,
33+
userId,
34+
};
35+
};
1936

20-
const mapDispatchToProps = dispatch =>
21-
bindActionCreators({ getStarredRepositories }, dispatch);
37+
const mapDispatchToProps = {
38+
getStarredReposForUser: RestClient.activity.getStarredReposForUser,
39+
};
2240

2341
class StarredRepositoryList extends Component {
2442
props: {
25-
user: Object,
26-
starredRepositories: Array,
43+
userId: String,
44+
starredRepos: Array,
45+
starredReposPagination: Object,
46+
getStarredReposForUser: Function,
2747
navigation: Object,
28-
isPendingStarredRepositories: boolean,
29-
getStarredRepositories: Function,
3048
};
3149

3250
componentWillMount() {
33-
const user = this.props.navigation.state.params.user;
51+
const { getStarredReposForUser, userId } = this.props;
3452

35-
this.props.getStarredRepositories(user);
53+
getStarredReposForUser(userId);
3654
}
3755

56+
renderFooter = () => {
57+
if (this.props.starredReposPagination.nextPageUrl === null) {
58+
return null;
59+
}
60+
61+
return (
62+
<View
63+
style={{
64+
paddingVertical: 20,
65+
}}
66+
>
67+
<ActivityIndicator animating size="large" />
68+
</View>
69+
);
70+
};
71+
3872
render() {
3973
const {
40-
starredRepositories,
74+
starredReposPagination,
75+
starredRepos,
76+
userId,
4177
navigation,
42-
isPendingStarredRepositories,
4378
} = this.props;
4479

4580
const repoCount = navigation.state.params.repoCount;
81+
const isPendingStarredRepositories =
82+
starredRepos.length === 0 && starredReposPagination.isFetching;
4683

4784
return (
4885
<ViewContainer>
@@ -52,7 +89,18 @@ class StarredRepositoryList extends Component {
5289
)}
5390
{!isPendingStarredRepositories && (
5491
<FlatList
55-
data={starredRepositories}
92+
data={starredRepos}
93+
onRefresh={() =>
94+
this.props.getStarredReposForUser(userId, {
95+
forceRefresh: true,
96+
})
97+
}
98+
refreshing={!starredRepos && starredReposPagination.isFetching}
99+
onEndReached={() =>
100+
this.props.getStarredReposForUser(userId, { loadMore: true })
101+
}
102+
onEndReachedThreshold={0.5}
103+
ListFooterComponent={this.renderFooter}
56104
renderItem={({ item }) => (
57105
<RepositoryListItem repository={item} navigation={navigation} />
58106
)}

src/user/user.action.js

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
GET_IS_FOLLOWING,
1313
GET_IS_FOLLOWER,
1414
GET_REPOSITORIES,
15-
GET_STARRED_REPOSITORIES,
1615
GET_FOLLOWERS,
1716
GET_FOLLOWING,
1817
SEARCH_USER_REPOS,
@@ -202,30 +201,6 @@ export const getRepositories = user => {
202201
};
203202
};
204203

205-
export const getStarredRepositories = user => {
206-
return (dispatch, getState) => {
207-
const url = `/users/${user.login}/starred?per_page=50`;
208-
const accessToken = getState().auth.accessToken;
209-
210-
dispatch({ type: GET_STARRED_REPOSITORIES.PENDING });
211-
212-
v3
213-
.getJson(url, accessToken)
214-
.then(data => {
215-
dispatch({
216-
type: GET_STARRED_REPOSITORIES.SUCCESS,
217-
payload: data,
218-
});
219-
})
220-
.catch(error => {
221-
dispatch({
222-
type: GET_STARRED_REPOSITORIES.ERROR,
223-
payload: error,
224-
});
225-
});
226-
};
227-
};
228-
229204
export const getFollowing = user => {
230205
return (dispatch, getState) => {
231206
const accessToken = getState().auth.accessToken;

src/user/user.reducer.js

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
GET_IS_FOLLOWING,
55
GET_IS_FOLLOWER,
66
GET_REPOSITORIES,
7-
GET_STARRED_REPOSITORIES,
87
GET_FOLLOWERS,
98
GET_FOLLOWING,
109
SEARCH_USER_REPOS,
@@ -165,23 +164,6 @@ export const userReducer = (state = initialState, action = {}) => {
165164
error: action.payload,
166165
isPendingRepositories: false,
167166
};
168-
case GET_STARRED_REPOSITORIES.PENDING:
169-
return {
170-
...state,
171-
isPendingStarredRepositories: true,
172-
};
173-
case GET_STARRED_REPOSITORIES.SUCCESS:
174-
return {
175-
...state,
176-
starredRepositories: action.payload,
177-
isPendingStarredRepositories: false,
178-
};
179-
case GET_STARRED_REPOSITORIES.ERROR:
180-
return {
181-
...state,
182-
error: action.payload,
183-
isPendingStarredRepositories: false,
184-
};
185167
case GET_FOLLOWERS.PENDING:
186168
return {
187169
...state,

src/user/user.type.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ export const GET_ORGS = createActionSet('GET_ORGS');
55
export const GET_IS_FOLLOWING = createActionSet('GET_IS_FOLLOWING');
66
export const GET_IS_FOLLOWER = createActionSet('GET_IS_FOLLOWER');
77
export const GET_REPOSITORIES = createActionSet('GET_REPOSITORIES');
8-
export const GET_STARRED_REPOSITORIES = createActionSet(
9-
'GET_STARRED_REPOSITORIES'
10-
);
118
export const GET_FOLLOWERS = createActionSet('GET_FOLLOWERS');
129
export const GET_FOLLOWING = createActionSet('GET_FOLLOWING');
1310
export const SEARCH_USER_REPOS = createActionSet('SEARCH_USER_REPOS');

0 commit comments

Comments
 (0)