* Fetch all conversations on startup of app, not on inbox load
A recent change to fetch conversations less didn't take into account all
that can happen in the app without the inbox loaded. That only happens
when the window is shown, and messages can come in with the app in the
background. In that case, the conversation wouldn't have been loaded
from the database, but would be saved to the database anyway, losing
data.
This change fetches all conversations as soon as the the data store is
ready for a fetch. It also introduces failsafe throws to ensure that
synchronous ConversationController accesses don't happen until the
initial fetch is complete. A new getUnsafe() method was required to
account for some of the model setup that happens during that initial
conversation fetch.
Fixes#1428
FREEBIE
* Fix tests: ConversationController.load() required before get()
FREEBIE
Discovered a user log where expiring message checks were happening
constantly. This ensures that a very large timeout doesn't roll over
into immediate callbacks.
FREEBIE
I believe this to be the reason behind some of the high resource usage
on startup. If a lot of read receipts come in for disappearing messages,
this method can be called many, many times very quickly.
FREEBIE
If some future client ever sends us an arbitrary timer value which we do
not currently support, present it as a duration in seconds in timer
update messages and ui, where we would otherwise have rendered nothing,
e.g., "You set the timer to ."
// FREEBIE
When initialized, or when expiration-related attributes change, expiring
messages will set timers to self-destruct. On self-destruct they trigger
'expired' events so that frontend listeners can clean up any collections
and views referencing them.
At startup, load all messages pending expiration so they can start their
timers even if they haven't been loaded in the frontend yet.
Todo: Remove expired conversation snippets from the left pane.