Class: Studio::EmailPreviewTarget

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

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

.allObject

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

Returns:

  • (Boolean)


59
# File 'app/services/studio/email_preview_target.rb', line 59

def admin? = !!@admin

#first_nameObject



60
# File 'app/services/studio/email_preview_target.rb', line 60

def first_name = name.to_s.strip.split.first

#initialsObject

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.

Returns:

  • (Boolean)


65
# File 'app/services/studio/email_preview_target.rb', line 65

def sample? = id.start_with?("sample-")

#to_paramObject



61
# File 'app/services/studio/email_preview_target.rb', line 61

def to_param = id