Pull changes on change event.

We don't do much yet with the changes, and clearly this state should be
incorporated into the client in a different way, but for now I want to
commit to this checkpoint as it represents an update to my understanding
of how the standard works. Specifically, whenever we do a get against a
basic type we are given a state. We need to use that to request changes
whenever we are alerted to changes. From there we update the cache and
the display on the client should change in the reactive way.

I don't yet do the actual update, but I'm nearly there.
This commit is contained in:
Eli Ribble 2024-09-04 12:49:38 -07:00
parent c686f5c8d9
commit e93cbbaab2
2 changed files with 78 additions and 5 deletions

View File

@ -25,6 +25,7 @@ export interface IAuth {
}
export interface ClientState {
emailState: string | null;
inFlight: {
emailContents: Set<string>;
emailStubs: Set<string>;
@ -33,7 +34,9 @@ export interface ClientState {
mailboxes: {
trash: IMailbox;
} | null;
mailboxState: string | null;
session: ISession | null;
threadState: string | null;
}
class Account implements IAccount {
@ -69,13 +72,16 @@ export default class Client {
callbacks: Array<Callback> = [];
jclient: jmapclient.Client | null = null;
state: ClientState = {
emailState: null,
inFlight: {
emailContents: new Set(),
emailStubs: new Set(),
mailboxes: new Set(),
},
mailboxes: null,
mailboxState: null,
session: null,
threadState: null,
};
// Get the currently active account
@ -247,8 +253,10 @@ export default class Client {
receivedAt: e.receivedAt,
subject: e.subject,
};
this._triggerChange(msg + e.id);
});
this._triggerChange(msg);
//this.state.session.state = response.sessionState;
this.state.emailState = response.state;
})
.catch((x) => {
console.error("Failed to get email stub", emailId, x);
@ -337,13 +345,57 @@ export default class Client {
c();
});
}
_onChangedEmail(accountId: string, state: string) {
console.log("Email changed", state);
if (this.jclient === null) return;
if (this.state.session === null) return;
const account = this.account(accountId);
if (account === null) return;
if (this.state.emailState === null) return;
const args = {
accountId: accountId,
sinceState: this.state.emailState,
};
this.jclient.email_changes(args).then((r) => {
console.log("Handle email changes ", r);
});
}
_onChangedMailbox(accountId: string, state: string) {
console.log("Mailbox changed", state);
if (this.jclient === null) return;
if (this.state.session === null) return;
const account = this.account(accountId);
if (account === null) return;
if (this.state.mailboxState === null) return;
const args = {
accountId: accountId,
sinceState: this.state.session.state,
};
this.jclient.mailbox_changes(args).then((r) => {
console.log("Handle mailbox changes ", r);
});
}
_onChangedThread(accountId: string, state: string) {
console.log("Thread changed", state);
if (this.jclient === null) return;
if (this.state.session === null) return;
const account = this.account(accountId);
if (account === null) return;
if (this.state.threadState === null) return;
const args = {
accountId: accountId,
sinceState: this.state.session.state,
};
this.jclient.thread_changes(args).then((r) => {
console.log("Handle thread changes ", r);
});
}
_onSession() {
console.log("Session received");
// For the type checker
if (!this.jclient) return;
const session = this.jclient.getSession();
console.log("Session received: ", session);
// Subscribe to server-pushed events
if (session.eventSourceUrl) {
this._subscribeToEventSource(session.eventSourceUrl);
@ -373,7 +425,28 @@ export default class Client {
this.jclient.subscribeToEvents(
eventSourceUrl,
(type: string, message: PushMessage) => {
console.log("Got an event!", type, message);
if (type === "ping") {
return;
}
if (type === "state") {
console.log("Got an event!", type, message);
const stateChange = message as jmaptypes.IStateChange;
for (const [accountId, changes] of Object.entries(
stateChange.changed,
)) {
for (const [changeType, state] of Object.entries(changes)) {
if (changeType === "Email") {
this._onChangedEmail(accountId, state);
} else if (changeType === "Mailbox") {
this._onChangedMailbox(accountId, state);
} else if (changeType === "Thread") {
this._onChangedThread(accountId, state);
}
}
}
} else {
console.log("Not sure what to do with event", type);
}
},
);
}

@ -1 +1 @@
Subproject commit 160a66caf7f385b18e25f224a64f75f213997bb2
Subproject commit ee2af71a8e764c1a8153a7dcd71f4085f970243f