talkie 0.1.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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +14 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +11 -0
  7. data/Gemfile.lock +205 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +120 -0
  10. data/Rakefile +23 -0
  11. data/app/assets/javascripts/talkie/application.js +5 -0
  12. data/app/assets/stylesheets/talkie/_comment.scss +103 -0
  13. data/app/assets/stylesheets/talkie/_form.scss +50 -0
  14. data/app/assets/stylesheets/talkie/_variables.scss +71 -0
  15. data/app/assets/stylesheets/talkie/application.scss +3 -0
  16. data/app/controllers/talkie/comments_controller.rb +45 -0
  17. data/app/controllers/talkie_controller.rb +19 -0
  18. data/app/helpers/talkie/application_helper.rb +20 -0
  19. data/app/models/talkie/comment.rb +13 -0
  20. data/app/views/talkie/comments/_comment.html.erb +44 -0
  21. data/app/views/talkie/comments/_form.html.erb +11 -0
  22. data/app/views/talkie/comments/_template.html.erb +3 -0
  23. data/bin/console +14 -0
  24. data/bin/setup +10 -0
  25. data/config/locales/en.yml +16 -0
  26. data/config/locales/es.yml +16 -0
  27. data/config/routes.rb +3 -0
  28. data/lib/generators/talkie/install_generator.rb +27 -0
  29. data/lib/generators/talkie/templates/create_talkie_comments.rb +27 -0
  30. data/lib/generators/talkie/templates/talkie.rb +46 -0
  31. data/lib/talkie.rb +30 -0
  32. data/lib/talkie/acts_as_commentable.rb +27 -0
  33. data/lib/talkie/acts_as_talker.rb +29 -0
  34. data/lib/talkie/comments_renderer.rb +43 -0
  35. data/lib/talkie/controller.rb +18 -0
  36. data/lib/talkie/engine.rb +15 -0
  37. data/lib/talkie/permission.rb +16 -0
  38. data/lib/talkie/renderer_helper.rb +42 -0
  39. data/lib/talkie/version.rb +3 -0
  40. data/talkie.gemspec +41 -0
  41. metadata +251 -0
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env rake
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
10
+
11
+ load 'rails/tasks/engine.rake'
12
+
13
+ Bundler::GemHelper.install_tasks
14
+
15
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
16
+
17
+ require 'rspec/core'
18
+ require 'rspec/core/rake_task'
19
+
20
+ desc 'Run all specs in spec directory (excluding plugin specs)'
21
+ RSpec::Core::RakeTask.new(spec: 'app:db:test:prepare')
22
+
23
+ task default: :spec
@@ -0,0 +1,5 @@
1
+ $("body").on("click", ".talkie-comment-reply-link", function(e){
2
+ e.preventDefault();
3
+
4
+ $(this).parent().parent().find("> .talkie-comments-reply-form-container").toggle();
5
+ });
@@ -0,0 +1,103 @@
1
+ .talkie {
2
+ &-comments-count {
3
+ color: $talkie-comments-count-color;
4
+ margin: $talkie-comments-count-margin;
5
+ }
6
+
7
+ &-comment-holder {
8
+ border-bottom: $talkie-comment-holder-border-bottom;
9
+ margin-bottom: $talkie-comment-holder-margin-bottom;
10
+ padding-bottom: $talkie-comment-holder-padding-bottom;
11
+ width: 90%;
12
+ }
13
+
14
+ &-comment-body {
15
+ color: $talkie-comment-body-color;
16
+ font-size: $talkie-comment-body-font-size;
17
+ line-height: $talkie-comment-body-line-height;
18
+ margin: $talkie-comment-body-margin;
19
+ }
20
+
21
+ &-comment-delete {
22
+ color: $talkie-comment-delete-color;
23
+ display: inline-block;
24
+ font: $talkie-comment-delete-font;
25
+ margin-left: $talkie-comment-delete-margin-left;
26
+ text-decoration: none;
27
+ }
28
+
29
+ &-comment-content {
30
+ margin-left: $talkie-comment-content-margin-left;
31
+
32
+ &::after {
33
+ content: "";
34
+ clear: both;
35
+ display: table;
36
+ }
37
+ }
38
+
39
+ &-comment-footer {
40
+ margin-top: $talkie-comment-footer-margin-top;
41
+
42
+ .talkie-comment-reply {
43
+ margin-bottom: $talkie-comment-reply-margin-bottom;
44
+ }
45
+
46
+ .talkie-comment-reply-link {
47
+ color: $talkie-comment-reply-link-color;
48
+ font: $talkie-comment-reply-link-font;
49
+ text-transform: $talkie-comment-reply-link-text-transform;
50
+ text-decoration: none;
51
+ -webkit-transition: $talkie-comment-reply-link-transition; /* Safari */
52
+ transition: $talkie-comment-reply-link-transition;
53
+
54
+ &:hover {
55
+ color: $talkie-comment-reply-link-hover-color;
56
+ }
57
+ }
58
+
59
+ .talkie-comments-reply-form-container {
60
+ border-bottom: none;
61
+ }
62
+ }
63
+
64
+ &-comment-created-at {
65
+ font-size: $talkie-comment-created-at-font-size;
66
+ text-transform: $talkie-comment-created-at-text-transform;
67
+ }
68
+
69
+ &-comment-creator {
70
+ &-avatar {
71
+ float: left;
72
+
73
+ img {
74
+ border-radius: $talkie-comment-creator-avatar-border-radius;
75
+ }
76
+ }
77
+
78
+ &-link {
79
+ color: $talkie-comment-creator-link-color;
80
+ display: block;
81
+ text-decoration: none;
82
+
83
+ &:hover {
84
+ text-decoration: underline;
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ // Nesting resets
91
+ .talkie-comment-holder
92
+ .talkie-comment-holder {
93
+ border-bottom: none;
94
+ margin-bottom: 0;
95
+ width: 100%;
96
+ }
97
+
98
+ .talkie-comment-content
99
+ .talkie-comment-content
100
+ .talkie-comment-content
101
+ .talkie-comment-content {
102
+ margin-left: 0;
103
+ }
@@ -0,0 +1,50 @@
1
+ .talkie {
2
+ &-comments-form-container,
3
+ &-comments-reply-form-container {
4
+ border-bottom: $talkie-form-border-bottom;
5
+ padding-bottom: $talkie-form-padding-bottom;
6
+ margin-bottom: $talkie-form-margin-bottom;
7
+
8
+ textarea {
9
+ background-color: $talkie-form-textarea-background-color;
10
+ border: $talkie-form-textarea-border;
11
+ border-radius: $talkie-form-textarea-border-radius;
12
+ box-sizing: border-box;
13
+ color: $talkie-form-textarea-color;
14
+ display: inline-block;
15
+ font-size: $talkie-form-textarea-font-size;
16
+ height: $talkie-form-textarea-height;
17
+ line-height: $talkie-form-textarea-line-height;
18
+ margin-bottom: 10px;
19
+ padding: 10px;
20
+ vertical-align: top;
21
+ width: 100%;
22
+ -moz-box-sizing: border-box;
23
+ -webkit-box-sizing: border-box;
24
+ -webkit-border-radius: $talkie-form-textarea-border-radius;
25
+ -moz-border-radius: $talkie-form-textarea-border-radius;
26
+ -webkit-appearance: none;
27
+ }
28
+ }
29
+
30
+ &-comments-form-submit {
31
+ background-color: $talkie-form-submit-background-color;
32
+ border: $talkie-form-submit-border;
33
+ border-radius: $talkie-form-submit-border-radius;
34
+ color: $talkie-form-submit-color;
35
+ font-size: $talkie-form-submit-font-size;
36
+ font-weight: $talkie-form-submit-font-weight;
37
+ margin: $talkie-form-submit-margin;
38
+ padding: $talkie-form-submit-padding;
39
+ text-align: center;
40
+ text-shadow: $talkie-form-submit-text-shadow;
41
+ vertical-align: top;
42
+
43
+ -webkit-border-radius: $talkie-form-submit-border-radius;
44
+ -moz-border-radius: $talkie-form-submit-border-radius;
45
+
46
+ &:hover {
47
+ cursor: pointer;
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,71 @@
1
+ // Form variable styles
2
+
3
+ $talkie-form-border-bottom: 1px solid #EEE !default;
4
+ $talkie-form-padding-bottom: 10px !default;
5
+ $talkie-form-margin-bottom: 10px !default;
6
+
7
+ $talkie-form-textarea-background-color: #FFF !default;
8
+ $talkie-form-textarea-border: 1px solid #E5E5E5 !default;
9
+ $talkie-form-textarea-border-radius: 5px !default;
10
+ $talkie-form-textarea-color: #222 !default;
11
+ $talkie-form-textarea-font-size: 13px !default;
12
+ $talkie-form-textarea-height: 60px !default;
13
+ $talkie-form-textarea-line-height: 1.5 !default;
14
+
15
+ $talkie-form-submit-background-color: #4D90F0 !default;
16
+ $talkie-form-submit-border: 1px solid #3079ED !default;
17
+ $talkie-form-submit-color: #FFF !default;
18
+ $talkie-form-submit-border-radius: 2px !default;
19
+ $talkie-form-submit-font-weight: bold !default;
20
+ $talkie-form-submit-margin: 0 8px 6px 0!default;
21
+ $talkie-form-submit-font-size: 11px !default;
22
+ $talkie-form-submit-padding: 10px 12px !default;
23
+ $talkie-form-submit-text-shadow: 0 1px rgba(0,0,0,.1) !default;
24
+
25
+ // Comment
26
+ //
27
+ // Comments count
28
+ $talkie-comments-count-color: #333 !default;
29
+ $talkie-comments-count-margin: 0 0 40px 0 !default;
30
+
31
+ // Comment holder
32
+ $talkie-comment-holder-border-bottom: 1px solid #EEE !default;
33
+ $talkie-comment-holder-margin-bottom: 40px !default;
34
+ $talkie-comment-holder-padding-bottom: 20px !default;
35
+
36
+ // Comment body
37
+ $talkie-comment-body-color: #222 !default;
38
+ $talkie-comment-body-font-size: 16px !default;
39
+ $talkie-comment-body-line-height: 1.2 !default;
40
+ $talkie-comment-body-margin: 25px 0 0 0 !default;
41
+
42
+ // Comment delete
43
+ $talkie-comment-delete-color: #666 !default;
44
+ $talkie-comment-delete-font: 11px 'Source Sans Pro', sans-serif !default;
45
+ $talkie-comment-delete-margin-left: 10px !default;
46
+
47
+ // Comment content
48
+ $talkie-comment-content-margin-left: 60px !default;
49
+
50
+ // Comment footer
51
+ $talkie-comment-footer-margin-top: 20px !default;
52
+
53
+ // Comment reply
54
+ $talkie-comment-reply-margin-bottom: 20px !default;
55
+
56
+ // Comment reply link
57
+ $talkie-comment-reply-link-color: #666 !default;
58
+ $talkie-comment-reply-link-font: 11px 'Source Sans Pro', sans-serif !default;
59
+ $talkie-comment-reply-link-text-transform: uppercase !default;
60
+ $talkie-comment-reply-link-transition: color 0.2s !default;
61
+ $talkie-comment-reply-link-hover-color: #222 !default;
62
+
63
+ // Comment created at
64
+ $talkie-comment-created-at-font-size: 10px !default;
65
+ $talkie-comment-created-at-text-transform: uppercase !default;
66
+
67
+ // Creator Avatar
68
+ $talkie-comment-creator-avatar-border-radius: 1000px !default;
69
+
70
+ // Creator link
71
+ $talkie-comment-creator-link-color: #222 !default;
@@ -0,0 +1,3 @@
1
+ @import "variables";
2
+ @import "form";
3
+ @import "comment";
@@ -0,0 +1,45 @@
1
+ module Talkie
2
+ class CommentsController < TalkieController
3
+ before_action :current_comment, only: [:destroy]
4
+
5
+ def create
6
+ @comment = Talkie::Comment.new(comment_params)
7
+ @comment.creator = current_user
8
+
9
+ respond_to do |format|
10
+ if @comment.save
11
+ make_child_comment if reply?
12
+ format.html { redirect_to main_app.polymorphic_path(@comment.commentable), notice: "Comment was successfully added." }
13
+ format.js
14
+ else
15
+ format.html { redirect_to :back, notice: "Something went wrong, blank comments are not allowed" }
16
+ format.js
17
+ end
18
+ end
19
+ end
20
+
21
+ def destroy
22
+ current_comment.destroy
23
+ redirect_to main_app.polymorphic_path(current_comment.commentable)
24
+ end
25
+
26
+ private
27
+
28
+ def comment_params
29
+ params.require(:comment).permit(:body, :commentable_id, :commentable_type)
30
+ end
31
+
32
+ def reply?
33
+ params[:parent_comment_id].present?
34
+ end
35
+
36
+ def make_child_comment
37
+ parent_comment = Comment.find params[:parent_comment_id]
38
+ @comment.move_to_child_of(parent_comment)
39
+ end
40
+
41
+ def current_comment
42
+ @current_comment ||= Talkie::Comment.find_by(id: params[:id])
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TalkieController < ApplicationController
4
+ include Talkie::Controller
5
+
6
+ before_action :authorize!
7
+
8
+ protected
9
+
10
+ def authorize!
11
+ if !current_permission.allow?(params[:action], current_comment)
12
+ redirect_back fallback_location: main_app.root_url, status: :unauthorized
13
+ end
14
+ end
15
+
16
+ def current_comment
17
+ nil
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ module Talkie
2
+ module ApplicationHelper
3
+ def link_to_creator(creator, options = {})
4
+ creator_handler = creator.send Talkie.comment_creator_handler
5
+ creator_path = Talkie.creator_path.call(creator, main_app)
6
+
7
+ link_to creator_handler, creator_path, options
8
+ end
9
+
10
+ def avatar_image_tag(creator)
11
+ creator_handler = creator.send Talkie.comment_creator_handler
12
+
13
+ image_tag avatar_url(creator), alt: creator_handler, title: creator_handler
14
+ end
15
+
16
+ def avatar_url(creator)
17
+ Talkie.creator_avatar_url.call(creator)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module Talkie
2
+ class Comment < ActiveRecord::Base
3
+ default_scope Talkie.default_comments_scope
4
+
5
+ acts_as_nested_set :scope => [:commentable_id, :commentable_type],
6
+ :counter_cache => :children_count
7
+
8
+ belongs_to :creator, polymorphic: true, inverse_of: :comments
9
+ belongs_to :commentable, polymorphic: true, inverse_of: :comments
10
+
11
+ validates :body, :creator, :commentable, presence: true
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ <div class="talkie-comment-holder">
2
+ <% if display_user_avatar? %>
3
+ <div class="talkie-comment-creator-avatar">
4
+ <%= avatar_image_tag comment.creator %>
5
+ </div>
6
+ <% end %>
7
+
8
+ <div class="talkie-comment-content">
9
+ <header class="talkie-comment-header">
10
+ <% if display_user_handler? %>
11
+ <div class="talkie-comment-creator">
12
+ <%= link_to_creator comment.creator, class: "talkie-comment-creator-link" %>
13
+ </div>
14
+ <% end %>
15
+ <small class="talkie-comment-created-at"><%= l comment.created_at, format: :long %></small>
16
+
17
+ </header>
18
+ <p class="talkie-comment-body">
19
+ <%= comment.body %>
20
+ </p>
21
+
22
+ <div class="talkie-comment-footer">
23
+ <% if nested_enabled? %>
24
+ <div class="talkie-comment-reply">
25
+ <a href="#" class="talkie-comment-reply-link"><%= t("talkie.comment.reply") %></a>
26
+ <% if allow? :destroy, comment %>
27
+ <%= link_to t("talkie.comment.delete"), [talkie, comment], method: :delete, class: "talkie-comment-delete" %>
28
+ <% end %>
29
+ </div>
30
+ <div class="talkie-comments-reply-form-container" style="display:none">
31
+ <%= form_for [talkie, Talkie::Comment.new] do |f| %>
32
+ <%= f.hidden_field :commentable_id, value: commentable.id %>
33
+ <%= f.hidden_field :commentable_type, value: commentable.class.name %>
34
+ <%= hidden_field_tag :parent_comment_id, comment.id %>
35
+
36
+ <%= f.text_area :body, placeholder: t("talkie.comment.form.body_placeholder") %>
37
+ <%= submit_tag t("talkie.comment.form.reply"), class: 'talkie-comments-form-submit' %>
38
+ <% end %>
39
+ </div>
40
+ <%= render comment.children %>
41
+ <% end %>
42
+ </div>
43
+ </div>
44
+ </div>
@@ -0,0 +1,11 @@
1
+ <div class="talkie-comments-form-container">
2
+ <%= form_for [talkie, Talkie::Comment.new] do |f| %>
3
+ <%= f.hidden_field :commentable_id, value: commentable.id %>
4
+ <%= f.hidden_field :commentable_type, value: commentable.class.name %>
5
+
6
+ <%= f.text_area :body, placeholder: t("talkie.comments.form.body_placeholder") %>
7
+ <%= f.submit t("talkie.comments.form.submit"), class: "talkie-comments-form-submit" %>
8
+ <% end %>
9
+ </div>
10
+
11
+ <h5 class="talkie-comments-count"><%= pluralize commentable.comments.size, t("talkie.comments.count.singular"), plural: t("talkie.comments.count.plural") %></h5>
@@ -0,0 +1,3 @@
1
+ <%= render "talkie/comments/form" %>
2
+
3
+ <%= render root_comments %>
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "talkie"
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(__FILE__)