diff --git a/app/assets/javascripts/app.coffee b/app/assets/javascripts/app.coffee index 2090aac2b1..cb25d50f17 100644 --- a/app/assets/javascripts/app.coffee +++ b/app/assets/javascripts/app.coffee @@ -37,9 +37,13 @@ window.App = type : likeable_type id : likeable_id success : (re) -> - if parseInt(re) >= 0 + likes_count = parseInt(re) + if likes_count >= 0 $(el).data("state","liked").attr("title", "取消喜欢") - $('span',el).text("#{re}人喜欢") + if likes_count == 0 + $('span',el).text("喜欢") + else + $('span',el).text("#{re}人喜欢") $("i.icon",el).attr("class","icon small_liked") else App.alert("抱歉,系统异常,提交失败。") @@ -50,9 +54,13 @@ window.App = data : type : likeable_type success : (re) -> - if parseInt(re) >= 0 + likes_count = parseInt(re) + if likes_count >= 0 $(el).data("state","").attr("title", "喜欢") - $('span',el).text("#{re}人喜欢") + if likes_count == 0 + $('span',el).text("喜欢") + else + $('span',el).text("#{re}人喜欢") $("i.icon",el).attr("class","icon small_like") else App.alert("抱歉,系统异常,提交失败。") @@ -90,7 +98,7 @@ $(document).ready -> App.initForDesktopView() $("abbr.timeago").timeago() - $(".alert").alert() + $(".alert").alert() $('.dropdown-toggle').dropdown() diff --git a/app/assets/stylesheets/topics.scss b/app/assets/stylesheets/topics.scss index 42ca508ece..739adf0f7c 100644 --- a/app/assets/stylesheets/topics.scss +++ b/app/assets/stylesheets/topics.scss @@ -39,6 +39,7 @@ text-align:right; height:16px; overflow:hidden; a:link, a:visited { + margin-left:5px; i { position:relative; margin-bottom:-1px; } text-decoration: none; } @@ -130,22 +131,31 @@ form .node_select { #replies { .total { padding-bottom:6px; color:#999; } .reply { + &.light { background:#F7F2FC; } + &.popular { background:#fffce9; } border-top:1px solid #DDD; padding:8px 10px; margin:0 -10px; .face { padding-right:8px; width:48px; margin-left:0; } .infos { padding-left:58px; } .info { margin-top:4px; color:#999;height:20px; a:link, - a:visited { color:#999; text-decoration: underline;} - .name { float:left; } - .time { float:right; text-align:right; } + a:visited { color:#999; } + .name { + float:left; + a { text-decoration:underline; margin-right:8px; } + } + .opts { + float:right; text-align:right; + a { margin-left:5px; } + a:hover { text-decoration:none; } + i.icon { margin-bottom:-1px; } + } a.reply_link img { vertical-align:middle;} } .body { img { max-width:622px;} } } - .reply.light { background:#F7F2FC;} } #reply.form { diff --git a/app/controllers/likes_controller.rb b/app/controllers/likes_controller.rb index 7b9de6429c..568932bd4e 100644 --- a/app/controllers/likes_controller.rb +++ b/app/controllers/likes_controller.rb @@ -17,7 +17,7 @@ def destroy def find_likeable @success = false @element_id = "likeable_#{params[:type]}_#{params[:id]}" - if not params[:type].in?(['Topic']) + if not params[:type].in?(['Topic','Reply']) render :text => "-1" return false end diff --git a/app/helpers/likes_helper.rb b/app/helpers/likes_helper.rb index 9397b37ee7..37ab428ae0 100644 --- a/app/helpers/likes_helper.rb +++ b/app/helpers/likes_helper.rb @@ -4,6 +4,10 @@ module LikesHelper def likeable_tag(likeable) return "" if likeable.blank? + label = "#{likeable.likes_count}人喜欢" + if likeable.likes_count == 0 + label = "喜欢" + end if current_user && likeable.liked_by_user?(current_user) title = "取消喜欢" state = "liked" @@ -13,7 +17,7 @@ def likeable_tag(likeable) state = "" icon = content_tag("i", "", :class => "icon small_like") end - like_label = raw "#{icon} #{likeable.likes_count}人喜欢" + like_label = raw "#{icon} #{label}" link_to(like_label,"#",:title => title, :rel => "twipsy", 'data-state' => state,'data-type' => likeable.class,'data-id' => likeable.id, :class => 'likeable', :onclick => "return App.likeable(this);") diff --git a/app/models/mongoid/likeable.rb b/app/models/mongoid/likeable.rb index c887d8546d..c9b01a6009 100644 --- a/app/models/mongoid/likeable.rb +++ b/app/models/mongoid/likeable.rb @@ -1,8 +1,16 @@ # coding: utf-8 module Mongoid module Likeable + extend ActiveSupport::Concern + + included do + field :liked_user_ids, :type => Array, :default => [] + field :likes_count, :type => Integer, :default => 0 + end + def liked_by_user?(user) - Like.where(:likeable_type => self.class, :likeable_id => self.id, :user_id => user.id).count > 0 + return false if user.blank? + self.liked_user_ids.include?(user.id) end end end diff --git a/app/models/reply.rb b/app/models/reply.rb index bdf33b2ded..07f8b59258 100644 --- a/app/models/reply.rb +++ b/app/models/reply.rb @@ -8,11 +8,13 @@ class Reply include Mongoid::SoftDelete include Mongoid::MarkdownBody include Mongoid::Mentionable + include Mongoid::Likeable field :body field :body_html field :source field :message_id + field :likes_count, :type => Integer, :default => 0 belongs_to :user, :inverse_of => :replies belongs_to :topic, :inverse_of => :replies @@ -59,6 +61,11 @@ def send_topic_reply_notification end end + # 是否热门 + def popular? + self.likes_count >= 5 + end + def destroy super notifications.delete_all diff --git a/app/models/topic.rb b/app/models/topic.rb index 984b084568..967ce49254 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -22,7 +22,6 @@ class Topic # 回复过的人的 ids 列表 field :follower_ids, :type => Array, :default => [] field :suggested_at, :type => DateTime - field :likes_count, :type => Integer, :default => 0 # 最后回复人的用户名 - cache 字段用于减少列表也的查询 field :last_reply_user_login # 节点名称 - cache 字段用于减少列表也的查询 diff --git a/app/models/user.rb b/app/models/user.rb index 1f944577dd..05e316b540 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -29,7 +29,6 @@ class User field :tagline field :topics_count, :type => Integer, :default => 0 field :replies_count, :type => Integer, :default => 0 - field :likes_count, :type => Integer, :default => 0 # 用户密钥,用于客户端验证 field :private_token field :favorite_topic_ids, :type => Array, :default => [] @@ -48,7 +47,6 @@ class User has_many :posts has_many :notifications, :class_name => 'Notification::Base', :dependent => :delete has_many :photos - has_many :likes def read_notifications(notifications) unread_ids = notifications.find_all{|notification| !notification.read?}.map(&:_id) @@ -191,16 +189,18 @@ def read_topic(topic) # 收藏东西 def like(likeable) - Like.find_or_create_by(:likeable_id => likeable.id, - :likeable_type => likeable.class, - :user_id => self.id) + return false if likeable.blank? + return false if likeable.liked_by_user?(self) + likeable.push(:liked_user_ids, self.id) + likeable.inc(:likes_count, 1) end # 取消收藏 def unlike(likeable) - Like.where(:likeable_id => likeable.id, - :likeable_type => likeable.class, - :user_id => self.id).destroy + return false if likeable.blank? + return false if not likeable.liked_by_user?(self) + likeable.pull(:liked_user_ids, self.id) + likeable.inc(:likes_count, -1) end # 收藏话题 diff --git a/app/views/replies/_reply.html.erb b/app/views/replies/_reply.html.erb index 41ba552a08..3f83b932ff 100644 --- a/app/views/replies/_reply.html.erb +++ b/app/views/replies/_reply.html.erb @@ -1,10 +1,13 @@ -
+
<%= user_avatar_tag(reply.user, :normal) %>
- <%= user_name_tag(reply.user) %> - + + <%= user_name_tag(reply.user) %> <%= reply_counter + 1 %><%= t("common.floor")%>, <%= raw t("common.reply_at", :time => timeago(reply.created_at)) %> + + + <%= likeable_tag(reply) %> <% if can?(:update,reply) %> <%= link_to("", edit_topic_reply_path(@topic,reply), :class => "edit icon small_edit", 'data-uid' => reply.user_id, :title => "修改回帖")%> <% end %> @@ -17,5 +20,7 @@
<%= raw reply.body_html %>
+ +
diff --git a/db/migrate/20120422061501_reply_mention_to_mentionable.rb b/db/migrate/20120422061501_reply_mention_to_mentionable.rb deleted file mode 100644 index 1f122f21c9..0000000000 --- a/db/migrate/20120422061501_reply_mention_to_mentionable.rb +++ /dev/null @@ -1,19 +0,0 @@ -class ReplyMentionToMentionable < Mongoid::Migration - def self.up - Notification::Mention.where(:reply_id.ne => nil).each do |mention| - mention[:mentionable_id] = mention["reply_id"] - mention[:mentionable_type] = 'Reply' - mention.save - mention.unset :reply_id - end - end - - def self.down - Notification::Mention.where(:reply_id => nil).each do |mention| - mention["reply_id"] = mention["mentionable_id"] - mention.save - mention.unset :mentionable_id - mention.unset :mentionable_type - end - end -end diff --git a/db/migrate/20120513024148_remove_old_topic_followers.rb b/db/migrate/20120513024148_remove_old_topic_followers.rb deleted file mode 100644 index de9f5a75d9..0000000000 --- a/db/migrate/20120513024148_remove_old_topic_followers.rb +++ /dev/null @@ -1,7 +0,0 @@ -class RemoveOldTopicFollowers < Mongoid::Migration - def self.up - Topic.unscoped.all.each do |topic| - topic.unset(:follower_ids) - end - end -end \ No newline at end of file diff --git a/spec/helpers/likes_helper_spec.rb b/spec/helpers/likes_helper_spec.rb index a0962b6cce..6f722e7a9b 100644 --- a/spec/helpers/likes_helper_spec.rb +++ b/spec/helpers/likes_helper_spec.rb @@ -14,12 +14,14 @@ it "should result when logined user liked" do helper.stub(:current_user).and_return(user) topic.stub(:liked_by_user?).and_return(true) + helper.likeable_tag(topic).should == %( 喜欢) + topic.stub!(:likes_count).and_return(3) helper.likeable_tag(topic).should == %( #{topic.likes_count}人喜欢) end it "should result when unlogin user" do helper.stub(:current_user).and_return(nil) - helper.likeable_tag(topic).should == %( #{topic.likes_count}人喜欢) + helper.likeable_tag(topic).should == %( 喜欢) end end end diff --git a/spec/models/like_spec.rb b/spec/models/like_spec.rb deleted file mode 100644 index 037376f9e3..0000000000 --- a/spec/models/like_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -require 'spec_helper' - -describe Like do - let(:topic) { Factory :topic } - let(:user) { Factory :user } - let(:user2) { Factory :user } - - describe "like topic" do - after do - Like.delete_all - end - - it "can like/unlike topic" do - user.like(topic) - user.likes.count.should == 1 - user.reload - user.likes_count.should == 1 - topic.reload - topic.likes_count.should == 1 - user2.like(topic) - topic.reload - topic.likes_count.should == 2 - user2.unlike(topic) - topic.reload - user2.likes.count.should == 0 - user2.reload - user2.likes_count.should == 0 - topic.likes_count.should == 1 - end - - it "can tell whether or not liked by a user" do - topic.liked_by_user?(user).should be_false - user.like(topic) - topic.liked_by_user?(user).should be_true - end - end -end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index d09cfbf84a..d7992007f7 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -39,7 +39,7 @@ user_for_delete1.authorizations.should == [] end end - + describe "location" do it "should not get results when user location not set" do Location.count == 0 @@ -50,7 +50,7 @@ user2.location = "Hongkong" Location.count == 2 end - + it "should update users_count when user location changed" do old_name = user.location new_name = "HongKong" @@ -141,17 +141,17 @@ user.private_token.should_not == old_token end end - + describe "favorite topic" do it "should favorite a topic" do user.favorite_topic(topic.id) user.favorite_topic_ids.include?(topic.id).should == true - + user.favorite_topic(nil).should == false user.favorite_topic(topic.id.to_s).should == false user.favorite_topic_ids.include?(topic.id).should == true end - + it "should unfavorite a topic" do user.unfavorite_topic(topic.id) user.favorite_topic_ids.include?(topic.id).should == false @@ -159,4 +159,35 @@ user.unfavorite_topic(topic.id.to_s).should == true end end + + describe "Like" do + let(:topic) { Factory :topic } + let(:user) { Factory :user } + let(:user2) { Factory :user } + + describe "like topic" do + it "can like/unlike topic" do + user.like(topic) + topic.reload + topic.likes_count.should == 1 + topic.liked_user_ids.should include(user.id) + + user2.like(topic) + topic.reload + topic.likes_count.should == 2 + topic.liked_user_ids.should include(user2.id) + + user2.unlike(topic) + topic.reload + topic.likes_count.should == 1 + topic.liked_user_ids.should_not include(user2.id) + end + + it "can tell whether or not liked by a user" do + topic.liked_by_user?(user).should be_false + user.like(topic) + topic.liked_by_user?(user).should be_true + end + end + end end