diff --git a/src/App.tsx b/src/App.tsx
index d16e502..872b96d 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -11,6 +11,12 @@ export const routeResolver = new RouteResolver({
_base: 'journals',
_id: {
_base: ':journalUid',
+ items: {
+ _base: 'items',
+ _id: {
+ _base: ':entryUid',
+ },
+ },
entries: {
_base: 'entries',
_id: {
diff --git a/src/JournalView.tsx b/src/JournalView.tsx
index 662fa25..422045b 100644
--- a/src/JournalView.tsx
+++ b/src/JournalView.tsx
@@ -7,6 +7,8 @@ import * as EteSync from './api/EteSync';
import { routeResolver } from './App';
import { JournalViewEntries } from './JournalViewEntries';
+import { JournalViewAddressBook } from './JournalViewAddressBook';
+import { JournalViewCalendar } from './JournalViewCalendar';
export class JournalView extends React.Component {
static defaultProps = {
@@ -54,8 +56,10 @@ export class JournalView extends React.Component {
const derived = this.props.etesync.encryptionKey;
const journal = this.state.journal;
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) => {
- let cryptoManager = new EteSync.CryptoManager(derived, journal.uid, journal.version);
let syncEntry = entry.getSyncEntry(cryptoManager, prevUid);
prevUid = entry.uid;
@@ -76,6 +80,19 @@ export class JournalView extends React.Component {
}
/>
+ {
+ if (collectionInfo.type === 'CALENDAR') {
+ return ;
+ } else if (collectionInfo.type === 'ADDRESS_BOOK') {
+ return ;
+ } else {
+ return Unsupported type
;
+ }
+ }
+ }
+ />
);
}
diff --git a/src/JournalViewAddressBook.tsx b/src/JournalViewAddressBook.tsx
new file mode 100644
index 0000000..cb8be9e
--- /dev/null
+++ b/src/JournalViewAddressBook.tsx
@@ -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,
+ };
+
+ render() {
+ if (this.props.journal === undefined) {
+ return (Loading
);
+ }
+
+ let items: Map = 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 = 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 (
+ {name}
+ );
+ });
+
+ return (
+
+ );
+ }
+}
diff --git a/src/JournalViewCalendar.tsx b/src/JournalViewCalendar.tsx
new file mode 100644
index 0000000..f4bc790
--- /dev/null
+++ b/src/JournalViewCalendar.tsx
@@ -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,
+ };
+
+ render() {
+ if (this.props.journal === undefined) {
+ return (Loading
);
+ }
+
+ let items: Map = 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 = 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 (
+ {entry.summary}
+ );
+ });
+
+ return (
+
+ );
+ }
+}
diff --git a/src/api/EteSync.tsx b/src/api/EteSync.tsx
index c745b50..4fc43bf 100644
--- a/src/api/EteSync.tsx
+++ b/src/api/EteSync.tsx
@@ -163,14 +163,14 @@ export class Journal extends BaseJournal {
}
}
-enum SyncEntryType {
+export enum SyncEntryAction {
Add = 'ADD',
Delete = 'DEL',
Change = 'CHANGE',
}
export class SyncEntry {
- action: SyncEntryType;
+ action: SyncEntryAction;
content: string;
constructor(json?: any) {