Fixes#264
Implement the equivalent of java's String.hashCode on the conversation model.
Change avatar template and attributes. Use css classes for colors.
On the conversations list, if the last message is too long, cut it with ellipsis (...) instead of going out of the screen.
On the single conversation view, if the message in the bubble contains a word that is longer than a bubble, break it anyway instead of going out of the screen.
As a chrome packaged app, we have to keep at least one window open in
order to maintain our websocket connection in the background page.
This change replaces the system window frame with custom buttons in the
inbox header, such that the 'close' button merely hides the window
rather than unloading it.
Fixes#237
FREEBIE
This reverts commit 31e7d285e3.
This seemed like a nice feature, but the popup bubble isn't very
conducive to nontrivial user inputs, e.g. file inputs.
Fixes#211
Clicking on a key conflict message opens the message detail view,
which displays the contact(s) in this conversation. If the message
contains a key conflict with any of these contacts, a button is
displayed which attempts to resolve that conflict and any other
conflicts in the conversation that are related to that contact.
Rather than opening the inbox in its own window, let it appear as a
browser action popup by default, but allow promotion to its own window
if requested.
Update unreadCounts per-conversation on incoming messages. Render unread
conversations with font-weigh: bold in the inbox view.
To ensure that the inbox and conversation views remain in sync, the
background page now ensures that the same models objects are used for
both views.
Closes#173
Previously, in the event of a failed websocket auth, we would attempt to
reconnect once a second ad infinitum. This changeset ensures that we
only reconnect automatically if the socket closed 'normally' as
indicated by the code on the socket's CloseEvent. Otherwise, show a
'Websocket closed' error on the inbox view.
Ideally we would show a more contextual error (ie, 'Unauthorized'), but
unfortunately the actual server response code is not available to our
code. It can be observed in the console output from the background page,
but programmatically, we only receive the WebSocket CloseEvent codes
listed here:
https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
The websocket error message is displayed by a normally-hidden but ever
present socket status element. Clicking this element will immediately
refresh the background page, which will try again to open the websocket
connection.
When first intalling, users will no longer be presented with the option
to register as a standalone client.
For developer convenience, the standalone form can still be found at
chrome-extension://.../register.html
Closes#159
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.
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.
Simplifies the grunt watch task for sass. Renames sass partials with
leading underscores. Flattens stylesheet directory. The only remaining
raw css file is options.css.
Move globally-relevant styles to _global. Shrink overall font size.
Previously, the ugly file input was hidden with opacity, and styled as a
square paperclip icon, but its drop and click zones were not constrained
to the visible square. They remained active across the whole 'Choose
File' button, which overlapped with the textarea. Instead, hide the file
input complete (display: none) and transmit click events from the
paperclip to the input programmatically.
Eventually, we'll need to address drag and drop events, but I want to do
that at the window level. Otherwise dropping a file outside the file
input drop zone causes the browser to navigate to the file://... url.
Render the entire conversation from a template, because some parts of it
must be rendered conditionally if it is a group vs private conversation.
Also apply some style fixes and restore lost functionality:
* Make conversation title bar fixed.
* Widens message bubbles.
* Unhide message list.
* Restore attachment rendering.
* Restore message sending and attachment file selection.
* Style attachments file input as a paperclip.
* Style send button like on Android and make it a submit input.
This was used to conditionally render messages in the group style, but
it's actually unnecessary. We can render the same markup in both cases
and change the appearance with css.
Move base64 encoding of attachments to an AttachmentView. This makes
image rendering an asynchronous task so we fire an update event to
indicate to the parent MessageListView that its content has changed
height and it is time to scroll down.
This dependency may be a little heavy for our current use case, but we can
roll with it for now and find something slimmer if it turns out yagni.
Closes#77Closes#40
Each conversation views now manages its own separate elements
rather than all binding to a shared #conversation element, and
similarly for message composition ui.
Also includes the beginnings of group creation UI (not working yet),
featuring bootstrap-tagsinput field for entering group recipients