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.

TWO REAL PEOPLE: the operator admin and an ordinary member.

A third, SYNTHETIC "No name on file" entry used to be appended here so the name-free fallback header could be previewed. Mr. McRitchie asked for the list to be just the two, knowing what it costs: the "header for someone with no name on file" field stays in the editor and still ships to strangers, it simply cannot be previewed from this page any more. Do not quietly re-add the sample to make that field previewable — if that needs solving, solve it somewhere this decision is not reversed by accident.



80
81
82
# File 'app/services/studio/email_preview_target.rb', line 80

def all
  [find_admin, find_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.



86
87
88
89
# File 'app/services/studio/email_preview_target.rb', line 86

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