message_train 0.7.5 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitattributes +1 -0
- data/.github/workflows/ci.yml +86 -0
- data/.gitignore +64 -0
- data/.rubocop.yml +9 -0
- data/.rubocop_todo.yml +854 -2
- data/.ruby-version +1 -1
- data/.simplecov +2 -4
- data/CHANGELOG.md +128 -0
- data/CLAUDE.md +5 -0
- data/Gemfile +30 -32
- data/LICENSE.txt +1 -1
- data/README.md +106 -35
- data/Rakefile +4 -18
- data/app/assets/stylesheets/message_train.scss +405 -67
- data/app/controllers/concerns/message_train_support.rb +2 -2
- data/app/controllers/message_train/boxes_controller.rb +4 -2
- data/app/controllers/message_train/conversations_controller.rb +1 -0
- data/app/helpers/message_train/application_helper.rb +68 -0
- data/app/helpers/message_train/attachments_helper.rb +7 -4
- data/app/helpers/message_train/conversations_helper.rb +16 -16
- data/app/helpers/message_train/messages_helper.rb +23 -10
- data/app/javascript/controllers/message_train/bulk_actions_controller.js +36 -0
- data/app/javascript/controllers/message_train/lightbox_controller.js +25 -0
- data/app/javascript/controllers/message_train/nested_form_controller.js +36 -0
- data/app/javascript/controllers/message_train/recipient_autocomplete_controller.js +31 -0
- data/app/mailers/message_train/previews/receipt_mailer_preview.rb +7 -5
- data/app/models/message_train/attachment.rb +54 -42
- data/app/models/message_train/box.rb +2 -2
- data/app/models/message_train/conversation.rb +28 -2
- data/app/models/message_train/ignore.rb +2 -2
- data/app/models/message_train/message.rb +10 -4
- data/app/models/message_train/receipt.rb +27 -4
- data/app/models/message_train/unsubscribe.rb +1 -1
- data/app/views/application/404.html.haml +1 -3
- data/app/views/kaminari/_first_page.html.haml +1 -1
- data/app/views/kaminari/_last_page.html.haml +1 -1
- data/app/views/kaminari/_next_page.html.haml +1 -1
- data/app/views/kaminari/_page.html.haml +3 -3
- data/app/views/kaminari/_paginator.html.haml +12 -11
- data/app/views/kaminari/_prev_page.html.haml +1 -1
- data/app/views/message_train/application/_attachment_fields.html.haml +10 -7
- data/app/views/message_train/application/_attachment_link.html.haml +2 -2
- data/app/views/message_train/application/_widget.html.haml +2 -4
- data/app/views/message_train/boxes/_widget.html.haml +5 -5
- data/app/views/message_train/boxes/show.html.haml +28 -45
- data/app/views/message_train/collectives/_widget.html.haml +4 -4
- data/app/views/message_train/conversations/_conversation.html.haml +11 -11
- data/app/views/message_train/conversations/_deleted_toggle.html.haml +1 -1
- data/app/views/message_train/conversations/_ignored_toggle.html.haml +2 -2
- data/app/views/message_train/conversations/_read_toggle.html.haml +2 -2
- data/app/views/message_train/conversations/_toggle.html.haml +6 -4
- data/app/views/message_train/conversations/_trashed_toggle.html.haml +2 -2
- data/app/views/message_train/conversations/show.html.haml +8 -6
- data/app/views/message_train/messages/_deleted_toggle.html.haml +1 -1
- data/app/views/message_train/messages/_form.html.haml +22 -30
- data/app/views/message_train/messages/_message.html.haml +27 -45
- data/app/views/message_train/messages/_read_toggle.html.haml +2 -2
- data/app/views/message_train/messages/_toggle.html.haml +5 -1
- data/app/views/message_train/messages/_trashed_toggle.html.haml +2 -2
- data/app/views/message_train/unsubscribes/index.html.haml +12 -15
- data/badges/coverage.json +1 -0
- data/config/importmap.rb +2 -0
- data/config/locales/en.yml +6 -3
- data/db/migrate/20150721145319_create_message_train_conversations.rb +1 -1
- data/db/migrate/20150721160322_create_message_train_messages.rb +1 -1
- data/db/migrate/20150721161144_create_message_train_attachments.rb +5 -2
- data/db/migrate/20150721161940_create_message_train_receipts.rb +1 -1
- data/db/migrate/20150721163838_create_message_train_ignores.rb +1 -1
- data/db/migrate/20150901183458_add_received_through_to_message_train_receipts.rb +1 -1
- data/db/migrate/20151004184347_add_unique_index_to_receipts.rb +1 -1
- data/db/migrate/20151124000820_create_message_train_unsubscribes.rb +1 -1
- data/db/migrate/20260827095938_remove_paperclip_columns_from_message_train_attachments.rb +8 -0
- data/db/migrate/20260827171549_remove_body_from_message_train_messages.rb +5 -0
- data/db/migrate/20260827180000_add_marking_indexes.rb +9 -0
- data/db/migrate/20260827200000_add_body_back_to_message_train_messages.rb +5 -0
- data/docs/screenshots/inbox-desktop.png +0 -0
- data/docs/screenshots/inbox-mobile.png +0 -0
- data/lib/generators/message_train/install/install_generator.rb +1 -1
- data/lib/message_train/engine.rb +11 -0
- data/lib/message_train/instance_methods.rb +13 -7
- data/lib/message_train/localization.rb +4 -3
- data/lib/message_train/version.rb +1 -1
- data/lib/message_train.rb +0 -2
- data/message_train.gemspec +57 -389
- data/spec/controllers/message_train/boxes_controller_spec.rb +13 -8
- data/spec/controllers/message_train/concerns_spec.rb +2 -2
- data/spec/controllers/message_train/conversations_controller_spec.rb +36 -7
- data/spec/controllers/message_train/messages_controller_spec.rb +4 -4
- data/spec/dummy/app/assets/stylesheets/application.scss +141 -12
- data/spec/dummy/app/controllers/application_controller.rb +1 -1
- data/spec/dummy/app/javascript/application.js +4 -0
- data/spec/dummy/app/javascript/controllers/application.js +9 -0
- data/spec/dummy/app/javascript/controllers/index.js +4 -0
- data/spec/dummy/app/models/role.rb +1 -1
- data/spec/dummy/app/views/active_storage/blobs/_blob.html.erb +14 -0
- data/spec/dummy/app/views/layouts/_top_navigation.html.haml +18 -7
- data/spec/dummy/app/views/layouts/application.html.haml +22 -26
- data/spec/dummy/bin/importmap +4 -0
- data/spec/dummy/config/application.rb +7 -20
- data/spec/dummy/config/environments/development.rb +17 -21
- data/spec/dummy/config/environments/production.rb +11 -63
- data/spec/dummy/config/environments/test.rb +21 -16
- data/spec/dummy/config/importmap.rb +7 -0
- data/spec/dummy/config/initializers/assets.rb +1 -6
- data/spec/dummy/config/routes.rb +1 -1
- data/spec/dummy/config/storage.yml +7 -0
- data/spec/dummy/db/migrate/20150721140013_devise_create_users.rb +1 -1
- data/spec/dummy/db/migrate/20150721141009_rolify_create_roles.rb +1 -1
- data/spec/dummy/db/migrate/20150721141128_create_groups.rb +1 -1
- data/spec/dummy/db/migrate/20150721150307_add_display_name_column_to_users.rb +1 -1
- data/spec/dummy/db/migrate/20160207190402_create_message_train_conversations.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190403_create_message_train_messages.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190404_create_message_train_attachments.message_train.rb +5 -2
- data/spec/dummy/db/migrate/20160207190405_create_message_train_receipts.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190406_create_message_train_ignores.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190407_add_received_through_to_message_train_receipts.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190408_add_unique_index_to_receipts.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190409_create_message_train_unsubscribes.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20260827095939_remove_paperclip_columns_from_message_train_attachments.message_train.rb +9 -0
- data/spec/dummy/db/migrate/20260827161141_create_active_storage_tables.active_storage.rb +57 -0
- data/spec/dummy/db/migrate/20260827171550_remove_body_from_message_train_messages.message_train.rb +6 -0
- data/spec/dummy/db/migrate/20260827225116_add_marking_indexes.message_train.rb +10 -0
- data/spec/dummy/db/migrate/20260828034830_add_body_back_to_message_train_messages.message_train.rb +6 -0
- data/spec/dummy/db/migrate/20260828040000_drop_action_text_tables.rb +5 -0
- data/spec/dummy/db/schema.rb +106 -72
- data/spec/dummy/db/seeds/conversations.seeds.rb +22 -22
- data/spec/dummy/db/seeds/development/conversations.seeds.rb +2 -2
- data/spec/dummy/db/seeds/groups.seeds.rb +4 -4
- data/spec/dummy/db/seeds/test/attachments.seeds.rb +4 -4
- data/spec/dummy/db/seeds/test/conversations.seeds.rb +2 -2
- data/spec/dummy/db/seeds/users.seeds.rb +8 -8
- data/spec/dummy/vendor/javascript/.keep +0 -0
- data/spec/factories/attachment.rb +5 -6
- data/spec/factories/group.rb +2 -2
- data/spec/factories/message.rb +7 -7
- data/spec/factories/user.rb +3 -3
- data/spec/features/boxes_spec.rb +38 -34
- data/spec/features/conversations_spec.rb +13 -6
- data/spec/features/messages_spec.rb +20 -20
- data/spec/features/unsubscribes_spec.rb +9 -9
- data/spec/helpers/message_train/application_helper_spec.rb +16 -18
- data/spec/helpers/message_train/attachment_helper_spec.rb +8 -18
- data/spec/helpers/message_train/boxes_helper_spec.rb +6 -6
- data/spec/helpers/message_train/collectives_helper_spec.rb +10 -10
- data/spec/helpers/message_train/conversations_helper_spec.rb +43 -85
- data/spec/helpers/message_train/messages_helper_spec.rb +41 -61
- data/spec/models/message_train/attachment_spec.rb +26 -36
- data/spec/models/message_train/box_spec.rb +2 -2
- data/spec/models/message_train/conversation_spec.rb +15 -0
- data/spec/models/message_train/message_spec.rb +5 -1
- data/spec/models/message_train/receipt_spec.rb +1 -1
- data/spec/models/message_train/unsubscribe_spec.rb +1 -1
- data/spec/rails_helper.rb +14 -13
- data/spec/support/controller_behaviors.rb +13 -13
- data/spec/support/factory_bot.rb +3 -0
- data/spec/support/feature_behaviors.rb +14 -14
- data/spec/support/loaded_site/attachments.rb +6 -2
- data/spec/support/utilities.rb +49 -20
- metadata +260 -189
- data/.travis.yml +0 -12
- data/VERSION +0 -1
- data/app/assets/javascripts/ckeditor/config.js +0 -49
- data/app/assets/javascripts/message_train.js +0 -149
- data/spec/dummy/app/assets/javascripts/application.js +0 -17
- data/spec/dummy/app/assets/stylesheets/bootstrap-everything.scss +0 -54
- data/spec/dummy/config/initializers/bootstrap_leather.rb +0 -7
- data/spec/dummy/config/initializers/paperclip.rb +0 -5
- data/spec/dummy/config/secrets.yml +0 -22
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/support/factory_girl.rb +0 -3
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
4.0.6
|
data/.simplecov
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
require 'simplecov'
|
|
2
|
-
require 'coveralls'
|
|
3
2
|
|
|
4
|
-
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
|
5
3
|
SimpleCov.start do
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
add_filter 'lib/message_train/localization.rb'
|
|
5
|
+
add_filter '/spec/'
|
|
8
6
|
end
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
**Breaking change.** This is a from-the-ground-up modernization: Rails
|
|
6
|
+
4/5 support is dropped in favor of Rails >= 7.1, < 9, and several
|
|
7
|
+
dependencies that no longer exist or no longer matter are removed.
|
|
8
|
+
There is no automated migration path from a 0.7.x installation with
|
|
9
|
+
real data — see "Upgrading to 1.0.0" in the README before adopting this
|
|
10
|
+
version.
|
|
11
|
+
|
|
12
|
+
### Breaking
|
|
13
|
+
|
|
14
|
+
- **Ruby >= 3.2, Rails >= 7.1, < 9** required (was Rails 4/5).
|
|
15
|
+
- **Paperclip replaced with ActiveStorage.** `MessageTrain::Attachment`
|
|
16
|
+
now uses `has_one_attached :attachment` with named `:thumb`/`:large`
|
|
17
|
+
variants instead of Paperclip styles. Host apps must run
|
|
18
|
+
`bin/rails active_storage:install` (if not already using
|
|
19
|
+
ActiveStorage) and `bin/rails db:migrate` before upgrading. **There is
|
|
20
|
+
no backfill for existing Paperclip-stored files** - this version
|
|
21
|
+
assumes a fresh attachments table. If you have production attachment
|
|
22
|
+
data on 0.7.x, either stay on 0.7.x or write your own backfill before
|
|
23
|
+
upgrading (walk `public/system/...`, attach each file via
|
|
24
|
+
`ActiveStorage::Attached::One#attach`, then run the paperclip-column
|
|
25
|
+
removal migration).
|
|
26
|
+
- **CKEditor replaced with plain markdown, not Action Text.** Action
|
|
27
|
+
Text was evaluated and dropped in favor of markdown: message_train's
|
|
28
|
+
file attachments are already a separate `Attachment` model/list, not
|
|
29
|
+
embedded inline in the body, so Action Text's real differentiator
|
|
30
|
+
(drag-and-drop embeds baked into rich text) had no use here - it would
|
|
31
|
+
only have been a fancier textarea, at the cost of a real dependency
|
|
32
|
+
(Trix JS, `action_text_rich_texts` table, ActiveStorage's `main_app`
|
|
33
|
+
route-proxy requirement). `Message#body` is a plain `text` column,
|
|
34
|
+
rendered with `redcarpet` and sanitized through Rails' own `sanitize`
|
|
35
|
+
helper. No `action_text:install` step, no `has_rich_text`.
|
|
36
|
+
- **Bootstrap and jQuery removed entirely** - not just the app-specific
|
|
37
|
+
vendor JS (cocoon, typeahead, tokenfield), but `bootstrap-sass`,
|
|
38
|
+
`bootstrap_form`, `bootstrap_leather`, and `jquery-rails` themselves.
|
|
39
|
+
Views are now semantic HTML styled by `message_train.scss` (still a
|
|
40
|
+
real stylesheet, now vanilla CSS) with Turbo Frames and hand-written
|
|
41
|
+
Stimulus controllers. If your host app's layout/theme assumed
|
|
42
|
+
MessageTrain's views were Bootstrap markup, expect visual changes.
|
|
43
|
+
- **`importmap-rails`, `turbo-rails`, `stimulus-rails` are now runtime
|
|
44
|
+
dependencies.** The engine ships its own Stimulus controllers and
|
|
45
|
+
registers its own importmap pins and asset paths automatically via an
|
|
46
|
+
engine initializer - no manual pin-in wiring needed in the host app,
|
|
47
|
+
but the host app does need those three gems' own install generators
|
|
48
|
+
already run (i.e. be a normal Hotwire-based Rails 7+ app).
|
|
49
|
+
- **Propshaft/`dartsass-rails` replace Sprockets.** If your host app is
|
|
50
|
+
still on Sprockets, either migrate it to Propshaft or vendor
|
|
51
|
+
`message_train.scss` yourself.
|
|
52
|
+
- Dead `'Fixnum'` keys in `Box::MARK_METHODS` and
|
|
53
|
+
`Ignore::(UN)IGNORE_METHODS` fixed to `'Integer'` - these had been
|
|
54
|
+
silently no-oping since Ruby 2.4 on any installation using bare
|
|
55
|
+
integer IDs to mark/ignore.
|
|
56
|
+
- **CSS classes are now scoped/prefixed** (`.icon` -> `.message-train-icon`,
|
|
57
|
+
`.badge` -> `.message-train-badge`, and similarly for
|
|
58
|
+
`.attachment-thumbnails`, `.box-actions`, `.conversation-actions`,
|
|
59
|
+
`.date-column`, `.btn-compose`, `.dropdown-nav-item`, `.message-actions`)
|
|
60
|
+
so a host app's own broad selectors (e.g. a bare `.badge` or `ul`
|
|
61
|
+
rule) can't reach into the engine's markup and override its styling.
|
|
62
|
+
Classes with no engine-defined rule (`btn`, `dropdown-menu`, etc. -
|
|
63
|
+
now `.message-train-button` where the engine does style them) were
|
|
64
|
+
left alone. If your host app styled MessageTrain by targeting the
|
|
65
|
+
old unprefixed class names, update those selectors.
|
|
66
|
+
- **The install generator's example mount point changed from `/` to
|
|
67
|
+
`/messages`** (`mount MessageTrain::Engine => '/messages', as:
|
|
68
|
+
'message_train'`) - mounting an engine at the host app's root is
|
|
69
|
+
unusually collision-prone. This only affects fresh installs using
|
|
70
|
+
the generator's suggested route; if you already mounted at a
|
|
71
|
+
specific path, nothing changes for you.
|
|
72
|
+
- **The box bulk-actions toolbar was redesigned**: the standalone
|
|
73
|
+
"Check All" checkbox is gone (the "Check Some" group's "All" button
|
|
74
|
+
does the same thing); the "Mark" actions are always-visible icon+text
|
|
75
|
+
buttons instead of hidden behind a dropdown. If your host app
|
|
76
|
+
customized this toolbar's markup or CSS, expect to redo that
|
|
77
|
+
customization.
|
|
78
|
+
|
|
79
|
+
### Fixed
|
|
80
|
+
|
|
81
|
+
- `Message#create_conversation_if_blank` now runs `before_validation`
|
|
82
|
+
instead of `before_create`, fixing conversation-presence validation
|
|
83
|
+
under Rails 5+'s default-required `belongs_to`.
|
|
84
|
+
- `Role#resource`, `Unsubscribe#from`, `Receipt#received_through` marked
|
|
85
|
+
`optional: true` where they're intentionally nullable (global roles,
|
|
86
|
+
unsubscribe-from-everything, direct receipts), matching Rails 5+'s
|
|
87
|
+
default-required `belongs_to`.
|
|
88
|
+
- `Receipt.mark`/`Message.mark` now bulk-update instead of looping a
|
|
89
|
+
per-row save, while still touching the affected messages/conversations
|
|
90
|
+
so inbox ordering and fragment-cache keys (which depend on
|
|
91
|
+
`Conversation#updated_at` bumping on mark) keep working.
|
|
92
|
+
- Several N+1 query sites addressed: box/conversation listing now
|
|
93
|
+
preloads what its views actually walk per row, `Box#unread_count` and
|
|
94
|
+
`collective_boxes` are memoized per-instance, and
|
|
95
|
+
`Conversation#participant_ignored?` filters in-memory instead of
|
|
96
|
+
querying on every call. (`Conversation#includes_*_for?`'s receipt-flag
|
|
97
|
+
N+1 is a known, documented remaining case - see the comment at
|
|
98
|
+
`Conversation#includes_matching_receipts?`.)
|
|
99
|
+
- New indexes on `message_train_receipts.marked_read/marked_trash/
|
|
100
|
+
marked_deleted`, `message_train_conversations.updated_at`, and
|
|
101
|
+
`message_train_messages.draft`.
|
|
102
|
+
- `Conversation#new_reply` no longer builds the reply body as
|
|
103
|
+
`<blockquote>...</blockquote>` HTML, stale from the Action Text era -
|
|
104
|
+
since `Message#body` is plain markdown text now, replies were being
|
|
105
|
+
pre-filled with literal HTML tags as visible text. Replies now quote
|
|
106
|
+
the previous message as proper markdown (`> ` per line).
|
|
107
|
+
- Attaching a file and submitting a message that then fails validation
|
|
108
|
+
(e.g. a blank subject) no longer crashes on re-render. The nested
|
|
109
|
+
attachment-fields partial checked `attachment.attached?`, which is
|
|
110
|
+
true as soon as a file is chosen in-memory even before its
|
|
111
|
+
ActiveStorage blob is persisted; it now also checks
|
|
112
|
+
`attachment.blob.persisted?` before building a thumbnail/link URL.
|
|
113
|
+
- The conversations listing table (box/collective show pages) now
|
|
114
|
+
actually fills its container (`width: 100%`, real cell padding/
|
|
115
|
+
borders) instead of shrinking to its content width.
|
|
116
|
+
|
|
117
|
+
### Tooling (shouldn't affect host apps)
|
|
118
|
+
|
|
119
|
+
- Juwelier replaced with a hand-written gemspec; `Rakefile` no longer
|
|
120
|
+
depends on it.
|
|
121
|
+
- Travis CI replaced with GitHub Actions.
|
|
122
|
+
- factory_girl -> factory_bot, poltergeist -> Cuprite, coveralls dropped,
|
|
123
|
+
`should` -> `expect` syntax throughout the spec suite, rubocop bumped
|
|
124
|
+
with rubocop-rails/rubocop-rspec.
|
|
125
|
+
|
|
126
|
+
## 0.7.6 and earlier
|
|
127
|
+
|
|
128
|
+
See git history - no changelog was kept before 1.0.0.
|
data/CLAUDE.md
ADDED
data/Gemfile
CHANGED
|
@@ -1,58 +1,56 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
# Add dependencies required to use your gem here.
|
|
3
3
|
# Example:
|
|
4
|
-
gem 'haml-rails', '>=
|
|
5
|
-
gem '
|
|
6
|
-
gem '
|
|
7
|
-
gem '
|
|
8
|
-
gem '
|
|
9
|
-
gem '
|
|
4
|
+
gem 'haml-rails', '>= 2'
|
|
5
|
+
gem 'rails', '>= 7.1', '< 9'
|
|
6
|
+
gem 'rails-i18n', '>= 7', '< 9'
|
|
7
|
+
gem 'image_processing', '~> 1.2'
|
|
8
|
+
gem 'mini_magick', '~> 4.12'
|
|
9
|
+
gem 'benchmark' # mini_magick requires it; no longer a Ruby default gem as of 4.0
|
|
10
10
|
|
|
11
11
|
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
|
|
12
12
|
gem 'jbuilder', '~> 2.0'
|
|
13
13
|
|
|
14
|
-
gem '
|
|
15
|
-
gem '
|
|
16
|
-
gem 'bootstrap_leather', '>= 0.10.11', '< 1'
|
|
14
|
+
gem 'dartsass-rails', '~> 0.5'
|
|
15
|
+
gem 'importmap-rails', '~> 2.0'
|
|
17
16
|
gem 'kaminari', '~> 1.0'
|
|
18
|
-
gem '
|
|
19
|
-
gem '
|
|
20
|
-
gem '
|
|
21
|
-
gem '
|
|
22
|
-
gem 'sass-rails', '~> 5'
|
|
23
|
-
gem 'twitter-typeahead-rails'
|
|
17
|
+
gem 'propshaft', '~> 1.1'
|
|
18
|
+
gem 'redcarpet', '~> 3.6'
|
|
19
|
+
gem 'stimulus-rails', '~> 1.3'
|
|
20
|
+
gem 'turbo-rails', '~> 2.0'
|
|
24
21
|
|
|
25
22
|
# Add dependencies to develop your gem here.
|
|
26
23
|
# Include everything needed to run rake, tests, features, etc.
|
|
27
24
|
group :development do
|
|
28
|
-
gem '
|
|
29
|
-
gem '
|
|
30
|
-
gem 'rubocop', '~> 0.
|
|
31
|
-
gem '
|
|
25
|
+
gem 'rubocop', '~> 1.6', require: false
|
|
26
|
+
gem 'rubocop-rails', '~> 2.25', require: false
|
|
27
|
+
gem 'rubocop-rake', '~> 0.7', require: false
|
|
28
|
+
gem 'rubocop-rspec', '~> 3.0', require: false
|
|
32
29
|
end
|
|
33
30
|
|
|
34
31
|
group :development, :test do
|
|
35
|
-
gem 'byebug', '~>
|
|
32
|
+
gem 'byebug', '~> 11'
|
|
36
33
|
gem 'devise', '~> 4'
|
|
37
|
-
gem '
|
|
38
|
-
gem 'faker', '~>
|
|
34
|
+
gem 'factory_bot_rails', '~> 6.4'
|
|
35
|
+
gem 'faker', '~> 3'
|
|
39
36
|
gem 'friendly_id', '~> 5'
|
|
40
37
|
gem 'high_voltage', '~> 3'
|
|
41
|
-
gem 'rolify', '>= 4'
|
|
42
|
-
gem 'rspec-its', '>= 1'
|
|
43
|
-
gem 'rspec-rails', '
|
|
38
|
+
gem 'rolify', '>= 4'
|
|
39
|
+
gem 'rspec-its', '>= 1', '< 2'
|
|
40
|
+
gem 'rspec-rails', '~> 7.0'
|
|
44
41
|
gem 'seedbank', '~> 0.3'
|
|
45
|
-
gem 'sqlite3', '~> 1
|
|
42
|
+
gem 'sqlite3', '~> 2.1'
|
|
46
43
|
end
|
|
47
44
|
|
|
48
45
|
group :test do
|
|
49
|
-
gem 'capybara', '~>
|
|
50
|
-
gem '
|
|
51
|
-
gem 'database_cleaner', '~> 1
|
|
46
|
+
gem 'capybara', '~> 3.40'
|
|
47
|
+
gem 'cuprite', '~> 0.15'
|
|
48
|
+
gem 'database_cleaner-active_record', '~> 2.1'
|
|
52
49
|
gem 'launchy', '~> 2', require: false
|
|
53
|
-
gem '
|
|
50
|
+
gem 'puma', '~> 6.0'
|
|
54
51
|
gem 'rails-controller-testing', '~> 1.0'
|
|
55
52
|
gem 'rspec-collection_matchers', '>= 1'
|
|
56
|
-
gem 'rspec-html-matchers', '~> 0.
|
|
57
|
-
gem 'shoulda-matchers', '
|
|
53
|
+
gem 'rspec-html-matchers', '~> 0.10'
|
|
54
|
+
gem 'shoulda-matchers', '~> 6.0'
|
|
55
|
+
gem 'simplecov', '~> 0.22', require: false
|
|
58
56
|
end
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
# MessageTrain
|
|
2
|
-
[](https://github.com/gemvein/message_train/actions/workflows/ci.yml)
|
|
3
|
+
[](https://rubygems.org/gems/message_train)
|
|
4
|
+
[](https://github.com/gemvein/message_train/actions/workflows/ci.yml)
|
|
5
|
+
[](http://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
<!--
|
|
8
|
+
MessageTrain ships real views/CSS/JS, so it's a candidate for these once
|
|
9
|
+
each has a real automated check backing it - add whichever apply as that
|
|
10
|
+
check is actually wired up and passing. Don't add a badge for a check
|
|
11
|
+
that isn't actually running; an unbacked badge is worse than none. None
|
|
12
|
+
of these checks exist yet as of 2026-08-28.
|
|
13
|
+
|
|
14
|
+
[](#)
|
|
15
|
+
[](#)
|
|
16
|
+
[](#)
|
|
17
|
+
[](#)
|
|
18
|
+
-->
|
|
19
|
+
|
|
20
|
+
MessageTrain is a Rails Engine for private messaging, built on Turbo
|
|
21
|
+
Frames and Stimulus, that lets users send and display private messages
|
|
22
|
+
to one another. It can also be configured to send messages to a user
|
|
23
|
+
collective (such as a certain Role or Group of users).
|
|
10
24
|
|
|
11
25
|
Messages can be saved as drafts instead of sending. Message composition
|
|
12
|
-
features type-ahead completion for recipients,
|
|
13
|
-
arbitrary number of attachments. Messages are grouped together into
|
|
26
|
+
features type-ahead completion for recipients, markdown-formatted bodies,
|
|
27
|
+
and an arbitrary number of attachments. Messages are grouped together into
|
|
14
28
|
conversations, and allow valid senders to reply to a given message. Any given
|
|
15
29
|
conversation can be ignored if it is no longer of interest to the user, at
|
|
16
30
|
which point no further messages will be received in that conversation. The
|
|
@@ -26,24 +40,47 @@ through a collective (unless they have unsubscribed from those notifications
|
|
|
26
40
|
or all notifications).
|
|
27
41
|
|
|
28
42
|
### Inbox Page
|
|
29
|
-
|
|
43
|
+
<p>
|
|
44
|
+
<img src="docs/screenshots/inbox-desktop.png" alt="Inbox on desktop" width="70%">
|
|
45
|
+
<img src="docs/screenshots/inbox-mobile.png" alt="Inbox on mobile" width="25%">
|
|
46
|
+
</p>
|
|
30
47
|
|
|
31
48
|
## Installation
|
|
32
49
|
|
|
33
|
-
|
|
34
|
-
|
|
50
|
+
MessageTrain is a normal Hotwire-based Rails 7.1+ app dependency - it
|
|
51
|
+
expects your host app already has `importmap-rails`, `turbo-rails`, and
|
|
52
|
+
`stimulus-rails` installed (their own install generators already run),
|
|
53
|
+
and is on Propshaft rather than Sprockets. It uses ActiveStorage for
|
|
54
|
+
attachments, so run its installer too if you haven't already:
|
|
55
|
+
|
|
35
56
|
```bash
|
|
36
|
-
|
|
37
|
-
gem 'message_train'
|
|
57
|
+
bin/rails active_storage:install
|
|
38
58
|
```
|
|
39
59
|
|
|
40
|
-
|
|
60
|
+
**Watch the file-conflict prompt carefully** if your app has customized
|
|
61
|
+
`spec/spec_helper.rb` or `spec/rails_helper.rb` - answering (or missing)
|
|
62
|
+
the overwrite prompt wrong can silently replace your project's own spec
|
|
63
|
+
config. Diff after running the installer if you're not sure what
|
|
64
|
+
changed.
|
|
65
|
+
|
|
66
|
+
Message bodies are plain markdown text, rendered with `redcarpet` and
|
|
67
|
+
sanitized through Rails' own `sanitize` helper - no Action
|
|
68
|
+
Text/Trix dependency, and no separate install step needed for it.
|
|
69
|
+
|
|
70
|
+
Then add the gem and run the install generator:
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
gem 'message_train'
|
|
74
|
+
```
|
|
41
75
|
|
|
42
76
|
```bash
|
|
43
77
|
rails g message_train:install
|
|
78
|
+
bin/rails db:migrate
|
|
44
79
|
```
|
|
45
80
|
|
|
46
|
-
|
|
81
|
+
The engine registers its own Stimulus controllers and importmap pins
|
|
82
|
+
automatically (via an engine initializer) - no manual pin-in wiring
|
|
83
|
+
needed in the host app.
|
|
47
84
|
|
|
48
85
|
Next, add to your models, each of which will need some kind of display
|
|
49
86
|
name column and some kind of slug (could be the same). See below for the
|
|
@@ -62,35 +99,30 @@ To include Message Train variables and helpers in your controllers, add
|
|
|
62
99
|
this concern to your controller or application controller:
|
|
63
100
|
|
|
64
101
|
```ruby
|
|
65
|
-
include
|
|
102
|
+
include MessageTrainSupport
|
|
66
103
|
```
|
|
67
104
|
|
|
68
|
-
Add to your application.css.scss
|
|
105
|
+
Add to your application.css (or application.scss, if you're using
|
|
106
|
+
dartsass-rails as message_train itself does):
|
|
69
107
|
|
|
70
108
|
```scss
|
|
71
109
|
@import 'message_train';
|
|
72
110
|
```
|
|
73
111
|
|
|
74
|
-
And in your application.js:
|
|
75
|
-
|
|
76
|
-
```js
|
|
77
|
-
//= require message_train
|
|
78
|
-
```
|
|
79
|
-
|
|
80
112
|
In your layout, supposing you use haml:
|
|
81
113
|
|
|
82
114
|
```haml
|
|
83
115
|
#alert_area
|
|
84
|
-
|
|
116
|
+
- flash.each do |type, message|
|
|
117
|
+
.alert{ class: flash_alert_class(type) }= message
|
|
85
118
|
```
|
|
86
119
|
|
|
87
|
-
If you
|
|
88
|
-
(makes use of bootstrap_leather, which is a dependency of this gem)
|
|
120
|
+
If you'd like the built-in boxes dropdown/widget for navigation:
|
|
89
121
|
|
|
90
122
|
```haml
|
|
91
123
|
- if user_signed_in?
|
|
124
|
+
= boxes_dropdown_list(current_user)
|
|
92
125
|
= message_train_widget
|
|
93
|
-
= render_widgets 'md', 3
|
|
94
126
|
```
|
|
95
127
|
|
|
96
128
|
### Required helper methods
|
|
@@ -155,13 +187,13 @@ config.address_book_methods[:users] = :valid_recipients_for
|
|
|
155
187
|
### Boxes
|
|
156
188
|
<dl>
|
|
157
189
|
<dt>boxes_dropdown_list</dt>
|
|
158
|
-
<dd>
|
|
190
|
+
<dd>Navigation dropdown list of boxes. (Be sure to check that user is signed in before calling, or you'll get errors.)</dd>
|
|
159
191
|
<dt>boxes_widget</dt>
|
|
160
|
-
<dd>
|
|
192
|
+
<dd>Widget with list of boxes</dd>
|
|
161
193
|
<dt>box_nav_item(box)</dt>
|
|
162
|
-
<dd>
|
|
194
|
+
<dd>List item for one box</dd>
|
|
163
195
|
<dt>box_list_item(box)</dt>
|
|
164
|
-
<dd>
|
|
196
|
+
<dd>List item for one box</dd>
|
|
165
197
|
<dt>box_participant_name(participant)</dt>
|
|
166
198
|
<dd>Name of the participant, according to the method specified in yourconfiguration or model.</dd>
|
|
167
199
|
<dt>box_participant_slug(participant)</dt>
|
|
@@ -237,6 +269,45 @@ config.address_book_methods[:users] = :valid_recipients_for
|
|
|
237
269
|
|
|
238
270
|
## Upgrading
|
|
239
271
|
|
|
272
|
+
### 1.0.0
|
|
273
|
+
|
|
274
|
+
This is a breaking change - see CHANGELOG.md for the full list. The
|
|
275
|
+
short version:
|
|
276
|
+
|
|
277
|
+
* Rails must be >= 7.1, < 9, and Ruby >= 3.2.
|
|
278
|
+
* Run `bin/rails active_storage:install` (if you haven't already) before
|
|
279
|
+
running MessageTrain's own migrations. **There is no automated
|
|
280
|
+
backfill for existing Paperclip-stored attachment data** - this
|
|
281
|
+
version assumes a fresh attachments table. If you have real attachment
|
|
282
|
+
data on 0.7.x in production, stay on 0.7.x until you've written your
|
|
283
|
+
own backfill (walk your existing `public/system/...` files, attach
|
|
284
|
+
each one via `ActiveStorage::Attached::One#attach`), or accept
|
|
285
|
+
starting fresh.
|
|
286
|
+
* `Message#body` is now a plain markdown text column instead of a
|
|
287
|
+
CKEditor-edited HTML column - rendered with `redcarpet` and sanitized
|
|
288
|
+
through Rails' `sanitize` helper. If you were on a pre-1.0 build of
|
|
289
|
+
this branch that used Action Text, there's no automated conversion
|
|
290
|
+
from stored rich-text HTML to markdown source; either write your own
|
|
291
|
+
conversion or start fresh.
|
|
292
|
+
* Bootstrap and jQuery are gone. If your host app's own layout/CSS
|
|
293
|
+
assumed MessageTrain's views were Bootstrap markup, expect visual
|
|
294
|
+
changes - views are now semantic HTML you can restyle directly.
|
|
295
|
+
* Your host app needs `importmap-rails`, `turbo-rails`, and
|
|
296
|
+
`stimulus-rails` already installed (a normal Rails 7+ Hotwire app) and
|
|
297
|
+
Propshaft instead of Sprockets.
|
|
298
|
+
* `alert_flash_messages` (a `bootstrap_leather` helper) no longer
|
|
299
|
+
exists - render `flash` yourself in `#alert_area`, using the new
|
|
300
|
+
`flash_alert_class(type)` helper to map Rails' flash keys to CSS
|
|
301
|
+
classes. See the Installation section above.
|
|
302
|
+
* MessageTrain's CSS classes are now prefixed (`.icon` ->
|
|
303
|
+
`.message-train-icon`, `.badge` -> `.message-train-badge`, etc.) so
|
|
304
|
+
the engine's markup can't be reached by a host app's own broad
|
|
305
|
+
selectors. If you styled MessageTrain by targeting the old
|
|
306
|
+
unprefixed class names, update those selectors.
|
|
307
|
+
* The install generator's example route now mounts at `/messages`
|
|
308
|
+
instead of `/` - only relevant if you re-run the generator or are
|
|
309
|
+
copying its suggested route for a fresh install.
|
|
310
|
+
|
|
240
311
|
### 0.7.1
|
|
241
312
|
|
|
242
313
|
Renamed `subscription` to `message_train_subscription` and `subscriptions` to `message_train_subscription`.
|
|
@@ -280,9 +351,9 @@ they will simply be skipped.
|
|
|
280
351
|
it.
|
|
281
352
|
|
|
282
353
|
## Contributors
|
|
283
|
-
* [
|
|
354
|
+
* [Loren Lundgren](https://github.com/nerakdon)
|
|
284
355
|
* [Chad Lundgren](https://github.com/chadlundgren)
|
|
285
356
|
|
|
286
357
|
## Copyright
|
|
287
358
|
|
|
288
|
-
Copyright (c) 2015-
|
|
359
|
+
Copyright (c) 2015-2026 Gem Vein. See LICENSE.txt for further details.
|
data/Rakefile
CHANGED
|
@@ -8,23 +8,9 @@ rescue Bundler::BundlerError => e
|
|
|
8
8
|
$stderr.puts 'Run `bundle install` to install missing gems'
|
|
9
9
|
exit e.status_code
|
|
10
10
|
end
|
|
11
|
+
require 'bundler/gem_tasks'
|
|
11
12
|
require 'rake'
|
|
12
13
|
|
|
13
|
-
require 'juwelier'
|
|
14
|
-
Juwelier::Tasks.new do |gem|
|
|
15
|
-
# gem is a Gem::Specification...
|
|
16
|
-
# see http://guides.rubygems.org/specification-reference/ for more options
|
|
17
|
-
gem.name = 'message_train'
|
|
18
|
-
gem.homepage = 'http://www.gemvein.com/museum/cases/message_train'
|
|
19
|
-
gem.license = 'MIT'
|
|
20
|
-
gem.summary = 'Rails 4 & 5 Engine providing messaging for any object'
|
|
21
|
-
gem.description = 'Rails 4 & 5 Engine providing private and public messaging'\
|
|
22
|
-
' for any object, such as Users or Groups'
|
|
23
|
-
gem.email = 'karen.e.lundgren@gmail.com'
|
|
24
|
-
gem.authors = ['Karen Lundgren']
|
|
25
|
-
end
|
|
26
|
-
Juwelier::RubygemsDotOrgTasks.new
|
|
27
|
-
|
|
28
14
|
require 'rspec/core'
|
|
29
15
|
require 'rspec/core/rake_task'
|
|
30
16
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
@@ -40,7 +26,7 @@ end
|
|
|
40
26
|
task default: :spec
|
|
41
27
|
|
|
42
28
|
require 'rdoc/task'
|
|
43
|
-
|
|
29
|
+
RDoc::Task.new do |rdoc|
|
|
44
30
|
version = File.exist?('VERSION') ? File.read('VERSION') : ''
|
|
45
31
|
|
|
46
32
|
rdoc.rdoc_dir = 'rdoc'
|
|
@@ -55,9 +41,9 @@ load 'rails/tasks/engine.rake'
|
|
|
55
41
|
# load 'rails/tasks/statistics.rake'
|
|
56
42
|
|
|
57
43
|
namespace :message_train do
|
|
58
|
-
desc 'Clean out development
|
|
44
|
+
desc 'Clean out development ActiveStorage files'
|
|
59
45
|
task files: :environment do
|
|
60
|
-
FileUtils.rm_rf(Dir["#{Rails.root}/
|
|
46
|
+
FileUtils.rm_rf(Dir["#{Rails.root}/storage/*"])
|
|
61
47
|
end
|
|
62
48
|
desc 'Recreate database from seeds and clean out all system files'
|
|
63
49
|
task clean: :environment do
|