Rip apart client, build a wrapper.
The goal here is to be able to augment the client with additional data as we get it. At this point I'm now augmenting with the mailbox data that the MailboxList is requesting and showing that. That's progress. There may be significant issues with making multiple requests in a single round-trip because my client library appears to do things like hard-coding the position of specific requests. I may have to work around this.
This commit is contained in:
parent
c17e8b9ad0
commit
bab5d421d4
7 changed files with 195 additions and 141 deletions
100
src/App.tsx
100
src/App.tsx
|
@ -1,92 +1,47 @@
|
|||
import "./App.css";
|
||||
import "bootstrap/dist/css/bootstrap.min.css";
|
||||
import * as base64 from "base-64";
|
||||
import { Client } from "jmap-client-ts";
|
||||
import { FetchTransport } from "jmap-client-ts/lib/utils/fetch-transport";
|
||||
|
||||
import { IAccount, ISession } from "./types";
|
||||
import Client, { IAuth } from "./client/Client";
|
||||
import { AccountIdMap, IAccount } from "./client/types";
|
||||
import AppLayout from "./AppLayout";
|
||||
import AuthModal from "./AuthModal";
|
||||
import React from "react";
|
||||
|
||||
interface IAuth {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
interface ILocation {
|
||||
accountId: string;
|
||||
}
|
||||
|
||||
type AppState = {
|
||||
auth: IAuth;
|
||||
account: IAccount | null;
|
||||
accounts: AccountIdMap;
|
||||
location: ILocation;
|
||||
session: ISession | null;
|
||||
};
|
||||
|
||||
type AppProps = {};
|
||||
|
||||
class App extends React.Component<AppProps, AppState> {
|
||||
account(): IAccount | null {
|
||||
if (!(this.state.session && this.state.session.accounts)) return null;
|
||||
return this.state.session.accounts[this.state.location.accountId];
|
||||
return this.client.account(this.state.location.accountId);
|
||||
}
|
||||
client: Client | null = null;
|
||||
client: Client = new Client();
|
||||
state: AppState = {
|
||||
account: null,
|
||||
accounts: {},
|
||||
auth: { email: "", password: "" },
|
||||
location: { accountId: "" },
|
||||
session: null,
|
||||
};
|
||||
|
||||
// Make the request to get system metadata
|
||||
doLogin(auth: IAuth) {
|
||||
const domain = auth.email.split("@")[1];
|
||||
const well_known_url = "https://" + domain + "/.well-known/jmap";
|
||||
const basic_auth =
|
||||
"Basic " + base64.encode(auth.email + ":" + auth.password);
|
||||
|
||||
this.client = new Client({
|
||||
accessToken: "fake token",
|
||||
httpHeaders: { Authorization: basic_auth },
|
||||
sessionUrl: well_known_url,
|
||||
transport: new FetchTransport(fetch.bind(window)),
|
||||
});
|
||||
|
||||
this.client
|
||||
.fetchSession()
|
||||
.then(() => {
|
||||
console.log("Session received");
|
||||
|
||||
// For the type checker
|
||||
if (!this.client) return;
|
||||
|
||||
const session = this.client.getSession();
|
||||
this.setState({
|
||||
...this.state,
|
||||
session: {
|
||||
...session,
|
||||
accounts: Object.fromEntries(
|
||||
Object.entries(session.accounts).map(([key, account]) => [
|
||||
key,
|
||||
{ ...account, id: key.toString(), mailboxes: [] },
|
||||
]),
|
||||
),
|
||||
},
|
||||
});
|
||||
})
|
||||
.catch((error) => console.error(error));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
onHashChange() {
|
||||
console.log(window.location.hash);
|
||||
const hash = window.location.hash.substring(1);
|
||||
this.setState({
|
||||
...this.state,
|
||||
account: this.account(),
|
||||
location: { accountId: hash },
|
||||
});
|
||||
}
|
||||
|
||||
// When the user provides credentials
|
||||
onLogin(email: string, password: string) {
|
||||
// Store the provided credentials for now
|
||||
|
@ -98,9 +53,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||
},
|
||||
});
|
||||
localStorage.setItem("auth", JSON.stringify(this.state.auth));
|
||||
this.doLogin({ email, password });
|
||||
this.client.doLogin({ email, password });
|
||||
}
|
||||
|
||||
// Load up auth credentials from the local store
|
||||
loadAuth() {
|
||||
const data = localStorage.getItem("auth");
|
||||
if (!data) return;
|
||||
|
@ -109,10 +65,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
...this.state,
|
||||
auth: auth,
|
||||
});
|
||||
if (this.client == null) {
|
||||
this.doLogin(auth);
|
||||
return;
|
||||
}
|
||||
this.client.ensureLogin(auth);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -125,6 +78,15 @@ class App extends React.Component<AppProps, AppState> {
|
|||
);
|
||||
this.loadAuth();
|
||||
this.onHashChange();
|
||||
this.client.onChange(() => {
|
||||
this.setState({
|
||||
...this.state,
|
||||
account: this.account(),
|
||||
accounts: this.client.state.session
|
||||
? this.client.state.session.accounts
|
||||
: {},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -140,15 +102,15 @@ class App extends React.Component<AppProps, AppState> {
|
|||
render() {
|
||||
return (
|
||||
<div className="App">
|
||||
{this.state && this.state.session ? (
|
||||
<AppLayout
|
||||
account={this.account()}
|
||||
accounts={this.state.session.accounts}
|
||||
client={this.client}
|
||||
/>
|
||||
) : (
|
||||
<AuthModal onLogin={this.onLogin}></AuthModal>
|
||||
)}
|
||||
<AppLayout
|
||||
account={this.state.account}
|
||||
accounts={this.state.accounts}
|
||||
client={this.client}
|
||||
/>
|
||||
<AuthModal
|
||||
show={this.client.state.session == null}
|
||||
onLogin={this.onLogin}
|
||||
></AuthModal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue