mailboxer-without-notification 0.11.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.travis.yml +11 -0
- data/.yardopts +2 -0
- data/Appraisals +19 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +298 -0
- data/Rakefile +11 -0
- data/app/mailers/message_mailer.rb +37 -0
- data/app/models/conversation.rb +179 -0
- data/app/models/mailbox.rb +122 -0
- data/app/models/message.rb +218 -0
- data/app/models/receipt.rb +176 -0
- data/app/uploaders/attachment_uploader.rb +3 -0
- data/app/views/message_mailer/new_message_email.html.erb +20 -0
- data/app/views/message_mailer/new_message_email.text.erb +10 -0
- data/app/views/message_mailer/reply_message_email.html.erb +20 -0
- data/app/views/message_mailer/reply_message_email.text.erb +10 -0
- data/config/locales/en.yml +7 -0
- data/config/locales/fr.yml +7 -0
- data/db/migrate/20110511145103_create_mailboxer.rb +61 -0
- data/db/migrate/20110719110700_add_notified_object.rb +17 -0
- data/db/migrate/20110912163911_add_notification_code.rb +13 -0
- data/db/migrate/20111204163911_add_attachments.rb +9 -0
- data/db/migrate/20120813110712_rename_receipts_read.rb +9 -0
- data/db/migrate/20130305144212_add_global_notification_support.rb +9 -0
- data/db/migrate/20131003144212_change_table_notification.rb +10 -0
- data/db/migrate/20131003214212_change_relations.rb +6 -0
- data/gemfiles/rails3.0.gemfile +8 -0
- data/gemfiles/rails3.1.gemfile +8 -0
- data/gemfiles/rails3.2.gemfile +8 -0
- data/gemfiles/rails4.0.gemfile +8 -0
- data/lib/generators/mailboxer/install_generator.rb +35 -0
- data/lib/generators/mailboxer/templates/initializer.rb +17 -0
- data/lib/generators/mailboxer/views_generator.rb +9 -0
- data/lib/mailboxer.rb +37 -0
- data/lib/mailboxer/concerns/configurable_mailer.rb +13 -0
- data/lib/mailboxer/engine.rb +17 -0
- data/lib/mailboxer/models/messageable.rb +225 -0
- data/mailboxer.gemspec +49 -0
- data/spec/dummy/.gitignore +5 -0
- data/spec/dummy/Gemfile +33 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/home_controller.rb +4 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/cylon.rb +7 -0
- data/spec/dummy/app/models/duck.rb +11 -0
- data/spec/dummy/app/models/user.rb +6 -0
- data/spec/dummy/app/views/home/index.html.haml +7 -0
- data/spec/dummy/app/views/layouts/application.html.haml +11 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +42 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +24 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +33 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mailboxer.rb +17 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/config/sunspot.yml +17 -0
- data/spec/dummy/db/migrate/20110228120600_create_users.rb +14 -0
- data/spec/dummy/db/migrate/20110306002940_create_ducks.rb +14 -0
- data/spec/dummy/db/migrate/20110306015107_create_cylons.rb +14 -0
- data/spec/dummy/db/migrate/20120305103200_create_mailboxer.rb +61 -0
- data/spec/dummy/db/migrate/20120305103201_add_notified_object.rb +17 -0
- data/spec/dummy/db/migrate/20120305103202_add_notification_code.rb +13 -0
- data/spec/dummy/db/migrate/20120305103203_add_attachments.rb +5 -0
- data/spec/dummy/db/migrate/20120813110712_rename_receipts_read.rb +9 -0
- data/spec/dummy/db/migrate/20130305144212_add_global_notification_support.rb +11 -0
- data/spec/dummy/db/migrate/20131003144212_change_table_notification.rb +10 -0
- data/spec/dummy/db/migrate/20131003214212_change_relations.rb +6 -0
- data/spec/dummy/db/schema.rb +74 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/index.html +239 -0
- data/spec/dummy/public/robots.txt +5 -0
- data/spec/dummy/public/uploads/testfile.txt +1 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/cylon.rb +10 -0
- data/spec/factories/duck.rb +10 -0
- data/spec/factories/user.rb +10 -0
- data/spec/integration/message_and_receipt_spec.rb +903 -0
- data/spec/integration/navigation_spec.rb +9 -0
- data/spec/mailboxer/concerns/configurable_mailer_spec.rb +27 -0
- data/spec/mailboxer_spec.rb +7 -0
- data/spec/mailers/message_mailer_spec.rb +109 -0
- data/spec/models/conversation_spec.rb +154 -0
- data/spec/models/mailbox_spec.rb +160 -0
- data/spec/models/mailboxer_models_messageable_spec.rb +324 -0
- data/spec/models/message_spec.rb +222 -0
- data/spec/models/receipt_spec.rb +56 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/testfile.txt +1 -0
- metadata +301 -0
data/.gitignore
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
.bundle/
|
2
|
+
log/*.log
|
3
|
+
pkg/
|
4
|
+
spec/dummy/db/*.sqlite3
|
5
|
+
spec/dummy/log/*.log
|
6
|
+
spec/dummy/log/*.lck
|
7
|
+
spec/dummy/tmp/
|
8
|
+
spec/dummy/.project
|
9
|
+
spec/dummy/solr
|
10
|
+
**.tmp_*
|
11
|
+
Gemfile.lock
|
12
|
+
.idea
|
13
|
+
.project
|
14
|
+
.document
|
15
|
+
.settings/
|
16
|
+
rdoc/
|
17
|
+
doc/
|
18
|
+
.yardoc/*
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/Appraisals
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# appraise "rails3.0" do
|
2
|
+
# gem "rails", "~> 3.0.15"
|
3
|
+
# gem "mailboxer", :path => "../"
|
4
|
+
# end
|
5
|
+
|
6
|
+
appraise "rails3.1" do
|
7
|
+
gem "rails", "~> 3.1.6"
|
8
|
+
gem "mailboxer", :path => "../"
|
9
|
+
end
|
10
|
+
|
11
|
+
appraise "rails3.2" do
|
12
|
+
gem "rails", "~> 3.2.6"
|
13
|
+
gem "mailboxer", :path => "../"
|
14
|
+
end
|
15
|
+
|
16
|
+
appraise "rails4.0" do
|
17
|
+
gem "rails", ">=4.0.0"
|
18
|
+
gem "mailboxer", :path => "../"
|
19
|
+
end
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2013 Justin Coyne
|
2
|
+
Copyright (c) 2012 Universidad Politécnica de Madrid
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,298 @@
|
|
1
|
+
I juste take the gem mailboxer and I remove the notifications. The table is now nammed messages (and not notifications).
|
2
|
+
I correct the spec tests too. Only 4 minors errors to corect. The gem is working.
|
3
|
+
|
4
|
+
We can now send messages without subject.
|
5
|
+
|
6
|
+
|
7
|
+
# Mailboxer 0.10.x [![](https://secure.travis-ci.org/ging/mailboxer.png)](http://travis-ci.org/ging/mailboxer) [![Gem Version](https://badge.fury.io/rb/mailboxer.png)](http://badge.fury.io/rb/mailboxer) [![](https://gemnasium.com/ging/mailboxer.png)](https://gemnasium.com/ging/mailboxer)
|
8
|
+
|
9
|
+
This project is based on the need for a private message system for [ging
|
10
|
+
/ social\_stream](https://github.com/ging/social_stream). Instead of creating our core message system heavily
|
11
|
+
dependent on our development, we are trying to implement a generic and
|
12
|
+
potent messaging gem.
|
13
|
+
|
14
|
+
After looking for a good gem to use we noticed the lack of messaging gems
|
15
|
+
and functionality in them. Mailboxer tries to fill this void delivering
|
16
|
+
a powerful and flexible message system. It supports the use of
|
17
|
+
conversations with two or more participants, sending notifications to
|
18
|
+
recipients (intended to be used as system notifications “Your picture has
|
19
|
+
new comments”, “John Doe has updated his document”, etc.), and emailing the
|
20
|
+
messageable model (if configured to do so). It has a complete implementation
|
21
|
+
of a `Mailbox` object for each messageable with `inbox`, `sentbox` and
|
22
|
+
`trash`.
|
23
|
+
|
24
|
+
The gem is constantly growing and improving its functionality. As it is
|
25
|
+
used with our parallel development [ging / social\_stream](https://github.com/ging/social_stream) we are finding and fixing bugs continously. If you want
|
26
|
+
some functionality not supported yet or marked as TODO, you can create
|
27
|
+
an [issue](https://github.com/ging/mailboxer/issues) to ask for it. It will be great feedback for us, and we
|
28
|
+
will know what you may find useful in the gem.
|
29
|
+
|
30
|
+
Mailboxer was born from the great, but outdated, code from [lpsergi /
|
31
|
+
acts*as*messageable](https://github.com/psergi/acts_as_messageable).
|
32
|
+
|
33
|
+
We are now working to make exhaustive documentation and some wiki
|
34
|
+
pages in order to make it even easier to use the gem to its full potencial.
|
35
|
+
Please, give us some time if you find something missing or [ask for
|
36
|
+
it](https://github.com/ging/mailboxer/issues).
|
37
|
+
|
38
|
+
Installation
|
39
|
+
------------
|
40
|
+
|
41
|
+
Add to your Gemfile:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
gem 'mailboxer'
|
45
|
+
```
|
46
|
+
|
47
|
+
Then run:
|
48
|
+
|
49
|
+
```sh
|
50
|
+
$ bundle update
|
51
|
+
```
|
52
|
+
|
53
|
+
Run install script:
|
54
|
+
|
55
|
+
```sh
|
56
|
+
$ rails g mailboxer:install
|
57
|
+
```
|
58
|
+
|
59
|
+
And don't forget to migrate your database:
|
60
|
+
|
61
|
+
```sh
|
62
|
+
$ rake db:migrate
|
63
|
+
```
|
64
|
+
|
65
|
+
## Requirements & Settings
|
66
|
+
|
67
|
+
### Emails
|
68
|
+
|
69
|
+
We are now adding support for sending emails when a Notification or a Message is sent to one or more recipients. You should modify the mailboxer initializer (/config/initializer/mailboxer.rb) to edit these settings.
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
Mailboxer.setup do |config|
|
73
|
+
#Enables or disables email sending for Notifications and Messages
|
74
|
+
config.uses_emails = true
|
75
|
+
#Configures the default `from` address for the email sent for Messages and Notifications of Mailboxer
|
76
|
+
config.default_from = "no-reply@dit.upm.es"
|
77
|
+
...
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
You can change the way in which emails are delivered by specifying a custom implementation of notification and message mailers
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
Mailboxer.setup do |config|
|
85
|
+
config.notification_mailer = CustomNotificationMailer
|
86
|
+
config.message_mailer = CustomMessageMailer
|
87
|
+
...
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
### User identities
|
92
|
+
|
93
|
+
Users must have an identity defined by a `name` and an `email`. We must ensure that Messageable models have some specific methods. These methods are:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
#Returning any kind of identification you want for the model
|
97
|
+
def name
|
98
|
+
return "You should add method :name in your Messageable model"
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
#Returning the email address of the model if an email should be sent for this object (Message or Notification).
|
104
|
+
#If no mail has to be sent, return nil.
|
105
|
+
def mailboxer_email(object)
|
106
|
+
#Check if an email should be sent for that object
|
107
|
+
#if true
|
108
|
+
return "define_email@on_your.model"
|
109
|
+
#if false
|
110
|
+
#return nil
|
111
|
+
end
|
112
|
+
```
|
113
|
+
|
114
|
+
These names are explicit enough to avoid colliding with other methods, but as long as you need to change them you can do it by using mailboxer initializer (/config/initializer/mailboxer.rb). Just add or uncomment the following lines:
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
Mailboxer.setup do |config|
|
118
|
+
# ...
|
119
|
+
#Configures the methods needed by mailboxer
|
120
|
+
config.email_method = :mailboxer_email
|
121
|
+
config.name_method = :name
|
122
|
+
# ...
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
126
|
+
You may change whatever you want or need. For example:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
config.email_method = :notifications_email
|
130
|
+
config.name_method = :display_name
|
131
|
+
```
|
132
|
+
|
133
|
+
Will use the method `notification_email(object)` instead of `mailboxer_email(object)` and `display_name` for `name`.
|
134
|
+
|
135
|
+
Using default or custom method names, if your model doesn't implement them, Mailboxer will use dummy methods so as to notify you of missing methods rather than crashing.
|
136
|
+
|
137
|
+
## Preparing your models
|
138
|
+
|
139
|
+
In your model:
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
class User < ActiveRecord::Base
|
143
|
+
acts_as_messageable
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
147
|
+
You are not limited to the User model. You can use Mailboxer in any other model and use it in serveral different models. If you have ducks and cylons in your application and you want to exchange messages as if they were the same, just add `acts_as_messageable` to each one and you will be able to send duck-duck, duck-cylon, cylon-duck and cylon-cylon messages. Of course, you can extend it for as many classes as you need.
|
148
|
+
|
149
|
+
Example:
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
class Duck < ActiveRecord::Base
|
153
|
+
acts_as_messageable
|
154
|
+
end
|
155
|
+
```
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
class Cylon < ActiveRecord::Base
|
159
|
+
acts_as_messageable
|
160
|
+
end
|
161
|
+
```
|
162
|
+
|
163
|
+
## Mailboxer API
|
164
|
+
|
165
|
+
### Warning for version 0.8.0
|
166
|
+
Version 0.8.0 sees `Messageable#read` and `Messageable#unread` renamed to `mark_as_(un)read`, and `Receipt#read` and `Receipt#unread` to `is_(un)read`. This may break existing applications, but `read` is a reserved name for Active Record, and the best pratice in this case is simply avoid using it.
|
167
|
+
|
168
|
+
### How can I send a message?
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
#alfa wants to send a message to beta
|
172
|
+
alfa.send_message(beta, "Body", "subject")
|
173
|
+
```
|
174
|
+
|
175
|
+
### How can I reply a message?
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
#alfa wants to reply to all in a conversation
|
179
|
+
#using a receipt
|
180
|
+
alfa.reply_to_all(receipt, "Reply body")
|
181
|
+
|
182
|
+
#using a conversation
|
183
|
+
alfa.reply_to_conversation(conversation, "Reply body")
|
184
|
+
```
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
#alfa wants to reply to the sender of a message (and ONLY the sender)
|
188
|
+
#using a receipt
|
189
|
+
alfa.reply_to_sender(receipt, "Reply body")
|
190
|
+
```
|
191
|
+
|
192
|
+
### How can I retrieve my conversations?
|
193
|
+
|
194
|
+
```ruby
|
195
|
+
#alfa wants to retrieve all his conversations
|
196
|
+
alfa.mailbox.conversations
|
197
|
+
|
198
|
+
#A wants to retrieve his inbox
|
199
|
+
alfa.mailbox.inbox
|
200
|
+
|
201
|
+
#A wants to retrieve his sent conversations
|
202
|
+
alfa.mailbox.sentbox
|
203
|
+
|
204
|
+
#alfa wants to retrieve his trashed conversations
|
205
|
+
alfa.mailbox.trash
|
206
|
+
```
|
207
|
+
|
208
|
+
### How can I delete a message from trash?
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
#delete conversations forever for one receipt (still in database)
|
212
|
+
receipt.mark_as_deleted
|
213
|
+
|
214
|
+
#you can mark conversation as deleted for one participant
|
215
|
+
conversation.mark_as_deleted participant
|
216
|
+
|
217
|
+
#Mark the object as deleted for messageable
|
218
|
+
#Object can be:
|
219
|
+
#* A Receipt
|
220
|
+
#* A Conversation
|
221
|
+
#* A Notification
|
222
|
+
#* A Message
|
223
|
+
#* An array with any of them
|
224
|
+
alfa.mark_as_deleted conversation
|
225
|
+
```
|
226
|
+
|
227
|
+
### How can I paginate conversations?
|
228
|
+
|
229
|
+
You can use Kaminari to paginate the conversations as normal. Please, make sure you use the last version as mailboxer uses `select('DISTINCT conversations.*')` which was not respected before Kaminari 0.12.4 according to its changelog. Working corretly on Kaminari 0.13.0.
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
#Paginating all conversations using :page parameter and 9 per page
|
233
|
+
conversations = alfa.mailbox.conversations.page(params[:page]).per(9)
|
234
|
+
|
235
|
+
#Paginating received conversations using :page parameter and 9 per page
|
236
|
+
conversations = alfa.mailbox.inbox.page(params[:page]).per(9)
|
237
|
+
|
238
|
+
#Paginating sent conversations using :page parameter and 9 per page
|
239
|
+
conversations = alfa.mailbox.sentbox.page(params[:page]).per(9)
|
240
|
+
|
241
|
+
#Paginating trashed conversations using :page parameter and 9 per page
|
242
|
+
conversations = alfa.mailbox.trash.page(params[:page]).per(9)
|
243
|
+
```
|
244
|
+
|
245
|
+
### How can I read the messages of a conversation?
|
246
|
+
|
247
|
+
As a messageable, what you receive are receipts, which are associated with the message itself. You should retrieve your receipts for the conversation a get the message associated with them.
|
248
|
+
|
249
|
+
This is done this way because receipts save the information about the relation between messageable and the messages: is it read?, is it trashed?, etc.
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
#alfa gets the last conversation (chronologically, the first in the inbox)
|
253
|
+
conversation = alfa.mailbox.inbox.first
|
254
|
+
|
255
|
+
#alfa gets it receipts chronologically ordered.
|
256
|
+
receipts = conversation.receipts_for alfa
|
257
|
+
|
258
|
+
#using the receipts (i.e. in the view)
|
259
|
+
receipts.each do |receipt|
|
260
|
+
...
|
261
|
+
message = receipt.message
|
262
|
+
read = receipt.is_unread? #or message.is_unread?(alfa)
|
263
|
+
...
|
264
|
+
end
|
265
|
+
```
|
266
|
+
|
267
|
+
You can take a look at the full documentation for Mailboxer in [rubydoc.info](http://rubydoc.info/gems/mailboxer/frames).
|
268
|
+
|
269
|
+
## Do you want to test Mailboxer?
|
270
|
+
|
271
|
+
Thanks to [Roman Kushnir (@RKushnir)](https://github.com/RKushnir/) you can test Mailboxer with this [sample app](https://github.com/RKushnir/mailboxer-app).
|
272
|
+
|
273
|
+
## I need a GUI!
|
274
|
+
|
275
|
+
If you need a GUI you should take a look a these links:
|
276
|
+
|
277
|
+
* The [rails-messaging](https://github.com/frodefi/rails-messaging) project.
|
278
|
+
* The wiki page [GUI Example on a real application](https://github.com/ging/mailboxer/wiki/GUI-Example-on-a-real-application).
|
279
|
+
|
280
|
+
## Contributors
|
281
|
+
* [Roendal](https://github.com/ging/mailboxer/commits/master?author=Roendal) (Eduardo Casanova)
|
282
|
+
* [dickeyxxx](https://github.com/ging/mailboxer/commits/master?author=dickeyxxx) (Jeff Dickey)
|
283
|
+
* [RKushnir](https://github.com/ging/mailboxer/commits/master?author=RKushnir) (Roman Kushnir)
|
284
|
+
* [amaierhofer](https://github.com/ging/mailboxer/commits/master?author=amaierhofer) (Andreas Maierhofer)
|
285
|
+
* [tonydewan](https://github.com/ging/mailboxer/commits/master?author=tonydewan) (Tony Dewan)
|
286
|
+
* [plentz](https://github.com/ging/mailboxer/commits/master?author=plentz) (Diego Plentz)
|
287
|
+
* [laserlemon](https://github.com/ging/mailboxer/commits/master?author=laserlemon) (Steve Richert)
|
288
|
+
* [daveworth](https://github.com/ging/mailboxer/commits/master?author=daveworth) (Dave Worth)
|
289
|
+
* [rafaelgg](https://github.com/ging/mailboxer/commits/master?author=rafaelgg) (Rafael Garcia)
|
290
|
+
* [joshblour](https://github.com/ging/mailboxer/commits/master?author=joshblour) (joshblour)
|
291
|
+
* [iamdeuterium](https://github.com/ging/mailboxer/commits/master?author=iamdeuterium) (iamdeuterium)
|
292
|
+
* [daveworth](https://github.com/ging/mailboxer/commits/master?author=daveworth) (Dave Worth)
|
293
|
+
* [parndt](https://github.com/ging/mailboxer/commits/master?author=parndt) (Philip Arndt)
|
294
|
+
* [atd](https://github.com/ging/mailboxer/commits/master?author=atd) (Antonio Tapiador)
|
295
|
+
* [mobilutz](https://github.com/ging/mailboxer/commits/master?author=mobilutz) (Lutz)
|
296
|
+
* [bennick](https://github.com/ging/mailboxer/commits/master?author=bennick) (Ryan Bennick)
|
297
|
+
* [rjst](https://github.com/ging/mailboxer/commits/master?author=rjst) (Ricardo Trindade)
|
298
|
+
* [fabianoalmeida](https://github.com/ging/mailboxer/commits/master?author=fabianoalmeida) (Fabiano Almeida)
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
class MessageMailer < ActionMailer::Base
|
2
|
+
default :from => Mailboxer.default_from
|
3
|
+
#Sends and email for indicating a new message or a reply to a receiver.
|
4
|
+
#It calls new_message_email if notifing a new message and reply_message_email
|
5
|
+
#when indicating a reply to an already created conversation.
|
6
|
+
def send_email(message, receiver)
|
7
|
+
if message.conversation.messages.size > 1
|
8
|
+
reply_message_email(message,receiver)
|
9
|
+
else
|
10
|
+
new_message_email(message,receiver)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
include ActionView::Helpers::SanitizeHelper
|
15
|
+
|
16
|
+
#Sends an email for indicating a new message for the receiver
|
17
|
+
def new_message_email(message,receiver)
|
18
|
+
@message = message
|
19
|
+
@receiver = receiver
|
20
|
+
subject = message.subject.to_s
|
21
|
+
subject = strip_tags(subject) unless subject.html_safe?
|
22
|
+
mail :to => receiver.send(Mailboxer.email_method,message),
|
23
|
+
:subject => t('mailboxer.message_mailer.subject_new', :subject => subject),
|
24
|
+
:template_name => 'new_message_email'
|
25
|
+
end
|
26
|
+
|
27
|
+
#Sends and email for indicating a reply in an already created conversation
|
28
|
+
def reply_message_email(message,receiver)
|
29
|
+
@message = message
|
30
|
+
@receiver = receiver
|
31
|
+
subject = message.subject.to_s
|
32
|
+
subject = strip_tags(subject) unless subject.html_safe?
|
33
|
+
mail :to => receiver.send(Mailboxer.email_method,message),
|
34
|
+
:subject => t('mailboxer.message_mailer.subject_reply', :subject => subject),
|
35
|
+
:template_name => 'reply_message_email'
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
class Conversation < ActiveRecord::Base
|
2
|
+
attr_accessible :subject if Mailboxer.protected_attributes?
|
3
|
+
|
4
|
+
has_many :messages, :dependent => :destroy
|
5
|
+
has_many :receipts, :through => :messages
|
6
|
+
|
7
|
+
#validates_presence_of :subject
|
8
|
+
|
9
|
+
before_validation :clean
|
10
|
+
|
11
|
+
scope :participant, lambda {|participant|
|
12
|
+
select('DISTINCT conversations.*').
|
13
|
+
#where('notifications.type'=> Message.name).
|
14
|
+
order("conversations.updated_at DESC").
|
15
|
+
joins(:receipts).merge(Receipt.recipient(participant))
|
16
|
+
}
|
17
|
+
scope :inbox, lambda {|participant|
|
18
|
+
participant(participant).merge(Receipt.inbox.not_trash.not_deleted)
|
19
|
+
}
|
20
|
+
scope :sentbox, lambda {|participant|
|
21
|
+
participant(participant).merge(Receipt.sentbox.not_trash.not_deleted)
|
22
|
+
}
|
23
|
+
scope :trash, lambda {|participant|
|
24
|
+
participant(participant).merge(Receipt.trash)
|
25
|
+
}
|
26
|
+
scope :unread, lambda {|participant|
|
27
|
+
participant(participant).merge(Receipt.is_unread)
|
28
|
+
}
|
29
|
+
scope :not_trash, lambda {|participant|
|
30
|
+
participant(participant).merge(Receipt.not_trash)
|
31
|
+
}
|
32
|
+
|
33
|
+
#Mark the conversation as read for one of the participants
|
34
|
+
def mark_as_read(participant)
|
35
|
+
return if participant.nil?
|
36
|
+
self.receipts_for(participant).mark_as_read
|
37
|
+
end
|
38
|
+
|
39
|
+
#Mark the conversation as unread for one of the participants
|
40
|
+
def mark_as_unread(participant)
|
41
|
+
return if participant.nil?
|
42
|
+
self.receipts_for(participant).mark_as_unread
|
43
|
+
end
|
44
|
+
|
45
|
+
#Move the conversation to the trash for one of the participants
|
46
|
+
def move_to_trash(participant)
|
47
|
+
return if participant.nil?
|
48
|
+
self.receipts_for(participant).move_to_trash
|
49
|
+
end
|
50
|
+
|
51
|
+
#Takes the conversation out of the trash for one of the participants
|
52
|
+
def untrash(participant)
|
53
|
+
return if participant.nil?
|
54
|
+
self.receipts_for(participant).untrash
|
55
|
+
end
|
56
|
+
|
57
|
+
#Mark the conversation as deleted for one of the participants
|
58
|
+
def mark_as_deleted(participant)
|
59
|
+
return if participant.nil?
|
60
|
+
deleted_receipts = self.receipts_for(participant).mark_as_deleted
|
61
|
+
if is_orphaned?
|
62
|
+
self.destroy
|
63
|
+
else
|
64
|
+
deleted_receipts
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
#Returns an array of participants
|
69
|
+
def recipients
|
70
|
+
if self.last_message
|
71
|
+
recps = self.last_message.recipients
|
72
|
+
recps = recps.is_a?(Array) ? recps : [recps]
|
73
|
+
recps
|
74
|
+
else
|
75
|
+
[]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
#Returns an array of participants
|
80
|
+
def participants
|
81
|
+
recipients
|
82
|
+
end
|
83
|
+
|
84
|
+
#Originator of the conversation.
|
85
|
+
def originator
|
86
|
+
@originator ||= self.original_message.sender
|
87
|
+
end
|
88
|
+
|
89
|
+
#First message of the conversation.
|
90
|
+
def original_message
|
91
|
+
@original_message ||= self.messages.order('created_at').first
|
92
|
+
end
|
93
|
+
|
94
|
+
#Sender of the last message.
|
95
|
+
def last_sender
|
96
|
+
@last_sender ||= self.last_message.sender
|
97
|
+
end
|
98
|
+
|
99
|
+
#Last message in the conversation.
|
100
|
+
def last_message
|
101
|
+
@last_message ||= self.messages.order('created_at DESC').first
|
102
|
+
end
|
103
|
+
|
104
|
+
#Returns the receipts of the conversation for one participants
|
105
|
+
def receipts_for(participant)
|
106
|
+
Receipt.conversation(self).recipient(participant)
|
107
|
+
end
|
108
|
+
|
109
|
+
#Returns the number of messages of the conversation
|
110
|
+
def count_messages
|
111
|
+
Message.conversation(self).count
|
112
|
+
end
|
113
|
+
|
114
|
+
#Returns true if the messageable is a participant of the conversation
|
115
|
+
def is_participant?(participant)
|
116
|
+
return false if participant.nil?
|
117
|
+
self.receipts_for(participant).count != 0
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
#Adds a new participant to the conversation
|
122
|
+
def add_participant(participant)
|
123
|
+
messages = self.messages
|
124
|
+
messages.each do |message|
|
125
|
+
receipt = Receipt.new
|
126
|
+
receipt.message = message
|
127
|
+
receipt.is_read = false
|
128
|
+
receipt.receiver = participant
|
129
|
+
receipt.mailbox_type = 'inbox'
|
130
|
+
receipt.updated_at = message.updated_at
|
131
|
+
receipt.created_at = message.created_at
|
132
|
+
receipt.save
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
#Returns true if the participant has at least one trashed message of the conversation
|
137
|
+
def is_trashed?(participant)
|
138
|
+
return false if participant.nil?
|
139
|
+
self.receipts_for(participant).trash.count != 0
|
140
|
+
end
|
141
|
+
|
142
|
+
#Returns true if the participant has deleted the conversation
|
143
|
+
def is_deleted?(participant)
|
144
|
+
return false if participant.nil?
|
145
|
+
return self.receipts_for(participant).deleted.count == self.receipts_for(participant).count
|
146
|
+
end
|
147
|
+
|
148
|
+
#Returns true if both participants have deleted the conversation
|
149
|
+
def is_orphaned?
|
150
|
+
participants.reduce(true) do |is_orphaned, participant|
|
151
|
+
is_orphaned && is_deleted?(participant)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
#Returns true if the participant has trashed all the messages of the conversation
|
156
|
+
def is_completely_trashed?(participant)
|
157
|
+
return false if participant.nil?
|
158
|
+
self.receipts_for(participant).trash.count == self.receipts_for(participant).count
|
159
|
+
end
|
160
|
+
|
161
|
+
def is_read?(participant)
|
162
|
+
!self.is_unread?(participant)
|
163
|
+
end
|
164
|
+
|
165
|
+
#Returns true if the participant has at least one unread message of the conversation
|
166
|
+
def is_unread?(participant)
|
167
|
+
return false if participant.nil?
|
168
|
+
self.receipts_for(participant).not_trash.is_unread.count != 0
|
169
|
+
end
|
170
|
+
|
171
|
+
protected
|
172
|
+
|
173
|
+
include ActionView::Helpers::SanitizeHelper
|
174
|
+
|
175
|
+
#Use the default sanitize to clean the conversation subject
|
176
|
+
def clean
|
177
|
+
self.subject = sanitize self.subject
|
178
|
+
end
|
179
|
+
end
|