The greeting includes the recipient's user name (as for the message notification mail), which should increase the recipient's trust that the message isn't spam. Greetings were reused from each language's respective locale flie.
Several notifications are about a message having been sent from one user to another via OSM. I've moved the code for the HTML table that holds the actual user message, with the avatar and the body text, to its own partial template, so that it can be reused. I've updated a second notifier message to the new template, diary_comment_notification.
Since all HTML mails will presumably share the same overall layout, and the markup is fairly dense, it makes sense to use Rails layouts to share the structure across mail templates. This commit moves the core structure of the HTML mail to a layout. It will need to be further refined so that notifications that involve a text message sent by another user can share the avatar-and-message-text structure.
Rather than including HTML markup in the locale file (which also has the inconvenience of requiring both a plain-text and an HTML duplicate of the same string), move the markup to the template. Also added a helper to reduce clutter in the template slightly.
Make the file paths to image assets more compact. I investigated using `image_path` but could only get it to return the path for a public URL, which is different and also includes the asset pipeline digest.
Got rid of that big ugly base64 blob which was only a temporary crutch anyway. Added a png file instead. Use File.read rather than File.open for a 66% reduction in verbosity.
Removed some cargo-cult HTML attributes and CSS. Styling HTML for email clients is trickier than for browsers, I'm trying to keep the code as succinct but also as compatible as possible.
By default the exception thrown by Timeout::timeout is caught
using Kernel::catch so that it cannot be stopped by intermediate
exception handlers. The problem with that is that it stops any
database transactions that were in progress being rolled back
because they never see the exception.
Fortunately passing a class to Timeout::timeout changes it's
behaviour so that the exception is thrown and caught in the normal
way, allowing the database transactions to rollback.
If a deadlock occurs then the transaction will be retried so we
need to make sure that the object will still be dirty so that it
will be saved again during the retry but that the version won't
be incremented a second time.