It's rare that we get in a state where we have a device record without a
session, but we should handle errors gracefully in that case. Catch them
and register them, except for identity key errors which are registered
in handleResult.
// FREEBIE
fixup error handling // FREEBIE
This function dynamically declares a bunch of functions which bind to
its input arguments. Instead, use a new prototypal class to define
these functions within the context of a particular message.
// FREEBIE
Add a pendingMessages object to MessageSender. This object holds
one promise per recipient number. We init this promise with
Promise.resolve(), and chain on promises for message sending, replacing
the previous promise with the newly chained promise each time. If the
current promise resolves and finds that it is still the last promise
in the chain, it removes itself.
This keeps it the same width as the conversation list items.
Also make those overflow-y: scroll so that they are consistent
width, whether or not they are currently overflowing.
// FREEBIE
Websocket resources should have their keepalive timers reset whenever a
message comes in. This is a nicety that slightly reduces the amount of
traffic we send when actively messaging.
Previously this was handled by MessageReceiver, but it's a bit cleaner
to just have the WebsocketResource add an extra 'message' event handler.
// FREEBIE
Lighten last-message color for both read/unread states.
Keep bold font weight on last-message for unread state.
Bring timestamp inward a bit
// FREEBIE
Styled the conversation list items so that:
- Timestamp is on the same line as the name
- The message text on an unread conversation is ligher than the rest of
the text
Resolves: #379
Bind the sub-view to some data when we initialize it, rather than
passing it in on render. That means the image view click handler will
only ever open the blob we bound it to, even if its src attr changes for
some reason, which should never happen, but if it does, it's nice to
guard against opening arbitrary urls found in the dom.
// FREEBIE
Images that are attached to messages, either sent or received
can be opened in a new tab by clicking on them.
The previous approach that used Anchors to open the image
attachmets failed in various systems because:
- Chrome on Windows recognised "blob" as protocol and tried
to find an app for it
- Chromium on Ubuntu didn't open a new window to load the URL
The new approach adds a "click" listener to the IMG element and
opens the link using window.open (which seems to be working globaly).
Resolves: #252
In rare cases, a race between delivery receipts and outgoing message
requests can cause the sent flag to be reversed. Fix by marking messages
sent at the same time they are marked delivered.
// FREEBIE
Per WhisperSystems/TextSecure@8a1428e, bump GIF limit to 5MB, and
audio/video limit to 100MB. Update toast to notify in correct
human-readable units. The only kB size limit is for images, and will
trigger only if after scaling up to 4 times, the rescaled image did not
come in under the size limit without unacceptable quality loss.
Closes#354
Using the search field produces a filtered view of all contacts and
groups containing the input. To make this fast and scalable, add an
index on a 'tokens' array containing words from the conversation name
and different forms of phone number.
Closes#365
// FREEBIE
These are failing because MockSocket doesn't implement an EventTarget
interface like an actual WebSocket does, so we get an exception when
trying to call addEventListener on it. :(
// FREEBIE
Split into separate encrypt and transmit functions. Let the encryption
function also handle all wire formatting (ie, jsonification and base64
encoding), which simplifes TextSecureServer.sendMessages, removes a
TODO, and lets us save fewer params to make network errors replayable.
// FREEBIE
The resend button should disappear once you've clicked it. This was not
happening because the message detail view held a cached copy of the old
message errors. Fix by re-reading the errors when we re-render.
// FREEBIE
This ensures that the containing promise is rejected without triggering
the side effects of an uncaught exception, such as causing the debugger
to pause.
// FREEBIE
Opening two message-detail views in two separate conversations would
disappear one of the conversations. Fixed by better encapsulating the
sub-views of a conversation.
// FREEBIE