Class: Studio::EmailPreviewTarget
- Inherits:
-
Object
- Object
- Studio::EmailPreviewTarget
- Defined in:
- app/services/studio/email_preview_target.rb
Overview
WHO the email manager previews an email as.
The banner's header is per-recipient ("Welcome Mason!"), so "what does this email look like" has no answer until you say who is receiving it. The page offers a small set of real people to stand in, and every variable on the page — first name, email — comes from the chosen one.
Why real records rather than made-up samples
A fabricated "Sample User sample@example.com" previews a person who cannot receive mail, and it hides the failures that actually happen: an account with no display name, a name that is one word, a name long enough to wrap the banner. Reading the host's own users puts those in front of the operator.
Why an ADMIN and a MEMBER
They differ in the ways that break email. An admin is usually the operator themselves — a full name on file, an internal address. A member is whoever signed up: often no name at all, which is the case that renders "Welcome !" if the fallback header is wrong. Being able to flip between them is how that gets caught here rather than in someone's inbox.
Nil-safe throughout. The host's User model may be absent, may not respond to
admin?, may have no rows. The preview degrades to a synthetic stand-in
rather than taking the manager down — this is a page for looking at pictures.
Constant Summary collapse
- ATTRIBUTES =
%i[id label name email admin avatar_url avatar_color].freeze
- DEFAULT_AVATAR_COLOR =
"#6b7280".freeze
Class Method Summary collapse
-
.all ⇒ Object
Every target the page can offer, admin first.
-
.resolve(id) ⇒ Object
The one to preview as.
Instance Method Summary collapse
- #admin? ⇒ Boolean
- #first_name ⇒ Object
-
#initialize(id:, label:, name: nil, email: nil, admin: false, avatar_url: nil, avatar_color: nil, initials: nil) ⇒ EmailPreviewTarget
constructor
A new instance of EmailPreviewTarget.
-
#initials ⇒ Object
The HOST's own initials when it has them, so this circle matches the one in the navbar rather than being a second opinion about the same person.
-
#sample? ⇒ Boolean
A stand-in used only when the host has no matching user.
- #to_param ⇒ Object
Constructor Details
#initialize(id:, label:, name: nil, email: nil, admin: false, avatar_url: nil, avatar_color: nil, initials: nil) ⇒ EmailPreviewTarget
Returns a new instance of EmailPreviewTarget.
31 32 33 34 35 36 37 38 39 40 41 |
# File 'app/services/studio/email_preview_target.rb', line 31 def initialize(id:, label:, name: nil, email: nil, admin: false, avatar_url: nil, avatar_color: nil, initials: nil) @id = id.to_s @label = label @name = name.presence @email = email.presence @admin = admin @avatar_url = avatar_url.presence @avatar_color = avatar_color.presence || DEFAULT_AVATAR_COLOR @initials = initials.presence end |
Class Method Details
.all ⇒ Object
Every target the page can offer, admin first.
The NAMELESS sample is always offered, even when a real member exists. It is the only way to see what the name-free fallback header sends, and the accounts an app actually parks tend to be real people with real names — McRitchie Studio's member is Mack McRitchie. The alternative was stripping a real person's name to make a preview reachable, which trades a worse app for a better test.
76 77 78 |
# File 'app/services/studio/email_preview_target.rb', line 76 def all [find_admin, find_member, sample_member].compact.uniq(&:id) end |
.resolve(id) ⇒ Object
The one to preview as. Falls back to the first available rather than erroring on a stale id from a bookmarked URL.
82 83 84 85 |
# File 'app/services/studio/email_preview_target.rb', line 82 def resolve(id) list = all list.find { |target| target.id == id.to_s } || list.first end |
Instance Method Details
#admin? ⇒ Boolean
59 |
# File 'app/services/studio/email_preview_target.rb', line 59 def admin? = !!@admin |
#first_name ⇒ Object
60 |
# File 'app/services/studio/email_preview_target.rb', line 60 def first_name = name.to_s.strip.split.first |
#initials ⇒ Object
The HOST's own initials when it has them, so this circle matches the one in the navbar rather than being a second opinion about the same person. Falls back to the address when there is no name, because "no name on file" is the ordinary case for a member and an empty circle identifies nobody.
47 48 49 50 51 52 53 54 55 |
# File 'app/services/studio/email_preview_target.rb', line 47 def initials return @initials if @initials source = name.presence || email.to_s.split("@").first.to_s parts = source.split(/[\s._-]+/).reject(&:empty?) return "?" if parts.empty? (parts.length == 1 ? parts.first[0, 2] : parts.first(2).map { |part| part[0] }.join).upcase end |
#sample? ⇒ Boolean
A stand-in used only when the host has no matching user. Named as a sample so nobody mistakes the preview for a real account.
65 |
# File 'app/services/studio/email_preview_target.rb', line 65 def sample? = id.start_with?("sample-") |
#to_param ⇒ Object
61 |
# File 'app/services/studio/email_preview_target.rb', line 61 def to_param = id |