c80_news_tz 0.1.1.23 → 0.1.1.24
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/images/loader_button.gif +0 -0
- data/app/assets/javascripts/c80_news_tz/frontend/comments/comments.js +97 -0
- data/app/assets/javascripts/c80_news_tz/frontend/comments/comments_icon_animate_scroll.js +16 -0
- data/app/assets/javascripts/c80_news_tz/frontend/comments/comments_utils.js +9 -0
- data/app/assets/stylesheets/c80_news_tz/application.scss +1 -1
- data/app/assets/stylesheets/c80_news_tz/frontend/comments/comment_form.scss +48 -0
- data/app/assets/stylesheets/c80_news_tz/frontend/comments/comments_block.scss +203 -0
- data/app/assets/stylesheets/c80_news_tz/frontend/pubs_medium.scss +5 -2
- data/app/controllers/c80_news_tz/comments_controller.rb +50 -0
- data/app/helpers/c80_news_tz/comments_helper.rb +98 -0
- data/app/helpers/c80_news_tz/publications_helper.rb +1 -1
- data/app/models/c80_news_tz/comment_validator.rb +9 -0
- data/app/models/c80_news_tz/comments.rb +29 -0
- data/app/models/c80_news_tz/fact.rb +1 -0
- data/app/models/c80_news_tz/r_blurb.rb +1 -0
- data/app/models/c80_news_tz/user.rb +2 -0
- data/app/views/c80_news_tz/comments/antispam.js.erb +21 -0
- data/app/views/c80_news_tz/comments/created.js.erb +16 -0
- data/app/views/c80_news_tz/comments/shared/_comment_item.html.erb +49 -0
- data/app/views/c80_news_tz/comments/shared/_comments_block.html.erb +18 -0
- data/app/views/c80_news_tz/comments/shared/_comments_list.html.erb +3 -0
- data/app/views/c80_news_tz/comments/shared/_reply_comment_form.html.erb +14 -0
- data/app/views/shared/_news_list.html.erb +6 -4
- data/config/routes.rb +2 -0
- data/db/migrate/20160325122727_create_comments.rb +12 -0
- data/db/migrate/20160330152627_add_antispam_last_comment_ts_to_users.rb +8 -0
- data/lib/c80_news_tz/version.rb +1 -1
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99c3ec7555759f8106b24a68a7268a991f371f22
|
4
|
+
data.tar.gz: 0c754f360cfb235f5c93fb862b8b13d1775f0e7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d539c98a390d1d0b3a6496ac8daacde71affae08308ca6d6584686870abb94daab0d76d90753238bad67bd086df494c847b0cd5f2ad934bc69fb8d841d393afd
|
7
|
+
data.tar.gz: bbff23e19172c63569c4b084bf8565d3dadcc77a29b82de00ed386aa6feedc43eb8f740e73f55c66ea8b518de701c0a57370bcf1956d7363de69617a5966bf0f
|
Binary file
|
@@ -0,0 +1,97 @@
|
|
1
|
+
$(document).ready(function () {
|
2
|
+
|
3
|
+
var $form = $("#comment_form");
|
4
|
+
var $comment_message = $("#comment_message");
|
5
|
+
|
6
|
+
var fCheckText = function (e) {
|
7
|
+
var $submit = $("input#comment_submit", $form);
|
8
|
+
if (!$submit.hasClass('loading')) {
|
9
|
+
if (!empty($(this).val())) {
|
10
|
+
$submit.removeAttr("disabled");
|
11
|
+
} else {
|
12
|
+
$submit.attr("disabled", true);
|
13
|
+
}
|
14
|
+
}
|
15
|
+
};
|
16
|
+
|
17
|
+
$comment_message.keyup(fCheckText);
|
18
|
+
$comment_message.change(fCheckText);
|
19
|
+
$comment_message.blur(fCheckText);
|
20
|
+
$comment_message.focus(fCheckText);
|
21
|
+
|
22
|
+
$form.submit(function () {
|
23
|
+
$("input#comment_submit", $form)
|
24
|
+
.attr('disabled', true)
|
25
|
+
.addClass('loading');
|
26
|
+
});
|
27
|
+
|
28
|
+
});
|
29
|
+
|
30
|
+
// показать форму "оставить комментарий к публикации"
|
31
|
+
function comment_show_form() {
|
32
|
+
//clearInterval(window.timer);
|
33
|
+
//$(".comment_item .reply").removeClass("hidden");
|
34
|
+
var $form = $("#comment_form");
|
35
|
+
var $placeholder = $("#comment_form_placeholder");
|
36
|
+
if ($form.length) {
|
37
|
+
//$("#preview_placeholder", form).hide();
|
38
|
+
//$('input[name="parent_id"]', form).val(0);
|
39
|
+
//$('input[name="comment_id"]', form).val(0);
|
40
|
+
//$(".time_left", form).text("");
|
41
|
+
$placeholder.append($form);
|
42
|
+
//$(".edit,.delete", form).addClass("hidden");
|
43
|
+
$("input#comment_submit", $form).removeAttr('disabled').removeClass("loading");
|
44
|
+
$form.show();
|
45
|
+
$("#comment_message", $form).val("").focus();
|
46
|
+
$('.comment_answers').addClass('hidden');
|
47
|
+
$form.attr('action', '/comments.js');
|
48
|
+
} else {
|
49
|
+
var $social = $("#social_buttons");
|
50
|
+
$social.attr('id','social_buttons_2');
|
51
|
+
$social.find('p').text('Чтобы иметь возможность оставлять комментарии, пожалуйста, авторизуйтесь через:');
|
52
|
+
$placeholder.append($social.clone());
|
53
|
+
}
|
54
|
+
return false
|
55
|
+
}
|
56
|
+
|
57
|
+
/*function comment_show_reply_form(comment_id) {
|
58
|
+
//clearInterval(window.timer);
|
59
|
+
//$(".comment_item .reply").removeClass("hidden");
|
60
|
+
var form = $("#comment_form");
|
61
|
+
if (form.length) {
|
62
|
+
//$("#preview_placeholder", form).hide();
|
63
|
+
//$('input[name="parent_id"]', form).val(comment_id);
|
64
|
+
//$('input[name="comment_id"]', form).val(0);
|
65
|
+
//$(".edit,.delete", form).addClass("hidden");
|
66
|
+
//$(".submit", form).removeClass("hidden");
|
67
|
+
//$(".time_left", form).text("");
|
68
|
+
//$("#comment_" + comment_id + " > .comment_body > .reply").addClass("hidden");
|
69
|
+
var $comment_answers = $("#comment_" + comment_id + " > .comment_body > .comment_answers");
|
70
|
+
_show_comment_answers($comment_answers);
|
71
|
+
$comment_answers.find("> .reply_form_placeholder").append(form);
|
72
|
+
form.show();
|
73
|
+
$("#comment_message", form).val("").focus();
|
74
|
+
//_activate_comment_body(comment_id);
|
75
|
+
//mention_autocomplete($("#comment_message"));
|
76
|
+
form.attr('action', '/comments');
|
77
|
+
} else {
|
78
|
+
//var placeholder = $("#expired_placeholder");
|
79
|
+
//$("#comment_" + comment_id + " > .comment_body > .reply").addClass("hidden");
|
80
|
+
//$("#comment_" + comment_id + " > .comment_body > .reply_form_placeholder").append(placeholder);
|
81
|
+
//placeholder.removeClass("hidden")
|
82
|
+
}
|
83
|
+
return false
|
84
|
+
}*/
|
85
|
+
|
86
|
+
// открыть ответы указанного коментария, ответы остальных комментариев - скрыть
|
87
|
+
function _show_comment_answers($comment_answers) {
|
88
|
+
$('.comment_answers').addClass('hidden');
|
89
|
+
$comment_answers.removeClass('hidden');
|
90
|
+
}
|
91
|
+
|
92
|
+
// подсветить коммент, в который вставлена reply_form
|
93
|
+
/*
|
94
|
+
function _activate_comment_body(comment_id) {
|
95
|
+
$('.comment_body').removeClass('active');
|
96
|
+
$("#comment_" + comment_id + " > .comment_body").addClass('active');
|
97
|
+
}*/
|
@@ -0,0 +1,16 @@
|
|
1
|
+
$(document).ready(function() {
|
2
|
+
$('.fact_time_issue').find('a.comments').click(function (e) {
|
3
|
+
e.preventDefault();
|
4
|
+
e.stopImmediatePropagation();
|
5
|
+
|
6
|
+
$('html, body').animate(
|
7
|
+
{
|
8
|
+
scrollTop: $("#comments_block").offset().top
|
9
|
+
}, {
|
10
|
+
duration: 1000,
|
11
|
+
easing: "easeOutSine"
|
12
|
+
}
|
13
|
+
);
|
14
|
+
|
15
|
+
});
|
16
|
+
});
|
@@ -0,0 +1,48 @@
|
|
1
|
+
form#comment_form {
|
2
|
+
display: block;
|
3
|
+
|
4
|
+
div.editor {
|
5
|
+
position: relative;
|
6
|
+
margin-bottom: 10px;
|
7
|
+
|
8
|
+
div.text_holder {
|
9
|
+
border: 1px solid #dcdcdc;
|
10
|
+
padding: 0;
|
11
|
+
background: #fff;
|
12
|
+
box-sizing: border-box;
|
13
|
+
|
14
|
+
textarea {
|
15
|
+
width: 100%;
|
16
|
+
padding: 4px;
|
17
|
+
border: 0;
|
18
|
+
margin: 0;
|
19
|
+
font-size: 14px;
|
20
|
+
outline: 0;
|
21
|
+
height: 120px;
|
22
|
+
vertical-align: top;
|
23
|
+
box-sizing: border-box;
|
24
|
+
}
|
25
|
+
|
26
|
+
}
|
27
|
+
|
28
|
+
}
|
29
|
+
|
30
|
+
span.error {
|
31
|
+
color: red;
|
32
|
+
}
|
33
|
+
|
34
|
+
.btn {
|
35
|
+
|
36
|
+
&:hover,
|
37
|
+
&:focus,
|
38
|
+
&.focus {
|
39
|
+
background-color: #ffffff !important;
|
40
|
+
}
|
41
|
+
|
42
|
+
&.loading {
|
43
|
+
background: #ffffff url(image_path('loader_button.gif')) repeat 0 0;
|
44
|
+
}
|
45
|
+
|
46
|
+
}
|
47
|
+
|
48
|
+
}
|
@@ -0,0 +1,203 @@
|
|
1
|
+
div#comments_block {
|
2
|
+
border-top: 1px solid #767676;
|
3
|
+
padding: 15px 0 20px 0;
|
4
|
+
|
5
|
+
h2 {
|
6
|
+
margin-top: 0;
|
7
|
+
color: #4d4d4d;
|
8
|
+
font-size: 18px;
|
9
|
+
line-height: 25px;
|
10
|
+
margin-bottom: 10px;
|
11
|
+
|
12
|
+
&.write_comment {
|
13
|
+
color: #AFA56A;
|
14
|
+
margin-bottom: 20px;
|
15
|
+
padding-left: 23px;
|
16
|
+
letter-spacing: -1px;
|
17
|
+
position: relative;
|
18
|
+
|
19
|
+
&:before {
|
20
|
+
display: block;
|
21
|
+
position: absolute;
|
22
|
+
font-family: FontAwesome;
|
23
|
+
content: '\f0e5';
|
24
|
+
top:0;
|
25
|
+
left:0;
|
26
|
+
}
|
27
|
+
|
28
|
+
a {
|
29
|
+
text-decoration: none;
|
30
|
+
border-bottom: 1px dashed;
|
31
|
+
color: #AFA56A;
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
ul#comments_list {
|
37
|
+
list-style: none;
|
38
|
+
padding-left: 0;
|
39
|
+
|
40
|
+
li.comment_item {
|
41
|
+
margin-bottom: 20px;
|
42
|
+
position: relative;
|
43
|
+
|
44
|
+
div.comment_body {
|
45
|
+
position: relative;
|
46
|
+
z-index: 10;
|
47
|
+
|
48
|
+
&.active {
|
49
|
+
/*background-color: #E7E7E8;*/
|
50
|
+
}
|
51
|
+
|
52
|
+
div.comment_info {
|
53
|
+
font-size: 11px;
|
54
|
+
font-family: tahoma, sans-serif;
|
55
|
+
height: 24px;
|
56
|
+
line-height: 24px;
|
57
|
+
background: #DEDFE1;
|
58
|
+
|
59
|
+
div.folding-dot-holder {
|
60
|
+
display: none;
|
61
|
+
position: absolute;
|
62
|
+
top: 0;
|
63
|
+
left: 0;
|
64
|
+
width: 1px;
|
65
|
+
height: 1px;
|
66
|
+
|
67
|
+
.folding-dot {
|
68
|
+
width: 500px;
|
69
|
+
height: 5px;
|
70
|
+
right: 1px;
|
71
|
+
top: 9px;
|
72
|
+
position: absolute;
|
73
|
+
background: transparent url(image_path('bg-folding-dot-light.png')) 5px 0 repeat-x;
|
74
|
+
}
|
75
|
+
|
76
|
+
}
|
77
|
+
|
78
|
+
span.user-info {
|
79
|
+
display: inline-block;
|
80
|
+
vertical-align: middle;
|
81
|
+
|
82
|
+
a.avatar {
|
83
|
+
display: inline-block;
|
84
|
+
vertical-align: top;
|
85
|
+
margin-right: 10px;
|
86
|
+
width: 24px;
|
87
|
+
height: 24px;
|
88
|
+
position: relative;
|
89
|
+
|
90
|
+
img {
|
91
|
+
display: block;
|
92
|
+
width: 24px;
|
93
|
+
height: 24px;
|
94
|
+
border-radius: 3px;
|
95
|
+
position: relative;
|
96
|
+
top: -1px;
|
97
|
+
}
|
98
|
+
|
99
|
+
}
|
100
|
+
|
101
|
+
a.username {
|
102
|
+
display: inline-block;
|
103
|
+
vertical-align: top;
|
104
|
+
margin-left: -3px;
|
105
|
+
margin-right: 10px;
|
106
|
+
color: #666;
|
107
|
+
font-weight: 700;
|
108
|
+
}
|
109
|
+
|
110
|
+
}
|
111
|
+
|
112
|
+
time.time_published {
|
113
|
+
margin-left: -3px;
|
114
|
+
font-size: 10px;
|
115
|
+
color: #666;
|
116
|
+
display: inline-block;
|
117
|
+
vertical-align: middle;
|
118
|
+
}
|
119
|
+
|
120
|
+
span.controls {
|
121
|
+
height: 100%;
|
122
|
+
display: inline-block;
|
123
|
+
vertical-align: middle;
|
124
|
+
line-height: 24px;
|
125
|
+
margin-left: 6px;
|
126
|
+
|
127
|
+
a.anchor {
|
128
|
+
text-decoration: none;
|
129
|
+
&:before {
|
130
|
+
color: #9ac2ce;
|
131
|
+
font-size: 12px;
|
132
|
+
content: "\e90a";
|
133
|
+
font-family: tacos;
|
134
|
+
/*speak: none;*/
|
135
|
+
font-style: normal;
|
136
|
+
font-weight: 400;
|
137
|
+
font-variant: normal;
|
138
|
+
text-transform: none;
|
139
|
+
line-height: 1;
|
140
|
+
display: inline-block;
|
141
|
+
vertical-align: text-top;
|
142
|
+
-webkit-font-smoothing: antialiased;
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
}
|
147
|
+
|
148
|
+
}
|
149
|
+
|
150
|
+
div.message {
|
151
|
+
font-size: 14px;
|
152
|
+
font-family: Arial, sans-serif;
|
153
|
+
line-height: 140%;
|
154
|
+
padding-bottom: 5px;
|
155
|
+
padding-top: 10px;
|
156
|
+
}
|
157
|
+
|
158
|
+
div.reply {
|
159
|
+
a.reply_link {
|
160
|
+
font-size: 11px;
|
161
|
+
text-decoration: none;
|
162
|
+
border-bottom: 1px dashed;
|
163
|
+
margin-right: 10px;
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
div.comment_answers {
|
168
|
+
padding: 15px 0 0 48px;
|
169
|
+
|
170
|
+
ul {
|
171
|
+
padding: 0;
|
172
|
+
margin: 0;
|
173
|
+
list-style: none;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
177
|
+
}
|
178
|
+
|
179
|
+
div.new_comment_indicator {
|
180
|
+
position: absolute;
|
181
|
+
top: -5px;
|
182
|
+
bottom: -5px;
|
183
|
+
left: -5px;
|
184
|
+
right: -5px;
|
185
|
+
z-index: 5;
|
186
|
+
background-color: rgba(127, 255, 0, 0.56);
|
187
|
+
display: none;
|
188
|
+
}
|
189
|
+
|
190
|
+
}
|
191
|
+
|
192
|
+
}
|
193
|
+
|
194
|
+
div#comment_form_placeholder {
|
195
|
+
div#social_buttons_2 {
|
196
|
+
background-color: rgba(204, 204, 204, 0.68);
|
197
|
+
padding: 20px;
|
198
|
+
border: 2px dashed rgba(9, 9, 9, 0.12);
|
199
|
+
text-align: center;
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
}
|
@@ -39,13 +39,16 @@ div.pub_medium {
|
|
39
39
|
}
|
40
40
|
}
|
41
41
|
|
42
|
-
|
42
|
+
a.comments {
|
43
43
|
cursor: pointer;
|
44
44
|
color: #9c9c9c;
|
45
45
|
font-size: 12px;
|
46
46
|
|
47
|
+
margin: 0;
|
48
|
+
height: 41px;
|
49
|
+
line-height: 41px;
|
47
50
|
position: absolute;
|
48
|
-
bottom:
|
51
|
+
bottom: 0;
|
49
52
|
|
50
53
|
i {
|
51
54
|
width: 12px;
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module C80NewsTz
|
2
|
+
class CommentsController < ApplicationController
|
3
|
+
|
4
|
+
def create
|
5
|
+
|
6
|
+
mark_spam = false
|
7
|
+
time_delta = 0
|
8
|
+
user = User.find(params[:comment][:user_id])
|
9
|
+
|
10
|
+
# проверим, не спамер ли это?
|
11
|
+
unless user.last_comment_ts.nil?
|
12
|
+
time_delta = Time.now.to_i - user.last_comment_ts
|
13
|
+
mark_spam = time_delta < 30
|
14
|
+
end
|
15
|
+
|
16
|
+
if mark_spam
|
17
|
+
respond_to do |format|
|
18
|
+
@time_elapsed = 30 - time_delta
|
19
|
+
format.js { render :action => 'antispam' }
|
20
|
+
end
|
21
|
+
else
|
22
|
+
@comment = Comment.create(comment_params)
|
23
|
+
if @comment.save
|
24
|
+
update_user_last_comment(user)
|
25
|
+
@comments_count = @comment.blurb_or_fact.comments.count
|
26
|
+
respond_to do |format|
|
27
|
+
format.js { render :action => 'created'}
|
28
|
+
end
|
29
|
+
else
|
30
|
+
respond_to do |format|
|
31
|
+
format.js { render :json => @comment.errors }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def comment_params
|
39
|
+
params.require(:comment).permit(:message, :user_id, :fact_id, :r_blurb_id)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def update_user_last_comment(user)
|
45
|
+
user.last_comment_ts = Time.now.to_i
|
46
|
+
user.save
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module C80NewsTz
|
2
|
+
module CommentsHelper
|
3
|
+
|
4
|
+
# рендер блока с комментариями к публикации
|
5
|
+
def render_comments_block(blurb_or_fact, current_user = nil)
|
6
|
+
|
7
|
+
n = blurb_or_fact.comments.count
|
8
|
+
# list = [
|
9
|
+
# {id: 12,
|
10
|
+
# parent_id: 0,
|
11
|
+
# user_name: 'Иван Николаевич',
|
12
|
+
# time_published: '28 Март 2016 в 13:40',
|
13
|
+
# user_profile_url: '/',
|
14
|
+
# user_avatar_url: 'https://habrastorage.org/getpro/habr/avatars/97b/8ed/8d6/97b8ed8d6a0d24783dedb33192aeb604_small.jpg',
|
15
|
+
# message: "все по поводу той же производительности ssd дисков.",
|
16
|
+
# answers: [
|
17
|
+
# {id: 22,
|
18
|
+
# parent_id: 12,
|
19
|
+
# user_name: 'Николай',
|
20
|
+
# time_published: '28 Март 2016 в 15:15',
|
21
|
+
# user_profile_url: '/',
|
22
|
+
# user_avatar_url: 'https://habrastorage.org/getpro/habr/avatars/a0b/46e/dfa/a0b46edfa07bca1309a04541cde4cd1a.jpg',
|
23
|
+
# message: "Кажется, ваш стэнд мы видели на NextCastleParty. Очень рад за вас, так держать."
|
24
|
+
# },
|
25
|
+
# {id: 23,
|
26
|
+
# parent_id: 12,
|
27
|
+
# user_name: 'Sample Dark',
|
28
|
+
# time_published: '28 Март 2016 в 15:45',
|
29
|
+
# user_profile_url: '/',
|
30
|
+
# user_avatar_url: 'https://habrastorage.org/getpro/habr/avatars/0f0/a62/41f/0f0a6241fb94bacfd568f0df071ce01a_small.jpg',
|
31
|
+
# message: "Бизнес суров, а игры — особенно применительно к теме краудфандинга — товар, который мы должны продать как можно большему числу людей."
|
32
|
+
# }
|
33
|
+
# ]
|
34
|
+
# },
|
35
|
+
# {id: 13,
|
36
|
+
# parent_id: 0,
|
37
|
+
# user_name: 'Sample Dark',
|
38
|
+
# time_published: '28 Март 2016 в 13:45',
|
39
|
+
# user_profile_url: '/',
|
40
|
+
# user_avatar_url: 'https://habrastorage.org/getpro/habr/avatars/43e/9b4/de5/43e9b4de535dc4d0477313f70c63a4d2_small.jpg',
|
41
|
+
# message: "Вот, например, большой открытый проект на 2.0: https://www.humhub.org/en",
|
42
|
+
# answers: []
|
43
|
+
# }
|
44
|
+
#
|
45
|
+
# ]
|
46
|
+
|
47
|
+
list = blurb_or_fact.comments
|
48
|
+
|
49
|
+
if blurb_or_fact.is_a?(Fact)
|
50
|
+
r_blurb_id = -1
|
51
|
+
fact_id = blurb_or_fact.id
|
52
|
+
else
|
53
|
+
r_blurb_id = blurb_or_fact.id
|
54
|
+
fact_id = -1
|
55
|
+
end
|
56
|
+
|
57
|
+
render :partial => "c80_news_tz/comments/shared/comments_block",
|
58
|
+
:locals => {
|
59
|
+
:comments_count => n,
|
60
|
+
:comments_list => list,
|
61
|
+
:form_params => {
|
62
|
+
:current_user => current_user,
|
63
|
+
:r_blurb_id => r_blurb_id,
|
64
|
+
:fact_id => fact_id
|
65
|
+
}
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
# рендер списка комментариев
|
70
|
+
def render_comments_list(list)
|
71
|
+
render :partial => 'c80_news_tz/comments/shared/comments_list',
|
72
|
+
:locals => {
|
73
|
+
:list => list
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
# рендер одного комментария (в списке)
|
78
|
+
def render_comment_item(comment)
|
79
|
+
render :partial => "c80_news_tz/comments/shared/comment_item",
|
80
|
+
:locals => {
|
81
|
+
comment: comment
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
# рендер формы либо отправки комментария, либо ответа на комментарий
|
86
|
+
def render_comment_form(options)
|
87
|
+
unless options[:current_user].nil?
|
88
|
+
render :partial => "c80_news_tz/comments/shared/reply_comment_form",
|
89
|
+
:locals => {
|
90
|
+
current_user_id: options[:current_user].id,
|
91
|
+
r_blurb_id: options[:r_blurb_id],
|
92
|
+
fact_id: options[:fact_id]
|
93
|
+
}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
@@ -76,7 +76,7 @@ module C80NewsTz
|
|
76
76
|
title: pub.title,
|
77
77
|
rubric: pub.rubric_title,
|
78
78
|
time: local_time(pub[:created_at], format: '%H:%M %d.%m.%Y'),
|
79
|
-
comments_count:
|
79
|
+
comments_count: pub.comments.count,
|
80
80
|
href: url_for_fact(pub) # TODO_MY:: используется в _simple_preview_list.html.erb, надо использовать везде
|
81
81
|
}
|
82
82
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module C80NewsTz
|
2
|
+
class Comment < ActiveRecord::Base
|
3
|
+
validates_with CommentValidator
|
4
|
+
belongs_to :fact
|
5
|
+
belongs_to :r_blurb
|
6
|
+
belongs_to :user
|
7
|
+
|
8
|
+
before_create :set_user_name
|
9
|
+
|
10
|
+
def answers
|
11
|
+
[]
|
12
|
+
end
|
13
|
+
|
14
|
+
def blurb_or_fact
|
15
|
+
if fact.present?
|
16
|
+
fact
|
17
|
+
else
|
18
|
+
r_blurb
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def set_user_name
|
25
|
+
self.user_name = user.name
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -14,6 +14,7 @@ module C80NewsTz
|
|
14
14
|
has_and_belongs_to_many :rubrics, :join_table => 'c80_news_tz_facts_rubrics'
|
15
15
|
has_and_belongs_to_many :companies, :join_table => 'c80_news_tz_companies_facts'
|
16
16
|
has_and_belongs_to_many :locations, :join_table => 'c80_news_tz_facts_locations'
|
17
|
+
has_many :comments, :dependent => :destroy
|
17
18
|
|
18
19
|
validates_with FactValidator
|
19
20
|
default_scope {order(:created_at => :desc)}
|
@@ -15,6 +15,7 @@ module C80NewsTz
|
|
15
15
|
has_and_belongs_to_many :issues, :join_table => 'c80_news_tz_blurbs_issues'
|
16
16
|
has_and_belongs_to_many :rubrics, :join_table => 'c80_news_tz_blurbs_rubrics'
|
17
17
|
has_and_belongs_to_many :r_advertisers, :join_table => 'c80_news_tz_advs_blurbs'
|
18
|
+
has_many :comments, :dependent => :destroy
|
18
19
|
|
19
20
|
validates_with FactValidator
|
20
21
|
default_scope {order(:created_at => :desc)}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
var $form = $('form#comment_form');
|
2
|
+
if ($form.find('span#t').length == 0) {
|
3
|
+
var time_elapsed = <%= @time_elapsed %>;
|
4
|
+
var $error_text = $form.find("span#error_text");
|
5
|
+
var $submit = $form.find('#comment_submit');
|
6
|
+
var $message = $('<span>Чтобы оставить новый комментарий, Вам необходимо подождать <span id="t"><%= @time_elapsed %></span> сек</span>');
|
7
|
+
var $time_elapsed = $message.find('span#t');
|
8
|
+
$error_text.append($message);
|
9
|
+
|
10
|
+
var refreshTimer = function () {
|
11
|
+
time_elapsed -= 1;
|
12
|
+
if (time_elapsed == 0) {
|
13
|
+
$error_text.html('');
|
14
|
+
$submit.removeClass('loading').removeAttr("disabled");
|
15
|
+
clearInterval(interval);
|
16
|
+
} else {
|
17
|
+
$time_elapsed.text(time_elapsed);
|
18
|
+
}
|
19
|
+
};
|
20
|
+
var interval = setInterval(refreshTimer, 1000);
|
21
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
var $comment = $("<%= j render_comment_item(@comment) %>");
|
3
|
+
var $comments_list = $('ul#comments_list');
|
4
|
+
var $form = $('form#comment_form');
|
5
|
+
var $comment_block = $('div#comments_block');
|
6
|
+
|
7
|
+
$comments_list.append($comment);
|
8
|
+
$form.hide();
|
9
|
+
|
10
|
+
var $li_bg = $comment.find('.new_comment_indicator');
|
11
|
+
$li_bg.css("display","block").fadeOut(10000);
|
12
|
+
|
13
|
+
$comment_block.find('h2.title span').text("<%= @comments_count %>");
|
14
|
+
$('div.fact_time_issue a.comments')
|
15
|
+
.attr('title','Комментариев: <%= @comments_count %>')
|
16
|
+
.find('span').text("<%= @comments_count %>");
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<li class="comment_item" id="comment_<%= comment.id %>">
|
2
|
+
|
3
|
+
<div class="comment_body">
|
4
|
+
|
5
|
+
<div class="comment_info" rel="<%= comment.id %>">
|
6
|
+
|
7
|
+
<%# аватар и никнейм %>
|
8
|
+
<span class="user-info" rel="user-popover" data-user-login="<%= comment.user_name %>" data-target="webuiPopover0">
|
9
|
+
<%= link_to image_tag(comment.user.image_url, :alt => comment.user_name),
|
10
|
+
comment.user.url,
|
11
|
+
:title => comment.user_name,
|
12
|
+
:class => 'avatar'
|
13
|
+
%>
|
14
|
+
<%= link_to comment.user_name, comment.user.url, :class => 'username' %>
|
15
|
+
</span>
|
16
|
+
|
17
|
+
<%# время комментария %>
|
18
|
+
<time class="time_published"><%= local_time(comment.created_at, format: '%H:%M %d.%m.%Y') %></time>
|
19
|
+
|
20
|
+
<%# кнопки взаимодействия с комментарием %>
|
21
|
+
<span class="controls">
|
22
|
+
<%= link_to "", "#comment_#{comment.id}", :class => 'anchor', :title => 'Ссылка на комментарий' %>
|
23
|
+
</span>
|
24
|
+
|
25
|
+
</div>
|
26
|
+
|
27
|
+
<div class="message"><%= comment.message %></div>
|
28
|
+
|
29
|
+
<% unless comment.answers.nil? %>
|
30
|
+
<%# кнопка покажет ответы на комментарий %>
|
31
|
+
<!--<div class="reply">-->
|
32
|
+
<%# TODO_MY:: вставить вместо 1 количество ответов на комментарий %>
|
33
|
+
<%# link_to "ответов: 1",
|
34
|
+
'#reply',
|
35
|
+
:class => 'reply_link',
|
36
|
+
:onclick => "return comment_show_reply_form(#{comment.id})"
|
37
|
+
%>
|
38
|
+
<!--</div>-->
|
39
|
+
|
40
|
+
<div class="comment_answers hidden">
|
41
|
+
<ul><%= render_comments_list(comment.answers) %></ul>
|
42
|
+
<div class="reply_form_placeholder"></div>
|
43
|
+
</div>
|
44
|
+
<% end %>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<div class="new_comment_indicator"></div>
|
48
|
+
|
49
|
+
</li>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<div id="comments_block">
|
2
|
+
<h2 class="title">Комментарии (<span><%= comments_count %></span>)</h2>
|
3
|
+
|
4
|
+
<ul id="comments_list">
|
5
|
+
<%= render_comments_list(comments_list) %>
|
6
|
+
</ul>
|
7
|
+
|
8
|
+
<h2 class="write_comment">
|
9
|
+
<%= link_to "Написать комментарий", "#", onclick: 'return comment_show_form()' %>
|
10
|
+
</h2>
|
11
|
+
|
12
|
+
<div id="comment_form_placeholder"></div>
|
13
|
+
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<div id="shadow" class="hidden">
|
17
|
+
<%= render_comment_form(form_params) %>
|
18
|
+
</div>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<%= form_for :comment, remote: true, :html => {id: 'comment_form'} do |f| %>
|
2
|
+
<%= f.hidden_field(:user_id, value: current_user_id) %>
|
3
|
+
<%= f.hidden_field(:fact_id, value: fact_id) %>
|
4
|
+
<%= f.hidden_field(:r_blurb_id, value: r_blurb_id) %>
|
5
|
+
<div class="editor">
|
6
|
+
<div class="text_holder">
|
7
|
+
<%= f.text_area :message, id: 'comment_message', rows: 10, cols: 30 %>
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
<div class="buttons">
|
11
|
+
<%= f.submit :id => 'comment_submit', class: 'btn btn-default', disabled:'disabled' %>
|
12
|
+
<span id="error_text" class="error"></span>
|
13
|
+
</div>
|
14
|
+
<% end %>
|
@@ -11,10 +11,12 @@
|
|
11
11
|
<a title="<%= pub[:title] %>" href="<%= pub[:pi][:a_href]%>"><%= pub[:title] %></a>
|
12
12
|
</div>
|
13
13
|
<%= render_image_link_lazy(pub[:cl]) if pub[:cl].present? %>
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
<%= link_to("#{pub[:href]}#comments_block",
|
15
|
+
title: "Комментариев: #{pub[:comments_count]}",
|
16
|
+
class: 'comments') do %>
|
17
|
+
<i class="fa fa-comment"></i>
|
18
|
+
<%= pub[:comments_count] %>
|
19
|
+
<% end %>
|
18
20
|
</div>
|
19
21
|
<% if k == 2 && index != news_for_render.count-1 %>
|
20
22
|
<div class="hr"></div>
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateComments < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :c80_news_tz_comments, :options => 'COLLATE=utf8_unicode_ci' do |t|
|
4
|
+
t.text :message, :limit => 1100
|
5
|
+
t.references :fact, :index => true
|
6
|
+
t.references :r_blurb, :index => true
|
7
|
+
t.references :user, :index => true
|
8
|
+
t.string :user_name # если удалить пользователя - здесь сохранится его имя
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/c80_news_tz/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: c80_news_tz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.1.
|
4
|
+
version: 0.1.1.24
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- C80609A
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -108,6 +108,7 @@ files:
|
|
108
108
|
- app/admin/c80_news_tz/rubrics.rb
|
109
109
|
- app/admin/c80_news_tz/spots.rb
|
110
110
|
- app/assets/images/c80_news_tz/.keep
|
111
|
+
- app/assets/images/loader_button.gif
|
111
112
|
- app/assets/javascripts/c80_news_tz/application.js.coffee
|
112
113
|
- app/assets/javascripts/c80_news_tz/backend.js.coffee
|
113
114
|
- app/assets/javascripts/c80_news_tz/backend/collapsable-groups.js
|
@@ -116,6 +117,9 @@ files:
|
|
116
117
|
- app/assets/javascripts/c80_news_tz/backend/r_advertisers.js
|
117
118
|
- app/assets/javascripts/c80_news_tz/backend/r_blurbs.js
|
118
119
|
- app/assets/javascripts/c80_news_tz/backend/rubrics.js
|
120
|
+
- app/assets/javascripts/c80_news_tz/frontend/comments/comments.js
|
121
|
+
- app/assets/javascripts/c80_news_tz/frontend/comments/comments_icon_animate_scroll.js
|
122
|
+
- app/assets/javascripts/c80_news_tz/frontend/comments/comments_utils.js
|
119
123
|
- app/assets/javascripts/c80_news_tz/frontend/facts_ajax.js
|
120
124
|
- app/assets/javascripts/c80_news_tz/frontend/nabbers.js
|
121
125
|
- app/assets/stylesheets/c80_news_tz/application.scss
|
@@ -127,14 +131,18 @@ files:
|
|
127
131
|
- app/assets/stylesheets/c80_news_tz/backend/r_advertisers.scss
|
128
132
|
- app/assets/stylesheets/c80_news_tz/backend/r_lives.scss
|
129
133
|
- app/assets/stylesheets/c80_news_tz/backend/spots.scss
|
134
|
+
- app/assets/stylesheets/c80_news_tz/frontend/comments/comment_form.scss
|
135
|
+
- app/assets/stylesheets/c80_news_tz/frontend/comments/comments_block.scss
|
130
136
|
- app/assets/stylesheets/c80_news_tz/frontend/pubs_medium.scss
|
131
137
|
- app/controllers/c80_news_tz/application_controller.rb
|
132
138
|
- app/controllers/c80_news_tz/banners_controller.rb
|
139
|
+
- app/controllers/c80_news_tz/comments_controller.rb
|
133
140
|
- app/controllers/c80_news_tz/sessions_controller.rb
|
134
141
|
- app/helpers/c80_news_tz/advertisers_helper.rb
|
135
142
|
- app/helpers/c80_news_tz/application_helper.rb
|
136
143
|
- app/helpers/c80_news_tz/banners_helper.rb
|
137
144
|
- app/helpers/c80_news_tz/blurbs_helper.rb
|
145
|
+
- app/helpers/c80_news_tz/comments_helper.rb
|
138
146
|
- app/helpers/c80_news_tz/publications_helper.rb
|
139
147
|
- app/helpers/c80_news_tz/subj_helper.rb
|
140
148
|
- app/models/c80_news_tz/adress.rb
|
@@ -142,6 +150,8 @@ files:
|
|
142
150
|
- app/models/c80_news_tz/banner02.rb
|
143
151
|
- app/models/c80_news_tz/banner03.rb
|
144
152
|
- app/models/c80_news_tz/banner_validator.rb
|
153
|
+
- app/models/c80_news_tz/comment_validator.rb
|
154
|
+
- app/models/c80_news_tz/comments.rb
|
145
155
|
- app/models/c80_news_tz/company.rb
|
146
156
|
- app/models/c80_news_tz/cphoto.rb
|
147
157
|
- app/models/c80_news_tz/fact.rb
|
@@ -176,6 +186,12 @@ files:
|
|
176
186
|
- app/uploaders/c80_news_tz/r_bphoto_uploader.rb
|
177
187
|
- app/views/c80_news_tz/application/guru.js.erb
|
178
188
|
- app/views/c80_news_tz/banners/counter.html.erb
|
189
|
+
- app/views/c80_news_tz/comments/antispam.js.erb
|
190
|
+
- app/views/c80_news_tz/comments/created.js.erb
|
191
|
+
- app/views/c80_news_tz/comments/shared/_comment_item.html.erb
|
192
|
+
- app/views/c80_news_tz/comments/shared/_comments_block.html.erb
|
193
|
+
- app/views/c80_news_tz/comments/shared/_comments_list.html.erb
|
194
|
+
- app/views/c80_news_tz/comments/shared/_reply_comment_form.html.erb
|
179
195
|
- app/views/layouts/c80_news_tz/application.html.erb
|
180
196
|
- app/views/shared/_banner_01.html.erb
|
181
197
|
- app/views/shared/_banner_02.html.erb
|
@@ -223,6 +239,8 @@ files:
|
|
223
239
|
- db/migrate/20160310114242_create_banners03.rb
|
224
240
|
- db/migrate/20160314093945_create_users.rb
|
225
241
|
- db/migrate/20160314093946_add_users_indexes.rb
|
242
|
+
- db/migrate/20160325122727_create_comments.rb
|
243
|
+
- db/migrate/20160330152627_add_antispam_last_comment_ts_to_users.rb
|
226
244
|
- db/seeds/19_fill_news_props.rb.example
|
227
245
|
- db/seeds/20_fill_rubrics.rb.example
|
228
246
|
- db/seeds/21_fill_facts.rb.example
|