This is a pretty big change. I'm now storing the mailboxes within the
account as a map of IDs, which is more consistent with the rest of the
client and makes it easier to update a single mailbox when we know it
has changes.
I've also added a new function for getting a single mailbox. This isn't
really well coded - I need to refactor the client before I can do that
properly. But for now the proof-of-concept works: I'm getting push
events from the server, I'm getting the changes from my last update
state, and I'm applying them to the UI.
This is essentially the whole point for doing React and doing JMAP.
Woot.
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 is the first time I'm creating some custom style. There's probably
a way to do this with Bootstrap that I'm not expert enough to know
about.
For now I'm just scratching itches.
This is the first time I'm modifying data instead of just displaying it.
And this commit is a mess, it's all over the place with duplicating
types and breaking my class layers.
But it works, technically, so, whatever, checkpoint!
I need to totally start reworking the base client library as I'm not
happy with it at all. Also, it turns out that we have very little type
protection on the "set" methods. I had a totally improper signature for
about an hour that led to useless debugging. Reading the standard, which
is excellent, helped me get sorted out, but they type checker should be
helping me.
Additionally, I should be creating this Account class type within the
client.
This allows me to modify the client in-place and get immediate feedback
that it's working.
There's likely a better way to do this. I'm not a node developer.
Turns out I was doubling-up unnecessarily and had an event handler _and_
a hash change detection. This just made things complex. Now I use the
hash for both the mailbox and the email navigation.
I don't yet do anything with the email part.
This includes a bunch of new things. I've introduced "ensureEmail..." to
indicate that the UI would like some data to be populated, but if it is
already present we don't need to do anything.
I've also introduced a cache for emails that is keyed on the email ID. I
don't know if email IDs are unique. They look like they should be
globally unique within a given server, but I'm not sure and the standard
is unclear. It'll need some experimentation.
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 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.
This was surprisingly complex because I tried to use react-router and
found no easily and reasonable way to do it, so instead I hooked the
location change event myself and plumbed it through. This required me to
switch to a class-style component rather than a functional one, which
required translating a bunch of coding styles through React.
Overall I'm happy, it works pretty well and simply.