From 9f396173b0b2082000df4e1c39b410f154ea195c Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Thu, 14 Dec 2017 14:31:17 +0000 Subject: [PATCH] Move etsync decryption logic to sync gate. This shares more of the code, and also lets us be more efficient because we now do these calculations less. --- src/Journal.tsx | 33 +++++--------------- src/Pim.tsx | 80 ++++++++++++++++-------------------------------- src/SyncGate.tsx | 60 +++++++++++++++++++++++++++++++++--- 3 files changed, 89 insertions(+), 84 deletions(-) diff --git a/src/Journal.tsx b/src/Journal.tsx index 49bbbcd..4e6177c 100644 --- a/src/Journal.tsx +++ b/src/Journal.tsx @@ -1,8 +1,6 @@ import * as React from 'react'; import { Tabs, Tab } from 'material-ui/Tabs'; -import * as EteSync from './api/EteSync'; - import Container from './Container'; import SecondaryHeader from './SecondaryHeader'; @@ -10,16 +8,13 @@ import SecondaryHeader from './SecondaryHeader'; import JournalEntries from './JournalEntries'; import JournalAddressBook from './JournalAddressBook'; import JournalCalendar from './JournalCalendar'; -import LoadingIndicator from './LoadingIndicator'; import { syncEntriesToItemMap, syncEntriesToCalendarItemMap } from './journal-processors'; -import { JournalsData, EntriesType, CredentialsData } from './store'; +import { SyncInfo } from './SyncGate'; interface PropsType { - journals: JournalsData; - entries: EntriesType; - etesync: CredentialsData; + syncInfo: SyncInfo; match: any; } @@ -39,29 +34,15 @@ class Journal extends React.PureComponent { render() { const journalUid = this.props.match.params.journalUid; - const entries = this.props.entries.get(journalUid); - - if ((!entries) || (entries.value === null)) { - return (); - } - const journal = this.props.journals.find((x) => (x.uid === journalUid)); - - if (journal === undefined) { + const syncJournal = this.props.syncInfo.get(journalUid); + if (!syncJournal) { return (
Journal not found!
); } - const derived = this.props.etesync.encryptionKey; - let prevUid: string | null = null; - const cryptoManager = new EteSync.CryptoManager(derived, journal.uid, journal.version); - const collectionInfo = journal.getInfo(cryptoManager); - - const syncEntries = entries.value.map((entry) => { - let syncEntry = entry.getSyncEntry(cryptoManager, prevUid); - prevUid = entry.uid; - - return syncEntry; - }); + const journal = syncJournal.journal; + const collectionInfo = syncJournal.collection; + const syncEntries = syncJournal.entries; let itemsTitle: string; let itemsView: JSX.Element; diff --git a/src/Pim.tsx b/src/Pim.tsx index dbca79d..957d091 100644 --- a/src/Pim.tsx +++ b/src/Pim.tsx @@ -17,7 +17,9 @@ import PimMain from './PimMain'; import { routeResolver } from './App'; -import { store, JournalsData, EntriesType, CredentialsData } from './store'; +import { store, CredentialsData } from './store'; + +import { SyncInfo } from './SyncGate'; import { createJournalEntry } from './etesync-helpers'; @@ -30,8 +32,7 @@ function objValues(obj: any) { class Pim extends React.PureComponent { props: { etesync: CredentialsData; - journals: JournalsData; - entries: EntriesType; + syncInfo: SyncInfo; match: any; history: any; }; @@ -43,97 +44,68 @@ class Pim extends React.PureComponent { } onEventSave(event: EventType, journalUid: string, originalEvent?: EventType) { - const journal = this.props.journals.find((x) => (x.uid === journalUid)); + const syncJournal = this.props.syncInfo.get(journalUid); - if (journal === undefined) { + if (syncJournal === undefined) { return; } - const entries = this.props.entries.get(journal.uid); - - if (!entries) { - return; - } - - if (entries.value === null) { - return; - } + const journal = syncJournal.journal; let action = (originalEvent === undefined) ? EteSync.SyncEntryAction.Add : EteSync.SyncEntryAction.Change; let saveEvent = store.dispatch( - createJournalEntry(this.props.etesync, journal, entries.value, action, event.toIcal())); + createJournalEntry(this.props.etesync, journal, syncJournal.journalEntries, action, event.toIcal())); (saveEvent as any).then(() => { this.props.history.goBack(); }); } onContactSave(contact: ContactType, journalUid: string, originalContact?: ContactType) { - const journal = this.props.journals.find((x) => (x.uid === journalUid)); + const syncJournal = this.props.syncInfo.get(journalUid); - if (journal === undefined) { + if (syncJournal === undefined) { return; } - const entries = this.props.entries[journal.uid]; - - if (entries.value === null) { - return; - } + const journal = syncJournal.journal; let action = (originalContact === undefined) ? EteSync.SyncEntryAction.Add : EteSync.SyncEntryAction.Change; let saveContact = store.dispatch( - createJournalEntry(this.props.etesync, journal, entries.value, action, contact.toIcal())); + createJournalEntry(this.props.etesync, journal, syncJournal.journalEntries, action, contact.toIcal())); (saveContact as any).then(() => { this.props.history.goBack(); }); } render() { - const derived = this.props.etesync.encryptionKey; - let collectionsAddressBook: Array = []; let collectionsCalendar: Array = []; - const journalMap = this.props.journals.reduce( - (ret, journal) => { - const journalEntries = this.props.entries.get(journal.uid); - const cryptoManager = new EteSync.CryptoManager(derived, journal.uid, journal.version); - - let prevUid: string | null = null; - - if (!journalEntries || !journalEntries.value) { - return ret; - } + let entriesAddressBook: Array<{[key: string]: ContactType}> = []; + let entriesCalendar: Array<{[key: string]: EventType}> = []; + this.props.syncInfo.forEach( + (syncJournal) => { + const syncEntries = syncJournal.entries; + const journal = syncJournal.journal; // FIXME: Skip shared journals for now if (journal.key) { - return ret; + return; } - const collectionInfo = journal.getInfo(cryptoManager); - - const syncEntries = journalEntries.value.map((entry: EteSync.Entry) => { - let syncEntry = entry.getSyncEntry(cryptoManager, prevUid); - prevUid = entry.uid; - - return syncEntry; - }); + const collectionInfo = syncJournal.collection; if (collectionInfo.type === 'ADDRESS_BOOK') { - ret.ADDRESS_BOOK.push(syncEntriesToItemMap(collectionInfo, syncEntries)); + entriesAddressBook.push(syncEntriesToItemMap(collectionInfo, syncEntries)); collectionsAddressBook.push(collectionInfo); } else if (collectionInfo.type === 'CALENDAR') { - ret.CALENDAR.push(syncEntriesToCalendarItemMap(collectionInfo, syncEntries)); + entriesCalendar.push(syncEntriesToCalendarItemMap(collectionInfo, syncEntries)); collectionsCalendar.push(collectionInfo); } + } + ); - return ret; - }, - { CALENDAR: [] as Array<{[key: string]: EventType}>, - ADDRESS_BOOK: [] as Array<{[key: string]: ContactType}>, - UNSUPPORTED: [] as Array}); - - let addressBookItems = journalMap.ADDRESS_BOOK.reduce((base, x) => Object.assign(base, x), {}); - let calendarItems = journalMap.CALENDAR.reduce((base, x) => Object.assign(base, x), {}); + let addressBookItems = entriesAddressBook.reduce((base, x) => Object.assign(base, x), {}); + let calendarItems = entriesCalendar.reduce((base, x) => Object.assign(base, x), {}); return ( diff --git a/src/SyncGate.tsx b/src/SyncGate.tsx index 22fea80..d2a0b3a 100644 --- a/src/SyncGate.tsx +++ b/src/SyncGate.tsx @@ -2,6 +2,8 @@ import * as React from 'react'; import { connect } from 'react-redux'; import { Route, Switch, Redirect, withRouter } from 'react-router'; +import { List, Map } from 'immutable'; + import { routeResolver } from './App'; import LoadingIndicator from './LoadingIndicator'; @@ -9,8 +11,19 @@ import LoadingIndicator from './LoadingIndicator'; import Journal from './Journal'; import Pim from './Pim'; +import * as EteSync from './api/EteSync'; + import { store, JournalsType, EntriesType, fetchJournals, fetchEntries, StoreState, CredentialsData } from './store'; +export interface SyncInfoJournal { + journal: EteSync.Journal; + journalEntries: List; + collection: EteSync.CollectionInfo; + entries: List; +} + +export type SyncInfo = Map; + interface PropsType { etesync: CredentialsData; } @@ -55,6 +68,43 @@ class SyncGate extends React.PureComponent { return (); } + const derived = this.props.etesync.encryptionKey; + + const journalMap = journals.reduce( + (ret, journal) => { + const journalEntries = this.props.entries.get(journal.uid); + const cryptoManager = new EteSync.CryptoManager(derived, journal.uid, journal.version); + + let prevUid: string | null = null; + + if (!journalEntries || !journalEntries.value) { + return ret; + } + + // FIXME: Skip shared journals for now + if (journal.key) { + return ret; + } + + const collectionInfo = journal.getInfo(cryptoManager); + + const syncEntries = journalEntries.value.map((entry: EteSync.Entry) => { + let syncEntry = entry.getSyncEntry(cryptoManager, prevUid); + prevUid = entry.uid; + + return syncEntry; + }); + + return ret.set(journal.uid, { + entries: syncEntries, + collection: collectionInfo, + journal, + journalEntries: journalEntries.value, + }); + }, + Map() + ); + return ( ( @@ -79,8 +128,11 @@ class SyncGate extends React.PureComponent { ( - - )} + + )} /> );