diff --git a/src/App.tsx b/src/App.tsx index 648ca80..abcaf8c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,7 +2,7 @@ import "./App.css"; import "bootstrap/dist/css/bootstrap.min.css"; import Client, { IAuth } from "./client/Client"; -import { AccountIdMap, IAccount } from "./client/types"; +import { AccountIdMap, IAccount, IMailbox } from "./client/types"; import AppLayout from "./AppLayout"; import AuthModal from "./AuthModal"; import React from "react"; @@ -16,6 +16,7 @@ type AppState = { account: IAccount | null; accounts: AccountIdMap; location: ILocation; + mailbox: IMailbox | null; }; type AppProps = {}; @@ -30,6 +31,7 @@ class App extends React.Component<AppProps, AppState> { accounts: {}, auth: { email: "", password: "" }, location: { accountId: "" }, + mailbox: null, }; onHashChange() { @@ -56,6 +58,10 @@ class App extends React.Component<AppProps, AppState> { this.client.doLogin({ email, password }); } + onMailboxSelect(mailboxId: string) { + console.log("Mailbox", mailboxId); + } + // Load up auth credentials from the local store loadAuth() { const data = localStorage.getItem("auth"); @@ -106,6 +112,8 @@ class App extends React.Component<AppProps, AppState> { account={this.state.account} accounts={this.state.accounts} client={this.client} + mailbox={this.state.mailbox} + onMailboxSelect={this.onMailboxSelect} /> <AuthModal show={this.client.state.session == null} diff --git a/src/AppLayout.tsx b/src/AppLayout.tsx index d4fedd9..3ec1e2d 100644 --- a/src/AppLayout.tsx +++ b/src/AppLayout.tsx @@ -4,14 +4,17 @@ import Row from "react-bootstrap/Row"; import Col from "react-bootstrap/Col"; import AccountList from "./AccountList"; +import EmailList from "./EmailList"; import MailboxList from "./MailboxList"; import Client from "./client/Client"; -import { AccountIdMap, IAccount } from "./client/types"; +import { AccountIdMap, IAccount, IMailbox } from "./client/types"; type TopProps = { account: IAccount | null; accounts: AccountIdMap; client: Client; + mailbox: IMailbox | null; + onMailboxSelect: (mailboxId: string) => void; }; const AppLayout: React.FC<TopProps> = (props) => { @@ -25,8 +28,19 @@ const AppLayout: React.FC<TopProps> = (props) => { <Col></Col> </Row> <Row> - <Col> - <MailboxList account={props.account} client={props.client} /> + <Col lg="1"> + <MailboxList + account={props.account} + client={props.client} + onMailboxSelect={props.onMailboxSelect} + /> + </Col> + <Col lg="11"> + <EmailList + account={props.account} + client={props.client} + mailbox={props.mailbox} + /> </Col> </Row> </Container> diff --git a/src/EmailList.tsx b/src/EmailList.tsx new file mode 100644 index 0000000..677c653 --- /dev/null +++ b/src/EmailList.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import Stack from "react-bootstrap/Stack"; + +import Client from "./client/Client"; +import { IAccount, IMailbox } from "./client/types"; + +type EmailListProps = { + account: IAccount | null; + client: Client | null; + mailbox: IMailbox | null; +}; + +type EmailListState = {}; + +class EmailList extends React.Component<EmailListProps, EmailListState> { + componentDidUpdate() { + if (this.props.account == null) return; + if (this.props.client == null) return; + if (this.props.mailbox == null) return; + this.props.client.emailList( + this.props.account.id, + this.props.mailbox.id, + [], + ); + } + + render() { + return !(this.props.account && this.props.mailbox) ? ( + <Stack /> + ) : ( + <Stack> + {this.props.mailbox.emails.map((m) => ( + <div className="p-2" key={m.id}> + {m.subject} + </div> + ))} + </Stack> + ); + } +} +export default EmailList; diff --git a/src/MailboxList.tsx b/src/MailboxList.tsx index eb045f5..bbc8771 100644 --- a/src/MailboxList.tsx +++ b/src/MailboxList.tsx @@ -1,10 +1,16 @@ import React from "react"; +import Button from "react-bootstrap/Button"; import Stack from "react-bootstrap/Stack"; import Client from "./client/Client"; import { IAccount } from "./client/types"; -type MailboxListProps = { account: IAccount | null; client: Client | null }; +type MailboxListProps = { + account: IAccount | null; + client: Client | null; + onMailboxSelect: (mailboxId: string) => void; +}; + type MailboxListState = {}; class MailboxList extends React.Component<MailboxListProps, MailboxListState> { @@ -14,13 +20,25 @@ class MailboxList extends React.Component<MailboxListProps, MailboxListState> { this.props.client.mailboxList(this.props.account.id, []); } + onMailboxClick(id: string) { + this.props.onMailboxSelect(id); + } + render() { return this.props.account == null ? ( <Stack /> ) : ( <Stack> {this.props.account.mailboxes.map((m) => ( - <li key={m.id}>{m.name}</li> + <Button + className="p-2" + key={m.id} + onClick={() => { + this.onMailboxClick(m.id); + }} + > + {m.name} + </Button> ))} </Stack> ); diff --git a/src/client/Client.tsx b/src/client/Client.tsx index ebb3e95..7bc3f97 100644 --- a/src/client/Client.tsx +++ b/src/client/Client.tsx @@ -6,7 +6,7 @@ import * as base64 from "base-64"; import * as jmapclient from "jmap-client-ts"; import { FetchTransport } from "jmap-client-ts/lib/utils/fetch-transport"; -import { IAccount, ISession } from "./types"; +import { IAccount, IMailbox, ISession } from "./types"; type Callback = () => void; @@ -65,6 +65,8 @@ export default class Client { return; } + emailList(accountId: string, mailboxId: string, ids: Array<string>) {} + mailboxList(accountId: string, ids: Array<string>) { if (this.jclient == null) return; this.jclient @@ -75,7 +77,14 @@ export default class Client { .then((response) => { if (this.state.session == null) return; const account = this.state.session.accounts[response.accountId]; - account.mailboxes = response.list; + const mailboxes: Array<IMailbox> = []; + response.list.forEach((m) => { + mailboxes.push({ + ...m, + emails: [], + }); + }); + account.mailboxes = mailboxes; this._triggerChange(); }); } diff --git a/src/client/types.tsx b/src/client/types.tsx index 7bec110..45be0f7 100644 --- a/src/client/types.tsx +++ b/src/client/types.tsx @@ -1,7 +1,12 @@ import client from "jmap-client-ts/lib/types"; + +export interface IMailbox extends client.IMailboxProperties { + emails: Array<client.IEmailProperties>; +} + export interface IAccount extends client.IAccount { id: string; - mailboxes: Array<client.IMailboxProperties>; + mailboxes: Array<IMailbox>; } export type AccountIdMap = { [accountId: string]: IAccount };