diff --git a/Gemfile b/Gemfile index e548957..01b401c 100644 --- a/Gemfile +++ b/Gemfile @@ -26,6 +26,8 @@ gem "nokogiri", "= 1.6.1" gem "htmlentities" gem "rdiscount" +gem "activerecord-typedstore" + # for twitter-posting bot gem "oauth" diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb index 622bab4..2d77117 100644 --- a/app/assets/javascripts/application.js.erb +++ b/app/assets/javascripts/application.js.erb @@ -338,6 +338,16 @@ $(document).ready(function() { return Lobsters.moderateStory(this); }), + $(".toggle_dragons").click(function(a) { + var c = $(".dragon_threads").first(); + if (c) { + if (c.hasClass("hidden")) + c.removeClass("hidden"); + else + c.addClass("hidden"); + } + }), + $(document).on("click", "a.comment_replier", function() { if (!Lobsters.curUser) { Lobsters.bounceToLogin(); @@ -408,6 +418,34 @@ $(document).ready(function() { }); } }); + $(document).on("click", "a.comment_undeletor", function() { + if (confirm("Êtes-vous sûr de vouloir restaurer ce commentaire ?")) { + var li = $(this).closest(".comment"); + $.post("/comments/" + $(li).attr("data-shortid") + "/undelete", + function(d) { + $(li).replaceWith(d); + }); + } + }); + + $(document).on("click", "a.comment_dragon", function() { + if (confirm("Êtes-vous sûr de vouloir marquer ce fil de discussion ?")) { + var li = $(this).closest(".comment"); + $.post("/comments/" + $(li).attr("data-shortid") + "/dragon", + function(d) { + window.location.reload(); + }); + } + }); + $(document).on("click", "a.comment_undragon", function() { + if (confirm("Êtes-vous sûr de vouloir supprimer la marque de ce fil de discussion ?")) { + var li = $(this).closest(".comment"); + $.post("/comments/" + $(li).attr("data-shortid") + "/undragon", + function(d) { + window.location.reload(); + }); + } + }); $(document).on("click", "a.comment_moderator", function() { var reason = prompt("Raison de la modération :"); @@ -421,16 +459,6 @@ $(document).ready(function() { }); }); - $(document).on("click", "a.comment_undeletor", function() { - if (confirm("Êtes-vous sûr de vouloir dé-supprimer ce commentaire ?")) { - var li = $(this).closest(".comment"); - $.post("/comments/" + $(li).attr("data-shortid") + "/undelete", - function(d) { - $(li).replaceWith(d); - }); - } - }); - Lobsters.runSelect2(); $(document).on("click", "div.markdown_help_toggler .markdown_help_label", diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 52fef5f..6810ee4 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -737,6 +737,23 @@ div.comment_actions a { text-decoration: none; } +div.dragons { +} +.dragon_text { + background-color: #f8f8f8; + color: gray; + font-style: italic; + margin: 1em; + padding: 2em 0 2.5em 0; + text-align: center; +} +.dragon_text a { + color: gray; +} +.dragon_threads.hidden { + display: none; +} + a.pagelink { border: 1px solid #ddd; background-color: #fbfbfb; diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 144a3f2..67b8a7e 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -128,6 +128,26 @@ class CommentsController < ApplicationController :content_type => "text/html", :locals => { :comment => comment } end + def dragon + if !((comment = find_comment) && @user.is_moderator?) + return render :text => "can't find comment", :status => 400 + end + + comment.become_dragon_for_user(@user) + + render :text => "ok" + end + + def undragon + if !((comment = find_comment) && @user.is_moderator?) + return render :text => "can't find comment", :status => 400 + end + + comment.remove_dragon_for_user(@user) + + render :text => "ok" + end + def update if !((comment = find_comment) && comment.is_editable_by_user?(@user)) return render :text => "can't find comment", :status => 400 diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb index 317c607..533b255 100644 --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -81,7 +81,7 @@ private :email_replies, :email_messages, :email_mentions, :pushover_replies, :pushover_messages, :pushover_mentions, :mailing_list_mode, :show_avatars, :show_story_previews, - :show_submitted_story_threads + :show_submitted_story_threads, :hide_dragons ) end end diff --git a/app/models/comment.rb b/app/models/comment.rb index b18d956..f838d24 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -50,8 +50,8 @@ class Comment < ActiveRecord::Base end def self.arrange_for_user(user) - parents = self.order("(upvotes - downvotes) < 0 ASC, confidence DESC"). - group_by(&:parent_comment_id) + parents = self.order("is_dragon ASC, (upvotes - downvotes) < 0 ASC, " << + "confidence DESC").group_by(&:parent_comment_id) # top-down list of comments, regardless of indent level ordered = [] @@ -168,6 +168,36 @@ class Comment < ActiveRecord::Base end end + def become_dragon_for_user(user) + Comment.record_timestamps = false + + self.is_dragon = true + + m = Moderation.new + m.comment_id = self.id + m.moderator_user_id = user.id + m.action = "turned into a dragon" + m.save + + self.save(:validate => false) + Comment.record_timestamps = true + end + + def remove_dragon_for_user(user) + Comment.record_timestamps = false + + self.is_dragon = false + + m = Moderation.new + m.comment_id = self.id + m.moderator_user_id = user.id + m.action = "slayed dragon" + m.save + + self.save(:validate => false) + Comment.record_timestamps = true + end + # http://evanmiller.org/how-not-to-sort-by-average-rating.html # https://github.com/reddit/reddit/blob/master/r2/r2/lib/db/_sorts.pyx def calculated_confidence diff --git a/app/models/user.rb b/app/models/user.rb index 3bff609..115f365 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -33,6 +33,20 @@ class User < ActiveRecord::Base has_secure_password + typed_store :settings do |s| + s.boolean :email_notifications, :default => false + s.boolean :email_replies, :default => false + s.boolean :pushover_replies, :default => false + s.string :pushover_user_key + s.boolean :email_messages, :default => false + s.boolean :pushover_messages, :default => false + s.boolean :email_mentions, :default => false + s.boolean :show_avatars, :default => true + s.boolean :show_story_previews, :default => false + s.boolean :show_submitted_story_threads, :default => false + s.boolean :hide_dragons, :default => false + end + validates :email, :format => { :with => /\A[^@ ]+@[^@ ]+\.[^@ ]+\Z/ }, :uniqueness => { :case_sensitive => false } diff --git a/app/views/comments/_comment.html.erb b/app/views/comments/_comment.html.erb index 38b9055..c4be4ce 100644 --- a/app/views/comments/_comment.html.erb +++ b/app/views/comments/_comment.html.erb @@ -83,6 +83,15 @@ class="comment <%= comment.current_vote ? (comment.current_vote[:vote] == 1 ? <% end %> <% end %> + <% if !comment.parent_comment_id && @user && @user.is_moderator? %> + | + <% if comment.is_dragon? %> + <%= t('.undragon') %> + <% else %> + <%= t('.dragon') %> + <% end %> + <% end %> + <% if @user && !comment.story.is_gone? && !comment.is_gone? %> | <%= t('.reply') %> diff --git a/app/views/settings/index.html.erb b/app/views/settings/index.html.erb index 73d800a..d4ab006 100644 --- a/app/views/settings/index.html.erb +++ b/app/views/settings/index.html.erb @@ -193,6 +193,10 @@ <%= f.check_box :show_avatars %> +