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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +3 -0
- data/.travis.yml +14 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +205 -0
- data/LICENSE.txt +21 -0
- data/README.md +120 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/talkie/application.js +5 -0
- data/app/assets/stylesheets/talkie/_comment.scss +103 -0
- data/app/assets/stylesheets/talkie/_form.scss +50 -0
- data/app/assets/stylesheets/talkie/_variables.scss +71 -0
- data/app/assets/stylesheets/talkie/application.scss +3 -0
- data/app/controllers/talkie/comments_controller.rb +45 -0
- data/app/controllers/talkie_controller.rb +19 -0
- data/app/helpers/talkie/application_helper.rb +20 -0
- data/app/models/talkie/comment.rb +13 -0
- data/app/views/talkie/comments/_comment.html.erb +44 -0
- data/app/views/talkie/comments/_form.html.erb +11 -0
- data/app/views/talkie/comments/_template.html.erb +3 -0
- data/bin/console +14 -0
- data/bin/setup +10 -0
- data/config/locales/en.yml +16 -0
- data/config/locales/es.yml +16 -0
- data/config/routes.rb +3 -0
- data/lib/generators/talkie/install_generator.rb +27 -0
- data/lib/generators/talkie/templates/create_talkie_comments.rb +27 -0
- data/lib/generators/talkie/templates/talkie.rb +46 -0
- data/lib/talkie.rb +30 -0
- data/lib/talkie/acts_as_commentable.rb +27 -0
- data/lib/talkie/acts_as_talker.rb +29 -0
- data/lib/talkie/comments_renderer.rb +43 -0
- data/lib/talkie/controller.rb +18 -0
- data/lib/talkie/engine.rb +15 -0
- data/lib/talkie/permission.rb +16 -0
- data/lib/talkie/renderer_helper.rb +42 -0
- data/lib/talkie/version.rb +3 -0
- data/talkie.gemspec +41 -0
- 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,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,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>
|
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__)
|