Add the ability to select a mailbox.

Just log the mailbox ID for now.
This commit is contained in:
Eli Ribble 2024-08-27 23:22:11 -07:00
parent bab5d421d4
commit 656495904b
6 changed files with 104 additions and 9 deletions

View File

@ -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}

View File

@ -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>

41
src/EmailList.tsx Normal file
View File

@ -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;

View File

@ -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>
);

View File

@ -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();
});
}

View File

@ -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 };