Move entry fetching to redux.

master
Tom Hacohen 7 years ago
parent f36e099bb9
commit 2e4c6b11aa

@ -1,5 +1,7 @@
import * as React from 'react';
const Fragment = (React as any).Fragment;
import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import { Tabs, Tab } from 'material-ui/Tabs';
import { EteSyncContextType } from './EteSyncContext';
@ -9,56 +11,77 @@ import JournalViewEntries from './JournalViewEntries';
import JournalViewAddressBook from './JournalViewAddressBook';
import JournalViewCalendar from './JournalViewCalendar';
import * as store from './store';
interface PropsType {
etesync: EteSyncContextType;
match: any;
}
interface PropsTypeInner extends PropsType {
journals: store.JournalsType;
entries: store.EntriesType;
}
function fetchEntries(etesync: EteSyncContextType, journalUid: string) {
const credentials = etesync.credentials;
const apiBase = etesync.serviceApiUrl;
return (dispatch: any) => {
const prevUid = null;
dispatch(store.entriesRequest(journalUid));
let entryManager = new EteSync.EntryManager(credentials, apiBase, journalUid);
entryManager.list(prevUid).then(
(entries) => {
dispatch(store.entriesSuccess(journalUid, entries));
},
(error) => {
dispatch(store.entriesFailure(journalUid, error));
}
);
};
}
class JournalView extends React.Component {
static defaultProps = {
prevUid: null,
};
state: {
journal?: EteSync.Journal,
entries: Array<EteSync.Entry>,
};
props: {
etesync: EteSyncContextType
match: any,
prevUid?: string | null,
};
props: PropsTypeInner;
constructor(props: any) {
super(props);
this.state = {
entries: [],
};
}
componentDidMount() {
const credentials = this.props.etesync.credentials;
const apiBase = this.props.etesync.serviceApiUrl;
const journal = this.props.match.params.journalUid;
let journalManager = new EteSync.JournalManager(credentials, apiBase);
journalManager.fetch(journal).then((journalInstance) => {
this.setState({ journal: journalInstance });
});
let entryManager = new EteSync.EntryManager(credentials, apiBase, journal);
entryManager.list(this.props.prevUid || null).then((entries) => {
this.setState({ entries });
});
store.store.dispatch(fetchEntries(this.props.etesync, journal));
}
render() {
if (this.state.journal === undefined) {
const journalUid = this.props.match.params.journalUid;
const entries = this.props.entries[journalUid];
(window as any).me = this.props.entries;
if ((this.props.journals.value === null) ||
(!entries) || (entries.value === null)) {
return (<div>Loading</div>);
}
const journal = this.props.journals.value.find((x) => (x.uid === journalUid));
if (journal === undefined) {
return (<div>Journal not found!</div>);
}
const derived = this.props.etesync.encryptionKey;
const journal = this.state.journal;
let prevUid = this.props.prevUid || null;
let prevUid: string | null = null;
const cryptoManager = new EteSync.CryptoManager(derived, journal.uid, journal.version);
const collectionInfo = journal.getInfo(cryptoManager);
const syncEntries = this.state.entries.map((entry) => {
const syncEntries = entries.value.map((entry) => {
let syncEntry = entry.getSyncEntry(cryptoManager, prevUid);
prevUid = entry.uid;
@ -99,4 +122,13 @@ class JournalView extends React.Component {
}
}
export default JournalView;
const mapStateToProps = (state: store.StoreState, props: PropsType) => {
return {
journals: state.cache.journals,
entries: state.cache.entries,
};
};
export default withRouter(connect(
mapStateToProps
)(JournalView));

@ -11,6 +11,7 @@ const loggerMiddleware = createLogger();
enum Actions {
FETCH_CREDENTIALS = 'FETCH_CREDENTIALS',
FETCH_JOURNALS = 'FETCH_JOURNALS',
FETCH_ENTRIES = 'FETCH_ENTRIES',
}
export enum FetchStatus {
@ -38,11 +39,16 @@ export type JournalsData = Array<EteSync.Journal>;
export type JournalsType = FetchType<JournalsData>;
export type EntriesData = Array<EteSync.Entry>;
export type EntriesType = {[key: string]: FetchType<EntriesData>};
export interface StoreState {
fetchCount: number;
credentials: CredentialsType;
cache: {
journals: JournalsType;
entries: EntriesType;
};
}
@ -88,7 +94,33 @@ export function journalsFailure(error: Error) {
return {
type: Actions.FETCH_JOURNALS,
status: FetchStatus.Failure,
error
error,
};
}
export function entriesSuccess(journal: string, value: EntriesData) {
return {
type: Actions.FETCH_ENTRIES,
status: FetchStatus.Success,
entries: value,
journal,
};
}
export function entriesRequest(journal: string) {
return {
type: Actions.FETCH_ENTRIES,
status: FetchStatus.Request,
journal,
};
}
export function entriesFailure(journal: string, error: Error) {
return {
type: Actions.FETCH_ENTRIES,
status: FetchStatus.Failure,
journal,
error,
};
}
@ -152,6 +184,38 @@ function journals(state: JournalsType = {status: FetchStatus.Initial, value: nul
}
}
function entries(state: EntriesType = {}, action: any) {
switch (action.type) {
case Actions.FETCH_ENTRIES:
switch (action.status) {
case FetchStatus.Success:
return { ...state,
[action.journal]: {
status: action.status,
value: action.entries,
},
};
case FetchStatus.Failure:
return { ...state,
[action.journal]: {
status: action.status,
value: null,
error: action.error,
},
};
default:
return { ...state,
[action.journal]: {
status: action.status,
value: null,
},
};
}
default:
return state;
}
}
function fetchCount(state: number = 0, action: any) {
if ('status' in action) {
switch (action.status) {
@ -180,7 +244,8 @@ const reducers = combineReducers({
fetchCount,
credentials: persistReducer(credentialsPersistConfig, credentials),
cache: combineReducers({
journals
journals,
entries,
})
});

Loading…
Cancel
Save