talkie 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +4 -0
- data/README.md +25 -0
- data/app/assets/javascripts/talkie/application.js +6 -0
- data/app/assets/javascripts/talkie/talkie.mentions.js +25 -0
- data/app/assets/stylesheets/talkie/_form.scss +7 -1
- data/app/assets/stylesheets/talkie/_variables.scss +6 -1
- data/app/assets/stylesheets/talkie/application.scss +2 -0
- data/app/blueprints/mentionees_blueprint.rb +15 -0
- data/app/controllers/talkie/comments_controller.rb +3 -1
- data/app/controllers/talkie/mentions_controller.rb +24 -0
- data/app/mailers/talkie/notifications_mailer.rb +15 -0
- data/app/models/concerns/talkie/mentionable.rb +55 -0
- data/app/models/talkie/comment.rb +6 -0
- data/app/models/talkie/subscription.rb +11 -0
- data/app/views/talkie/comments/_comment.html.erb +7 -3
- data/app/views/talkie/comments/_form.html.erb +6 -2
- data/app/views/talkie/notifications_mailer/mentioned.html.erb +15 -0
- data/app/views/talkie/notifications_mailer/mentioned.text.erb +5 -0
- data/config/locales/en.yml +8 -0
- data/config/locales/es.yml +8 -0
- data/config/routes.rb +4 -0
- data/lib/generators/talkie/templates/create_talkie_comments.rb +14 -0
- data/lib/generators/talkie/templates/talkie.rb +28 -1
- data/lib/generators/talkie/views_generator.rb +15 -0
- data/lib/talkie/acts_as_talker.rb +7 -0
- data/lib/talkie/blueprinter.rb +5 -0
- data/lib/talkie/nil_mention_tokens.rb +18 -0
- data/lib/talkie/permission.rb +3 -3
- data/lib/talkie/subscription_error.rb +6 -0
- data/lib/talkie/version.rb +1 -1
- data/lib/talkie.rb +28 -0
- data/talkie.gemspec +2 -0
- data/vendor/assets/javascripts/jquery.elastic.js +151 -0
- data/vendor/assets/javascripts/jquery.mentionsinput.js +543 -0
- data/vendor/assets/javascripts/underscore.js +1590 -0
- data/vendor/assets/stylesheets/jquery.mentionsinput.css +112 -0
- metadata +46 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d5b6edfa12387d4b10f492f9a518f3e4fcbf21b684429a62580c2b2fea20dfb
|
4
|
+
data.tar.gz: efef1cb019c0c484c01f00eeea7a845726345b5d70b350f8f0813e5e5a2d42b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ededccc1c6b9e9e085d1afb9e8593e052e3afa10dacbab0318a6cf3e2f39cb5cc85d60740aec15f177ce3b99f0abebbdf06e3e25367aeb22ee1c24024816c08
|
7
|
+
data.tar.gz: f09bbbf6c55d1cb25b340094961bfa304de3bf91bc49bf782a508541e656586c65d7fce4d0358b55971976986fc06e60542a61f9165b8a57d6bde361144ebf55
|
data/Gemfile.lock
CHANGED
@@ -3,6 +3,8 @@ PATH
|
|
3
3
|
specs:
|
4
4
|
talkie (0.2.0)
|
5
5
|
awesome_nested_set (~> 3.1)
|
6
|
+
blueprinter
|
7
|
+
oj
|
6
8
|
rails (~> 5.0)
|
7
9
|
sassc-rails (~> 2.1)
|
8
10
|
|
@@ -57,6 +59,7 @@ GEM
|
|
57
59
|
arel (9.0.0)
|
58
60
|
awesome_nested_set (3.1.4)
|
59
61
|
activerecord (>= 4.0.0, < 5.3)
|
62
|
+
blueprinter (0.18.0)
|
60
63
|
builder (3.2.3)
|
61
64
|
coderay (1.1.2)
|
62
65
|
concurrent-ruby (1.1.5)
|
@@ -90,6 +93,7 @@ GEM
|
|
90
93
|
nio4r (2.3.1)
|
91
94
|
nokogiri (1.10.3)
|
92
95
|
mini_portile2 (~> 2.4.0)
|
96
|
+
oj (3.7.12)
|
93
97
|
pry (0.12.2)
|
94
98
|
coderay (~> 1.1.0)
|
95
99
|
method_source (~> 0.9.0)
|
data/README.md
CHANGED
@@ -11,6 +11,7 @@ Talkie is highly customizable comments engine to easily integrate threads to any
|
|
11
11
|
- [Usage](#usage)
|
12
12
|
- [Customization](#customization)
|
13
13
|
- [Styles](#styles)
|
14
|
+
- [Enabling mentions](#enabling-mentions)
|
14
15
|
- [Development](#development)
|
15
16
|
- [Contributing](#contributing)
|
16
17
|
- [License](#license)
|
@@ -104,6 +105,30 @@ Talkie is all about customization, so almost every default style provided by the
|
|
104
105
|
@import "talkie/application";
|
105
106
|
```
|
106
107
|
|
108
|
+
#### Enabling mentions
|
109
|
+
|
110
|
+
Talkie comes with a handy feature that you can toggle in order to
|
111
|
+
enable/disable user mentions.
|
112
|
+
|
113
|
+
To enable it, just go to you `talkie.rb` initializer file and uncomment
|
114
|
+
or add:
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
config.enable_mentions = true
|
118
|
+
```
|
119
|
+
|
120
|
+
For customization, check the
|
121
|
+
[template](lib/generators/talkie/templates/talkie.rb), you can basically
|
122
|
+
override anything to fulfill your needs.
|
123
|
+
|
124
|
+
When enabling this module, you need to setup your mailer configuration,
|
125
|
+
as with each mentions the commenter subscribes to the comment and
|
126
|
+
receives an email, just be aware of that.
|
127
|
+
|
128
|
+
If you have a hard time understanding this, you can check the [dummy
|
129
|
+
application](spec/dummy) I use for testing or contact
|
130
|
+
[me](https://twitter.com/kurenn)
|
131
|
+
|
107
132
|
## Development
|
108
133
|
|
109
134
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake` to run the tests.
|
@@ -1,5 +1,11 @@
|
|
1
|
+
//= require underscore
|
2
|
+
//= require jquery.elastic
|
3
|
+
//= require jquery.mentionsinput
|
4
|
+
//= require talkie/talkie.mentions
|
5
|
+
|
1
6
|
$("body").on("click", ".talkie-comment-reply-link", function(e){
|
2
7
|
e.preventDefault();
|
3
8
|
|
4
9
|
$(this).parent().parent().find("> .talkie-comments-reply-form-container").toggle();
|
5
10
|
});
|
11
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
$( document ).on('ready turbolinks:load', function() {
|
2
|
+
$('textarea.talkie-comment-body-textarea').mentionsInput({
|
3
|
+
showAvatars: false,
|
4
|
+
allowRepeat: true,
|
5
|
+
minChars: 2,
|
6
|
+
onDataRequest: function (mode, query, callback) {
|
7
|
+
$.getJSON('/talkie/mentions',
|
8
|
+
{ q: query },
|
9
|
+
function(responseData) {
|
10
|
+
callback.call(this, responseData);
|
11
|
+
});
|
12
|
+
}
|
13
|
+
});
|
14
|
+
|
15
|
+
$("form.talkie-comments-form").on("submit", function(event) {
|
16
|
+
event.stopPropagation();
|
17
|
+
|
18
|
+
$commentsForm = $(this);
|
19
|
+
|
20
|
+
$commentsForm.find('textarea.talkie-comment-body-textarea').mentionsInput('getMentions', function(data) {
|
21
|
+
$commentsForm.find(".comment-mentions").val(JSON.stringify(data));
|
22
|
+
});
|
23
|
+
|
24
|
+
})
|
25
|
+
})
|
@@ -1,4 +1,11 @@
|
|
1
1
|
.talkie {
|
2
|
+
&-hint {
|
3
|
+
color: $talkie-hint-color;
|
4
|
+
font-size: $talkie-hint-font-size;
|
5
|
+
font-style: $talkie-hint-font-style;
|
6
|
+
margin: $talkie-hint-margin;
|
7
|
+
}
|
8
|
+
|
2
9
|
&-comments-form-container,
|
3
10
|
&-comments-reply-form-container {
|
4
11
|
border-bottom: $talkie-form-border-bottom;
|
@@ -15,7 +22,6 @@
|
|
15
22
|
font-size: $talkie-form-textarea-font-size;
|
16
23
|
height: $talkie-form-textarea-height;
|
17
24
|
line-height: $talkie-form-textarea-line-height;
|
18
|
-
margin-bottom: 10px;
|
19
25
|
padding: 10px;
|
20
26
|
vertical-align: top;
|
21
27
|
width: 100%;
|
@@ -1,5 +1,10 @@
|
|
1
1
|
// Form variable styles
|
2
2
|
|
3
|
+
$talkie-hint-color: #666 !default;
|
4
|
+
$talkie-hint-font-size: 14px !default;
|
5
|
+
$talkie-hint-font-style: italic !default;
|
6
|
+
$talkie-hint-margin: 0 0 10px 0 !default;
|
7
|
+
|
3
8
|
$talkie-form-border-bottom: 1px solid #EEE !default;
|
4
9
|
$talkie-form-padding-bottom: 10px !default;
|
5
10
|
$talkie-form-margin-bottom: 10px !default;
|
@@ -17,7 +22,7 @@ $talkie-form-submit-border: 1px solid #3079ED !default;
|
|
17
22
|
$talkie-form-submit-color: #FFF !default;
|
18
23
|
$talkie-form-submit-border-radius: 2px !default;
|
19
24
|
$talkie-form-submit-font-weight: bold !default;
|
20
|
-
$talkie-form-submit-margin:
|
25
|
+
$talkie-form-submit-margin: 10px 8px 6px 0 !default;
|
21
26
|
$talkie-form-submit-font-size: 11px !default;
|
22
27
|
$talkie-form-submit-padding: 10px 12px !default;
|
23
28
|
$talkie-form-submit-text-shadow: 0 1px rgba(0,0,0,.1) !default;
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MentioneesBlueprint < Blueprinter::Base
|
4
|
+
identifier :id
|
5
|
+
|
6
|
+
fields :email
|
7
|
+
|
8
|
+
field :type do |mentionee, _|
|
9
|
+
"#{mentionee.class.to_s}"
|
10
|
+
end
|
11
|
+
|
12
|
+
field :name do |mentionee, _|
|
13
|
+
"#{Talkie.autocomplete_mention_display.call(mentionee)}"
|
14
|
+
end
|
15
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Talkie
|
2
4
|
class CommentsController < TalkieController
|
3
5
|
before_action :current_comment, only: [:destroy]
|
@@ -28,7 +30,7 @@ module Talkie
|
|
28
30
|
private
|
29
31
|
|
30
32
|
def comment_params
|
31
|
-
params.require(:comment).permit(:body, :commentable_id, :commentable_type)
|
33
|
+
params.require(:comment).permit(:body, :commentable_id, :commentable_type, :mention_tokens)
|
32
34
|
end
|
33
35
|
|
34
36
|
def reply?
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Talkie
|
4
|
+
class MentionsController < TalkieController
|
5
|
+
def index
|
6
|
+
if query.size < 2
|
7
|
+
render json: { error: 'Query string is too short (minimum 2 characters)' },
|
8
|
+
status: :unprocessable_entity
|
9
|
+
else
|
10
|
+
render json: MentioneesBlueprint.render(mentionees)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def query
|
17
|
+
@query ||= params[:q].to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def mentionees
|
21
|
+
@mentionees ||= current_user.class.mentionees(query)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Talkie
|
4
|
+
class NotificationsMailer < ActionMailer::Base
|
5
|
+
default from: Talkie.from_mailer_address
|
6
|
+
|
7
|
+
def mentioned
|
8
|
+
@comment = params[:comment]
|
9
|
+
@creator = @comment.creator
|
10
|
+
recipients = params[:recipients]
|
11
|
+
mail to: recipients,
|
12
|
+
subject: t("talkie.mailers.notifications.subject", creator: @creator.email)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Talkie
|
4
|
+
module Mentionable
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
attr_writer :mention_tokens
|
9
|
+
|
10
|
+
before_create :check_for_mentions!, if: :mentions?
|
11
|
+
after_create :notify_mentionees!, if: :enabled_notifications?
|
12
|
+
end
|
13
|
+
|
14
|
+
def check_for_mentions!
|
15
|
+
subscribers.each do |subscriber|
|
16
|
+
self.subscriptions.build(subscriber: subscriber)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def mentions?
|
21
|
+
mention_tokens.present?
|
22
|
+
end
|
23
|
+
|
24
|
+
def notify_mentionees!
|
25
|
+
NotificationsMailer.with(comment: self, recipients: subscribers.pluck(:email)).mentioned.deliver_now
|
26
|
+
end
|
27
|
+
|
28
|
+
def mention_tokens
|
29
|
+
@mention_tokens || Talkie::NilMentionTokens.new.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def subscribers
|
35
|
+
@subscribers ||= mentionee_klass.find(subscriber_ids)
|
36
|
+
end
|
37
|
+
|
38
|
+
def subscriber_ids
|
39
|
+
@subscriber_ids ||= mentions.map { |mention| mention["id"] }
|
40
|
+
end
|
41
|
+
|
42
|
+
def mentionee_klass
|
43
|
+
@mentionee_klass ||= mentions.first["type"]&.constantize
|
44
|
+
end
|
45
|
+
|
46
|
+
def mentions
|
47
|
+
@mentions ||= JSON.parse(mention_tokens)
|
48
|
+
end
|
49
|
+
|
50
|
+
def enabled_notifications?
|
51
|
+
Talkie.notifications_mentions_enabled?
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -1,5 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Talkie
|
2
4
|
class Comment < ActiveRecord::Base
|
5
|
+
include Talkie::Mentionable if Talkie.mentions_enabled?
|
6
|
+
|
3
7
|
default_scope Talkie.default_comments_scope
|
4
8
|
|
5
9
|
acts_as_nested_set :scope => [:commentable_id, :commentable_type],
|
@@ -8,6 +12,8 @@ module Talkie
|
|
8
12
|
belongs_to :creator, polymorphic: true, inverse_of: :comments
|
9
13
|
belongs_to :commentable, polymorphic: true, inverse_of: :comments
|
10
14
|
|
15
|
+
has_many :subscriptions, dependent: :destroy, inverse_of: :comment
|
16
|
+
|
11
17
|
validates :body, :creator, :commentable, presence: true
|
12
18
|
end
|
13
19
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Talkie
|
4
|
+
class Subscription < ActiveRecord::Base
|
5
|
+
belongs_to :subscriber, polymorphic: true, inverse_of: :subscriptions
|
6
|
+
belongs_to :comment, inverse_of: :subscriptions, class_name: "Talkie::Comment"
|
7
|
+
|
8
|
+
validates_presence_of :subscriber, :comment
|
9
|
+
validates_uniqueness_of :comment, scope: [:subscriber_type, :subscriber_id]
|
10
|
+
end
|
11
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<div class="talkie-comment-holder">
|
1
|
+
<div class="talkie-comment-holder" id="talkie-comment-<%= comment.id %>">
|
2
2
|
<% if display_user_avatar? %>
|
3
3
|
<div class="talkie-comment-creator-avatar">
|
4
4
|
<%= avatar_image_tag comment.creator %>
|
@@ -32,12 +32,16 @@
|
|
32
32
|
<% end %>
|
33
33
|
</div>
|
34
34
|
<div class="talkie-comments-reply-form-container" style="display:none">
|
35
|
-
<%= form_for [talkie, Talkie::Comment.new] do |f| %>
|
35
|
+
<%= form_for [talkie, Talkie::Comment.new], html: { class: "talkie-comments-form" } do |f| %>
|
36
36
|
<%= f.hidden_field :commentable_id, value: commentable.id %>
|
37
37
|
<%= f.hidden_field :commentable_type, value: commentable.class.name %>
|
38
38
|
<%= hidden_field_tag :parent_comment_id, comment.id %>
|
39
39
|
|
40
|
-
<%= f.text_area :body, placeholder: t("talkie.comment.form.body_placeholder") %>
|
40
|
+
<%= f.text_area :body, placeholder: t("talkie.comment.form.body_placeholder"), class: "talkie-comment-body-textarea", required: "required" %>
|
41
|
+
<% if Talkie.mentions_enabled? %>
|
42
|
+
<p class="talkie-hint"><%= t("talkie.comments.form.hint_html") %></p>
|
43
|
+
<%= f.hidden_field :mention_tokens, class: "comment-mentions" %>
|
44
|
+
<% end %>
|
41
45
|
<%= submit_tag t("talkie.comment.form.reply"), class: 'talkie-comments-form-submit' %>
|
42
46
|
<% end %>
|
43
47
|
</div>
|
@@ -1,9 +1,13 @@
|
|
1
1
|
<div class="talkie-comments-form-container">
|
2
|
-
<%= form_for [talkie, Talkie::Comment.new] do |f| %>
|
2
|
+
<%= form_for [talkie, Talkie::Comment.new], html: { class: "talkie-comments-form" } do |f| %>
|
3
3
|
<%= f.hidden_field :commentable_id, value: commentable.id %>
|
4
4
|
<%= f.hidden_field :commentable_type, value: commentable.class.name %>
|
5
5
|
|
6
|
-
<%= f.text_area :body, placeholder: t("talkie.comments.form.body_placeholder") %>
|
6
|
+
<%= f.text_area :body, placeholder: t("talkie.comments.form.body_placeholder"), class: "talkie-comment-body-textarea", required: "required" %>
|
7
|
+
<% if Talkie.mentions_enabled? %>
|
8
|
+
<p class="talkie-hint"><%= t("talkie.comments.form.hint_html") %></p>
|
9
|
+
<%= f.hidden_field :mention_tokens, class: "comment-mentions" %>
|
10
|
+
<% end %>
|
7
11
|
<%= f.submit t("talkie.comments.form.submit"), class: "talkie-comments-form-submit" %>
|
8
12
|
<% end %>
|
9
13
|
</div>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<h4><%= t("talkie.mailers.notifications.headline") %></h4>
|
8
|
+
<p>
|
9
|
+
<%= t("talkie.mailers.notifications.reason", creator: @creator.email) %>
|
10
|
+
</p>
|
11
|
+
<p>
|
12
|
+
<%= t "talkie.mailers.notifications.to_view_conversation_html", link_to: (link_to t("talkie.mailers.notifications.here"), main_app.polymorphic_url(@comment.commentable, anchor: "talkie-comment-#{@comment.id}")) %>
|
13
|
+
</p>
|
14
|
+
</body>
|
15
|
+
</html>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<%= t("talkie.mailers.notifications.headline") %>
|
2
|
+
|
3
|
+
<%= t("talkie.mailers.notifications.reason", creator: @creator.email) %>
|
4
|
+
|
5
|
+
<%= t "talkie.mailers.notifications.to_view_conversation_html", link_to: (link_to t("talkie.mailers.notifications.here"), main_app.polymorphic_url(@comment.commentable, anchor: "talkie-comment-#{@comment.id}")) %>
|
data/config/locales/en.yml
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
---
|
2
2
|
en:
|
3
3
|
talkie:
|
4
|
+
mailers:
|
5
|
+
notifications:
|
6
|
+
subject: "You have been mentioned by %{creator}"
|
7
|
+
headline: "This is an automatic notification system"
|
8
|
+
reason: "You are receiving this notification because %{creator} mentioned you on a conversation."
|
9
|
+
to_view_conversation_html: "To view the conversation on the site, just click %{link_to}"
|
10
|
+
here: "here"
|
4
11
|
controllers:
|
5
12
|
comments:
|
6
13
|
flash:
|
@@ -8,6 +15,7 @@ en:
|
|
8
15
|
error: "Something went wrong, blank comments are not allowed."
|
9
16
|
comments:
|
10
17
|
form:
|
18
|
+
hint_html: "<strong>Hint: </strong> To autocomplete the users, you can add an '@' to activate the autocomplete"
|
11
19
|
submit: "Publish"
|
12
20
|
body_placeholder: "Write your comment..."
|
13
21
|
count:
|
data/config/locales/es.yml
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
---
|
2
2
|
es:
|
3
3
|
talkie:
|
4
|
+
mailers:
|
5
|
+
notifications:
|
6
|
+
subject: "%{creator} te ha mencionado en una conversación"
|
7
|
+
headline: "Esto es un sistema automático de notificación"
|
8
|
+
reason: "Estas recibiendo este correo por que %{creator} te menciono en una conversación."
|
9
|
+
to_view_conversation_html: "Para responder da clic %{link_to}"
|
10
|
+
here: "aquí"
|
4
11
|
controllers:
|
5
12
|
comments:
|
6
13
|
flash:
|
@@ -8,6 +15,7 @@ es:
|
|
8
15
|
error: "Algo salió mal, tu comentario no puede estar en blanco."
|
9
16
|
comments:
|
10
17
|
form:
|
18
|
+
hint_html: "<strong>Ayuda: </strong> Para autocompletar a los usuarios, puedes agregar un '@' antes de su nombre"
|
11
19
|
submit: "Publicar"
|
12
20
|
body_placeholder: "Escribe tu comentario..."
|
13
21
|
count:
|
data/config/routes.rb
CHANGED
@@ -18,6 +18,20 @@ class CreateTalkieComments < ActiveRecord::Migration[5.0]
|
|
18
18
|
add_index :talkie_comments, :commentable_type
|
19
19
|
add_index :talkie_comments, [:creator_id, :creator_type],
|
20
20
|
name: 'index_talkie_comments_on_creator_id_and_creator_type'
|
21
|
+
|
22
|
+
create_table :talkie_subscriptions do |t|
|
23
|
+
t.string :subscriber_type, null: false
|
24
|
+
t.integer :subscriber_id, null: false
|
25
|
+
t.integer :comment_id, null: false
|
26
|
+
|
27
|
+
t.timestamps null: false
|
28
|
+
end
|
29
|
+
|
30
|
+
add_index :talkie_subscriptions, [:subscriber_id, :subscriber_type, :comment_id],
|
31
|
+
unique: true,
|
32
|
+
name: 'index_talkie_subscriptions_on_s_id_and_s_type_and_c_id'
|
33
|
+
|
34
|
+
add_index :talkie_subscriptions, :comment_id
|
21
35
|
end
|
22
36
|
|
23
37
|
def self.down
|
@@ -29,7 +29,6 @@ Talkie.configure do |config|
|
|
29
29
|
# The default looks like:
|
30
30
|
# config.creator_path = lambda { |user, router| "#" }
|
31
31
|
|
32
|
-
|
33
32
|
# ==> Creator avatar url
|
34
33
|
# Configure the avatar url for the comment creator
|
35
34
|
# By default it will use a http:////api.adorable.io/avatars/40/abott@adorable.png
|
@@ -43,7 +42,35 @@ Talkie.configure do |config|
|
|
43
42
|
#
|
44
43
|
# The default looks like:
|
45
44
|
# config.creator_avatar_url = lambda { |user| "//api.adorable.io/avatars/40/abott@adorable.png" }
|
45
|
+
|
46
|
+
# ==> Mentions support
|
47
|
+
# If you decide to enable mentions, be aware on some further configuration
|
48
|
+
# The first thing to do is to just enable it:
|
49
|
+
#
|
50
|
+
# config.enable_mentions = true
|
51
|
+
#
|
52
|
+
# By default it will send an email to notify the mentioned users
|
53
|
+
# but you can override this default configuration like:
|
54
|
+
#
|
55
|
+
# config.enable_mentions_notifications = false
|
56
|
+
#
|
57
|
+
# You can override the query that filter the mentionees
|
58
|
+
# By default the lambda function is
|
59
|
+
# config.mentions_scope_query = lambda { |query| where("email LIKE ?", "#{query}%") }
|
60
|
+
# Just keep in mind that the query variable is what you receive when the user
|
61
|
+
# types '@' on the textarea, so maybe kurenn@icalialabs.com or so
|
62
|
+
# You can change to obey a username column, like so:
|
63
|
+
#
|
64
|
+
# config.mentions_scope_query = lambda { |query| where("username ILIKE ?", "%#{query}%") }
|
65
|
+
#
|
66
|
+
# There is another configuration for the mention module you may want to look at it
|
67
|
+
# The autocomplete text, which is by default the email, but probably that would look nasty,
|
68
|
+
# you can override this and use any method or attribute you want for your talker class:
|
69
|
+
#
|
70
|
+
# config.autocomplete_mention_display = lambda { |mentionee| mentionee.username }
|
46
71
|
#
|
72
|
+
# Or maybe something more complex
|
73
|
+
# config.autocomplete_mention_display = lambda { |mentionee| "#{mentionee.first_name} #{mentionee.last_name}" }
|
47
74
|
|
48
75
|
# ==> Redirect for comments controller
|
49
76
|
# There are sometimes you want to redirect to different locations
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators/base'
|
4
|
+
|
5
|
+
module Talkie
|
6
|
+
module Generators
|
7
|
+
class ViewsGenerator < Rails::Generators::Base
|
8
|
+
source_root File.expand_path('../../../../app/views/talkie', __FILE__)
|
9
|
+
|
10
|
+
def copy_views
|
11
|
+
directory "notifications_mailer", "app/views/talkie/notifications_mailer"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -13,6 +13,13 @@ module Talkie
|
|
13
13
|
class_name: 'Talkie::Comment',
|
14
14
|
inverse_of: :creator
|
15
15
|
|
16
|
+
has_many :subscriptions, as: :subscriber,
|
17
|
+
class_name: 'Talkie::Subscription',
|
18
|
+
dependent: :destroy,
|
19
|
+
inverse_of: :subscriber
|
20
|
+
|
21
|
+
scope :mentionees, Talkie.mentions_scope_query if Talkie.mentions_enabled?
|
22
|
+
|
16
23
|
def owns_comment?(comment)
|
17
24
|
self == comment.creator
|
18
25
|
end
|
data/lib/talkie/permission.rb
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
module Talkie
|
4
4
|
class Permission < Struct.new(:user)
|
5
|
-
def allow?(action, comment)
|
5
|
+
def allow?(action, comment = Talkie::Comment.new)
|
6
6
|
action = action.to_s
|
7
7
|
|
8
8
|
if user
|
9
|
-
return true if action.in? %w[create]
|
10
|
-
return true if
|
9
|
+
return true if action.in? %w[create index]
|
10
|
+
return true if action.in?(%w[destroy]) && user.owns_comment?(comment)
|
11
11
|
end
|
12
12
|
|
13
13
|
false
|
data/lib/talkie/version.rb
CHANGED
data/lib/talkie.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require "talkie/version"
|
4
4
|
require "talkie/engine"
|
5
5
|
require "awesome_nested_set"
|
6
|
+
require "blueprinter"
|
6
7
|
|
7
8
|
module Talkie
|
8
9
|
|
@@ -24,6 +25,30 @@ module Talkie
|
|
24
25
|
mattr_accessor :fail_redirect_to,
|
25
26
|
default: lambda { |router| router.root_url }
|
26
27
|
|
28
|
+
mattr_accessor :enable_mentions,
|
29
|
+
default: false
|
30
|
+
|
31
|
+
mattr_accessor :mentions_scope_query,
|
32
|
+
default: lambda { |query| where("email LIKE ?", "#{query}%") }
|
33
|
+
|
34
|
+
|
35
|
+
mattr_accessor :enable_mentions_notifications,
|
36
|
+
default: true
|
37
|
+
|
38
|
+
mattr_accessor :from_mailer_address,
|
39
|
+
default: "no-reply@change-me-to-your-domain.com"
|
40
|
+
|
41
|
+
mattr_accessor :autocomplete_mention_display,
|
42
|
+
default: lambda { |mentionee| mentionee.email }
|
43
|
+
|
44
|
+
def self.mentions_enabled?
|
45
|
+
@@enable_mentions
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.notifications_mentions_enabled?
|
49
|
+
@@enable_mentions_notifications
|
50
|
+
end
|
51
|
+
|
27
52
|
def self.configure
|
28
53
|
yield self
|
29
54
|
end
|
@@ -34,3 +59,6 @@ require "talkie/acts_as_commentable"
|
|
34
59
|
require "talkie/permission"
|
35
60
|
require "talkie/controller"
|
36
61
|
require "talkie/renderer_helper"
|
62
|
+
require "talkie/subscription_error"
|
63
|
+
require "talkie/blueprinter"
|
64
|
+
require "talkie/nil_mention_tokens"
|
data/talkie.gemspec
CHANGED
@@ -38,4 +38,6 @@ Gem::Specification.new do |spec|
|
|
38
38
|
spec.add_dependency "rails", "~> 5.0"
|
39
39
|
spec.add_dependency "sassc-rails", "~> 2.1"
|
40
40
|
spec.add_dependency "awesome_nested_set", "~> 3.1"
|
41
|
+
spec.add_dependency "blueprinter", "~> 0.18.0"
|
42
|
+
spec.add_dependency "oj", "~> 3.17"
|
41
43
|
end
|