Class: Chats::Configuration
- Inherits:
-
Object
- Object
- Chats::Configuration
- Defined in:
- lib/chats/configuration.rb
Overview
All of the gem’s knobs, with delightful defaults: a fresh ‘Configuration` is fully working out of the box for the classic Devise + `User` Rails app.
Two design rules, shared across the gem ecosystem (moderate, api_keys, …):
1. Class names are stored as STRINGS and constantized lazily, so the
initializer can reference app classes before they're loaded and
everything survives Zeitwerk reloads.
2. Cross-gem seams are PROCS with no-op defaults, so `chats` runs
standalone and lights up when the host wires moderate / Noticed /
goodmail in.
Constant Summary collapse
- ATTACHMENT_MODES =
[false, :images, :any].freeze
- DELETION_MODES =
[false, :soft, :hard].freeze
Instance Attribute Summary collapse
-
#attachments ⇒ Object
Message attachments: ‘false` (none), `:images` (images only — the default), or `:any` (any content type).
-
#authenticate_method ⇒ Object
Method called as a ‘before_action` to require authentication (`:authenticate_user!` works with Devise out of the box).
-
#blocked_messager_ids ⇒ Object
->(messager) { ids } — every messager id that can’t talk with the given one (bidirectional).
-
#can_create_group ⇒ Object
May
creatorcreate a group conversation?. -
#can_message ⇒ Object
Host authorization on top of block enforcement: may
senderopen a conversation with / send torecipient? Blocking is ALWAYS enforced underneath this (see Chats.can_message?) so a permissive or buggy policy can never let a blocked pair talk. -
#current_messager_method ⇒ Object
Method called on the controller to fetch the current messager (‘:current_user` works with Devise out of the box).
-
#deletion ⇒ Object
What “delete” means: ‘:soft` keeps a tombstone (“message deleted”, body gone — the WhatsApp model, and the safest for Trust & Safety evidence), `:hard` destroys the row, `false` disables deletion entirely.
-
#editing ⇒ Object
Whether senders can edit their own messages after sending.
-
#encrypt_messages ⇒ Object
Encrypt message bodies at rest with ActiveRecord Encryption (‘encrypts :body`).
-
#groups ⇒ Object
Group conversations (3+ participants, a title, join/leave).
-
#layout ⇒ Object
Optional explicit layout for the engine’s screens.
-
#max_attachment_size ⇒ Object
— Limits —————————————————————.
-
#max_attachments_per_message ⇒ Object
— Limits —————————————————————.
-
#max_group_size ⇒ Object
— Limits —————————————————————.
-
#max_message_length ⇒ Object
— Limits —————————————————————.
-
#messager_avatar ⇒ Object
->(messager) { url/attachment/nil } — an avatar for the messager.
-
#messager_class ⇒ Object
The primary conversing model.
-
#messager_display_name ⇒ Object
->(messager) { String } — how a messager is named in inboxes, bubbles and typing indicators.
-
#messages_per_page ⇒ Object
— Limits —————————————————————.
-
#notifier ⇒ Object
->(event, **payload) — domain-moment fan-out (see Chats.notify).
-
#parent_controller ⇒ Object
The controller the engine inherits from.
-
#reactions ⇒ Object
Emoji reactions on messages.
-
#read_receipts ⇒ Object
Read receipts (“Seen”) + unread tracking.
-
#search ⇒ Object
Inbox search box (partial matching across participant names, conversation titles, subject labels, and message bodies — no extra dependencies; swap in pg_search & friends by overriding the controller if you outgrow it).
-
#send_rate_limit ⇒ Object
Per-sender send throttle, enforced with Rails 8’s built-in controller ‘rate_limit` when available (feature-detected; on Rails 7.1 it’s a no-op).
-
#typing_indicators ⇒ Object
Live “X is typing…” indicators (Turbo Stream custom action; no Action Cable channel of its own, see Chats::ConversationsController#typing).
Instance Method Summary collapse
-
#initialize ⇒ Configuration
constructor
A new instance of Configuration.
-
#messager_model ⇒ Object
The constantized messager class (resolved lazily — see class comment).
-
#validate! ⇒ Object
Cross-field validation, run at the end of ‘Chats.configure`.
Constructor Details
#initialize ⇒ Configuration
Returns a new instance of Configuration.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/chats/configuration.rb', line 133 def initialize @messager_class = "User" @parent_controller = "::ApplicationController" @current_messager_method = :current_user @authenticate_method = :authenticate_user! @layout = nil @groups = true @reactions = true @read_receipts = true @typing_indicators = true @editing = true @deletion = :soft @attachments = :images @search = true @messages_per_page = 30 @max_message_length = 5_000 @max_group_size = 32 @max_attachment_size = 10 * 1024 * 1024 # 10 MB @max_attachments_per_message = 4 @send_rate_limit = { to: 60, within: 60 } # 60 messages per minute per sender @encrypt_messages = false @can_message = ->(_sender, _recipient) { true } @can_create_group = ->(_creator) { true } @blocked_messager_ids = ->() { [] } @notifier = ->(_event, **_payload) {} @messager_display_name = lambda do || .try(:display_name) || .try(:name) || .try(:full_name) || .try(:username) || .try(:email) || "#{.class.model_name.human} #{.id}" end @messager_avatar = ->() { .try(:avatar) } end |
Instance Attribute Details
#attachments ⇒ Object
Message attachments: ‘false` (none), `:images` (images only — the default), or `:any` (any content type). Backed by ActiveStorage’s ‘has_many_attached`, so the host must have ActiveStorage installed to enable this.
77 78 79 |
# File 'lib/chats/configuration.rb', line 77 def @attachments end |
#authenticate_method ⇒ Object
Method called as a ‘before_action` to require authentication (`:authenticate_user!` works with Devise out of the box).
39 40 41 |
# File 'lib/chats/configuration.rb', line 39 def authenticate_method @authenticate_method end |
#blocked_messager_ids ⇒ Object
->(messager) { ids } — every messager id that can’t talk with the given one (bidirectional). Wire to the moderate gem with one line:
config. = ->(user) { Moderate.blocked_ids_for(user) }
117 118 119 |
# File 'lib/chats/configuration.rb', line 117 def @blocked_messager_ids end |
#can_create_group ⇒ Object
May creator create a group conversation?
110 111 112 |
# File 'lib/chats/configuration.rb', line 110 def can_create_group @can_create_group end |
#can_message ⇒ Object
Host authorization on top of block enforcement: may sender open a conversation with / send to recipient? Blocking is ALWAYS enforced underneath this (see Chats.can_message?) so a permissive or buggy policy can never let a blocked pair talk.
107 108 109 |
# File 'lib/chats/configuration.rb', line 107 def @can_message end |
#current_messager_method ⇒ Object
Method called on the controller to fetch the current messager (‘:current_user` works with Devise out of the box).
35 36 37 |
# File 'lib/chats/configuration.rb', line 35 def @current_messager_method end |
#deletion ⇒ Object
What “delete” means: ‘:soft` keeps a tombstone (“message deleted”, body gone — the WhatsApp model, and the safest for Trust & Safety evidence), `:hard` destroys the row, `false` disables deletion entirely.
71 72 73 |
# File 'lib/chats/configuration.rb', line 71 def deletion @deletion end |
#editing ⇒ Object
Whether senders can edit their own messages after sending.
66 67 68 |
# File 'lib/chats/configuration.rb', line 66 def editing @editing end |
#encrypt_messages ⇒ Object
Encrypt message bodies at rest with ActiveRecord Encryption (‘encrypts :body`). Requires the host to have AR encryption keys configured (`bin/rails db:encryption:init`). Note: turning this on makes message-body search degrade to title/participant matching.
99 100 101 |
# File 'lib/chats/configuration.rb', line 99 def @encrypt_messages end |
#groups ⇒ Object
Group conversations (3+ participants, a title, join/leave). Direct 1:1 conversations are always available.
51 52 53 |
# File 'lib/chats/configuration.rb', line 51 def groups @groups end |
#layout ⇒ Object
Optional explicit layout for the engine’s screens. ‘nil` (default) inherits whatever layout the parent controller resolves — usually the host’s ‘application` layout. Set to e.g. `“app”` if your host renders its logged-in surfaces with a different layout.
45 46 47 |
# File 'lib/chats/configuration.rb', line 45 def layout @layout end |
#max_attachment_size ⇒ Object
— Limits —————————————————————
86 87 88 |
# File 'lib/chats/configuration.rb', line 86 def @max_attachment_size end |
#max_attachments_per_message ⇒ Object
— Limits —————————————————————
86 87 88 |
# File 'lib/chats/configuration.rb', line 86 def @max_attachments_per_message end |
#max_group_size ⇒ Object
— Limits —————————————————————
86 87 88 |
# File 'lib/chats/configuration.rb', line 86 def max_group_size @max_group_size end |
#max_message_length ⇒ Object
— Limits —————————————————————
86 87 88 |
# File 'lib/chats/configuration.rb', line 86 def @max_message_length end |
#messager_avatar ⇒ Object
->(messager) { url/attachment/nil } — an avatar for the messager. Return anything ‘image_tag` accepts (a URL, an ActiveStorage attachment or variant), or nil to render an initials placeholder.
131 132 133 |
# File 'lib/chats/configuration.rb', line 131 def @messager_avatar end |
#messager_class ⇒ Object
The primary conversing model. Participants stay polymorphic regardless (any ‘acts_as_messager` model can join a conversation); this is the class the engine’s controllers resolve ‘current_messager` against and the default for docs/generators.
25 26 27 |
# File 'lib/chats/configuration.rb', line 25 def @messager_class end |
#messager_display_name ⇒ Object
->(messager) { String } — how a messager is named in inboxes, bubbles and typing indicators. The default tries the obvious candidates.
126 127 128 |
# File 'lib/chats/configuration.rb', line 126 def @messager_display_name end |
#messages_per_page ⇒ Object
— Limits —————————————————————
86 87 88 |
# File 'lib/chats/configuration.rb', line 86 def @messages_per_page end |
#notifier ⇒ Object
->(event, **payload) — domain-moment fan-out (see Chats.notify).
120 121 122 |
# File 'lib/chats/configuration.rb', line 120 def notifier @notifier end |
#parent_controller ⇒ Object
The controller the engine inherits from. Pointing this at the host’s ‘ApplicationController` (the default) gives the engine the host’s layout, helpers, ‘current_user`, locale switching, etc. — the same pattern api_keys uses for its dashboard.
31 32 33 |
# File 'lib/chats/configuration.rb', line 31 def parent_controller @parent_controller end |
#reactions ⇒ Object
Emoji reactions on messages.
54 55 56 |
# File 'lib/chats/configuration.rb', line 54 def reactions @reactions end |
#read_receipts ⇒ Object
Read receipts (“Seen”) + unread tracking. Read state is stored on the participant (‘last_read_at`), not per-message — see Chats::Participant for the rationale.
59 60 61 |
# File 'lib/chats/configuration.rb', line 59 def read_receipts @read_receipts end |
#search ⇒ Object
Inbox search box (partial matching across participant names, conversation titles, subject labels, and message bodies — no extra dependencies; swap in pg_search & friends by overriding the controller if you outgrow it).
82 83 84 |
# File 'lib/chats/configuration.rb', line 82 def search @search end |
#send_rate_limit ⇒ Object
Per-sender send throttle, enforced with Rails 8’s built-in controller ‘rate_limit` when available (feature-detected; on Rails 7.1 it’s a no-op). Shape: ‘{ to: Integer, within: ActiveSupport::Duration }`. Set to `nil` to disable.
93 94 95 |
# File 'lib/chats/configuration.rb', line 93 def send_rate_limit @send_rate_limit end |
#typing_indicators ⇒ Object
Live “X is typing…” indicators (Turbo Stream custom action; no Action Cable channel of its own, see Chats::ConversationsController#typing).
63 64 65 |
# File 'lib/chats/configuration.rb', line 63 def typing_indicators @typing_indicators end |
Instance Method Details
#messager_model ⇒ Object
The constantized messager class (resolved lazily — see class comment).
266 267 268 |
# File 'lib/chats/configuration.rb', line 266 def .constantize end |
#validate! ⇒ Object
Cross-field validation, run at the end of ‘Chats.configure`.
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/chats/configuration.rb', line 248 def validate! if && < 1 raise ConfigurationError, "max_message_length must be positive (got #{})" end if max_group_size && max_group_size < 3 # 2 participants is a direct conversation; a "group" of 2 is a smell. raise ConfigurationError, "max_group_size must be at least 3 (got #{max_group_size})" end if .to_i < 1 raise ConfigurationError, "messages_per_page must be positive (got #{.inspect})" end true end |