denshobato 0.0.1
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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +413 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/denshobato.gemspec +33 -0
- data/lib/denshobato/engine.rb +5 -0
- data/lib/denshobato/extenders/core.rb +34 -0
- data/lib/denshobato/helpers/controller_helper.rb +23 -0
- data/lib/denshobato/helpers/core_helper.rb +12 -0
- data/lib/denshobato/helpers/core_modules/blacklist_helper.rb +22 -0
- data/lib/denshobato/helpers/core_modules/chat_panel_helper.rb +44 -0
- data/lib/denshobato/helpers/core_modules/conversation_helper.rb +30 -0
- data/lib/denshobato/helpers/core_modules/message_helper.rb +60 -0
- data/lib/denshobato/helpers/helper_utils.rb +21 -0
- data/lib/denshobato/helpers/view_helper.rb +61 -0
- data/lib/denshobato/helpers/view_messaging_helper.rb +52 -0
- data/lib/denshobato/models/blacklist.rb +13 -0
- data/lib/denshobato/models/conversation.rb +103 -0
- data/lib/denshobato/models/message.rb +96 -0
- data/lib/denshobato/models/notification.rb +17 -0
- data/lib/denshobato/version.rb +3 -0
- data/lib/denshobato.rb +35 -0
- data/lib/generators/denshobato/install_generator.rb +40 -0
- data/lib/generators/denshobato/migrations/create_blacklists.rb +8 -0
- data/lib/generators/denshobato/migrations/create_conversations.rb +11 -0
- data/lib/generators/denshobato/migrations/create_messages.rb +10 -0
- data/lib/generators/denshobato/migrations/create_notifications.rb +10 -0
- metadata +215 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1d59c4062e19fbdc958c66414757db47955fd6b0
|
4
|
+
data.tar.gz: 55d70a9a5e61cdb6dd0fc4dd382aa489eebe95e6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 62b1df33d46fd412176eeda92d5418dc4ceab95b21ff3cd721e4d894323646475bbbca46580eb57c22d887ba8e36edeea31be135500668de6098069ff444104c
|
7
|
+
data.tar.gz: eb62fe49f37f7884db56126c29db3ae00d81481a012f1504339e2156086a27820f041e6b6305384f4700811d938a6bfee6a7d6979978fd08a3397142828a11b5
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,413 @@
|
|
1
|
+
# Denshobato - Private messaging between models.
|
2
|
+
|
3
|
+

|
4
|
+
|
5
|
+
Denshobato is a Rails gem that helps models communicate with each other. It gives simple api for creating a complete conversation system. You can create conversation with any model. Denshobato provides api methods for making conversation, messages, blacklists and trash. It also provides Helper methods for controller and view.
|
6
|
+
***
|
7
|
+
|
8
|
+
##### [Install Gem](#install_gem)
|
9
|
+
##### [Tutorial](#-tutorial)
|
10
|
+
##### [Conversation API](#conversation)
|
11
|
+
##### [Message API](#message)
|
12
|
+
##### [Trash API](#trash)
|
13
|
+
##### [BlackList API](#blacklist)
|
14
|
+
##### [Controller Herper API](#controller)
|
15
|
+
##### [View Herper API](#view)
|
16
|
+
##### [Extensions](#extensions-1)
|
17
|
+
|
18
|
+
### Requirements
|
19
|
+
```
|
20
|
+
Rails 4.
|
21
|
+
|
22
|
+
Rails 3 isn't supported.
|
23
|
+
Not ready for 5, while it is in Beta.
|
24
|
+
```
|
25
|
+
|
26
|
+
### <a name="install_gem"> </a>Install Gem
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
gem 'denshobato'
|
30
|
+
```
|
31
|
+
or
|
32
|
+
|
33
|
+
```gem install denshobato```
|
34
|
+
|
35
|
+
Then run installation:
|
36
|
+
|
37
|
+
```shell
|
38
|
+
rails g denshobato:install
|
39
|
+
```
|
40
|
+
|
41
|
+
Run migrations
|
42
|
+
|
43
|
+
```shell
|
44
|
+
rake db:migrate
|
45
|
+
```
|
46
|
+
|
47
|
+
Add this line to your model. This will make it able to send messages.
|
48
|
+
```ruby
|
49
|
+
denshobato_for :your_class
|
50
|
+
```
|
51
|
+
|
52
|
+
### <a name="tutorial"> </a>Tutorial
|
53
|
+
#### Create messaging system between reseller and customer.
|
54
|
+
[Part 1](http://id25.github.io/2016/03/01/make-private-dialog-between-reseller-and-customer-part-1.html)
|
55
|
+
|
56
|
+
[Part 2](http://id25.github.io/2016/03/02/make-private-dialog-between-reseller-and-customer-part-2.html)
|
57
|
+
|
58
|
+
|
59
|
+
### Example:
|
60
|
+
```ruby
|
61
|
+
class User < ActiveRecord::Base
|
62
|
+
denshobato_for :user
|
63
|
+
end
|
64
|
+
|
65
|
+
class Customer < ActiveRecord::Base
|
66
|
+
denshobato_for :customer
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
@user.make_conversation_with(@customer).save
|
72
|
+
|
73
|
+
@user.send_message('Hello', @customer)
|
74
|
+
```
|
75
|
+
|
76
|
+
You're ready!
|
77
|
+
|
78
|
+
### <a name="conversation"></a>Conversations API
|
79
|
+
|
80
|
+
#####Create conversation with user
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
current_user.make_conversation_with(customer)
|
84
|
+
# => #<Denshobato::Conversation id: nil, sender_id: 1, sender_type: "User", recipient_id: 1,
|
85
|
+
# recipient_type: "User", created_at: nil, updated_at: nil, trashed: false>
|
86
|
+
|
87
|
+
# Example:
|
88
|
+
# In your view:
|
89
|
+
|
90
|
+
- @users.each do |user|
|
91
|
+
= link_to user.email, user if current_user != user
|
92
|
+
= button_to 'Start Conversation', start_conversation_path(id: user.id, class: user.class.name),
|
93
|
+
class: 'btn btn-success'
|
94
|
+
|
95
|
+
# Create route
|
96
|
+
# We need specify controller, because by default rails search for denshobato_conversations
|
97
|
+
post 'start_conversation', to: 'conversations#start_conversation', as: :start_conversation
|
98
|
+
|
99
|
+
# And action
|
100
|
+
def start_conversation
|
101
|
+
recipient = params[:class].constantize.find(params[:id])
|
102
|
+
conversation = current_account.make_conversation_with(recipient)
|
103
|
+
|
104
|
+
if conversation.save
|
105
|
+
redirect_to :conversations
|
106
|
+
end
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
Another way to create a conversation.
|
111
|
+
```ruby
|
112
|
+
|
113
|
+
# In your view
|
114
|
+
# @conversation = current_user.hato_conversations.build
|
115
|
+
|
116
|
+
= form_for @conversation, url: :conversations do |form|
|
117
|
+
= fill_conversation_form(form, user) # => denshobato view helper, for conversation creating
|
118
|
+
= f.submit 'Start Conversation', class: 'btn btn-primary'
|
119
|
+
|
120
|
+
# Route, simple rest actions, i.e create for this.
|
121
|
+
resources :denshobato_conversations, as: :conversations,
|
122
|
+
path: 'conversations', controller: 'conversations'
|
123
|
+
|
124
|
+
def create
|
125
|
+
@conversation = current_account.hato_conversations.build(conversation_params)
|
126
|
+
if @conversation.save
|
127
|
+
redirect_to conversation_path(@conversation)
|
128
|
+
else
|
129
|
+
redirect_to :new, notice: 'Something went wrong'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
```
|
133
|
+
|
134
|
+
#####Fetch all conversations, where you're present.
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
current_user.my_converstions
|
138
|
+
# => #<ActiveRecord::Relation [#<Denshobato::Conversation id: 118, sender_id: 1, sender_type: "User",
|
139
|
+
# recipient_id: 2, recipient_type: "User", created_at: "2016-02-28 01:45:11",
|
140
|
+
# updated_at: "2016-02-28 01:45:11", trashed: false>,
|
141
|
+
# <Denshobato::Conversation id: 119, sender_id: 1, sender_type: "User", recipient_id: 1,
|
142
|
+
# recipient_type: "Customer", created_at: "2016-02-28 02:05:59",
|
143
|
+
# updated_at: "2016-02-28 02:05:59", trashed: false>]>
|
144
|
+
```
|
145
|
+
|
146
|
+
#####Find conversation with another user
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
current_user.find_conversation_with(customer)
|
150
|
+
# => #<Denshobato::Conversation id: 119, sender_id: 1, sender_type: "User",
|
151
|
+
# recipient_id: 1, recipient_type: "Customer",
|
152
|
+
# created_at: "2016-02-28 02:05:59", updated_at: "2016-02-28 02:05:59", trashed: false>
|
153
|
+
```
|
154
|
+
|
155
|
+
#####Return all your trashed conversation
|
156
|
+
```ruby
|
157
|
+
current_user.trashed_conversations
|
158
|
+
# => #<ActiveRecord::Relation [#<Denshobato::Conversation id: 119, sender_id: 1, sender_type: "User",
|
159
|
+
# recipient_id: 1, recipient_type: "Customer", created_at: "2016-02-28 02:05:59",
|
160
|
+
# updated_at: "2016-02-28 02:21:48", trashed: true>]>
|
161
|
+
```
|
162
|
+
|
163
|
+
##### Return all messages from conversation
|
164
|
+
```ruby
|
165
|
+
@conversation.messages
|
166
|
+
# => [#<Denshobato::Message id: 224, body: "Hi", author_id: 1, author_type: "User",
|
167
|
+
# created_at: "2016-02-28 00:51:00", updated_at: "2016-02-28 00:51:00">,
|
168
|
+
# #<Denshobato::Message id: 225, body: "Hello", author_id: 1,
|
169
|
+
# author_type: "Customer", created_at: "2016-02-28 00:53:11", updated_at: "2016-02-28 00:53:11">]
|
170
|
+
```
|
171
|
+
|
172
|
+
### <a name="message"></a>Messages API
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
# This method sends message directly to the recipient
|
176
|
+
# Takes responsibility to create conversation if it doesn`t exist yet or sends message to an existing conversation
|
177
|
+
|
178
|
+
# Important!
|
179
|
+
# After each created message, send notification
|
180
|
+
if @message.save
|
181
|
+
@message.send_notification(@conversation.id)
|
182
|
+
end
|
183
|
+
# See example below
|
184
|
+
|
185
|
+
msg = current_user.send_message(body: 'Hello', recipient)
|
186
|
+
# => #<Denshobato::Message:0x000000054dc790 id: nil, body: "Hello", author_id: 1,
|
187
|
+
# author_type: "User", created_at: nil, updated_at: nil>
|
188
|
+
msg.save
|
189
|
+
```
|
190
|
+
|
191
|
+
Another way - send message directly to a conversation
|
192
|
+
```ruby
|
193
|
+
current_user.send_message_to(conversation.id, body: 'Hello')
|
194
|
+
|
195
|
+
# Example
|
196
|
+
# @message_form = current_user.hato_messages.build
|
197
|
+
|
198
|
+
= form_for @message_form, url: :messages do |form|
|
199
|
+
= form.text_field :body, class: 'form-control'
|
200
|
+
= fill_message_form(form, current_account, @conversation.id) # => denshobato helper, for message creating
|
201
|
+
= form.submit 'Send message', class: 'btn btn-primary'
|
202
|
+
|
203
|
+
# Controller
|
204
|
+
def create
|
205
|
+
conversation_id = params[:denshobato_message][:conversation_id]
|
206
|
+
@message = current_account.send_message_to(conversation_id, message_params)
|
207
|
+
|
208
|
+
if @message.save
|
209
|
+
# Important, send notifications after save message
|
210
|
+
@message.send_notification(conversation_id)
|
211
|
+
redirect_to conversation_path(conversation_id)
|
212
|
+
else
|
213
|
+
render :new, notice: 'Error'
|
214
|
+
end
|
215
|
+
end
|
216
|
+
```
|
217
|
+
|
218
|
+
### <a name="trash"></a>Trash API
|
219
|
+
|
220
|
+
##### Move conversation to trash and remove it out of there
|
221
|
+
```ruby
|
222
|
+
# @conversation.to_trash
|
223
|
+
# @conversation.from_tash
|
224
|
+
|
225
|
+
#Example
|
226
|
+
# In your view
|
227
|
+
- @conversations.each do |room|
|
228
|
+
= link_to "Conversation with #{room.recipient.email}", conversation_path(room)
|
229
|
+
= button_to 'Move to Trash', to_trash_path(id: room), class: 'btn btn-warning', method: :patch
|
230
|
+
= button_to 'Move from Trash', from_trash_path(id: room), class: 'btn btn-warning', method: :patch
|
231
|
+
|
232
|
+
# Route
|
233
|
+
patch :to_trash, to: 'conversations#to_trash', as: :to_trash
|
234
|
+
patch :from_trash, to: 'conversations#from_trash', as: :from_trash
|
235
|
+
|
236
|
+
# In your conversation controller
|
237
|
+
%w(to_trash from_trash).each do |name|
|
238
|
+
define_method name do
|
239
|
+
room = Denshobato::Conversation.find(params[:id])
|
240
|
+
room.send(name)
|
241
|
+
redirect_to :conversations
|
242
|
+
end
|
243
|
+
end
|
244
|
+
```
|
245
|
+
|
246
|
+
### <a name="blacklist"></a>BlackList API
|
247
|
+
|
248
|
+
```ruby
|
249
|
+
# current_user.add_to_blacklist(customer)
|
250
|
+
# current_user.remove_from_blacklist(customer)
|
251
|
+
|
252
|
+
- @users.each do |user|
|
253
|
+
= link_to user.email, user if current_account != user
|
254
|
+
- if user_in_black_list?(current_account, user)
|
255
|
+
p This user in your blacklist
|
256
|
+
= button_to 'Remove from black list', remove_from_blacklist_path(user: user,
|
257
|
+
klass: user.class.name), class: 'btn btn-info'
|
258
|
+
- else
|
259
|
+
= button_to 'Add to black list', black_list_path(user: user, klass: user.class.name),
|
260
|
+
class: 'btn btn-danger'
|
261
|
+
|
262
|
+
# Routes
|
263
|
+
post :black_list, to: 'users#add_to_blacklist', as: :black_list
|
264
|
+
post :remove_from_blacklist, to: 'users#remove_from_blacklist', as: :remove_from_blacklist
|
265
|
+
|
266
|
+
# Controller
|
267
|
+
[%w(add_to_blacklist save), %w(remove_from_blacklist destroy)].each do |name, action|
|
268
|
+
define_method name do
|
269
|
+
user = params[:klass].constantize.find(params[:user])
|
270
|
+
record = current_account.send(name, user)
|
271
|
+
record.send(action) ? (redirect_to :users) : (redirect_to :root)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
```
|
275
|
+
|
276
|
+
### <a name="controller"></a>Controller Helpers
|
277
|
+
|
278
|
+
Check if user is already in conversation
|
279
|
+
```ruby
|
280
|
+
# user_in_conversation?(current_user, room)
|
281
|
+
|
282
|
+
# Example
|
283
|
+
@conversation = Denshobato::Conversation.find(params[:id])
|
284
|
+
unless user_in_conversation?(current_user, @conversation)
|
285
|
+
redirect_to :conversations, notice: 'You can`t join this conversation'
|
286
|
+
end
|
287
|
+
```
|
288
|
+
|
289
|
+
Check if sender and recipient already have conversation together.
|
290
|
+
```ruby
|
291
|
+
# conversation_exists?(sender, recipient)
|
292
|
+
|
293
|
+
if conversation_exists?(current_user, @customer)
|
294
|
+
do_somthing
|
295
|
+
end
|
296
|
+
```
|
297
|
+
|
298
|
+
Check if user can create conversation with other user
|
299
|
+
```ruby
|
300
|
+
# can_create_conversation?(sender, recipient)
|
301
|
+
|
302
|
+
if can_create_conversation?(current_user, @customer)
|
303
|
+
@conversation_form = ...
|
304
|
+
end
|
305
|
+
```
|
306
|
+
|
307
|
+
|
308
|
+
### <a name="view"></a>View Helpers
|
309
|
+
|
310
|
+
Check if conversation exists, return `true` or `false`
|
311
|
+
```ruby
|
312
|
+
# @conversation = current_user.find_conversation(@user)
|
313
|
+
|
314
|
+
- if conversation_exists?(current_user, @user)
|
315
|
+
= link_to 'Open chat', your_path(@conversation)
|
316
|
+
```
|
317
|
+
|
318
|
+
Check if user can create conversation with another user
|
319
|
+
```ruby
|
320
|
+
# can_create_conversation?(sender, recipient)
|
321
|
+
|
322
|
+
- if can_create_conversation?(current_user, @customer)
|
323
|
+
= link_to 'Start Conversation', your_path...
|
324
|
+
```
|
325
|
+
|
326
|
+
Check if recipient is in blacklist
|
327
|
+
```ruby
|
328
|
+
# user_in_black_list?(sender, recipient)
|
329
|
+
|
330
|
+
- if user_in_black_list?(current_user, @customer)
|
331
|
+
= button_to 'Remove from black list', remove_path...
|
332
|
+
```
|
333
|
+
|
334
|
+
Show name of recipient in conversation list
|
335
|
+
```ruby
|
336
|
+
- @conversations.includes(:sender).each do |room|
|
337
|
+
= link_to "Conversation with: #{interlocutor_name(current_user, room, :first_name, :last_name)}",
|
338
|
+
conversation_path(room)
|
339
|
+
|
340
|
+
# => Conversation with: John Doe
|
341
|
+
```
|
342
|
+
|
343
|
+
Show avatar for recipient
|
344
|
+
```ruby
|
345
|
+
= interlocutor_avatar(current_user, :user_avatar, @conversation, 'img-responsive')
|
346
|
+
|
347
|
+
# => <img src="..." class='img-responsive'/>
|
348
|
+
```
|
349
|
+
|
350
|
+
Show the last message, it's author and his avatar
|
351
|
+
```ruby
|
352
|
+
= "Last message: #{room.messages.last.try(:body)}"
|
353
|
+
= "#{interlocutor_image(room.messages.last.try(:author), :user_avatar, 'img-circle')}"
|
354
|
+
= "Last message from: #{message_from(room.messages.last, :first_name, :last_name)}"
|
355
|
+
```
|
356
|
+
|
357
|
+
Same inside of a conversation
|
358
|
+
```ruby
|
359
|
+
- @messages.includes(:author).each do |msg|
|
360
|
+
p = interlocutor_info(msg.author, :fist_name, :last_name)
|
361
|
+
= interlocutor_image(msg.author, :user_avatar, 'img-circle')
|
362
|
+
p = msg.body
|
363
|
+
hr
|
364
|
+
```
|
365
|
+
|
366
|
+
### Pagination
|
367
|
+
If you use Kaminari, or Will Paginate, just follow their guide.
|
368
|
+
|
369
|
+
Example:
|
370
|
+
```ruby
|
371
|
+
@messages = @conversation.messages.page(params[:page]).per(25) # => Kaminari
|
372
|
+
@messages = @conversation.messages.page(params[:page]).per_page(25) # => Will Paginate
|
373
|
+
```
|
374
|
+
|
375
|
+
And in your view
|
376
|
+
```ruby
|
377
|
+
= paginate @messages # => Kaminari
|
378
|
+
= will_paginate @messages # => Will Paginate
|
379
|
+
```
|
380
|
+
|
381
|
+
***
|
382
|
+
|
383
|
+
### <a name="extensions"></a>Extensions
|
384
|
+

|
385
|
+
Denshobato has addon [denshobato_chat_panel](https://github.com/ID25/denshobato_chat_panel). This is simple chat panel for you. If you don't need any special customization for dialog panel, or if you want to try messaging quickly, you can use chat panel.
|
386
|
+
|
387
|
+
That`s all for now.
|
388
|
+
|
389
|
+
## Upcoming features
|
390
|
+
+ Conference
|
391
|
+
+ Read/Unread messages
|
392
|
+
|
393
|
+
## Issues
|
394
|
+
|
395
|
+
If you've found a bug, or have proposal/feature request, create an issue with your thoughts.
|
396
|
+
[Denshobato Issues](https://github.com/ID25/denshobato/issues)
|
397
|
+
|
398
|
+
## Contributing
|
399
|
+
|
400
|
+
+ Fork it
|
401
|
+
+ Create your feature branch (git checkout -b my-new-feature)
|
402
|
+
+ Write tests for new feature/bug fix
|
403
|
+
+ Make sure that tests pass and everything works like a charm
|
404
|
+
+ Commit your changes (git commit -am 'Added some feature')
|
405
|
+
+ Push to the branch (git push origin my-new-feature)
|
406
|
+
+ Create new Pull Request
|
407
|
+
|
408
|
+
## The MIT License (MIT)
|
409
|
+
|
410
|
+
#### Denshobato - Private messaging between models.
|
411
|
+

|
412
|
+
|
413
|
+
Copyright (c) 2016 Eugene Domosedov (ID25)
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'denshobato'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/denshobato.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'denshobato/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'denshobato'
|
8
|
+
spec.version = Denshobato::VERSION
|
9
|
+
spec.authors = ['ID25']
|
10
|
+
spec.email = ['xid25x@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'Denshobato - private messaging between models'
|
13
|
+
spec.description = 'Denshobato - private messaging between models'
|
14
|
+
spec.homepage = 'https://github.com/ID25/denshobato'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = 'exe'
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_runtime_dependency 'rails', '>= 3.2.0'
|
23
|
+
spec.add_runtime_dependency 'grape'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
|
+
spec.add_development_dependency 'activerecord'
|
29
|
+
spec.add_development_dependency 'sqlite3'
|
30
|
+
spec.add_development_dependency 'database_cleaner'
|
31
|
+
spec.add_development_dependency 'factory_girl', '~> 4.0'
|
32
|
+
spec.add_development_dependency 'shoulda-matchers', '~> 3.1'
|
33
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Denshobato
|
2
|
+
module Extenders
|
3
|
+
module Core
|
4
|
+
def denshobato_for(_klass)
|
5
|
+
# Adds associations and methods to messagable model
|
6
|
+
|
7
|
+
adds_methods_to_model
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def adds_methods_to_model
|
13
|
+
include Denshobato::CoreHelper # Adds helper methods for the core model
|
14
|
+
|
15
|
+
# Adds has_many association for a model, to allow it to create conversations
|
16
|
+
class_eval do
|
17
|
+
# Add conversations
|
18
|
+
has_many :denshobato_conversations, as: :sender, class_name: '::Denshobato::Conversation', dependent: :destroy
|
19
|
+
|
20
|
+
# Add messages
|
21
|
+
has_many :denshobato_messages, as: :author, class_name: '::Denshobato::Message', dependent: :destroy
|
22
|
+
|
23
|
+
# Add blacklists
|
24
|
+
has_many :denshobato_blacklists, as: :blocker, class_name: '::Denshobato::Blacklist', dependent: :destroy
|
25
|
+
|
26
|
+
# Added alias for the sake of brevity
|
27
|
+
alias_method :hato_conversations, :denshobato_conversations
|
28
|
+
alias_method :hato_messages, :denshobato_messages
|
29
|
+
alias_method :blacklist, :denshobato_blacklists
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Denshobato
|
2
|
+
module ControllerHelper
|
3
|
+
include Denshobato::HelperUtils
|
4
|
+
|
5
|
+
def user_in_conversation?(user, room)
|
6
|
+
# redirect_to :root, notice: 'You can`t join this conversation unless user_in_conversation?(current_account, @conversation)'
|
7
|
+
|
8
|
+
hato_conversation.where(id: room.id, sender: user).present? || hato_conversation.where(id: room.id, recipient: user).present?
|
9
|
+
end
|
10
|
+
|
11
|
+
def conversation_exists?(sender, recipient)
|
12
|
+
# Check if sender and recipient already have conversation together.
|
13
|
+
|
14
|
+
hato_conversation.find_by(sender: sender, recipient: recipient)
|
15
|
+
end
|
16
|
+
|
17
|
+
def can_create_conversation?(sender, recipient)
|
18
|
+
# If current sender is current recipient, return false
|
19
|
+
|
20
|
+
sender == recipient ? false : true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Denshobato
|
2
|
+
module CoreHelper
|
3
|
+
include Denshobato::HelperUtils # Useful helpers
|
4
|
+
include Denshobato::ConversationHelper # Methods of Conversation model
|
5
|
+
include Denshobato::MessageHelper # Methods of Message model
|
6
|
+
include Denshobato::BlacklistHelper # Methods of BlackList model
|
7
|
+
|
8
|
+
# Methods for chat panel (json api)
|
9
|
+
# gem 'denshobato_chat_panel'
|
10
|
+
include Denshobato::ChatPanelHelper if defined?(DenshobatoChatPanel)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Denshobato
|
2
|
+
module BlacklistHelper
|
3
|
+
def add_to_blacklist(user)
|
4
|
+
# Add user to blacklist
|
5
|
+
# User can`t create conversation or send message to a blocked model
|
6
|
+
|
7
|
+
blacklist.build(blocked: user)
|
8
|
+
end
|
9
|
+
|
10
|
+
def remove_from_blacklist(user)
|
11
|
+
# Remove user from blacklist
|
12
|
+
|
13
|
+
hato_blacklist.find_by(blocker: self, blocked: user)
|
14
|
+
end
|
15
|
+
|
16
|
+
def my_blacklist
|
17
|
+
# Show blocked users
|
18
|
+
|
19
|
+
blacklist.includes(:blocked)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Denshobato
|
2
|
+
module ChatPanelHelper
|
3
|
+
# Default methods only for built-in Chat Panel
|
4
|
+
# Overwrite this methods when using Chat Panel
|
5
|
+
|
6
|
+
# class User < ActiveRecord::Base
|
7
|
+
# def full_name
|
8
|
+
# "#{first_name}", #{last_name}
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# def image
|
12
|
+
# user_avatar.url
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
|
16
|
+
DEFAULT_EMAIL = 'john.doe@gmail.com'.freeze
|
17
|
+
|
18
|
+
def full_name
|
19
|
+
# Set up default name for chat panel
|
20
|
+
# By default class name will be used, e.g => User
|
21
|
+
|
22
|
+
self.class.name.titleize
|
23
|
+
end
|
24
|
+
|
25
|
+
def image
|
26
|
+
# Show gravatar image
|
27
|
+
|
28
|
+
# Email field is expected by default for gravatar and for messagable model.
|
29
|
+
# If a model doesn`t have email field, send to method 'default' email, to show default gravatar
|
30
|
+
gravatar_image = Digest::MD5.hexdigest(email.downcase)
|
31
|
+
email == DEFAULT_EMAIL ? gravatar(gravatar_image, '?d=mm') : gravatar(gravatar_image)
|
32
|
+
end
|
33
|
+
|
34
|
+
def method_missing(method, *_args)
|
35
|
+
DEFAULT_EMAIL if method.to_s == 'email'
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def gravatar(email, args = nil)
|
41
|
+
"https://secure.gravatar.com/avatar/#{email}/#{args}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Denshobato
|
2
|
+
module ConversationHelper
|
3
|
+
def my_conversations
|
4
|
+
# Return active user conversations (which is not in trash)
|
5
|
+
|
6
|
+
trashed = block_given? ? yield : false
|
7
|
+
hato_conversation.my_conversations(self, trashed)
|
8
|
+
end
|
9
|
+
|
10
|
+
def trashed_conversations
|
11
|
+
# Return trashed conversations
|
12
|
+
|
13
|
+
my_conversations { true } # => hato_conversation.where trashed: true
|
14
|
+
end
|
15
|
+
|
16
|
+
def make_conversation_with(recipient)
|
17
|
+
# Build conversation
|
18
|
+
# = form_for current_user.make_conversation_with(recipient) do |f|
|
19
|
+
# = f.submit 'Start Chat', class: 'btn btn-primary'
|
20
|
+
|
21
|
+
hato_conversations.build(recipient: recipient)
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_conversation_with(user)
|
25
|
+
# Return an existing conversation between sender and recipient
|
26
|
+
|
27
|
+
hato_conversation.find_by(sender: self, recipient: user)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|