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.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/loader_button.gif +0 -0
  3. data/app/assets/javascripts/c80_news_tz/frontend/comments/comments.js +97 -0
  4. data/app/assets/javascripts/c80_news_tz/frontend/comments/comments_icon_animate_scroll.js +16 -0
  5. data/app/assets/javascripts/c80_news_tz/frontend/comments/comments_utils.js +9 -0
  6. data/app/assets/stylesheets/c80_news_tz/application.scss +1 -1
  7. data/app/assets/stylesheets/c80_news_tz/frontend/comments/comment_form.scss +48 -0
  8. data/app/assets/stylesheets/c80_news_tz/frontend/comments/comments_block.scss +203 -0
  9. data/app/assets/stylesheets/c80_news_tz/frontend/pubs_medium.scss +5 -2
  10. data/app/controllers/c80_news_tz/comments_controller.rb +50 -0
  11. data/app/helpers/c80_news_tz/comments_helper.rb +98 -0
  12. data/app/helpers/c80_news_tz/publications_helper.rb +1 -1
  13. data/app/models/c80_news_tz/comment_validator.rb +9 -0
  14. data/app/models/c80_news_tz/comments.rb +29 -0
  15. data/app/models/c80_news_tz/fact.rb +1 -0
  16. data/app/models/c80_news_tz/r_blurb.rb +1 -0
  17. data/app/models/c80_news_tz/user.rb +2 -0
  18. data/app/views/c80_news_tz/comments/antispam.js.erb +21 -0
  19. data/app/views/c80_news_tz/comments/created.js.erb +16 -0
  20. data/app/views/c80_news_tz/comments/shared/_comment_item.html.erb +49 -0
  21. data/app/views/c80_news_tz/comments/shared/_comments_block.html.erb +18 -0
  22. data/app/views/c80_news_tz/comments/shared/_comments_list.html.erb +3 -0
  23. data/app/views/c80_news_tz/comments/shared/_reply_comment_form.html.erb +14 -0
  24. data/app/views/shared/_news_list.html.erb +6 -4
  25. data/config/routes.rb +2 -0
  26. data/db/migrate/20160325122727_create_comments.rb +12 -0
  27. data/db/migrate/20160330152627_add_antispam_last_comment_ts_to_users.rb +8 -0
  28. data/lib/c80_news_tz/version.rb +1 -1
  29. metadata +20 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 882d379fd838ab5304443cba28d6583514cdbc06
4
- data.tar.gz: 769985240918b79a42d7d40b1377597721053723
3
+ metadata.gz: 99c3ec7555759f8106b24a68a7268a991f371f22
4
+ data.tar.gz: 0c754f360cfb235f5c93fb862b8b13d1775f0e7f
5
5
  SHA512:
6
- metadata.gz: da3c15500734ba6eaaff3a7e3cb09876751b000d850cf1b59860446d59dcaab959b2557966bb3c23960abbffda4a7e10ba79aad36bf6067197e9a018020d6ba9
7
- data.tar.gz: 856a9c44a7573a5cf2c2e90288873b9349bea36eb5abddd873ce953a6ed31bab1d28d3cd856ed8fc4dea2622e5b6de3691fcb197913f6731f6aed9e6e1a32d8e
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,9 @@
1
+ function empty(text) {
2
+ var allSpacesRe = /\s+/g;
3
+ text = text.replace(allSpacesRe, "");
4
+ if (text === "") {
5
+ return true
6
+ } else {
7
+ return false
8
+ }
9
+ }
@@ -2,4 +2,4 @@
2
2
  *= require_self
3
3
  */
4
4
 
5
- @import "frontend/*";
5
+ @import "frontend/**/*";
@@ -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
- div.comments {
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: 5px;
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: 12,
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,9 @@
1
+ module C80NewsTz
2
+ class CommentValidator < ActiveModel::Validator
3
+ def validate(record)
4
+ unless record.message.present?
5
+ record.errors[:message] = 'Сообщение не может быть пустым.'
6
+ end
7
+ end
8
+ end
9
+ end
@@ -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)}
@@ -1,6 +1,8 @@
1
1
  module C80NewsTz
2
2
  class User < ActiveRecord::Base
3
3
 
4
+ has_many :comments, :dependent => :nullify
5
+
4
6
  def self.from_omniauth(auth_hash)
5
7
  user = find_or_create_by(uid: auth_hash['uid'], provider: auth_hash['provider'])
6
8
  user.name = auth_hash['info']['name']
@@ -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,3 @@
1
+ <% list.each do |comment| %>
2
+ <%= render_comment_item(comment) %>
3
+ <% end %>
@@ -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
- <div class="comments" title="Комментариев: <%= pub[:comments_count]%>">
15
- <i class="fa fa-comment"></i>
16
- <%= pub[:comments_count]%>
17
- </div>
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
@@ -5,4 +5,6 @@ C80NewsTz::Engine.routes.draw do
5
5
  get '/auth/:provider/callback', to: 'sessions#create'
6
6
  delete '/logout', to: 'sessions#destroy'
7
7
 
8
+ resources :comments, :only => :create
9
+
8
10
  end
@@ -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
@@ -0,0 +1,8 @@
1
+ class AddAntispamLastCommentTsToUsers < ActiveRecord::Migration
2
+ def change
3
+
4
+ #remove_column :c80_news_tz_users, :last_comment_ts
5
+ add_column :c80_news_tz_users, :last_comment_ts, :integer
6
+
7
+ end
8
+ end
@@ -1,3 +1,3 @@
1
1
  module C80NewsTz
2
- VERSION = "0.1.1.23"
2
+ VERSION = "0.1.1.24"
3
3
  end
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.23
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-28 00:00:00.000000000 Z
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