Add views for actual collection items.

I.e calendar events and address book content.
master
Tom Hacohen 7 years ago
parent 8c20687a72
commit f5c31a3dbe

@ -11,6 +11,12 @@ export const routeResolver = new RouteResolver({
_base: 'journals', _base: 'journals',
_id: { _id: {
_base: ':journalUid', _base: ':journalUid',
items: {
_base: 'items',
_id: {
_base: ':entryUid',
},
},
entries: { entries: {
_base: 'entries', _base: 'entries',
_id: { _id: {

@ -7,6 +7,8 @@ import * as EteSync from './api/EteSync';
import { routeResolver } from './App'; import { routeResolver } from './App';
import { JournalViewEntries } from './JournalViewEntries'; import { JournalViewEntries } from './JournalViewEntries';
import { JournalViewAddressBook } from './JournalViewAddressBook';
import { JournalViewCalendar } from './JournalViewCalendar';
export class JournalView extends React.Component { export class JournalView extends React.Component {
static defaultProps = { static defaultProps = {
@ -54,8 +56,10 @@ export class JournalView extends React.Component {
const derived = this.props.etesync.encryptionKey; const derived = this.props.etesync.encryptionKey;
const journal = this.state.journal; const journal = this.state.journal;
let prevUid = this.props.prevUid || null; let prevUid = this.props.prevUid || 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 = this.state.entries.map((entry) => {
let cryptoManager = new EteSync.CryptoManager(derived, journal.uid, journal.version);
let syncEntry = entry.getSyncEntry(cryptoManager, prevUid); let syncEntry = entry.getSyncEntry(cryptoManager, prevUid);
prevUid = entry.uid; prevUid = entry.uid;
@ -76,6 +80,19 @@ export class JournalView extends React.Component {
<JournalViewEntries journal={journal} entries={syncEntries} /> <JournalViewEntries journal={journal} entries={syncEntries} />
} }
/> />
<Route
path={routeResolver.getRoute('journals._id.items')}
render={() => {
if (collectionInfo.type === 'CALENDAR') {
return <JournalViewCalendar journal={journal} entries={syncEntries} />;
} else if (collectionInfo.type === 'ADDRESS_BOOK') {
return <JournalViewAddressBook journal={journal} entries={syncEntries} />;
} else {
return <div>Unsupported type</div>;
}
}
}
/>
</div> </div>
); );
} }

@ -0,0 +1,66 @@
import * as React from 'react';
import * as ICAL from 'ical.js';
import * as EteSync from './api/EteSync';
export class JournalViewAddressBook extends React.Component {
static defaultProps = {
prevUid: null,
};
props: {
journal: EteSync.Journal,
entries: Array<EteSync.SyncEntry>,
};
render() {
if (this.props.journal === undefined) {
return (<div>Loading</div>);
}
let items: Map<string, any> = new Map();
for (const syncEntry of this.props.entries) {
let comp = new ICAL.Component(ICAL.parse(syncEntry.content));
const uid = comp.getFirstPropertyValue('uid');
if ((syncEntry.action === EteSync.SyncEntryAction.Add) ||
(syncEntry.action === EteSync.SyncEntryAction.Change)) {
items.set(uid, comp);
} else if (syncEntry.action === EteSync.SyncEntryAction.Delete) {
items.delete(uid);
}
}
// FIXME: should be ICAL.component
let entries: Array<any> = Array.from(items.values()).sort((_a: any, _b: any) => {
const a = _a.getFirstPropertyValue('fn');
const b = _b.getFirstPropertyValue('fn');
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
});
let itemList = entries.map((entry, idx) => {
const name = entry.getFirstPropertyValue('fn');
return (
<li key={idx}>{name}</li>
);
});
return (
<div>
<ul>
{itemList}
</ul>
</div>
);
}
}

@ -0,0 +1,64 @@
import * as React from 'react';
import * as ICAL from 'ical.js';
import * as EteSync from './api/EteSync';
export class JournalViewCalendar extends React.Component {
static defaultProps = {
prevUid: null,
};
props: {
journal: EteSync.Journal,
entries: Array<EteSync.SyncEntry>,
};
render() {
if (this.props.journal === undefined) {
return (<div>Loading</div>);
}
let items: Map<string, any> = new Map();
for (const syncEntry of this.props.entries) {
let comp = new ICAL.Component(ICAL.parse(syncEntry.content)).getFirstSubcomponent('vevent');
const uid = comp.getFirstPropertyValue('uid');
if ((syncEntry.action === EteSync.SyncEntryAction.Add) ||
(syncEntry.action === EteSync.SyncEntryAction.Change)) {
items.set(uid, comp);
} else if (syncEntry.action === EteSync.SyncEntryAction.Delete) {
items.delete(uid);
}
}
// FIXME: should be ICAL.component
let entries: Array<any> = Array.from(items.values()).map((value: string) => (
new ICAL.Event(value)
)).sort((a: any, b: any) => {
if (a.summary < b.summary) {
return -1;
} else if (a.summary > b.summary) {
return 1;
} else {
return 0;
}
});
let itemList = entries.map((entry, idx) => {
return (
<li key={idx}>{entry.summary}</li>
);
});
return (
<div>
<ul>
{itemList}
</ul>
</div>
);
}
}

@ -163,14 +163,14 @@ export class Journal extends BaseJournal<JournalJson> {
} }
} }
enum SyncEntryType { export enum SyncEntryAction {
Add = 'ADD', Add = 'ADD',
Delete = 'DEL', Delete = 'DEL',
Change = 'CHANGE', Change = 'CHANGE',
} }
export class SyncEntry { export class SyncEntry {
action: SyncEntryType; action: SyncEntryAction;
content: string; content: string;
constructor(json?: any) { constructor(json?: any) {

Loading…
Cancel
Save