Move journal fetching to redux.

master
Tom Hacohen 7 years ago
parent 57f89e3840
commit e75d586c0f

@ -1,4 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { List, ListItem } from 'material-ui/List'; import { List, ListItem } from 'material-ui/List';
@ -8,40 +10,56 @@ import { EteSyncContextType } from './EteSyncContext';
import * as EteSync from './api/EteSync'; import * as EteSync from './api/EteSync';
import { routeResolver } from './App'; import { routeResolver } from './App';
import * as store from './store';
export class JournalList extends React.Component { interface PropsType {
props: { etesync: EteSyncContextType;
etesync: EteSyncContextType }
};
interface PropsTypeInner extends PropsType {
journals: store.JournalsType;
}
function fetchJournals(etesync: EteSyncContextType) {
const credentials = etesync.credentials;
const apiBase = etesync.serviceApiUrl;
return (dispatch: any) => {
dispatch(store.journalsRequest());
state: { let journalManager = new EteSync.JournalManager(credentials, apiBase);
journals: Array<EteSync.Journal>, journalManager.list().then(
(journals) => {
dispatch(store.journalsSuccess(journals));
},
(error) => {
dispatch(store.journalsFailure(error));
}
);
}; };
}
class JournalListInner extends React.Component {
props: PropsTypeInner;
constructor(props: any) { constructor(props: any) {
super(props); super(props);
this.state = {
journals: [],
};
} }
componentDidMount() { componentDidMount() {
const credentials = this.props.etesync.credentials; store.store.dispatch(fetchJournals(this.props.etesync));
const apiBase = this.props.etesync.serviceApiUrl;
let journalManager = new EteSync.JournalManager(credentials, apiBase);
journalManager.list().then((journals) => {
journals = journals.filter((x) => (
// Skip shared journals for now.
!x.key
));
this.setState({ journals });
});
} }
render() { render() {
if (this.props.journals.value === null) {
return (<div/>);
}
const derived = this.props.etesync.encryptionKey; const derived = this.props.etesync.encryptionKey;
const journalMap = this.state.journals.reduce( const journalMap = this.props.journals.value.filter((x) => (
// Skip shared journals for now.
!x.key
)).reduce(
(ret, journal) => { (ret, journal) => {
let cryptoManager = new EteSync.CryptoManager(derived, journal.uid, journal.version); let cryptoManager = new EteSync.CryptoManager(derived, journal.uid, journal.version);
let info = journal.getInfo(cryptoManager); let info = journal.getInfo(cryptoManager);
@ -90,3 +108,13 @@ export class JournalList extends React.Component {
); );
} }
} }
const mapStateToProps = (state: store.StoreState, props: PropsType) => {
return {
journals: state.cache.journals,
};
};
export const JournalList = withRouter(connect(
mapStateToProps
)(JournalListInner));

@ -10,6 +10,7 @@ const loggerMiddleware = createLogger();
enum Actions { enum Actions {
FETCH_CREDENTIALS = 'FETCH_CREDENTIALS', FETCH_CREDENTIALS = 'FETCH_CREDENTIALS',
FETCH_JOURNALS = 'FETCH_JOURNALS',
} }
export enum FetchStatus { export enum FetchStatus {
@ -33,9 +34,16 @@ export interface CredentialsData {
export type CredentialsType = FetchType<CredentialsData>; export type CredentialsType = FetchType<CredentialsData>;
export type JournalsData = Array<EteSync.Journal>;
export type JournalsType = FetchType<JournalsData>;
export interface StoreState { export interface StoreState {
fetchCount: number; fetchCount: number;
credentials: CredentialsType; credentials: CredentialsType;
cache: {
journals: JournalsType;
};
} }
export function credentialsSuccess(creds: CredentialsData) { export function credentialsSuccess(creds: CredentialsData) {
@ -61,6 +69,29 @@ export function credentialsFailure(error: Error) {
}; };
} }
export function journalsSuccess(value: JournalsData) {
return {
type: Actions.FETCH_JOURNALS,
status: FetchStatus.Success,
journals: value,
};
}
export function journalsRequest() {
return {
type: Actions.FETCH_JOURNALS,
status: FetchStatus.Request,
};
}
export function journalsFailure(error: Error) {
return {
type: Actions.FETCH_JOURNALS,
status: FetchStatus.Failure,
error
};
}
export function logout() { export function logout() {
return { return {
type: Actions.FETCH_CREDENTIALS, type: Actions.FETCH_CREDENTIALS,
@ -95,6 +126,32 @@ function credentials(state: CredentialsType = {status: FetchStatus.Initial, valu
} }
} }
function journals(state: JournalsType = {status: FetchStatus.Initial, value: null}, action: any) {
switch (action.type) {
case Actions.FETCH_JOURNALS:
switch (action.status) {
case FetchStatus.Success:
return {
status: action.status,
value: action.journals,
};
case FetchStatus.Failure:
return {
status: action.status,
value: null,
error: action.error,
};
default:
return {
status: action.status,
value: null,
};
}
default:
return state;
}
}
function fetchCount(state: number = 0, action: any) { function fetchCount(state: number = 0, action: any) {
if ('status' in action) { if ('status' in action) {
switch (action.status) { switch (action.status) {
@ -122,6 +179,9 @@ const credentialsPersistConfig = {
const reducers = combineReducers({ const reducers = combineReducers({
fetchCount, fetchCount,
credentials: persistReducer(credentialsPersistConfig, credentials), credentials: persistReducer(credentialsPersistConfig, credentials),
cache: combineReducers({
journals
})
}); });
export const store = createStore( export const store = createStore(

Loading…
Cancel
Save