message_train 0.7.6 → 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.
Files changed (171) hide show
  1. checksums.yaml +5 -5
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/ci.yml +86 -0
  4. data/.gitignore +64 -0
  5. data/.rubocop.yml +9 -0
  6. data/.rubocop_todo.yml +854 -2
  7. data/.ruby-version +1 -1
  8. data/.simplecov +2 -4
  9. data/CHANGELOG.md +128 -0
  10. data/CLAUDE.md +5 -0
  11. data/Gemfile +29 -31
  12. data/LICENSE.txt +1 -1
  13. data/README.md +106 -35
  14. data/Rakefile +4 -18
  15. data/app/assets/stylesheets/message_train.scss +405 -67
  16. data/app/controllers/concerns/message_train_support.rb +2 -2
  17. data/app/controllers/message_train/boxes_controller.rb +4 -2
  18. data/app/controllers/message_train/conversations_controller.rb +1 -0
  19. data/app/helpers/message_train/application_helper.rb +68 -0
  20. data/app/helpers/message_train/attachments_helper.rb +7 -4
  21. data/app/helpers/message_train/conversations_helper.rb +16 -16
  22. data/app/helpers/message_train/messages_helper.rb +23 -10
  23. data/app/javascript/controllers/message_train/bulk_actions_controller.js +36 -0
  24. data/app/javascript/controllers/message_train/lightbox_controller.js +25 -0
  25. data/app/javascript/controllers/message_train/nested_form_controller.js +36 -0
  26. data/app/javascript/controllers/message_train/recipient_autocomplete_controller.js +31 -0
  27. data/app/mailers/message_train/previews/receipt_mailer_preview.rb +7 -5
  28. data/app/models/message_train/attachment.rb +54 -42
  29. data/app/models/message_train/box.rb +2 -2
  30. data/app/models/message_train/conversation.rb +28 -2
  31. data/app/models/message_train/ignore.rb +2 -2
  32. data/app/models/message_train/message.rb +10 -4
  33. data/app/models/message_train/receipt.rb +27 -4
  34. data/app/models/message_train/unsubscribe.rb +1 -1
  35. data/app/views/application/404.html.haml +1 -3
  36. data/app/views/kaminari/_first_page.html.haml +1 -1
  37. data/app/views/kaminari/_last_page.html.haml +1 -1
  38. data/app/views/kaminari/_next_page.html.haml +1 -1
  39. data/app/views/kaminari/_page.html.haml +3 -3
  40. data/app/views/kaminari/_paginator.html.haml +12 -11
  41. data/app/views/kaminari/_prev_page.html.haml +1 -1
  42. data/app/views/message_train/application/_attachment_fields.html.haml +10 -7
  43. data/app/views/message_train/application/_attachment_link.html.haml +2 -2
  44. data/app/views/message_train/application/_widget.html.haml +2 -4
  45. data/app/views/message_train/boxes/_widget.html.haml +5 -5
  46. data/app/views/message_train/boxes/show.html.haml +28 -45
  47. data/app/views/message_train/collectives/_widget.html.haml +4 -4
  48. data/app/views/message_train/conversations/_conversation.html.haml +11 -11
  49. data/app/views/message_train/conversations/_deleted_toggle.html.haml +1 -1
  50. data/app/views/message_train/conversations/_ignored_toggle.html.haml +2 -2
  51. data/app/views/message_train/conversations/_read_toggle.html.haml +2 -2
  52. data/app/views/message_train/conversations/_toggle.html.haml +6 -4
  53. data/app/views/message_train/conversations/_trashed_toggle.html.haml +2 -2
  54. data/app/views/message_train/conversations/show.html.haml +8 -6
  55. data/app/views/message_train/messages/_deleted_toggle.html.haml +1 -1
  56. data/app/views/message_train/messages/_form.html.haml +22 -30
  57. data/app/views/message_train/messages/_message.html.haml +27 -45
  58. data/app/views/message_train/messages/_read_toggle.html.haml +2 -2
  59. data/app/views/message_train/messages/_toggle.html.haml +5 -1
  60. data/app/views/message_train/messages/_trashed_toggle.html.haml +2 -2
  61. data/app/views/message_train/unsubscribes/index.html.haml +12 -15
  62. data/badges/coverage.json +1 -0
  63. data/config/importmap.rb +2 -0
  64. data/config/locales/en.yml +6 -3
  65. data/db/migrate/20150721145319_create_message_train_conversations.rb +1 -1
  66. data/db/migrate/20150721160322_create_message_train_messages.rb +1 -1
  67. data/db/migrate/20150721161144_create_message_train_attachments.rb +5 -2
  68. data/db/migrate/20150721161940_create_message_train_receipts.rb +1 -1
  69. data/db/migrate/20150721163838_create_message_train_ignores.rb +1 -1
  70. data/db/migrate/20150901183458_add_received_through_to_message_train_receipts.rb +1 -1
  71. data/db/migrate/20151004184347_add_unique_index_to_receipts.rb +1 -1
  72. data/db/migrate/20151124000820_create_message_train_unsubscribes.rb +1 -1
  73. data/db/migrate/20260827095938_remove_paperclip_columns_from_message_train_attachments.rb +8 -0
  74. data/db/migrate/20260827171549_remove_body_from_message_train_messages.rb +5 -0
  75. data/db/migrate/20260827180000_add_marking_indexes.rb +9 -0
  76. data/db/migrate/20260827200000_add_body_back_to_message_train_messages.rb +5 -0
  77. data/docs/screenshots/inbox-desktop.png +0 -0
  78. data/docs/screenshots/inbox-mobile.png +0 -0
  79. data/lib/generators/message_train/install/install_generator.rb +1 -1
  80. data/lib/message_train/engine.rb +11 -0
  81. data/lib/message_train/instance_methods.rb +13 -7
  82. data/lib/message_train/localization.rb +4 -3
  83. data/lib/message_train/version.rb +1 -1
  84. data/lib/message_train.rb +0 -2
  85. data/message_train.gemspec +57 -389
  86. data/spec/controllers/message_train/boxes_controller_spec.rb +13 -8
  87. data/spec/controllers/message_train/concerns_spec.rb +2 -2
  88. data/spec/controllers/message_train/conversations_controller_spec.rb +36 -7
  89. data/spec/controllers/message_train/messages_controller_spec.rb +4 -4
  90. data/spec/dummy/app/assets/stylesheets/application.scss +141 -12
  91. data/spec/dummy/app/controllers/application_controller.rb +1 -1
  92. data/spec/dummy/app/javascript/application.js +4 -0
  93. data/spec/dummy/app/javascript/controllers/application.js +9 -0
  94. data/spec/dummy/app/javascript/controllers/index.js +4 -0
  95. data/spec/dummy/app/models/role.rb +1 -1
  96. data/spec/dummy/app/views/active_storage/blobs/_blob.html.erb +14 -0
  97. data/spec/dummy/app/views/layouts/_top_navigation.html.haml +18 -7
  98. data/spec/dummy/app/views/layouts/application.html.haml +22 -26
  99. data/spec/dummy/bin/importmap +4 -0
  100. data/spec/dummy/config/application.rb +7 -20
  101. data/spec/dummy/config/environments/development.rb +17 -21
  102. data/spec/dummy/config/environments/production.rb +11 -63
  103. data/spec/dummy/config/environments/test.rb +21 -16
  104. data/spec/dummy/config/importmap.rb +7 -0
  105. data/spec/dummy/config/initializers/assets.rb +1 -6
  106. data/spec/dummy/config/routes.rb +1 -1
  107. data/spec/dummy/config/storage.yml +7 -0
  108. data/spec/dummy/db/migrate/20150721140013_devise_create_users.rb +1 -1
  109. data/spec/dummy/db/migrate/20150721141009_rolify_create_roles.rb +1 -1
  110. data/spec/dummy/db/migrate/20150721141128_create_groups.rb +1 -1
  111. data/spec/dummy/db/migrate/20150721150307_add_display_name_column_to_users.rb +1 -1
  112. data/spec/dummy/db/migrate/20160207190402_create_message_train_conversations.message_train.rb +1 -1
  113. data/spec/dummy/db/migrate/20160207190403_create_message_train_messages.message_train.rb +1 -1
  114. data/spec/dummy/db/migrate/20160207190404_create_message_train_attachments.message_train.rb +5 -2
  115. data/spec/dummy/db/migrate/20160207190405_create_message_train_receipts.message_train.rb +1 -1
  116. data/spec/dummy/db/migrate/20160207190406_create_message_train_ignores.message_train.rb +1 -1
  117. data/spec/dummy/db/migrate/20160207190407_add_received_through_to_message_train_receipts.message_train.rb +1 -1
  118. data/spec/dummy/db/migrate/20160207190408_add_unique_index_to_receipts.message_train.rb +1 -1
  119. data/spec/dummy/db/migrate/20160207190409_create_message_train_unsubscribes.message_train.rb +1 -1
  120. data/spec/dummy/db/migrate/20260827095939_remove_paperclip_columns_from_message_train_attachments.message_train.rb +9 -0
  121. data/spec/dummy/db/migrate/20260827161141_create_active_storage_tables.active_storage.rb +57 -0
  122. data/spec/dummy/db/migrate/20260827171550_remove_body_from_message_train_messages.message_train.rb +6 -0
  123. data/spec/dummy/db/migrate/20260827225116_add_marking_indexes.message_train.rb +10 -0
  124. data/spec/dummy/db/migrate/20260828034830_add_body_back_to_message_train_messages.message_train.rb +6 -0
  125. data/spec/dummy/db/migrate/20260828040000_drop_action_text_tables.rb +5 -0
  126. data/spec/dummy/db/schema.rb +106 -72
  127. data/spec/dummy/db/seeds/conversations.seeds.rb +22 -22
  128. data/spec/dummy/db/seeds/development/conversations.seeds.rb +2 -2
  129. data/spec/dummy/db/seeds/groups.seeds.rb +4 -4
  130. data/spec/dummy/db/seeds/test/attachments.seeds.rb +4 -4
  131. data/spec/dummy/db/seeds/test/conversations.seeds.rb +2 -2
  132. data/spec/dummy/db/seeds/users.seeds.rb +8 -8
  133. data/spec/dummy/vendor/javascript/.keep +0 -0
  134. data/spec/factories/attachment.rb +5 -6
  135. data/spec/factories/group.rb +2 -2
  136. data/spec/factories/message.rb +7 -7
  137. data/spec/factories/user.rb +3 -3
  138. data/spec/features/boxes_spec.rb +38 -34
  139. data/spec/features/conversations_spec.rb +13 -6
  140. data/spec/features/messages_spec.rb +20 -20
  141. data/spec/features/unsubscribes_spec.rb +9 -9
  142. data/spec/helpers/message_train/application_helper_spec.rb +16 -18
  143. data/spec/helpers/message_train/attachment_helper_spec.rb +8 -18
  144. data/spec/helpers/message_train/boxes_helper_spec.rb +6 -6
  145. data/spec/helpers/message_train/collectives_helper_spec.rb +10 -10
  146. data/spec/helpers/message_train/conversations_helper_spec.rb +43 -85
  147. data/spec/helpers/message_train/messages_helper_spec.rb +41 -61
  148. data/spec/models/message_train/attachment_spec.rb +26 -36
  149. data/spec/models/message_train/box_spec.rb +2 -2
  150. data/spec/models/message_train/conversation_spec.rb +15 -0
  151. data/spec/models/message_train/message_spec.rb +5 -1
  152. data/spec/models/message_train/receipt_spec.rb +1 -1
  153. data/spec/models/message_train/unsubscribe_spec.rb +1 -1
  154. data/spec/rails_helper.rb +14 -13
  155. data/spec/support/controller_behaviors.rb +13 -13
  156. data/spec/support/factory_bot.rb +3 -0
  157. data/spec/support/feature_behaviors.rb +14 -14
  158. data/spec/support/loaded_site/attachments.rb +6 -2
  159. data/spec/support/utilities.rb +49 -20
  160. metadata +260 -213
  161. data/.travis.yml +0 -12
  162. data/VERSION +0 -1
  163. data/app/assets/javascripts/ckeditor/config.js +0 -49
  164. data/app/assets/javascripts/message_train.js +0 -149
  165. data/spec/dummy/app/assets/javascripts/application.js +0 -17
  166. data/spec/dummy/app/assets/stylesheets/bootstrap-everything.scss +0 -54
  167. data/spec/dummy/config/initializers/bootstrap_leather.rb +0 -7
  168. data/spec/dummy/config/initializers/paperclip.rb +0 -5
  169. data/spec/dummy/config/secrets.yml +0 -22
  170. data/spec/dummy/db/test.sqlite3 +0 -0
  171. data/spec/support/factory_girl.rb +0 -3
data/.travis.yml DELETED
@@ -1,12 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.2.2
4
- - 2.2.3
5
- before_install:
6
- - export TZ=America/Denver
7
- before_script:
8
- - export DISPLAY=:99.0
9
- - sh -e /etc/init.d/xvfb start
10
- script: bundle exec rspec
11
- notifications:
12
- email: false
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.7.6
@@ -1,49 +0,0 @@
1
- CKEDITOR.editorConfig = function(config) {
2
- config.allowedContent = true;
3
- config.width = '100%';
4
- config.toolbar_full = [
5
- {
6
- name: 'links',
7
- items: [
8
- 'Link',
9
- 'Unlink'
10
- ]
11
- },
12
- {
13
- name: 'paragraph',
14
- groups: [
15
- 'list',
16
- 'indent',
17
- 'blocks',
18
- 'align',
19
- 'bidi'
20
- ],
21
- items: [
22
- 'NumberedList',
23
- 'BulletedList',
24
- '-',
25
- 'Outdent',
26
- 'Indent',
27
- '-',
28
- 'Blockquote'
29
- ]
30
- },
31
- {
32
- name: 'basicstyles',
33
- groups: [
34
- 'basicstyles',
35
- 'cleanup'
36
- ],
37
- items: [
38
- 'Format',
39
- 'Bold',
40
- 'Italic',
41
- 'Strike',
42
- '-',
43
- 'RemoveFormat'
44
- ]
45
- }
46
- ];
47
- config.toolbar = 'full';
48
- return true;
49
- };
@@ -1,149 +0,0 @@
1
- //= require twitter/typeahead.min
2
- //= require bootstrap-tokenfield
3
- //= require cocoon
4
- //= require ckeditor/init
5
-
6
- function create_alert(level, message) {
7
- $('#alert_area').append('<div class="alert alert-' + level + ' alert-dismissible fade in" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>' + message + ' </div>');
8
- }
9
-
10
- function set_and_change(selector, value) {
11
- $(selector).prop('checked', value).trigger('change');
12
- }
13
-
14
- function flicker(selector, count) {
15
- $(selector).addClass('flicker')
16
- .delay(100)
17
- .queue(function() {
18
- $(this).removeClass('flicker');
19
- $(this).dequeue();
20
- })
21
- .delay(100)
22
- .queue(function() {
23
- if(count > 1) {
24
- flicker(selector, count - 1);
25
- } else {
26
- flick_out(selector);
27
- }
28
- $(this).dequeue();
29
- });
30
- }
31
-
32
- function flick_out(selector) {
33
- $(selector).addClass('flicker')
34
- .delay(100)
35
- .queue(function() {
36
- $(this).addClass('flicker-out');
37
- $(this).dequeue();
38
- }).delay(1000)
39
- .queue(function() {
40
- $(this).removeClass('flicker').removeClass('flicker-out');
41
- $(this).dequeue();
42
- })
43
- }
44
-
45
- function replace_via_ajax(selector, path) {
46
- $.getJSON( path, function( data ) {
47
- $(selector).replaceWith(data.html);
48
- flicker(selector, 3);
49
- });
50
- }
51
-
52
- function process_results(data) {
53
- if(typeof data.results === 'undefined' || data.results.length == 0) {
54
- create_alert('warning', data.message);
55
- } else {
56
- create_alert('info', data.message);
57
- for(var key in data.results) {
58
- var item = data.results[key];
59
- replace_via_ajax('#' + item.css_id, item.path);
60
- }
61
- }
62
- }
63
-
64
- function add_tag_magic(selector) {
65
- $(selector).tokenfield({
66
- typeahead: [
67
- {
68
- hint: true,
69
- highlight: true
70
- },
71
- {
72
- source: suggestions.ttAdapter()
73
- }
74
- ],
75
- showAutocompleteOnFocus: true
76
- });
77
- }
78
-
79
- $(document).ready(function(){
80
-
81
- $('.message_train_conversation input[type="checkbox"]').change(function(event) {
82
- if (event.target.checked) {
83
- //Checkbox has been checked
84
- $(this).parents('.message_train_conversation').addClass('selected');
85
- } else {
86
- //Checkbox has been unchecked
87
- $(this).parents('.message_train_conversation').removeClass('selected');
88
- }
89
- });
90
-
91
- $('#check_all').change(function(event) {
92
- if (event.target.checked) {
93
- set_and_change( '.message_train_conversation input[type="checkbox"]', true);
94
- } else {
95
- set_and_change( '.message_train_conversation input[type="checkbox"]', false);
96
- }
97
- });
98
-
99
- $('#box-actions .check').click(function(event) {
100
- event.preventDefault();
101
- selector = $(this).data('selector');
102
- set_and_change( '.message_train_conversation input[type="checkbox"]', false);
103
- if(selector == '.message_train_conversation') {
104
- $('#check_all').prop('checked', true);
105
- } else {
106
- $('#check_all').prop('checked', false);
107
- }
108
- if(selector != '') {
109
- set_and_change( selector + ' input[type="checkbox"]', true);
110
- }
111
- });
112
-
113
- $('#box-actions .mark-all-link').click(function(event) {
114
- event.preventDefault();
115
- $('#spinner').removeClass('hide');
116
- mark_to_set = $(this).data('mark');
117
- if(mark_to_set == 'ignore' || mark_to_set == 'unignore') {
118
- $('input[name="_method"]').val('delete');
119
- } else {
120
- $('input[name="_method"]').val('put');
121
- }
122
- $('input[name="mark_to_set"]').val(mark_to_set);
123
- $('#box').submit();
124
- });
125
-
126
- $('#box').on('ajax:success', function (e, data, status, xhr) {
127
- $('#spinner').addClass('hide');
128
- process_results(data);
129
- }).on('ajax:error', function (e, data, status, xhr) {
130
- create_alert('danger', data.responseJSON.message);
131
- });
132
-
133
- $('#box #message_train_messages .read').each(function(e){
134
- $(this).find('.collapse').collapse('hide');
135
- });
136
-
137
- $('.recipient-input').each(function() {
138
- add_tag_magic('#' + $(this).attr('id'));
139
- });
140
-
141
- $('#attachment_preview').on('show.bs.modal', function (event) {
142
- var button = $(event.relatedTarget); // Button that triggered the modal
143
- var src = button.data('src'); // Extract info from data-* attributes
144
- var original = button.data('original');
145
- var text = button.data('text');
146
- var modal = $(this);
147
- modal.find('#image_placeholder').html('<a href="' + original + '" title="' + text + '"><img src="' + src + '" /></a>')
148
- });
149
- });
@@ -1,17 +0,0 @@
1
- // This is a manifest file that'll be compiled into application.js, which will include all the files
2
- // listed below.
3
- //
4
- // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
- // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
- //
7
- // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
- // compiled file.
9
- //
10
- // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
- // about supported directives.
12
- //
13
- //= require jquery
14
- //= require jquery_ujs
15
- //= require bootstrap-sprockets
16
- //= require message_train
17
- //= require_tree .
@@ -1,54 +0,0 @@
1
- /*!
2
- * This file exists to fix a naming conflict.
3
- */
4
-
5
- // Core variables and mixins
6
- @import 'bootstrap/variables';
7
- @import 'bootstrap/mixins';
8
-
9
- // Reset and dependencies
10
- @import 'bootstrap/normalize';
11
- @import 'bootstrap/print';
12
- @import 'bootstrap/glyphicons';
13
-
14
- // Core CSS
15
- @import 'bootstrap/scaffolding';
16
- @import 'bootstrap/type';
17
- @import 'bootstrap/code';
18
- @import 'bootstrap/grid';
19
- @import 'bootstrap/tables';
20
- @import 'bootstrap/forms';
21
- @import 'bootstrap/buttons';
22
-
23
- // Components
24
- @import 'bootstrap/component-animations';
25
- @import 'bootstrap/dropdowns';
26
- @import 'bootstrap/button-groups';
27
- @import 'bootstrap/input-groups';
28
- @import 'bootstrap/navs';
29
- @import 'bootstrap/navbar';
30
- @import 'bootstrap/breadcrumbs';
31
- @import 'bootstrap/pagination';
32
- @import 'bootstrap/pager';
33
- @import 'bootstrap/labels';
34
- @import 'bootstrap/badges';
35
- @import 'bootstrap/jumbotron';
36
- @import 'bootstrap/thumbnails';
37
- @import 'bootstrap/alerts';
38
- @import 'bootstrap/progress-bars';
39
- @import 'bootstrap/media';
40
- @import 'bootstrap/list-group';
41
- @import 'bootstrap/panels';
42
- @import 'bootstrap/responsive-embed';
43
- @import 'bootstrap/wells';
44
- @import 'bootstrap/close';
45
-
46
- // Components w/ JavaScript
47
- @import 'bootstrap/modals';
48
- @import 'bootstrap/tooltip';
49
- @import 'bootstrap/popovers';
50
- @import 'bootstrap/carousel';
51
-
52
- // Utility classes
53
- @import 'bootstrap/utilities';
54
- @import 'bootstrap/responsive-utilities';
@@ -1,7 +0,0 @@
1
- BootstrapLeather.configure do |config|
2
- config.application_logo = 'logo.svg'
3
- config.application_path = '/'
4
- config.application_title = 'Message Train'
5
- config.application_description = 'Rails 4 Private Messaging Engine'
6
- config.application_keywords = 'rails-4, private-messaging, messaging, engines'
7
- end
@@ -1,5 +0,0 @@
1
- Paperclip::Attachment.default_options[:path] =
2
- ':rails_root/public/system/:rails_env/:class/:attachment/:id_partition/'\
3
- ':style/:filename'
4
- Paperclip::Attachment.default_options[:url] =
5
- '/system/:rails_env/:class/:attachment/:id_partition/:style/:filename'
@@ -1,22 +0,0 @@
1
- # Be sure to restart your server when you modify this file.
2
-
3
- # Your secret key is used for verifying the integrity of signed cookies.
4
- # If you change this key, all old signed cookies will become invalid!
5
-
6
- # Make sure the secret is at least 30 characters and all random,
7
- # no regular words or you'll be exposed to dictionary attacks.
8
- # You can use `rake secret` to generate a secure secret key.
9
-
10
- # Make sure the secrets in this file are kept private
11
- # if you're sharing your code publicly.
12
-
13
- development:
14
- secret_key_base: ac4907450d833ae9cdd320e25bdeedbf3ecb2617dd15e628bd9704882a26eb298f6cc0d5a11543d287de47f39c60c47e81290600189fe72205f34e84143260c9
15
-
16
- test:
17
- secret_key_base: 8b9c1409e1f4fbe98767d7df8e83d024eb7a2965217977a68bdfc7e4fd0940bab4bd61f658032fc7cfc9c0ec68d0d9ebdf99c2f1ab385f8f9306cb15330f1ab8
18
-
19
- # Do not keep production secrets in the repository,
20
- # instead read values from the environment.
21
- production:
22
- secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Binary file
@@ -1,3 +0,0 @@
1
- RSpec.configure do |config|
2
- config.include FactoryGirl::Syntax::Methods
3
- end