From c17e8b9ad0e99c7deb64e0e2a0bdf37a70199421 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Tue, 27 Aug 2024 18:24:20 -0700 Subject: [PATCH] Get to where I'm querying for mailboxes This won't work, not in the long term, but it's a better direction. I've created proxy classes for the classes coming from the JMAP client. The issue here is that this client is likely to have a bunch of things wrong. Specifically, the standard indicates that the client can be extremely stateful, to the point where it's just getting a stream of updates and keeping most of the structure in memory. The client, as presently built, does not make it easy to honor this part of the standard, so I'm going to have to structure the client interaction differently. However, what I've done here, while interesting, is not good. The problem is that I am correctly telling the client "I need the list of mailboxes" when I render the mailbox list, but I'm not able to propogate that information back to the client since it's passed down through props. I'm going to need to separate out the client into its own class and have an eventing system of some kind between it and the app. --- src/AccountList.tsx | 5 ++--- src/App.tsx | 17 +++++++++++++---- src/AppLayout.tsx | 28 ++++++++++++++++++++++++++++ src/MailboxList.tsx | 39 +++++++++++++++++++++++++++++++++++++++ src/types.tsx | 21 +++++++++++++++++++++ 5 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 src/AppLayout.tsx create mode 100644 src/MailboxList.tsx create mode 100644 src/types.tsx diff --git a/src/AccountList.tsx b/src/AccountList.tsx index 50d045b..611fbb0 100644 --- a/src/AccountList.tsx +++ b/src/AccountList.tsx @@ -1,10 +1,9 @@ import React from "react"; import Dropdown from "react-bootstrap/Dropdown"; -import { IAccount } from "jmap-client-ts/lib/types"; +import { IAccount, AccountIdMap } from "./types"; -type AccountIdMap = { [accountId: string]: IAccount }; -type AccountListProps = { +export type AccountListProps = { account: IAccount | null; accounts: AccountIdMap; }; diff --git a/src/App.tsx b/src/App.tsx index f938d7c..e9c5895 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,10 +2,10 @@ import "./App.css"; import "bootstrap/dist/css/bootstrap.min.css"; import * as base64 from "base-64"; import { Client } from "jmap-client-ts"; -import { IAccount, ISession } from "jmap-client-ts/lib/types"; import { FetchTransport } from "jmap-client-ts/lib/utils/fetch-transport"; -import AccountList from "./AccountList"; +import { IAccount, ISession } from "./types"; +import AppLayout from "./AppLayout"; import AuthModal from "./AuthModal"; import React from "react"; @@ -63,7 +63,15 @@ class App extends React.Component { const session = this.client.getSession(); this.setState({ ...this.state, - session: session, + session: { + ...session, + accounts: Object.fromEntries( + Object.entries(session.accounts).map(([key, account]) => [ + key, + { ...account, id: key.toString(), mailboxes: [] }, + ]), + ), + }, }); }) .catch((error) => console.error(error)); @@ -133,9 +141,10 @@ class App extends React.Component { return (
{this.state && this.state.session ? ( - ) : ( diff --git a/src/AppLayout.tsx b/src/AppLayout.tsx new file mode 100644 index 0000000..99b88ad --- /dev/null +++ b/src/AppLayout.tsx @@ -0,0 +1,28 @@ +import React from "react"; +import Container from "react-bootstrap/Container"; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; + +import AccountList, { AccountListProps } from "./AccountList"; +import MailboxList from "./MailboxList"; +import { IAccount, TopProps } from "./types"; + +const AppLayout: React.FC = (props) => { + return ( + + + + + + + + + + + + + + + ); +}; +export default AppLayout; diff --git a/src/MailboxList.tsx b/src/MailboxList.tsx new file mode 100644 index 0000000..51b342e --- /dev/null +++ b/src/MailboxList.tsx @@ -0,0 +1,39 @@ +import React from "react"; +import Stack from "react-bootstrap/Stack"; + +import { Client, IAccount } from "./types"; + +type MailboxListProps = { account: IAccount | null; client: Client | null }; +type MailboxListState = {}; + +class MailboxList extends React.Component { + componentDidMount() { + if (this.props.account == null) return; + if (this.props.client == null) return; + const args = { + accountId: this.props.account.id, + ids: [], + }; + this.props.client + .mailbox_get(args) + .then(() => { + console.log("got mailboxen"); + }) + .catch(() => { + console.error("Failed to get mailboxes"); + }); + } + + render() { + return this.props.account == null ? ( + + ) : ( + + {this.props.account.mailboxes.map((m) => ( +
  • {m.name}
  • + ))} +
    + ); + } +} +export default MailboxList; diff --git a/src/types.tsx b/src/types.tsx new file mode 100644 index 0000000..f0585a5 --- /dev/null +++ b/src/types.tsx @@ -0,0 +1,21 @@ +import client from "jmap-client-ts/lib/types"; +import { Client } from "jmap-client-ts"; + +export type { Client } from "jmap-client-ts"; + +export interface IAccount extends client.IAccount { + id: string; + mailboxes: Array; +} + +export type AccountIdMap = { [accountId: string]: IAccount }; + +export interface ISession extends client.ISession { + accounts: AccountIdMap; +} + +export type TopProps = { + account: IAccount | null; + accounts: AccountIdMap; + client: Client | null; +};