Add names and sizes for all attachments except images, and (as with
arbitrary attachments), clicking on the text will open a save dialog.
In the absence of a filename, choose something that makes sense.
Display different icons for different media types, including distinct icons
for voice notes and audio files.
In iOS theme, audio, video, voice, and files are all encapsulated in bubbles.
Closes#804Closes#842Closes#836
// FREEBIE
Make arbitrary files look nicer and display the filename.
If an audio or video element fails to load for any reason, timeout after
a few seconds and render it as an arbitrary file. Also short circuit to
this treatment for common audio and video file types that we know are
going to fail, e.g., proprietary formats from apple.
// 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.
Previously we only declared the message body as selectable, but Chrome's
implementation of user-select is a little quirky in that it allows
unselectable text to be copied if you select elements around it. Oddly
enough, styling the entire bubble contents as selectable, including the
timestamp, actually prevents chrome from copying the timestamp text when
it's not supposed to, i.e., when triple-clicking the message body.
Fixes#887
// FREEBIE
Move away from inline style attributes for setting contact colors.
Apply colors by name via css classes instead. Also lays groundwork
for syncing contact colors.
// FREEBIE
The bar is effectively invisible, but having it present means that we
don't see a jarring change in width when the content expands into the
overflow zone and triggers the scrollbar to suddenly appear.
// FREEBIE