Although I find the previous implementation more elegant, it results in
a deeper nesting of Promises than necessary, which can make debugging
more complicated. The canvas scaling and compression apis are actually
synchronous, so the callback structure isn't really recessary here.
Converting to a loop also makes this process easier to understand at
a glance.
Fixed some bugs along the way:
* accidentally scaling small images up to 1920px
* jpeg compressing gifs and other formats even if unnecessary
Previously we would not scale large resolution images with small file
sizes, but in fact, both resolution and file size constraints should be
enforced.
With these changes, message bubbles in the default-sized chat popup are
just wide enough to display the full complement of html5 media player
controls.
Converting attachment data to base64-encoded data uris takes O(n) and
there's no need! URL.createObjectURL returns a magic link that can be
set as the `src` attribute to `img`, `video`, and `audio` tags to load
blob data directly without copying.
https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
Add contentType-specific limits, switch to lazy-init iff we encounter an
oversized file, and restyle as a toast, factoring out a generic
ToastView along the way.
Wait a little longer on initial scroll down. Previous timeout sometimes
triggered before all text is finished rendering.
Remove redundant resize calls.
Sometimes a conversation's messages would be reverse-ordered on first
load, correcting themselves after a refresh. This is an artifact of the
order we load messages from the database. To fix, load them in the
opposite order.
The alternative solution would be to reset the collection every time we
fetch new messages, but this would create an entirely new set of model
objects each time, which seems unnecessary.
Background page conversations were trying to trigger events on the inbox
list view which had been destroyed, resulting in a background page
console error of "can't read innerHeight of null".
Avoid this by removing listeners when the inbox window is closed.
When sending an constrct a copy of the PushMessageContent protobuf, add
a SyncMessageContext, and send it to ourselves. Do this for all kinds of
group messages, and individual text/media messages, but not closeSession
messages as the latter are device-specific.
Do not sync messages if we are the primary device, which should only be
supported in development. Normal web clients must be paired with a
android or ios master device, and even in dev, a primary/standalone web
client does not support linking additional devices.
The message view has three flavors so far, a normal text+attachments
message, a group update, and an end session message. This changeset
extracts the normal message rendering into its own subview, and adds
some convenience functions to the message model in order to simplify
some of that flavoring logic.
The first message sent to a new contact was throwing 'Unknown Group'.
This was because we didn't wait for the initial save to sync the `type`
attribute to indexedDB. Instead, don't trigger the conversation to open
until it has finished saving.