Improve HTML e-mails based on Litmus tests (#6301)
* Use PNG images in HTML e-mails * Make webpack use URLs with host so fonts load inside HTML e-mails Convert this back to a relative URL in the premailer CSS loader since local requests are quicker * Improve responsive design * Add missing PNG icon
BIN
app/javascript/images/mailer/icon_cached.png
Normal file
After Width: | Height: | Size: 754 B |
BIN
app/javascript/images/mailer/icon_done.png
Normal file
After Width: | Height: | Size: 279 B |
BIN
app/javascript/images/mailer/icon_email.png
Normal file
After Width: | Height: | Size: 520 B |
BIN
app/javascript/images/mailer/icon_grade.png
Normal file
After Width: | Height: | Size: 541 B |
BIN
app/javascript/images/mailer/icon_lock_open.png
Normal file
After Width: | Height: | Size: 550 B |
BIN
app/javascript/images/mailer/icon_person_add.png
Normal file
After Width: | Height: | Size: 512 B |
BIN
app/javascript/images/mailer/icon_reply.png
Normal file
After Width: | Height: | Size: 391 B |
BIN
app/javascript/images/mailer/logo_full.png
Normal file
After Width: | Height: | Size: 3 KiB |
BIN
app/javascript/images/mailer/logo_transparent.png
Normal file
After Width: | Height: | Size: 627 B |
|
@ -17,7 +17,7 @@ body {
|
||||||
-ms-text-size-adjust: 100%;
|
-ms-text-size-adjust: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.email_body {
|
.email-body {
|
||||||
td,
|
td,
|
||||||
div,
|
div,
|
||||||
a,
|
a,
|
||||||
|
@ -235,6 +235,12 @@ h5 {
|
||||||
color: lighten($ui-base-color, 34%);
|
color: lighten($ui-base-color, 34%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-cell {
|
||||||
|
h5 {
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
td {
|
td {
|
||||||
background: darken($ui-base-color, 8%);
|
background: darken($ui-base-color, 8%);
|
||||||
|
@ -512,3 +518,29 @@ ul {
|
||||||
min-height: 1024px !important;
|
min-height: 1024px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 697px) {
|
||||||
|
.email-container,
|
||||||
|
.col-1,
|
||||||
|
.col-2,
|
||||||
|
.col-3,
|
||||||
|
.col-4,
|
||||||
|
.col-5,
|
||||||
|
.col-6 {
|
||||||
|
width: 100% !important;
|
||||||
|
max-width: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-start {
|
||||||
|
padding-top: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-end {
|
||||||
|
padding-bottom: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padded {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
%tr
|
%tr
|
||||||
%td.column-cell
|
%td.column-cell
|
||||||
= link_to root_url do
|
= link_to root_url do
|
||||||
= image_tag full_pack_url('logo_full.svg'), alt: 'Mastodon', height: 34, class: 'logo'
|
= image_tag full_pack_url('logo_full.png'), alt: 'Mastodon', height: 34, class: 'logo'
|
||||||
|
|
||||||
= yield
|
= yield
|
||||||
|
|
||||||
|
@ -41,15 +41,12 @@
|
||||||
%tr
|
%tr
|
||||||
%td.blank-cell.footer
|
%td.blank-cell.footer
|
||||||
.email-row
|
.email-row
|
||||||
.col-4
|
.col-6
|
||||||
%table.column{ cellspacing: 0, cellpadding: 0 }
|
%table.column{ cellspacing: 0, cellpadding: 0 }
|
||||||
%tbody
|
%tbody
|
||||||
%td.column-cell
|
%td.column-cell
|
||||||
%p= t 'about.hosted_on', domain: site_hostname
|
%p= t 'about.hosted_on', domain: site_hostname
|
||||||
%p= link_to t('application_mailer.notification_preferences'), settings_notifications_url
|
%p= link_to t('application_mailer.notification_preferences'), settings_notifications_url
|
||||||
.col-2
|
|
||||||
%table.column{ cellspacing: 0, cellpadding: 0 }
|
|
||||||
%tbody
|
|
||||||
%td.column-cell.text-right
|
%td.column-cell.text-right
|
||||||
= link_to root_url do
|
= link_to root_url do
|
||||||
= image_tag full_pack_url('logo_transparent.svg'), alt: 'Mastodon', height: 24
|
= image_tag full_pack_url('logo_transparent.png'), alt: 'Mastodon', height: 24
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= image_tag full_pack_url('icon_grade.svg'), alt:''
|
= image_tag full_pack_url('icon_grade.png'), alt:''
|
||||||
|
|
||||||
%h1= t 'notification_mailer.favourite.title'
|
%h1= t 'notification_mailer.favourite.title'
|
||||||
%p.lead= t('notification_mailer.favourite.body', name: @account.acct)
|
%p.lead= t('notification_mailer.favourite.body', name: @account.acct)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= image_tag full_pack_url('icon_person_add.svg'), alt: ''
|
= image_tag full_pack_url('icon_person_add.png'), alt: ''
|
||||||
|
|
||||||
%h1= t 'notification_mailer.follow.title'
|
%h1= t 'notification_mailer.follow.title'
|
||||||
%p.lead= t('notification_mailer.follow.body', name: @account.acct)
|
%p.lead= t('notification_mailer.follow.body', name: @account.acct)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= image_tag full_pack_url('icon_person_add.svg'), alt: ''
|
= image_tag full_pack_url('icon_person_add.png'), alt: ''
|
||||||
|
|
||||||
%h1= t 'notification_mailer.follow_request.title'
|
%h1= t 'notification_mailer.follow_request.title'
|
||||||
%p.lead= t('notification_mailer.follow_request.body', name: @account.acct)
|
%p.lead= t('notification_mailer.follow_request.body', name: @account.acct)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= image_tag full_pack_url('icon_reply.svg'), alt: ''
|
= image_tag full_pack_url('icon_reply.png'), alt: ''
|
||||||
|
|
||||||
%h1= t 'notification_mailer.mention.title'
|
%h1= t 'notification_mailer.mention.title'
|
||||||
%p.lead= t('notification_mailer.mention.body', name: @status.account.acct)
|
%p.lead= t('notification_mailer.mention.body', name: @status.account.acct)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= image_tag full_pack_url('icon_cached.svg'), alt: ''
|
= image_tag full_pack_url('icon_cached.png'), alt: ''
|
||||||
|
|
||||||
%h1= t 'notification_mailer.reblog.title'
|
%h1= t 'notification_mailer.reblog.title'
|
||||||
%p.lead= t('notification_mailer.reblog.body', name: @account.acct)
|
%p.lead= t('notification_mailer.reblog.body', name: @account.acct)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= image_tag full_pack_url('icon_email.svg'), alt: ''
|
= image_tag full_pack_url('icon_email.png'), alt: ''
|
||||||
|
|
||||||
%h1= t 'devise.mailer.confirmation_instructions.title'
|
%h1= t 'devise.mailer.confirmation_instructions.title'
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= image_tag full_pack_url('icon_email.svg'), alt: ''
|
= image_tag full_pack_url('icon_email.png'), alt: ''
|
||||||
|
|
||||||
%h1= t 'devise.mailer.email_changed.title'
|
%h1= t 'devise.mailer.email_changed.title'
|
||||||
%p.lead= t 'devise.mailer.email_changed.explanation'
|
%p.lead= t 'devise.mailer.email_changed.explanation'
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= image_tag full_pack_url('icon_lock_open.svg'), alt: ''
|
= image_tag full_pack_url('icon_lock_open.png'), alt: ''
|
||||||
|
|
||||||
%h1= t 'devise.mailer.password_change.title'
|
%h1= t 'devise.mailer.password_change.title'
|
||||||
%p.lead= t 'devise.mailer.password_change.explanation'
|
%p.lead= t 'devise.mailer.password_change.explanation'
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= image_tag full_pack_url('icon_email.svg'), alt: ''
|
= image_tag full_pack_url('icon_email.png'), alt: ''
|
||||||
|
|
||||||
%h1= t 'devise.mailer.reconfirmation_instructions.title'
|
%h1= t 'devise.mailer.reconfirmation_instructions.title'
|
||||||
%p.lead= t 'devise.mailer.reconfirmation_instructions.explanation'
|
%p.lead= t 'devise.mailer.reconfirmation_instructions.explanation'
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= image_tag full_pack_url('icon_lock_open.svg'), alt: ''
|
= image_tag full_pack_url('icon_lock_open.png'), alt: ''
|
||||||
|
|
||||||
%h1= t 'devise.mailer.reset_password_instructions.title'
|
%h1= t 'devise.mailer.reset_password_instructions.title'
|
||||||
%p.lead= t 'devise.mailer.reset_password_instructions.explanation'
|
%p.lead= t 'devise.mailer.reset_password_instructions.explanation'
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= image_tag full_pack_url('icon_done.svg'), alt: ''
|
= image_tag full_pack_url('icon_done.png'), alt: ''
|
||||||
|
|
||||||
%h1= t 'user_mailer.welcome.title', name: @resource.account.username
|
%h1= t 'user_mailer.welcome.title', name: @resource.account.username
|
||||||
%p.lead= t 'user_mailer.welcome.explanation'
|
%p.lead= t 'user_mailer.welcome.explanation'
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
%table.content-section{ cellspacing: 0, cellpadding: 0 }
|
%table.content-section{ cellspacing: 0, cellpadding: 0 }
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td.content-cell
|
%td.content-cell.content-start
|
||||||
.email-row
|
.email-row
|
||||||
.col-3
|
.col-3
|
||||||
%table.column{ cellspacing: 0, cellpadding: 0 }
|
%table.column{ cellspacing: 0, cellpadding: 0 }
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
%table.column{ cellspacing: 0, cellpadding: 0 }
|
%table.column{ cellspacing: 0, cellpadding: 0 }
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td.column-cell.content-start
|
%td.column-cell
|
||||||
%p= t 'user_mailer.welcome.full_handle_hint', instance: @instance
|
%p= t 'user_mailer.welcome.full_handle_hint', instance: @instance
|
||||||
|
|
||||||
%table.email-table{ cellspacing: 0, cellpadding: 0 }
|
%table.email-table{ cellspacing: 0, cellpadding: 0 }
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
%table.column{ cellspacing: 0, cellpadding: 0 }
|
%table.column{ cellspacing: 0, cellpadding: 0 }
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td.column-cell
|
%td.column-cell.padded
|
||||||
%table.button.button-small{ align: 'left', cellspacing: 0, cellpadding: 0 }
|
%table.button.button-small{ align: 'left', cellspacing: 0, cellpadding: 0 }
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
|
@ -89,7 +89,7 @@
|
||||||
%table.column{ cellspacing: 0, cellpadding: 0 }
|
%table.column{ cellspacing: 0, cellpadding: 0 }
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td.column-cell
|
%td.column-cell.padded
|
||||||
%table.button.button-small{ align: 'left', cellspacing: 0, cellpadding: 0 }
|
%table.button.button-small{ align: 'left', cellspacing: 0, cellpadding: 0 }
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
%table.column{ cellspacing: 0, cellpadding: 0 }
|
%table.column{ cellspacing: 0, cellpadding: 0 }
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%td.column-cell
|
%td.column-cell.padded
|
||||||
%table.button.button-small{ align: 'left', cellspacing: 0, cellpadding: 0 }
|
%table.button.button-small{ align: 'left', cellspacing: 0, cellpadding: 0 }
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
|
|
|
@ -27,7 +27,7 @@ function formatPublicPath(host = '', path = '') {
|
||||||
|
|
||||||
const output = {
|
const output = {
|
||||||
path: resolve('public', settings.public_output_path),
|
path: resolve('public', settings.public_output_path),
|
||||||
publicPath: formatPublicPath(env.ASSET_HOST, settings.public_output_path),
|
publicPath: formatPublicPath(env.ASSET_HOST || env.LOCAL_DOMAIN, settings.public_output_path),
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
module PremailerWebpackStrategy
|
module PremailerWebpackStrategy
|
||||||
def load(url)
|
def load(url)
|
||||||
|
public_path_host = ENV['ASSET_HOST'] || ENV['LOCAL_DOMAIN']
|
||||||
|
url = url.gsub(/\A\/\/#{public_path_host}/, '')
|
||||||
|
|
||||||
if Webpacker.dev_server.running?
|
if Webpacker.dev_server.running?
|
||||||
url = File.join("#{Webpacker.dev_server.protocol}://#{Webpacker.dev_server.host_with_port}", url)
|
url = File.join("#{Webpacker.dev_server.protocol}://#{Webpacker.dev_server.host_with_port}", url)
|
||||||
HTTP.get(url).to_s
|
HTTP.get(url).to_s
|
||||||
|
|