message_train 0.1.7 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.simplecov +8 -0
- data/.travis.yml +7 -2
- data/Gemfile +3 -0
- data/README.rdoc +37 -1
- data/Rakefile +5 -6
- data/VERSION +1 -1
- data/app/assets/javascripts/message_train.js +33 -0
- data/app/assets/stylesheets/message_train.scss +26 -0
- data/app/controllers/concerns/message_train_support.rb +127 -0
- data/app/controllers/message_train/application_controller.rb +1 -60
- data/app/controllers/message_train/boxes_controller.rb +0 -4
- data/app/controllers/message_train/messages_controller.rb +12 -6
- data/app/controllers/message_train/participants_controller.rb +1 -1
- data/app/controllers/message_train/unsubscribes_controller.rb +59 -0
- data/app/helpers/message_train/application_helper.rb +26 -0
- data/app/helpers/message_train/attachments_helper.rb +19 -0
- data/app/helpers/message_train/boxes_helper.rb +16 -11
- data/app/helpers/message_train/collectives_helper.rb +48 -0
- data/app/helpers/message_train/conversations_helper.rb +24 -16
- data/app/helpers/message_train/messages_helper.rb +14 -12
- data/app/mailers/message_train/application_mailer.rb +8 -0
- data/app/mailers/message_train/previews/receipt_mailer_preview.rb +10 -0
- data/app/mailers/message_train/receipt_mailer.rb +17 -0
- data/app/models/message_train/attachment.rb +28 -10
- data/app/models/message_train/box.rb +114 -83
- data/app/models/message_train/conversation.rb +48 -39
- data/app/models/message_train/ignore.rb +2 -6
- data/app/models/message_train/message.rb +40 -24
- data/app/models/message_train/receipt.rb +20 -10
- data/app/models/message_train/unsubscribe.rb +7 -0
- data/app/views/layouts/mailer.html.haml +6 -0
- data/app/views/message_train/application/_attachment_fields.html.haml +7 -0
- data/app/views/message_train/application/_attachment_link.html.haml +4 -0
- data/app/views/message_train/application/_widget.html.haml +6 -0
- data/app/views/message_train/boxes/_dropdown_list.html.haml +1 -2
- data/app/views/message_train/boxes/_list_item.html.haml +2 -2
- data/app/views/message_train/boxes/_widget.html.haml +4 -1
- data/app/views/message_train/boxes/show.html.haml +12 -4
- data/app/views/message_train/collectives/_dropdown_list.html.haml +6 -0
- data/app/views/message_train/collectives/_list_item.html.haml +5 -0
- data/app/views/message_train/collectives/_widget.html.haml +7 -0
- data/app/views/message_train/conversations/_conversation.html.haml +22 -7
- data/app/views/message_train/conversations/_deleted_toggle.html.haml +1 -1
- data/app/views/message_train/conversations/_ignored_toggle.html.haml +3 -3
- data/app/views/message_train/conversations/_read_toggle.html.haml +3 -3
- data/app/views/message_train/conversations/_toggle.html.haml +4 -1
- data/app/views/message_train/conversations/_trashed_toggle.html.haml +3 -3
- data/app/views/message_train/conversations/show.html.haml +4 -3
- data/app/views/message_train/messages/_deleted_toggle.html.haml +1 -1
- data/app/views/message_train/messages/_form.html.haml +22 -7
- data/app/views/message_train/messages/_message.html.haml +14 -4
- data/app/views/message_train/messages/_read_toggle.html.haml +1 -1
- data/app/views/message_train/messages/_trashed_toggle.html.haml +1 -1
- data/app/views/message_train/messages/edit.html.haml +1 -1
- data/app/views/message_train/messages/new.html.haml +4 -1
- data/app/views/message_train/participants/_field.html.haml +1 -1
- data/app/views/message_train/participants/_prefilled_field.html.haml +4 -0
- data/app/views/message_train/receipt_mailer/notification_email.html.haml +13 -0
- data/app/views/message_train/unsubscribes/index.html.haml +10 -0
- data/config/environment.rb +1 -0
- data/config/locales/en.yml +49 -7
- data/config/routes.rb +10 -2
- data/db/migrate/20150901183458_add_received_through_to_message_train_receipts.rb +6 -0
- data/db/migrate/20151004184347_add_unique_index_to_receipts.rb +5 -0
- data/db/migrate/20151124000820_create_message_train_unsubscribes.rb +14 -0
- data/lib/generators/message_train/install/install_generator.rb +8 -2
- data/lib/generators/message_train/install/templates/initializer.rb +5 -1
- data/lib/message_train/configuration.rb +11 -1
- data/lib/message_train/engine.rb +1 -0
- data/lib/message_train/mixin.rb +206 -21
- data/message_train.gemspec +66 -13
- data/spec/controllers/message_train/boxes_controller_spec.rb +10 -3
- data/spec/controllers/message_train/concerns_spec.rb +40 -0
- data/spec/controllers/message_train/conversations_controller_spec.rb +3 -3
- data/spec/controllers/message_train/messages_controller_spec.rb +60 -27
- data/spec/controllers/message_train/participants_controller_spec.rb +41 -6
- data/spec/controllers/message_train/unsubscribes_controller_spec.rb +56 -0
- data/spec/dummy/app/assets/files/message_train/attachments/{1917-Boys_Race_Above-Wiki.jpg → image-sample.jpg} +0 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/models/group.rb +16 -1
- data/spec/dummy/app/models/role.rb +22 -0
- data/spec/dummy/app/models/user.rb +1 -1
- data/spec/dummy/app/views/layouts/_top_navigation.html.haml +4 -2
- data/spec/dummy/app/views/layouts/application.html.haml +2 -3
- data/spec/dummy/app/views/pages/index.html.haml +4 -0
- data/spec/dummy/config/application.rb +6 -0
- data/spec/dummy/config/environments/development.rb +1 -0
- data/spec/dummy/config/environments/test.rb +1 -0
- data/spec/dummy/config/initializers/high_voltage.rb +3 -0
- data/spec/dummy/config/initializers/message_train.rb +6 -1
- data/spec/dummy/config/initializers/paperclip.rb +2 -2
- data/spec/dummy/config/routes.rb +2 -2
- data/spec/dummy/config/settings.yml +9 -0
- data/spec/dummy/db/migrate/{20150724142846_create_message_train_conversations.night_train.rb → 20150901183629_create_message_train_conversations.message_train.rb} +0 -0
- data/spec/dummy/db/migrate/{20150724142847_create_message_train_messages.night_train.rb → 20150901183630_create_message_train_messages.message_train.rb} +0 -0
- data/spec/dummy/db/migrate/{20150724142848_create_message_train_attachments.night_train.rb → 20150901183631_create_message_train_attachments.message_train.rb} +0 -0
- data/spec/dummy/db/migrate/{20150724142849_create_message_train_receipts.night_train.rb → 20150901183632_create_message_train_receipts.message_train.rb} +0 -0
- data/spec/dummy/db/migrate/{20150724142850_create_message_train_ignores.night_train.rb → 20150901183633_create_message_train_ignores.message_train.rb} +0 -0
- data/spec/dummy/db/migrate/20150901183634_add_received_through_to_message_train_receipts.message_train.rb +7 -0
- data/spec/dummy/db/migrate/20151004184519_add_unique_index_to_receipts.message_train.rb +6 -0
- data/spec/dummy/db/migrate/20151124001417_create_message_train_unsubscribes.message_train.rb +15 -0
- data/spec/dummy/db/schema.rb +24 -7
- data/spec/dummy/db/seeds/conversations.seeds.rb +92 -3
- data/spec/dummy/db/seeds/groups.seeds.rb +27 -0
- data/spec/dummy/db/seeds/test/attachments.seeds.rb +4 -0
- data/spec/dummy/db/seeds/unsubscribes.seeds.rb +12 -0
- data/spec/dummy/db/seeds/users.seeds.rb +27 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/factories/group.rb +4 -4
- data/spec/factories/message.rb +10 -3
- data/spec/features/boxes_spec.rb +160 -33
- data/spec/features/conversations_spec.rb +11 -4
- data/spec/features/messages_spec.rb +20 -6
- data/spec/features/unsubscribes_spec.rb +38 -0
- data/spec/helpers/message_train/application_helper_spec.rb +60 -0
- data/spec/helpers/message_train/attachment_helper_spec.rb +35 -0
- data/spec/helpers/message_train/boxes_helper_spec.rb +11 -5
- data/spec/helpers/message_train/collectives_helper_spec.rb +76 -0
- data/spec/helpers/message_train/conversations_helper_spec.rb +295 -0
- data/spec/helpers/message_train/messages_helper_spec.rb +217 -0
- data/spec/models/group_spec.rb +112 -2
- data/spec/models/message_train/attachment_spec.rb +44 -1
- data/spec/models/message_train/box_spec.rb +306 -51
- data/spec/models/message_train/conversation_spec.rb +84 -6
- data/spec/models/message_train/ignore_spec.rb +0 -4
- data/spec/models/message_train/message_spec.rb +49 -12
- data/spec/models/message_train/receipt_spec.rb +44 -8
- data/spec/models/message_train/unsubscribe_spec.rb +16 -0
- data/spec/models/role_spec.rb +125 -0
- data/spec/models/user_spec.rb +155 -26
- data/spec/rails_helper.rb +8 -1
- data/spec/support/attachments.rb +4 -0
- data/spec/support/controller_behaviors.rb +28 -0
- data/spec/support/conversations.rb +13 -0
- data/spec/support/groups.rb +3 -0
- data/spec/support/loaded_site.rb +3 -0
- data/spec/support/messages.rb +23 -0
- data/spec/support/roles.rb +4 -0
- data/spec/support/users.rb +6 -0
- data/spec/support/wysihtml5_helper.rb +8 -0
- metadata +99 -12
- data/spec/dummy/app/assets/files/message_train/attachments/Haie_rci.svg +0 -1714
- data/spec/dummy/public/capybara.html +0 -193
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f8b74012f45f8321860ca7bc6f48ec9a5741ebf
|
4
|
+
data.tar.gz: 79423ee5ff4c48be2ac56f6a66a2138a981b7442
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 307096ad03c2d35a41bab46d1aca7d6c6f0f28dfe58a7327ada339ae4390157935aecac47232a450512a3d9f0e6db7261ce200469a70dd1d7686bfc28b94164f
|
7
|
+
data.tar.gz: eeb0da18f5c3fd979b0effd9a82f66afc82462c9dc9e7a5f25f1d1fa14dbaca7428939f8bd772151fdae4152cd9eb21b008356da8514501ff5079282cc6d1700
|
data/.simplecov
ADDED
data/.travis.yml
CHANGED
@@ -2,6 +2,11 @@ language: ruby
|
|
2
2
|
rvm:
|
3
3
|
- ruby-2.2.1
|
4
4
|
- 2.2.2
|
5
|
+
before_install:
|
6
|
+
- export TZ=America/Denver
|
5
7
|
before_script:
|
6
|
-
|
7
|
-
|
8
|
+
- export DISPLAY=:99.0
|
9
|
+
- sh -e /etc/init.d/xvfb start
|
10
|
+
script: bundle exec rspec
|
11
|
+
notifications:
|
12
|
+
email: false
|
data/Gemfile
CHANGED
@@ -17,6 +17,8 @@ gem 'bootstrap-sass', '~> 3.3'
|
|
17
17
|
gem 'bootstrap_leather', '~> 0.8'
|
18
18
|
gem 'bootstrap_pager', '~> 0.10'
|
19
19
|
gem 'bootstrap_form', '~> 2.3'
|
20
|
+
gem 'bootstrap-wysihtml5-rails', '> 0.3'
|
21
|
+
gem 'cocoon', '~> 1.2'
|
20
22
|
|
21
23
|
# Add dependencies to develop your gem here.
|
22
24
|
# Include everything needed to run rake, tests, features, etc.
|
@@ -37,6 +39,7 @@ group :development, :test do
|
|
37
39
|
gem 'seedbank', '~> 0.3'
|
38
40
|
gem 'friendly_id', '~> 5'
|
39
41
|
gem 'byebug', '~> 5'
|
42
|
+
gem 'high_voltage', '~> 2.4'
|
40
43
|
end
|
41
44
|
|
42
45
|
group :test do
|
data/README.rdoc
CHANGED
@@ -4,7 +4,13 @@
|
|
4
4
|
{<img src="https://badge.fury.io/rb/message_train.svg" alt="Gem Version" />}[http://badge.fury.io/rb/message_train]
|
5
5
|
|
6
6
|
|
7
|
-
Rails 4 Private Messaging Gem
|
7
|
+
MessageTrain is a Rails 4 Private Messaging Gem that uses bootstrap to send and display private messages from one user to another. It can also be configured to send messages to a user collective (such as a certain Role or Group of users).
|
8
|
+
|
9
|
+
Messages can be saved as drafts instead of sending. Message composition features type-ahead completion for recipients, wysiwyg html bodies, and an arbitrary number of attachments. Messages are grouped together into conversations, and allow valid senders to reply to a given message. Any given conversation can be ignored if it is no longer of interest to the user, at which point no further messages will be received in that conversation. The "read" or "unread" status of messages is tracked automatically, and can also be changed manually by the user.
|
10
|
+
|
11
|
+
Conversations are grouped into various boxes, depending on their status for that user: in, sent, all, drafts, trash, ignored. Any message can be trashed by the user, at which point the user has the option to permanently delete it.
|
12
|
+
|
13
|
+
Email messages are sent when a user receives a message, either directly or through a collective (unless they have unsubscribed from those notifications).
|
8
14
|
|
9
15
|
== Installation
|
10
16
|
|
@@ -27,6 +33,10 @@ OR to set the name and slug columns:
|
|
27
33
|
|
28
34
|
message_train slug_column: :short_name, name_column: :display_name
|
29
35
|
|
36
|
+
To include Message Train variables and helpers in your controllers, add this concern to your controller or application controller:
|
37
|
+
|
38
|
+
include MessageTrainSupport
|
39
|
+
|
30
40
|
Add to your application.css.scss:
|
31
41
|
|
32
42
|
@import "message_train";
|
@@ -55,6 +65,8 @@ The `message_train` mixin takes the following options:
|
|
55
65
|
[:only] A symbol or array of symbols to be the only relationships used, which can include: [:sender, :recipient]
|
56
66
|
[:except] A symbol or array of symbols not to create relationships for, which can include: [:sender, :recipient]
|
57
67
|
[:valid_senders] A method name to call for a list of valid senders for this model
|
68
|
+
[:collectives_for_recipient] A method that, when passed @box_user, will return a collection of valid instances of this model for that @box_user to receive. Probably a scope. (e.g. it might return groups that the user is a member of)
|
69
|
+
[:valid_recipients] A method that returns a collection of valid recipients for this model. default: nil
|
58
70
|
[:name_column] The column by which to name and find this model. default: :name
|
59
71
|
[:slug_column] The column with the short, typeable form of the name. default: :slug
|
60
72
|
|
@@ -102,6 +114,30 @@ Or in your initializer:
|
|
102
114
|
[message_toggle(message, icon, mark_to_set, title, options = {})] Link to toggle some status of a message
|
103
115
|
[message_recipients(message)] Recipients for a given message
|
104
116
|
|
117
|
+
== Configuration
|
118
|
+
|
119
|
+
[config.slug_columns] Usually populated by options on the `message_train` mixin for models, this contains a `Hash` of tables and their slug columns
|
120
|
+
[config.name_columns] Usually populated by options on the `message_train` mixin for models, this contains a `Hash` of tables and their name columns
|
121
|
+
[config.current_user_method] Defaults to `Devise`'s `current_user`
|
122
|
+
[config.user_sign_in_path] Defaults to `Devise`'s `/users/sign_in`
|
123
|
+
[config.user_route_authentication_method] Defaults to `Devise`'s `:user`
|
124
|
+
[config.address_book_method] Default value if `address_book_methods` doesn't have a match for this table
|
125
|
+
[config.address_book_methods] `Hash` of tables and the methods those tables use to provide a tab-completion address book for that table.
|
126
|
+
[config.recipient_tables] Usually populated by options on the `message_train` mixin for models, this contains a `Hash` of tables and their class names
|
127
|
+
[config.collectives_for_recipient_methods] Usually populated by options on the `message_train` mixin for models, this contains a list of collectives that act as recipients through which users receive messages.
|
128
|
+
[config.valid_senders_methods] Usually populated by options on the `message_train` mixin for models, this contains a `Hash` of tables and the methods that indicate which users can send messages to a given instance from that table.
|
129
|
+
[config.valid_recipients_methods] Usually populated by options on the `message_train` mixin for models, this contains a `Hash` of tables and the methods that indicate which users can receive messages from a given instance from that table.
|
130
|
+
[config.from_email] The email address from which notification emails are sent.
|
131
|
+
[config.site_name] The name of the site, for use in notification emails.
|
132
|
+
|
133
|
+
== Upgrading
|
134
|
+
|
135
|
+
New columns were added with version 0.2.0, so when upgrading be sure to install the latest migrations:
|
136
|
+
|
137
|
+
rake message_train:install:migrations
|
138
|
+
|
139
|
+
Running this command is harmless if the migrations are already installed, they will simply be skipped.
|
140
|
+
|
105
141
|
== Contributing to MessageTrain
|
106
142
|
|
107
143
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
data/Rakefile
CHANGED
@@ -17,8 +17,8 @@ Jeweler::Tasks.new do |gem|
|
|
17
17
|
gem.name = "message_train"
|
18
18
|
gem.homepage = "http://www.gemvein.com/museum/cases/message_train"
|
19
19
|
gem.license = "MIT"
|
20
|
-
gem.summary = %Q{
|
21
|
-
gem.description = %Q{
|
20
|
+
gem.summary = %Q{Rails 4 Engine providing messaging for any object}
|
21
|
+
gem.description = %Q{Rails 4 Engine providing private/public messaging for any object, such as Users or Groups}
|
22
22
|
gem.email = "karen.e.lundgren@gmail.com"
|
23
23
|
gem.authors = ["Karen Lundgren"]
|
24
24
|
# dependencies defined in Gemfile
|
@@ -62,10 +62,9 @@ namespace :message_train do
|
|
62
62
|
end
|
63
63
|
desc "Recreate database from seeds and clean out all system files"
|
64
64
|
task clean: :environment do
|
65
|
+
import 'spec/dummy/Rakefile'
|
65
66
|
Rake::Task["message_train:files"].invoke
|
66
|
-
|
67
|
-
|
68
|
-
Rake::Task["app:db:migrate"].invoke
|
69
|
-
Rake::Task["app:db:seed"].invoke
|
67
|
+
dummy_app_path = MessageTrain::Engine.root.join('spec', 'dummy')
|
68
|
+
system "bundle exec rake -f #{dummy_app_path.join('Rakefile')} db:drop db:create db:migrate db:seed db:test:prepare"
|
70
69
|
end
|
71
70
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -1,4 +1,6 @@
|
|
1
1
|
//= require bootstrap-tags
|
2
|
+
//= require cocoon
|
3
|
+
//= require bootstrap-wysihtml5
|
2
4
|
|
3
5
|
function create_alert(level, message) {
|
4
6
|
$('#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>');
|
@@ -61,6 +63,11 @@ function process_results(data) {
|
|
61
63
|
function add_tag_magic(selector) {
|
62
64
|
var div = $(selector);
|
63
65
|
var model = div.data('model');
|
66
|
+
if ( div.data('read-only') ) {
|
67
|
+
var readOnly = true;
|
68
|
+
} else {
|
69
|
+
var readOnly = false;
|
70
|
+
}
|
64
71
|
var request_string = '/box/in/participants/' + model + '.json';
|
65
72
|
$.getJSON(request_string, function(data){
|
66
73
|
var form = div.parents('form');
|
@@ -69,6 +76,7 @@ function add_tag_magic(selector) {
|
|
69
76
|
suggestions.push(participant.slug);
|
70
77
|
});
|
71
78
|
var tags = div.tags({
|
79
|
+
readOnly: readOnly,
|
72
80
|
suggestions: suggestions,
|
73
81
|
tagSize: 'lg',
|
74
82
|
promptText: 'Comma separated list'
|
@@ -138,4 +146,29 @@ $(document).ready(function(){
|
|
138
146
|
$('.recipient-input').each(function() {
|
139
147
|
add_tag_magic('#' + $(this).attr('id'));
|
140
148
|
});
|
149
|
+
|
150
|
+
$('#attachment_preview').on('show.bs.modal', function (event) {
|
151
|
+
var button = $(event.relatedTarget); // Button that triggered the modal
|
152
|
+
var src = button.data('src'); // Extract info from data-* attributes
|
153
|
+
var original = button.data('original');
|
154
|
+
var text = button.data('text');
|
155
|
+
var modal = $(this);
|
156
|
+
modal.find('#image_placeholder').html('<a href="' + original + '" title="' + text + '"><img src="' + src + '" /></a>')
|
157
|
+
})
|
158
|
+
|
159
|
+
$('.wysiwyg').wysihtml5({
|
160
|
+
toolbar: {
|
161
|
+
'font-styles': true,
|
162
|
+
'color': false,
|
163
|
+
'emphasis': {
|
164
|
+
'small': true
|
165
|
+
},
|
166
|
+
'blockquote': true,
|
167
|
+
'lists': true,
|
168
|
+
'html': false,
|
169
|
+
'link': true,
|
170
|
+
'image': false,
|
171
|
+
'smallmodals': true
|
172
|
+
}
|
173
|
+
});
|
141
174
|
});
|
@@ -1,4 +1,17 @@
|
|
1
1
|
@import 'bootstrap-tags';
|
2
|
+
@import "bootstrap-wysihtml5/bootstrap3-wysihtml5";
|
3
|
+
|
4
|
+
img {
|
5
|
+
max-width: 100%;
|
6
|
+
}
|
7
|
+
|
8
|
+
.attachment-thumbnails {
|
9
|
+
text-align: center;
|
10
|
+
|
11
|
+
.thumbnail {
|
12
|
+
text-align: center;
|
13
|
+
}
|
14
|
+
}
|
2
15
|
|
3
16
|
#message_train_conversations {
|
4
17
|
a, a:link, a:visited {
|
@@ -65,10 +78,18 @@
|
|
65
78
|
white-space: nowrap;
|
66
79
|
}
|
67
80
|
|
81
|
+
.date-column {
|
82
|
+
white-space: nowrap;
|
83
|
+
}
|
84
|
+
|
68
85
|
tr:hover .conversation-actions a {
|
69
86
|
visibility: visible;
|
70
87
|
}
|
71
88
|
|
89
|
+
.glyphicon-thumbnail {
|
90
|
+
font-size: 170px;
|
91
|
+
}
|
92
|
+
|
72
93
|
.glyphicon.spinning {
|
73
94
|
animation: spin 1s infinite linear;
|
74
95
|
-webkit-animation: spin2 1s infinite linear;
|
@@ -99,9 +120,14 @@ tr:hover .conversation-actions a {
|
|
99
120
|
.btn-compose {
|
100
121
|
margin: 0 auto 10px auto;
|
101
122
|
width: 100%;
|
123
|
+
white-space: inherit;
|
102
124
|
}
|
103
125
|
|
104
126
|
.tags-input {
|
105
127
|
border-radius: 4px;
|
106
128
|
padding-left: 12px;
|
129
|
+
}
|
130
|
+
|
131
|
+
.dropdown-menu {
|
132
|
+
width: 240px;
|
107
133
|
}
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module MessageTrainSupport
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
|
6
|
+
# Last in first out
|
7
|
+
prepend_before_filter :load_collective_boxes,
|
8
|
+
:load_box,
|
9
|
+
:load_collective,
|
10
|
+
:load_division,
|
11
|
+
:load_box_user,
|
12
|
+
unless: :devise_controller?
|
13
|
+
before_filter :load_objects
|
14
|
+
before_action :set_locale
|
15
|
+
|
16
|
+
helper MessageTrain::ApplicationHelper
|
17
|
+
helper MessageTrain::BoxesHelper
|
18
|
+
helper MessageTrain::CollectivesHelper
|
19
|
+
helper MessageTrain::ConversationsHelper
|
20
|
+
helper MessageTrain::MessagesHelper
|
21
|
+
helper MessageTrain::AttachmentsHelper
|
22
|
+
|
23
|
+
rescue_from ActiveRecord::RecordNotFound do
|
24
|
+
render '404', status: :not_found
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def require_authentication
|
32
|
+
redirect_to url_for(MessageTrain.configuration.user_sign_in_path), flash: { notice: :you_must_sign_in_or_sign_up_to_continue.l }
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_locale
|
36
|
+
I18n.locale = params[:locale] || I18n.default_locale
|
37
|
+
end
|
38
|
+
|
39
|
+
def load_box_user
|
40
|
+
@box_user = send(MessageTrain.configuration.current_user_method) || require_authentication
|
41
|
+
end
|
42
|
+
|
43
|
+
def load_division
|
44
|
+
@division = (params[:division] || params[:box_division] || 'in').to_sym
|
45
|
+
end
|
46
|
+
|
47
|
+
def load_collective
|
48
|
+
if params[:collective_id].present?
|
49
|
+
collective_table, collective_id = params[:collective_id].split(':')
|
50
|
+
collective_class_name = MessageTrain.configuration.recipient_tables[collective_table.to_sym]
|
51
|
+
collective_model = collective_class_name.constantize
|
52
|
+
slug_column = MessageTrain.configuration.slug_columns[collective_table.to_sym]
|
53
|
+
@collective = collective_model.find_by!(slug_column => collective_id)
|
54
|
+
|
55
|
+
unless @collective.allows_receiving_by?(@box_user) || @collective.allows_sending_by?(@box_user)
|
56
|
+
flash[:error] = :access_to_that_box_denied.l
|
57
|
+
redirect_to main_app.root_url
|
58
|
+
return
|
59
|
+
end
|
60
|
+
|
61
|
+
case @division
|
62
|
+
when :in, :ignored
|
63
|
+
unless @collective.allows_receiving_by? @box_user
|
64
|
+
flash[:error] = :access_to_that_box_denied.l
|
65
|
+
redirect_to message_train.collective_box_url(@collective.path_part, :sent)
|
66
|
+
end
|
67
|
+
when :sent, :drafts
|
68
|
+
unless @collective.allows_sending_by? @box_user
|
69
|
+
flash[:error] = :access_to_that_box_denied.l
|
70
|
+
redirect_to message_train.collective_box_url(@collective.path_part, :in)
|
71
|
+
end
|
72
|
+
else
|
73
|
+
# do nothing
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def load_box
|
79
|
+
if !@collective.nil?
|
80
|
+
@box = @collective.box(@division, @box_user)
|
81
|
+
else
|
82
|
+
@box = @box_user.box(@division)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def load_collective_boxes
|
87
|
+
@collective_boxes = @box_user.collective_boxes(@division, @box_user)
|
88
|
+
end
|
89
|
+
|
90
|
+
def load_objects
|
91
|
+
@objects = {}
|
92
|
+
@objects['conversations'] = {}
|
93
|
+
@objects['messages'] = {}
|
94
|
+
if params[:objects].present?
|
95
|
+
params[:objects].each do |type, list|
|
96
|
+
list.each do |key, list_item|
|
97
|
+
@objects[type][key.to_s] = list_item.to_i
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def respond_to_marking
|
104
|
+
if !@box.errors.all.empty?
|
105
|
+
respond_to do |format|
|
106
|
+
format.html {
|
107
|
+
flash[:error] = @box.message
|
108
|
+
show
|
109
|
+
}
|
110
|
+
format.json { render :results, status: :unprocessable_entity }
|
111
|
+
end
|
112
|
+
else
|
113
|
+
respond_to do |format|
|
114
|
+
format.html {
|
115
|
+
if @box.results.all.empty?
|
116
|
+
flash[:alert] = @box.message
|
117
|
+
else
|
118
|
+
flash[:notice] = @box.message
|
119
|
+
end
|
120
|
+
show
|
121
|
+
}
|
122
|
+
format.json { render :results, status: :accepted }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
@@ -1,64 +1,5 @@
|
|
1
1
|
module MessageTrain
|
2
2
|
class ApplicationController < ::ApplicationController
|
3
|
-
|
4
|
-
helper ConversationsHelper
|
5
|
-
helper MessagesHelper
|
6
|
-
before_filter :load_box
|
7
|
-
before_filter :load_objects
|
8
|
-
before_action :set_locale
|
9
|
-
|
10
|
-
rescue_from ActiveRecord::RecordNotFound do
|
11
|
-
render '404', status: :not_found
|
12
|
-
end
|
13
|
-
|
14
|
-
rescue_from ActionController::RoutingError do
|
15
|
-
redirect_to url_for(MessageTrain.configuration.user_sign_in_path), flash: { notice: :you_must_sign_in_or_sign_up_to_continue.l }
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
def set_locale
|
20
|
-
I18n.locale = params[:locale] || I18n.default_locale
|
21
|
-
end
|
22
|
-
|
23
|
-
def load_box
|
24
|
-
@box = send(MessageTrain.configuration.current_user_method).box(params[:box_division].to_sym)
|
25
|
-
end
|
26
|
-
|
27
|
-
def load_objects
|
28
|
-
@objects = {}
|
29
|
-
@objects['conversations'] = {}
|
30
|
-
@objects['messages'] = {}
|
31
|
-
if params[:objects].present?
|
32
|
-
params[:objects].each do |type, list|
|
33
|
-
list.each do |key, list_item|
|
34
|
-
@objects[type][key.to_s] = list_item.to_i
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def respond_to_marking
|
41
|
-
if !@box.errors.all.empty?
|
42
|
-
respond_to do |format|
|
43
|
-
format.html {
|
44
|
-
flash[:error] = @box.message
|
45
|
-
show
|
46
|
-
}
|
47
|
-
format.json { render :results, status: :unprocessable_entity }
|
48
|
-
end
|
49
|
-
else
|
50
|
-
respond_to do |format|
|
51
|
-
format.html {
|
52
|
-
if @box.results.all.empty?
|
53
|
-
flash[:alert] = @box.message
|
54
|
-
else
|
55
|
-
flash[:notice] = @box.message
|
56
|
-
end
|
57
|
-
show
|
58
|
-
}
|
59
|
-
format.json { render :results, status: :accepted }
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
3
|
+
include MessageTrainSupport
|
63
4
|
end
|
64
5
|
end
|
@@ -26,9 +26,9 @@ module MessageTrain
|
|
26
26
|
@message = @box.send_message(message_params)
|
27
27
|
if @box.errors.all.empty?
|
28
28
|
if @message.draft
|
29
|
-
redirect_to message_train.box_path(:drafts), alert:
|
29
|
+
redirect_to message_train.box_path(:drafts), alert: @box.message
|
30
30
|
else
|
31
|
-
redirect_to message_train.box_path(:sent), notice:
|
31
|
+
redirect_to message_train.box_path(:sent), notice: @box.message
|
32
32
|
end
|
33
33
|
else
|
34
34
|
flash[:error] = @box.message
|
@@ -44,9 +44,9 @@ module MessageTrain
|
|
44
44
|
@box.update_message(@message, message_params)
|
45
45
|
if @box.errors.all.empty?
|
46
46
|
if @message.draft
|
47
|
-
redirect_to message_train.box_conversation_url(@box, @message.conversation), alert:
|
47
|
+
redirect_to message_train.box_conversation_url(@box, @message.conversation), alert: @box.message
|
48
48
|
else
|
49
|
-
redirect_to message_train.box_path(:sent), notice:
|
49
|
+
redirect_to message_train.box_path(:sent), notice: @box.message
|
50
50
|
end
|
51
51
|
else
|
52
52
|
flash[:error] = @box.message
|
@@ -61,14 +61,20 @@ module MessageTrain
|
|
61
61
|
|
62
62
|
# Never trust parameters from the scary internet, only allow the white list through.
|
63
63
|
def message_params
|
64
|
-
params.require(:message).permit(
|
64
|
+
permitted = params.require(:message).permit(
|
65
65
|
:conversation_id,
|
66
66
|
:subject,
|
67
67
|
:body,
|
68
68
|
:draft,
|
69
|
-
|
69
|
+
attachments_attributes: [:id, :attachment, :_destroy],
|
70
70
|
recipients_to_save: MessageTrain.configuration.recipient_tables.keys
|
71
71
|
)
|
72
|
+
if permitted['draft'] == :save_as_draft.l
|
73
|
+
permitted['draft'] = true
|
74
|
+
elsif permitted['draft'] == :send.l
|
75
|
+
permitted['draft'] = false
|
76
|
+
end
|
77
|
+
permitted
|
72
78
|
end
|
73
79
|
end
|
74
80
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module MessageTrain
|
2
|
+
class UnsubscribesController < MessageTrain::ApplicationController
|
3
|
+
|
4
|
+
# GET /unsubscribes
|
5
|
+
def index
|
6
|
+
@subscriptions = @box_user.subscriptions
|
7
|
+
end
|
8
|
+
|
9
|
+
# POST /unsubscribes
|
10
|
+
def create
|
11
|
+
unsub = unsubscribe_params
|
12
|
+
model = unsub[:from_type].constantize
|
13
|
+
@from = model.find(unsub[:from_id])
|
14
|
+
if @from == @box_user || @from.allows_receiving_by?(@box_user)
|
15
|
+
@unsubscribe = @box_user.unsubscribe_from(@from)
|
16
|
+
if @unsubscribe.errors.empty?
|
17
|
+
if @from == @box_user
|
18
|
+
flash[:notice] = :unsubscribe_message.l
|
19
|
+
else
|
20
|
+
name_column = MessageTrain.configuration.name_columns[@from.class.table_name.to_sym]
|
21
|
+
collective_name = @from.send(name_column)
|
22
|
+
collective_type = @from.class.name
|
23
|
+
flash[:notice] = :collective_unsubscribe_message.l(collective_name: collective_name, collective_type: collective_type)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
flash[:error] = @unsubscribe.errors.full_messages.to_sentence
|
27
|
+
end
|
28
|
+
redirect_to message_train.unsubscribes_url
|
29
|
+
else
|
30
|
+
flash[:error] = :you_are_not_in_that_collective_type.l(collective_type: model.name)
|
31
|
+
raise ActiveRecord::RecordNotFound
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# DELETE /unsubscribes/:id
|
36
|
+
def destroy
|
37
|
+
@unsubscribe = @box_user.unsubscribes.find(params[:id])
|
38
|
+
@from = @unsubscribe.from
|
39
|
+
if @from == @box_user
|
40
|
+
message = :unsubscribe_removed_message.l
|
41
|
+
else
|
42
|
+
name_column = MessageTrain.configuration.name_columns[@unsubscribe.from.class.table_name.to_sym]
|
43
|
+
collective_name = @unsubscribe.from.send(name_column)
|
44
|
+
collective_type = @unsubscribe.from_type
|
45
|
+
message = :collective_unsubscribe_removed_message.l(collective_name: collective_name, collective_type: collective_type)
|
46
|
+
end
|
47
|
+
@unsubscribe.destroy
|
48
|
+
flash[:notice] = message
|
49
|
+
redirect_to message_train.unsubscribes_url
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Never trust parameters from the scary internet, only allow the white list through.
|
55
|
+
def unsubscribe_params
|
56
|
+
params.require(:unsubscribe).permit(:from_type, :from_id)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module MessageTrain
|
2
|
+
module ApplicationHelper
|
3
|
+
|
4
|
+
def message_train_widget
|
5
|
+
render partial: 'message_train/application/widget'
|
6
|
+
end
|
7
|
+
|
8
|
+
def fuzzy_date(date)
|
9
|
+
time = Time.parse(date.strftime('%F %T'))
|
10
|
+
# Don't get confused: ">" here means "after", not "more than"
|
11
|
+
if time > 1.minute.ago
|
12
|
+
:just_now.l
|
13
|
+
elsif time > 1.day.ago
|
14
|
+
l(time, format: :fuzzy_today)
|
15
|
+
elsif time > 1.week.ago
|
16
|
+
l(time, format: :fuzzy_this_week)
|
17
|
+
elsif time > 1.year.ago
|
18
|
+
l(time, format: :fuzzy_date_without_year)
|
19
|
+
else
|
20
|
+
l(time, format: :fuzzy_date)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module MessageTrain
|
2
|
+
module AttachmentsHelper
|
3
|
+
def attachment_icon(attachment)
|
4
|
+
html = ""
|
5
|
+
if attachment.image?
|
6
|
+
html << image_tag(attachment.attachment.url(:thumb))
|
7
|
+
else
|
8
|
+
html << content_tag(:span, '', class: 'glyphicon glyphicon-save-file glyphicon-thumbnail')
|
9
|
+
html << tag(:br)
|
10
|
+
html << attachment.attachment_file_name
|
11
|
+
end
|
12
|
+
html.html_safe
|
13
|
+
end
|
14
|
+
|
15
|
+
def attachment_link(attachment)
|
16
|
+
render partial: 'message_train/application/attachment_link', locals: { attachment: attachment }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,30 +1,35 @@
|
|
1
1
|
module MessageTrain
|
2
2
|
module BoxesHelper
|
3
|
+
|
3
4
|
def box_nav_item(box)
|
4
5
|
text = box.title
|
5
6
|
link = message_train.box_path(box.division)
|
6
|
-
|
7
|
-
|
8
|
-
text << badge(
|
7
|
+
unread_count = box.unread_count
|
8
|
+
if unread_count > 0
|
9
|
+
text << badge(unread_count.to_s.gsub(/\s+/, ""), 'info pull-right')
|
9
10
|
end
|
10
|
-
nav_item text, link
|
11
|
+
nav_item text.gsub(/[\n\t]/,'').html_safe, link
|
11
12
|
end
|
13
|
+
|
12
14
|
def box_list_item(box, html_options = {})
|
13
|
-
render partial: 'message_train/boxes/list_item', locals: { box: box, html_options: html_options }
|
15
|
+
render partial: 'message_train/boxes/list_item', locals: { box: box, html_options: html_options, unread_count: box.unread_count }
|
14
16
|
end
|
15
|
-
|
16
|
-
|
17
|
-
render partial: 'message_train/boxes/widget', locals: { boxes:
|
17
|
+
|
18
|
+
def boxes_widget(box_user)
|
19
|
+
render partial: 'message_train/boxes/widget', locals: { boxes: box_user.all_boxes }
|
18
20
|
end
|
19
|
-
|
20
|
-
|
21
|
-
render partial: 'message_train/boxes/dropdown_list', locals: { boxes:
|
21
|
+
|
22
|
+
def boxes_dropdown_list(box_user, options = {})
|
23
|
+
render partial: 'message_train/boxes/dropdown_list', locals: { boxes: box_user.all_boxes }
|
22
24
|
end
|
25
|
+
|
23
26
|
def box_participant_name(participant)
|
24
27
|
participant.send(MessageTrain.configuration.name_columns[participant.class.table_name.to_sym])
|
25
28
|
end
|
29
|
+
|
26
30
|
def box_participant_slug(participant)
|
27
31
|
participant.send(MessageTrain.configuration.slug_columns[participant.class.table_name.to_sym])
|
28
32
|
end
|
33
|
+
|
29
34
|
end
|
30
35
|
end
|