mirror of
https://github.com/zhigang1992/devhub.git
synced 2026-06-18 03:58:44 +08:00
Loading user feed using redux-saga
This commit is contained in:
@@ -4,8 +4,6 @@ import android.app.Application;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.rnfs.RNFSPackage;
|
||||
import com.rnfs.RNFSPackage;
|
||||
import com.BV.LinearGradient.LinearGradientPackage;
|
||||
import com.reactnativenavigation.NavigationReactPackage;
|
||||
import com.oblador.vectoricons.VectorIconsPackage;
|
||||
@@ -31,8 +29,6 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
protected List<ReactPackage> getPackages() {
|
||||
return Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage(),
|
||||
new RNFSPackage(),
|
||||
new RNFSPackage(),
|
||||
new LinearGradientPackage(),
|
||||
new NavigationReactPackage(),
|
||||
new VectorIconsPackage(),
|
||||
|
||||
@@ -3,11 +3,22 @@
|
||||
|
||||
import {
|
||||
SET_THEME,
|
||||
LOAD_FEED_REQUEST,
|
||||
LOAD_USER_FEED_REQUEST,
|
||||
LOAD_USER_FEED_SUCCESS,
|
||||
LOAD_USER_FEED_FAILURE,
|
||||
} from '../utils/constants/actions';
|
||||
|
||||
import { action } from '../utils/helpers/actions';
|
||||
import { action, errorAction } from '../utils/helpers/actions';
|
||||
import type { Theme } from '../utils/types';
|
||||
|
||||
export const setTheme = (theme: Theme) => action(SET_THEME, theme);
|
||||
export const loadFeedRequest = () => action(LOAD_FEED_REQUEST);
|
||||
|
||||
export const loadUserFeedRequest = (username: string) => (
|
||||
action(LOAD_USER_FEED_REQUEST, { username })
|
||||
);
|
||||
|
||||
export const loadUserFeedSuccess = (username: string, data: any, meta: Object) => (
|
||||
action(LOAD_USER_FEED_SUCCESS, { username, data, meta })
|
||||
);
|
||||
|
||||
export const loadUserFeedFailure = (error: any) => errorAction(LOAD_USER_FEED_FAILURE, error);
|
||||
|
||||
3
src/api/github.js
Normal file
3
src/api/github.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import GitHubAPI from 'github';
|
||||
|
||||
export default new GitHubAPI();
|
||||
@@ -19,12 +19,8 @@ export default class extends React.Component {
|
||||
theme: this.props.theme || this.context.theme,
|
||||
});
|
||||
|
||||
children: {
|
||||
theme: ThemeObject,
|
||||
};
|
||||
|
||||
props: {
|
||||
children: React.Element<*>,
|
||||
children?: ?React.Element<*>,
|
||||
theme: ThemeObject,
|
||||
};
|
||||
|
||||
|
||||
@@ -6,21 +6,34 @@ import { connect } from 'react-redux';
|
||||
import Columns from '../components/Columns';
|
||||
import Screen from '../components/Screen';
|
||||
import ThemeProvider from '../components/ThemeProvider';
|
||||
import { loadUserFeedRequest } from '../actions';
|
||||
import { loadTheme } from '../reducers/config';
|
||||
import type { State, ThemeObject } from '../utils/types';
|
||||
|
||||
type Props = State & {
|
||||
theme: ThemeObject,
|
||||
};
|
||||
class Page extends React.Component {
|
||||
componentDidMount() {
|
||||
this.props.loadUserFeedRequest('brunolemos');
|
||||
}
|
||||
|
||||
const Page = ({ feed, theme }: Props) => (
|
||||
<ThemeProvider theme={theme}>
|
||||
<Screen>
|
||||
<Columns columns={feed} />
|
||||
</Screen>
|
||||
</ThemeProvider>
|
||||
);
|
||||
props: State & {
|
||||
theme: ThemeObject,
|
||||
loadUserFeedRequest: Function,
|
||||
};
|
||||
|
||||
render() {
|
||||
const { feed, theme } = this.props;
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<Screen>
|
||||
<Columns columns={feed} />
|
||||
</Screen>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = ({ feed, config }: State) => ({ feed, theme: loadTheme(config) });
|
||||
const mapDispatchToProps = { loadUserFeedRequest };
|
||||
|
||||
export default connect(mapStateToProps)(Page);
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Page);
|
||||
|
||||
13
src/index.js
13
src/index.js
@@ -17,16 +17,3 @@ export default () => (
|
||||
</NavigationProvider>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
// import GitHubAPI from 'github';
|
||||
//
|
||||
// const github = new GitHubAPI();
|
||||
//
|
||||
// (async () => {
|
||||
// try {
|
||||
// const result = await github.activity.getEventsReceived({ username: 'brunolemos' });
|
||||
// console.log(result);
|
||||
// } catch(e) {
|
||||
// console.log('Error', e);
|
||||
// }
|
||||
// })();
|
||||
|
||||
@@ -2,29 +2,34 @@
|
||||
|
||||
import { combineReducers } from 'redux';
|
||||
|
||||
import { LOAD_FEED_SUCCESS } from '../utils/constants/actions';
|
||||
import { LOAD_USER_FEED_SUCCESS } from '../utils/constants/actions';
|
||||
import type { Action } from '../utils/types';
|
||||
import type { GithubEvent } from '../utils/types/github';
|
||||
|
||||
// static data
|
||||
import allEventsData from '../../test/data/github-bigquery.json';
|
||||
import repoEventsData from '../../test/data/github-repo-events.json';
|
||||
import userEventsData from '../../test/data/github-user-events.json';
|
||||
import userReceivedEventsData from '../../test/data/github-user-received_events.json';
|
||||
// // static data
|
||||
// import allEventsData from '../../test/data/github-bigquery.json';
|
||||
// import repoEventsData from '../../test/data/github-repo-events.json';
|
||||
// import userEventsData from '../../test/data/github-user-events.json';
|
||||
// import userReceivedEventsData from '../../test/data/github-user-received_events.json';
|
||||
//
|
||||
// const data = [
|
||||
// { id: 0, title: 'all', data: allEventsData },
|
||||
// { id: 1, title: 'react', data: repoEventsData },
|
||||
// { id: 2, title: 'sibelius', data: userReceivedEventsData },
|
||||
// { id: 3, title: 'brunolemos', data: userEventsData },
|
||||
// ];
|
||||
|
||||
const data = [
|
||||
{ id: 0, title: 'all', data: allEventsData },
|
||||
{ id: 1, title: 'react', data: repoEventsData },
|
||||
{ id: 2, title: 'sibelius', data: userReceivedEventsData },
|
||||
{ id: 3, title: 'brunolemos', data: userEventsData },
|
||||
];
|
||||
type Column = { id: string, title: string, data: Array<GithubEvent>, meta: Object };
|
||||
type LoadUserFeedPayload = { username: string, data: Array<GithubEvent> };
|
||||
export default (state :Array<Column> = [], action: Action<LoadUserFeedPayload>): Array<Column> => {
|
||||
const { type, payload: { username, data } = {} } = action || {};
|
||||
|
||||
export default (state:Array<GithubEvent> = data, { type, payload }: Action<Array<GithubEvent>>): Array<GithubEvent> => {
|
||||
switch (type) {
|
||||
case LOAD_FEED_SUCCESS: return [
|
||||
...payload,
|
||||
...state,
|
||||
];
|
||||
case LOAD_USER_FEED_SUCCESS: return [{
|
||||
id: '0',
|
||||
title: username,
|
||||
data,
|
||||
}];
|
||||
default: return state;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,24 +1,33 @@
|
||||
// @flow
|
||||
|
||||
import { put, takeEvery } from 'redux-saga';
|
||||
import { takeEvery } from 'redux-saga';
|
||||
import { call, put } from 'redux-saga/effects';
|
||||
|
||||
import { LOAD_USER_FEED_REQUEST } from '../utils/constants/actions';
|
||||
|
||||
import {
|
||||
LOAD_FEED_REQUEST,
|
||||
} from '../utils/constants/actions';
|
||||
loadUserFeedSuccess,
|
||||
loadUserFeedFailure,
|
||||
} from '../actions';
|
||||
|
||||
import { loadFeedRequest } from '../actions';
|
||||
import github from '../api/github';
|
||||
|
||||
export function* loadFeed(): Generator<*, *, *> {
|
||||
yield put(loadFeedRequest())
|
||||
export function* loadUserFeed({ payload: { username } = {} }: Object): Generator<*, *, *> {
|
||||
try {
|
||||
const { data, meta } = yield call(github.activity.getEventsReceived, { username });
|
||||
yield put(loadUserFeedSuccess(username, data, meta))
|
||||
} catch (error) {
|
||||
yield put(loadUserFeedFailure(error))
|
||||
}
|
||||
}
|
||||
|
||||
// Our watcher Saga: spawn a new incrementAsync task on each INCREMENT_ASYNC
|
||||
export function* watchLoadFeed(): Generator<*, *, *> {
|
||||
yield takeEvery(LOAD_FEED_REQUEST, loadFeed)
|
||||
export function* watchloadUserFeed(): Generator<*, *, *> {
|
||||
yield takeEvery(LOAD_USER_FEED_REQUEST, loadUserFeed)
|
||||
}
|
||||
|
||||
export default function* (): Generator<*, *, *> {
|
||||
return yield [
|
||||
watchLoadFeed
|
||||
watchloadUserFeed()
|
||||
];
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ const store = createStoreWithNavigation(
|
||||
|
||||
sagaMiddleware.run(sagas);
|
||||
|
||||
// TODO: Don't ignore feed
|
||||
persistStore(store, { storage: AsyncStorage, whitelist: ['config'] });
|
||||
persistStore(store, { storage: AsyncStorage, blacklist: ['navigation'] });
|
||||
|
||||
export default store;
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
|
||||
export const SET_THEME = 'SET_THEME';
|
||||
export const LOAD_FEED_REQUEST = 'LOAD_FEED_REQUEST';
|
||||
export const LOAD_FEED_SUCCESS = 'LOAD_FEED_SUCCESS';
|
||||
export const LOAD_FEED_FAILURE = 'LOAD_FEED_FAILURE';
|
||||
export const LOAD_USER_FEED_REQUEST = 'LOAD_USER_FEED_REQUEST';
|
||||
export const LOAD_USER_FEED_SUCCESS = 'LOAD_USER_FEED_SUCCESS';
|
||||
export const LOAD_USER_FEED_FAILURE = 'LOAD_USER_FEED_FAILURE';
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import type { ActionType } from '../types';
|
||||
|
||||
/**
|
||||
* Create the action object
|
||||
* Create an action object
|
||||
*
|
||||
* Example:
|
||||
* action('LOGIN_REQUEST', { email, password })
|
||||
@@ -13,3 +13,15 @@ import type { ActionType } from '../types';
|
||||
export function action(type: ActionType, payload: any) {
|
||||
return { type, payload };
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an action error object
|
||||
*
|
||||
* Example:
|
||||
* errorAction('LOGIN_FAILURE', { message: 'No internet connection' })
|
||||
* produces
|
||||
* { type: 'LOGIN_FAILURE', error: { message: '...' } }
|
||||
*/
|
||||
export function errorAction(type: ActionType, error: any) {
|
||||
return { type, error };
|
||||
}
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
*/
|
||||
|
||||
export type SET_THEME = 'SET_THEME';
|
||||
export type LOAD_FEED_REQUEST = 'LOAD_FEED_REQUEST';
|
||||
export type LOAD_FEED_SUCCESS = 'LOAD_FEED_SUCCESS';
|
||||
export type LOAD_FEED_FAILURE = 'LOAD_FEED_FAILURE';
|
||||
export type LOAD_USER_FEED_REQUEST = 'LOAD_USER_FEED_REQUEST';
|
||||
export type LOAD_USER_FEED_SUCCESS = 'LOAD_USER_FEED_SUCCESS';
|
||||
export type LOAD_USER_FEED_FAILURE = 'LOAD_USER_FEED_FAILURE';
|
||||
|
||||
export type ActionType =
|
||||
| SET_THEME
|
||||
| LOAD_FEED_REQUEST
|
||||
| LOAD_FEED_SUCCESS
|
||||
| LOAD_FEED_FAILURE;
|
||||
| LOAD_USER_FEED_REQUEST
|
||||
| LOAD_USER_FEED_SUCCESS
|
||||
| LOAD_USER_FEED_FAILURE;
|
||||
|
||||
export type Action<T> = {
|
||||
type: ActionType,
|
||||
|
||||
Reference in New Issue
Block a user