* Apply the same rounding to in message bubbles and conversation list.
Also make them consistent with Android's relative times. Fixes#682
* Show full timestamps when hovering on relative time
* Compute timestamp update delays more precisely:
Set timestamps to self-update as soon as they are able to change
rather than a fixed time since the last update.
* Refactor for customizable/localizable relative times
* Update timestamp tests
* Log timestamp update intervals to help debug #460
When deleting all messages in a conversation, the entry in the left pane
should be inserted into the alphabetical portion of the list. To keep it
in this collection, do not nullify active_at.
To ensure the list view is keeping itself correctly sorted, make sure
that resorting behavior is triggered any time a relevant attribute is
changed.
This fixes deleted conversations jumping to the top of the list, and
conversation order scrambling when getting a group or contact sync
message from our master device.
Fixes#734
// FREEBIE
For messages that failed to send due to network errors, this change
allows retrying them directly from the main conversation view rather
than only from the message detail view.
// FREEBIE
The onChangeActiveAt listener promotes newly activated conversations to
the top of the inbox. By firing on an 'add' event, if the conversation
list happened to load after the inbox frontend was initialized, each new
entry would be incorrectly moved to the top, effectively reversing the
list.
// FREEBIE
This flow broke a bit with transition to modal debug log.
Restructure such that the loading class can be applied to an appropriate
element inside the modal. Ensure that the input elements are hidden when
submit is clicked, the result elements are shown when the log upload is
completed.
// FREEBIE
Untangle these two views into their component parts, consolidating all
the key conflict logic in the key conflict view. Contact view now simply
renders basic contact info and miscellaneous errors but not conflicts or
message errors.
// FREEBIE
Network errors render as a resend dialogue at the top of the message
detail and need not be re-reported in the contact list or errors
section.
// FREEBIE
When `millis_since` becomes larger than one week, `delay` becomes
negative and is set to Zero. This causes an infinite loop and therefore
100% CPU usage (single thread).
// FREEBIE
Some basic modifications to the Confirmation Dialog:
* Always attached to <body> regardless of view that called it.
* Always centered horizontally on screen.
* A black semi-transparent overlay is now displayed over everything, and under
the dialog.
* Various other style changes.
fixes#389
// FREEBIE
* Move install flow i18n logic to install_view.js (from options.js)
* Switch to using placeholders (instead of jQuery) for i18n messages with html.
* Switch to using moustache template instead of jQuery for i18n substitution.
// FREEBIE
Only show sent_at for outgoing messages, matching Android.
The received_at timestamp reflects the time a message was saved locally.
It is necessary on both incoming and outgoing messages for sorting
purposes, but can be confusing in the context of an outgoing message
detail view, since users don't think about themselves "receiving" their
own messages, and may even interpret this as the time that a message was
received by their conversation partner's device.
// FREEBIE
Typically, a view can specify its templateName and then use the default
render method on Whisper.View, except in some special cases like message
view or message detail where other operations are performed during
render.
// FREEBIE
While typing a number, the new contact element is faded out. When the
number becomes valid it is opaque. If the element is clicked while
invalid, it displays 'Invalid number' and waits for the input to change
again. A new conversation is only opened if the number is valid.
// FREEBIE
Refactor libphonenumber.validateNumber into libphonenumber.parseNumber,
which encapsulates the try-catch pattern used in number parsing and
returns an object of info about the input number rather tha throwing
since we expect to get some invalid number inputs the user is typing.
In the conversation model,
* Separate phone number validation from search token updating.
* Perform token update before save if the number was valid.
* Stop storing unneeded number variants as conversation properties.
// FREEBIE
Here lies the remains of the old compose flow, which must eventually be
restored for group creation flow, but will likely be rewritten entirely.
// FREEBIE
Search view triggers an open event when a valid phone number is entered
and the 'Create new contact' card is clicked.
Inbox view should listen and respond to this event. It should also
disregard select events on the new contact element since those are fired
before phone number validation.
Finally, the search view can stop listening to select events because the
inbox view is already doing so.
// FREEBIE
Search box finds or creates a conversation given a phone number in
local (to the user's region) or international format.
Previously you had to enter e164 format to set up the conversation
correctly.
If the number is not valid, do not open the conversation.
TODO: user feedback on invalid numbers.
// FREEBIE
By adding the drag and drop support for media files, the default
event handlers were overwritten. Thus drag and drop did not support
text. Now, the drag and drop listeners revert to the default behaviour
when the user does not drag a file.
Resolves: #478
This file is loaded by the background page, which means it is already
bound to the background page's global context. This was not true at some
time in the distant past but is true now.
// FREEBIE
Messages that are received in the active conversation while the window
is focused, are automatically marked as read.
The conversation appears as unread for a split second as the incoming message
arrives but it gets marked as read as soon as the message is displayed.
The window title now shows the global number of unread messages as
"Signal (1)". This way the user can see the number of unread messages
in the task bar and when alt-tabbing.
Resolves: #384
We don't need to keep them in memory if we're done viewing them,
plus it avoids having to re-render a large collection when we re-open a
conversation. Now that we only load a sensible number of messages at a
time, caching them between usages is less valuable. Removing them from
the collection should free them for garbage collection.
// FREEBIE
Messages with images or media were causing the scroll position to jump
around when they loaded, because rendering them changed the height of their
elements from 0 to full-height sometime after they were inserted into
the DOM.
Now when rendering attachments, we wait for them to load so they can
render at full height immediately, then warn our parent message list
before and after a potential height change, so the scroll position can
be saved and reset.
// FREEBIE
Only load the most recent messages when initially rendering a
conversation. Scrolling to the top of a message list loads older
messages.
This required some slight refactoring of how we insert message elements
into the dom. If the message is added to the end of the collection,
append it at the end. Otherwise, assume it is an older message and
prepend it.
When adding elements to the top, reset the scrollPosition to its
previous distance from scrollHeight. This keeps the current set of
elements fixed in the viewport.
// FREEBIE
Renames extension.windows.beforeUnload to onSuspend, to match the
underlying chrome api call. onClosed fires when the frontend app window
is closed, while onSuspend fires when the background page is closed or
refreshed (which amounts to an app restart).
Frontend views are initialized iff the inbox window is opened, and so
should always be listening to onClosed in order to know when they are no
longer needed.
// FREEBIE
Create a cleaner seperation between generating notifications
and updating frontend conversation views. The former is now
handled by `conversation.notify` while the latter is achieved
by triggering an event on the conversation model, which will
only be acted on if there are any views listening for it.
Additionally, instead of re-fetching the entire message history,
which is overkill, just add or update the new/modified message.
This will help speed up the newmessage event handler and also
help avoid unnecessary re-rendering when resolving key conflicts.
// FREEBIE
Follow up to ddd2e67eb5
but for incoming messages.
* Conflict state sometimes failed to be removed even though the
conflict was resolved.
* Messages failed to re-render after a conflict. We want to
re-render only the error state on outgoing messages, to avoid
flickering attachments. On incoming messages, we need to call
render to populate the message text, avatar, etc...
// FREEBIE
Display format consistent with Android:
* relative time for everything from today
* Day of week + time for within the past 7 days
* Static Month Day time for everything older
Each timestamp will only update as often as needed to stay accurate,
which is once a minute, once an hour, once a week, or never.
// FREEBIE
* Don't open message detail views from message detail views
* When message errors change, re-render the error state, but
not the message markup and contents.
* Fix renderErrors bug not removing the error class correctly.
// FREEBIE
* Refactor options.js into a view
* Break up install flow into a series of screens
* Remove bootstrap
* Make installer window static size, mostly to facilitate positioning
// FREEBIE