Change userInfo to also not be a complex fetch type.

master
Tom Hacohen 5 years ago
parent 118d26ce83
commit 23048cfa63

@ -115,7 +115,7 @@ class SideMenu extends React.PureComponent<PropsTypeInner> {
const mapStateToProps = (state: StoreState, _props: PropsType) => { const mapStateToProps = (state: StoreState, _props: PropsType) => {
return { return {
journals: state.cache.journals, journals: state.cache.journals,
userInfo: state.cache.userInfo.value, userInfo: state.cache.userInfo,
}; };
}; };

@ -22,7 +22,7 @@ import Pim from './Pim';
import * as EteSync from 'etesync'; import * as EteSync from 'etesync';
import { CURRENT_VERSION } from 'etesync'; import { CURRENT_VERSION } from 'etesync';
import { store, SettingsType, JournalsType, EntriesType, StoreState, CredentialsData, UserInfoType } from './store'; import { store, SettingsType, JournalsType, EntriesType, StoreState, CredentialsData, UserInfoData } from './store';
import { addJournal, fetchAll, fetchEntries, fetchUserInfo, createUserInfo } from './store/actions'; import { addJournal, fetchAll, fetchEntries, fetchUserInfo, createUserInfo } from './store/actions';
export interface SyncInfoJournal { export interface SyncInfoJournal {
@ -42,7 +42,7 @@ type PropsTypeInner = RouteComponentProps<{}> & PropsType & {
settings: SettingsType; settings: SettingsType;
journals: JournalsType; journals: JournalsType;
entries: EntriesType; entries: EntriesType;
userInfo: UserInfoType; userInfo: UserInfoData;
fetchCount: number; fetchCount: number;
}; };
@ -50,7 +50,7 @@ const syncInfoSelector = createSelector(
(props: PropsTypeInner) => props.etesync, (props: PropsTypeInner) => props.etesync,
(props: PropsTypeInner) => props.journals.value!, (props: PropsTypeInner) => props.journals.value!,
(props: PropsTypeInner) => props.entries, (props: PropsTypeInner) => props.entries,
(props: PropsTypeInner) => props.userInfo.value!, (props: PropsTypeInner) => props.userInfo,
(etesync, journals, entries, userInfo) => { (etesync, journals, entries, userInfo) => {
const derived = etesync.encryptionKey; const derived = etesync.encryptionKey;
const userInfoCryptoManager = userInfo.getCryptoManager(etesync.encryptionKey); const userInfoCryptoManager = userInfo.getCryptoManager(etesync.encryptionKey);
@ -132,10 +132,14 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
}); });
}; };
const sync = () => { if (this.props.userInfo) {
if (this.props.userInfo.value) {
syncAll(); syncAll();
} else { } else {
const fetching = fetchUserInfo(this.props.etesync, me);
fetching.payload?.then(() => {
store.dispatch(fetching);
syncAll();
}).catch(() => {
const userInfo = new EteSync.UserInfo(me, CURRENT_VERSION); const userInfo = new EteSync.UserInfo(me, CURRENT_VERSION);
const keyPair = EteSync.AsymmetricCryptoManager.generateKeyPair(); const keyPair = EteSync.AsymmetricCryptoManager.generateKeyPair();
const cryptoManager = userInfo.getCryptoManager(this.props.etesync.encryptionKey); const cryptoManager = userInfo.getCryptoManager(this.props.etesync.encryptionKey);
@ -143,14 +147,7 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
userInfo.setKeyPair(cryptoManager, keyPair); userInfo.setKeyPair(cryptoManager, keyPair);
store.dispatch<any>(createUserInfo(this.props.etesync, userInfo)).then(syncAll); store.dispatch<any>(createUserInfo(this.props.etesync, userInfo)).then(syncAll);
} });
};
if (this.props.userInfo.value) {
syncAll();
} else {
const fetching = store.dispatch(fetchUserInfo(this.props.etesync, me)) as any;
fetching.then(sync).catch(() => sync());
} }
} }
@ -158,9 +155,7 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
const entryArrays = this.props.entries; const entryArrays = this.props.entries;
const journals = this.props.journals.value; const journals = this.props.journals.value;
if (this.props.userInfo.error) { if (this.props.journals.error) {
return <PrettyError error={this.props.userInfo.error} />;
} else if (this.props.journals.error) {
return <PrettyError error={this.props.journals.error} />; return <PrettyError error={this.props.journals.error} />;
} else { } else {
const errors: Array<{journal: string, error: Error}> = []; const errors: Array<{journal: string, error: Error}> = [];
@ -179,7 +174,7 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
} }
} }
if ((this.props.userInfo.value === null) || (journals === null) || if ((this.props.userInfo === null) || (journals === null) ||
((this.props.fetchCount > 0) && ((this.props.fetchCount > 0) &&
((entryArrays.size === 0) || !entryArrays.every((x: any) => (x.value !== null)))) ((entryArrays.size === 0) || !entryArrays.every((x: any) => (x.value !== null))))
) { ) {
@ -208,7 +203,7 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
<AppBarOverride title="EteSync" /> <AppBarOverride title="EteSync" />
<PimRouter <PimRouter
etesync={this.props.etesync} etesync={this.props.etesync}
userInfo={this.props.userInfo.value!} userInfo={this.props.userInfo}
syncInfo={journalMap} syncInfo={journalMap}
history={history} history={history}
/> />
@ -220,7 +215,7 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
render={({ location, history }) => ( render={({ location, history }) => (
<Journals <Journals
etesync={this.props.etesync} etesync={this.props.etesync}
userInfo={this.props.userInfo.value!} userInfo={this.props.userInfo}
syncInfo={journalMap} syncInfo={journalMap}
journals={journals} journals={journals}
location={location} location={location}
@ -243,7 +238,7 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
render={() => ( render={() => (
<Debug <Debug
etesync={this.props.etesync} etesync={this.props.etesync}
userInfo={this.props.userInfo.value!} userInfo={this.props.userInfo}
/> />
)} )}
/> />

@ -7,8 +7,8 @@ import { List, Map as ImmutableMap } from 'immutable';
import * as EteSync from 'etesync'; import * as EteSync from 'etesync';
import { import {
JournalsData, FetchType, EntriesData, EntriesFetchRecord, UserInfoData, JournalsFetchRecord, UserInfoFetchRecord, JournalsData, FetchType, EntriesData, EntriesFetchRecord, UserInfoData, JournalsFetchRecord,
CredentialsDataRemote, JournalsType, EntriesType, UserInfoType, SettingsType, CredentialsDataRemote, JournalsType, EntriesType, SettingsType,
fetchCount, journals, entries, credentials, userInfo, settingsReducer, encryptionKeyReducer, errorsReducer, fetchCount, journals, entries, credentials, userInfo, settingsReducer, encryptionKeyReducer, errorsReducer,
} from './reducers'; } from './reducers';
@ -20,7 +20,7 @@ export interface StoreState {
cache: { cache: {
journals: JournalsType; journals: JournalsType;
entries: EntriesType; entries: EntriesType;
userInfo: UserInfoType; userInfo: UserInfoData;
}; };
errors: List<Error>; errors: List<Error>;
} }
@ -84,12 +84,12 @@ const entriesDeserialize = (state: EteSync.EntryJson[]): FetchType<EntriesData>
})) }); })) });
}; };
const userInfoSerialize = (state: FetchType<UserInfoData>) => { const userInfoSerialize = (state: UserInfoData) => {
if ((state === null) || (state.value == null)) { if (state === null) {
return null; return null;
} }
return state.value.serialize(); return state.serialize();
}; };
const userInfoDeserialize = (state: EteSync.UserInfoJson) => { const userInfoDeserialize = (state: EteSync.UserInfoJson) => {
@ -128,7 +128,7 @@ const cacheDeserialize = (state: any, key: string) => {
} else if (key === 'journals') { } else if (key === 'journals') {
return new JournalsFetchRecord({ value: journalsDeserialize(state) }); return new JournalsFetchRecord({ value: journalsDeserialize(state) });
} else if (key === 'userInfo') { } else if (key === 'userInfo') {
return new UserInfoFetchRecord({ value: userInfoDeserialize(state) }); return userInfoDeserialize(state);
} }
return state; return state;

@ -1,4 +1,5 @@
import { Action, ActionFunctionAny, combineActions, handleAction, handleActions } from 'redux-actions'; import { Action, ActionFunctionAny, combineActions, handleAction, handleActions } from 'redux-actions';
import { shallowEqual } from 'react-redux';
import { List, Map as ImmutableMap, Record } from 'immutable'; import { List, Map as ImmutableMap, Record } from 'immutable';
@ -45,9 +46,6 @@ export type EntriesTypeImmutable = ImmutableMap<string, Record<FetchType<Entries
export type EntriesType = ImmutableMap<string, FetchType<EntriesData>>; export type EntriesType = ImmutableMap<string, FetchType<EntriesData>>;
export type UserInfoData = EteSync.UserInfo; export type UserInfoData = EteSync.UserInfo;
export const UserInfoFetchRecord = fetchTypeRecord<UserInfoData>();
export type UserInfoType = FetchType<UserInfoData>;
export type UserInfoTypeImmutable = Record<UserInfoType>;
function fetchTypeIdentityReducer( function fetchTypeIdentityReducer(
state: Record<FetchType<any>> = fetchTypeRecord<any>()(), action: any, extend = false) { state: Record<FetchType<any>> = fetchTypeRecord<any>()(), action: any, extend = false) {
@ -213,29 +211,35 @@ export const journals = handleActions(
new JournalsFetchRecord() new JournalsFetchRecord()
); );
export const userInfo = handleAction( export const userInfo = handleActions(
combineActions( {
[combineActions(
actions.fetchUserInfo, actions.fetchUserInfo,
actions.createUserInfo actions.createUserInfo
), ).toString()]: (state: UserInfoData | null, action: any) => {
(state: Record<FetchType<any>> = fetchTypeRecord<any>()(), action: any) => {
if (action.error) { if (action.error) {
return state.set('error', action.payload); return state;
} else { } else {
let payload = (action.payload === undefined) ? null : action.payload; let payload = action.payload ?? null;
state = state.set('error', undefined);
if (payload === null) { if (payload === null) {
return state; return state;
} }
payload = (action.meta === undefined) ? payload : action.meta.userInfo; payload = action.meta?.userInfo ?? payload;
return state.set('value', payload); if (!state || !shallowEqual(state.serialize(), payload.serialize())) {
return payload;
} }
return state;
}
},
[actions.logout.toString()]: (_state: any, _action: any) => {
return null;
},
}, },
new UserInfoFetchRecord() null
); );
const fetchActions = [ const fetchActions = [

Loading…
Cancel
Save