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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +4 -0
  3. data/README.md +25 -0
  4. data/app/assets/javascripts/talkie/application.js +6 -0
  5. data/app/assets/javascripts/talkie/talkie.mentions.js +25 -0
  6. data/app/assets/stylesheets/talkie/_form.scss +7 -1
  7. data/app/assets/stylesheets/talkie/_variables.scss +6 -1
  8. data/app/assets/stylesheets/talkie/application.scss +2 -0
  9. data/app/blueprints/mentionees_blueprint.rb +15 -0
  10. data/app/controllers/talkie/comments_controller.rb +3 -1
  11. data/app/controllers/talkie/mentions_controller.rb +24 -0
  12. data/app/mailers/talkie/notifications_mailer.rb +15 -0
  13. data/app/models/concerns/talkie/mentionable.rb +55 -0
  14. data/app/models/talkie/comment.rb +6 -0
  15. data/app/models/talkie/subscription.rb +11 -0
  16. data/app/views/talkie/comments/_comment.html.erb +7 -3
  17. data/app/views/talkie/comments/_form.html.erb +6 -2
  18. data/app/views/talkie/notifications_mailer/mentioned.html.erb +15 -0
  19. data/app/views/talkie/notifications_mailer/mentioned.text.erb +5 -0
  20. data/config/locales/en.yml +8 -0
  21. data/config/locales/es.yml +8 -0
  22. data/config/routes.rb +4 -0
  23. data/lib/generators/talkie/templates/create_talkie_comments.rb +14 -0
  24. data/lib/generators/talkie/templates/talkie.rb +28 -1
  25. data/lib/generators/talkie/views_generator.rb +15 -0
  26. data/lib/talkie/acts_as_talker.rb +7 -0
  27. data/lib/talkie/blueprinter.rb +5 -0
  28. data/lib/talkie/nil_mention_tokens.rb +18 -0
  29. data/lib/talkie/permission.rb +3 -3
  30. data/lib/talkie/subscription_error.rb +6 -0
  31. data/lib/talkie/version.rb +1 -1
  32. data/lib/talkie.rb +28 -0
  33. data/talkie.gemspec +2 -0
  34. data/vendor/assets/javascripts/jquery.elastic.js +151 -0
  35. data/vendor/assets/javascripts/jquery.mentionsinput.js +543 -0
  36. data/vendor/assets/javascripts/underscore.js +1590 -0
  37. data/vendor/assets/stylesheets/jquery.mentionsinput.css +112 -0
  38. metadata +46 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82f6715118d4b0022047d97dc002dba51f831e09da19bc374cc0d75ddc2a62aa
4
- data.tar.gz: df4af0404f088395e42c5c92c5dfdd55624292dc0759dbb421d18a941a775e1b
3
+ metadata.gz: 6d5b6edfa12387d4b10f492f9a518f3e4fcbf21b684429a62580c2b2fea20dfb
4
+ data.tar.gz: efef1cb019c0c484c01f00eeea7a845726345b5d70b350f8f0813e5e5a2d42b4
5
5
  SHA512:
6
- metadata.gz: 3dea24f754eb1f95328120601f284ef6530f798c1de001ff233963b8bff83becad84d98cf064741df7df74c3541887c11c7d3855f535785b6538b8be11a100cf
7
- data.tar.gz: f52e51279684b0fa5266ed13d30d5a5ca29d4ff247f76b32012ffacb41549c0a3598d0de4ca2b6707b75538c08d3d76fecede184aa0afcba34755c1d56ebae47
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: 0 8px 6px 0!default;
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;
@@ -1,3 +1,5 @@
1
1
  @import "variables";
2
2
  @import "form";
3
3
  @import "comment";
4
+ @import "jquery.mentionsinput";
5
+
@@ -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}")) %>
@@ -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:
@@ -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
@@ -1,3 +1,7 @@
1
1
  Talkie::Engine.routes.draw do
2
2
  resources :comments, only: [:create, :destroy]
3
+
4
+ if Talkie.mentions_enabled?
5
+ resources :mentions, only: [:index]
6
+ end
3
7
  end
@@ -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
@@ -0,0 +1,5 @@
1
+ require 'oj'
2
+
3
+ Blueprinter.configure do |config|
4
+ config.generator = Oj # default is JSON
5
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Talkie
4
+ class NilMentionTokens
5
+
6
+ def self.find(ids = [])
7
+ []
8
+ end
9
+
10
+ def to_s
11
+ %Q{#{[
12
+ {
13
+ type: self.class.to_s
14
+ }
15
+ ].to_json}}
16
+ end
17
+ end
18
+ end
@@ -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 user.owns_comment?(comment) && action.in?(%w[destroy])
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
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Talkie
4
+ class SubscriptionError < StandardError
5
+ end
6
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Talkie
4
- VERSION = '0.2.0'.freeze
4
+ VERSION = '0.3.0'.freeze
5
5
  end
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