Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

More detailed view tracking + visual indication of new topics #163

Merged
merged 5 commits into from

3 participants

John Gadbois Ryan Bigg Philip Arndt
John Gadbois

No description provided.

John Gadbois

Still need some specs for overall view tracking of forums and topics. Also specs for register_view_by(user) to make sure that is only updating timestamps when appropriate.

John Gadbois

@radar - Added specs - think this is good to go. Please let me know what you think.

Ryan Bigg
Owner

Yup, seems good. @parndt, go for it!

Philip Arndt parndt merged commit 2072a5d into from
Philip Arndt
Collaborator

Did it live

John Gadbois

Thanks guys!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 28, 2012
  1. John Gadbois
Commits on Feb 29, 2012
  1. John Gadbois
Commits on Mar 2, 2012
  1. John Gadbois
  2. John Gadbois
Commits on Mar 12, 2012
  1. John Gadbois
This page is out of date. Refresh to see the latest.
7 app/controllers/forem/forums_controller.rb
View
@@ -9,8 +9,15 @@ def index
def show
@forum = Forem::Forum.find(params[:id])
+ register_view
+
@topics = forem_admin? ? @forum.topics : @forum.topics.visible
@topics = @topics.by_pinned_or_most_recent_post.page(params[:page]).per(20)
end
+
+ private
+ def register_view
+ @forum.register_view_by(forem_user)
+ end
end
end
13 app/helpers/forem/topics_helper.rb
View
@@ -4,5 +4,18 @@ def link_to_latest_post(post)
text = "#{time_ago_in_words(post.created_at)} #{t("ago_by")} #{post.user}"
link_to text, forum_topic_path(post.topic.forum, post.topic, :anchor => "post-#{post.id}")
end
+
+ def new_since_last_view_text(topic)
+ if forem_user
+ topic_view = topic.view_for(forem_user)
+ forum_view = topic.forum.view_for(forem_user)
+
+ if forum_view
+ if topic_view.nil? && topic.created_at > forum_view.past_viewed_at
+ content_tag :super, "New"
+ end
+ end
+ end
+ end
end
end
33 app/models/forem/concerns/viewable.rb
View
@@ -0,0 +1,33 @@
+require 'active_support/concern'
+
+module Forem
+ module Concerns
+ module Viewable
+ extend ActiveSupport::Concern
+
+ included do
+ has_many :views, :as => :viewable
+ end
+
+ def view_for(user)
+ views.find_by_user_id(user.id)
+ end
+
+ # Track when users last viewed topics
+ def register_view_by(user)
+ if user
+ view = views.find_or_create_by_user_id(user.id)
+ view.increment!("count")
+ increment!(:views_count)
+
+ # update current viewed at if more than 15 minutes ago
+ if view.current_viewed_at < 15.minutes.ago
+ view.past_viewed_at = view.current_viewed_at
+ view.current_viewed_at = Time.now
+ view.save
+ end
+ end
+ end
+ end
+ end
+end
3  app/models/forem/forum.rb
View
@@ -1,9 +1,10 @@
module Forem
class Forum < ActiveRecord::Base
+ include Forem::Concerns::Viewable
+
belongs_to :category
has_many :topics, :dependent => :destroy
has_many :posts, :through => :topics, :dependent => :destroy
- has_many :views, :through => :topics, :dependent => :destroy
validates :category, :presence => true
validates :title, :presence => true
16 app/models/forem/topic.rb
View
@@ -1,9 +1,10 @@
module Forem
class Topic < ActiveRecord::Base
+ include Forem::Concerns::Viewable
+
attr_protected :pinned, :locked
belongs_to :forum
- has_many :views
has_many :subscriptions
belongs_to :user, :class_name => Forem.user_class.to_s
@@ -65,18 +66,7 @@ def unpin!
def can_be_replied_to?
!locked?
end
-
- def view_for(user)
- views.find_by_user_id(user.id)
- end
-
- # Track when users last viewed topics
- def register_view_by(user)
- if user
- view = views.find_or_create_by_user_id(user.id)
- view.increment!("count")
- end
- end
+
def subscribe_poster
subscribe_user(self.user_id)
17 app/models/forem/view.rb
View
@@ -1,8 +1,21 @@
module Forem
class View < ActiveRecord::Base
- belongs_to :topic
+ before_create :set_viewed_at_to_now
+
+ belongs_to :viewable, :polymorphic => true
belongs_to :user, :class_name => Forem.user_class.to_s
- validates :topic_id, :presence => true
+ validates :viewable_id, :presence => true
+ validates :viewable_type, :presence => true
+
+ def viewed_at
+ updated_at
+ end
+
+ private
+ def set_viewed_at_to_now
+ self.current_viewed_at = Time.now
+ self.past_viewed_at = current_viewed_at
+ end
end
end
3  app/views/forem/topics/_topic.html.erb
View
@@ -13,6 +13,7 @@
<% end %>
</td>
<td class='byline'>
+ <%= new_since_last_view_text(topic) %>
<div class='subject'><%= link_to topic.subject, forum_topic_path(@forum, topic) %></div>
<div class='started-by'><%= t "started_by" %><%= topic.posts.by_created_at.first.user %></div>
</td>
@@ -20,5 +21,5 @@
<%= link_to_latest_post(topic.posts.by_created_at.last) -%>
</td>
<td class='posts-count'><%= topic.posts.count %></td>
- <td class='views-count'><%= topic.views.sum(:count) %></td>
+ <td class='views-count'><%= topic.views_count %></td>
</tr>
12 db/migrate/20120229165013_make_forem_views_polymorphic.rb
View
@@ -0,0 +1,12 @@
+class MakeForemViewsPolymorphic < ActiveRecord::Migration
+ def up
+ rename_column :forem_views, :topic_id, :viewable_id
+ add_column :forem_views, :viewable_type, :string
+ Forem::View.update_all("viewable_type='Forem::Topic'")
+ end
+
+ def down
+ remove_column :forem_views, :viewable_type
+ rename_column :forem_views, :viewable_id, :topic_id
+ end
+end
23 db/migrate/20120302152918_add_forem_view_fields.rb
View
@@ -0,0 +1,23 @@
+class AddForemViewFields < ActiveRecord::Migration
+ def up
+ add_column :forem_views, :current_viewed_at, :datetime
+ add_column :forem_views, :past_viewed_at, :datetime
+ add_column :forem_topics, :views_count, :integer, :default=>0
+ add_column :forem_forums, :views_count, :integer, :default=>0
+
+ Forem::Topic.find_each do |topic|
+ topic.update_column(:views_count, topics.views.sum(:count))
+ end
+
+ Forem::Forum.find_each do |forum|
+ forum.update_column(:views_count, forum.topics.sum(:views_count))
+ end
+ end
+
+ def down
+ remove_column :forem_views, :current_viewed_at, :datetime
+ remove_column :forem_views, :past_viewed_at, :datetime
+ remove_column :forem_topics, :views_count, :integer, :default=>0
+ remove_column :forem_forums, :views_count, :integer, :default=>0
+ end
+end
38 spec/models/topic_spec.rb
View
@@ -77,5 +77,43 @@
@topic.subscriptions.size.should == 1
end
end
+
+ describe "#register_view_by" do
+ before do
+ @user = FactoryGirl.create(:user)
+ end
+
+ it "increments the overall topic view count" do
+ count = @topic.views_count
+ @topic.register_view_by(@user)
+ @topic.views_count.should eq(count+1)
+ end
+
+ it "increments the users view count for the topic" do
+ @topic.views.create(:user => @user, :count => 1)
+ @topic.register_view_by(@user)
+
+ @topic.view_for(@user).count.should eq(2)
+ end
+
+ it "doesn't update the view time if less than 15 minutes ago" do
+ cur_time = Time.now.utc
+ @topic.views.create(:user => @user, :current_viewed_at => cur_time)
+ @topic.register_view_by(@user)
+
+ @topic.view_for(@user).current_viewed_at.to_i.should eq(cur_time.to_i)
+ end
+
+ it "does update the view time if more than 15 minutes ago" do
+ t = Time.parse("03/01/2012 10:00")
+ Time.stub(:now).and_return(t)
+
+ last_hour = 1.hour.ago.utc
+ @topic.views.create(:user => @user, :current_viewed_at => last_hour)
+ @topic.register_view_by(@user)
+
+ @topic.view_for(@user).current_viewed_at.to_i.should eq(t.to_i)
+ end
+ end
end
end
29 spec/requests/forums_spec.rb
View
@@ -37,8 +37,8 @@
context "when logged in" do
before do
- user = Factory(:user)
- sign_in(user)
+ @user = Factory(:user)
+ sign_in(@user)
end
it "calls out topics that have been posted to since your last visit, if you've visited" do
visit forum_topic_path(forum.id, @topic_2)
@@ -47,6 +47,31 @@
topic_subjects = Nokogiri::HTML(page.body).css(".topics tbody tr .new_posts")
topic_subjects.should_not be_empty
end
+
+ context "checking new topics" do
+ before do
+ forum.register_view_by(@user)
+ forum.view_for(@user).update_attribute(:past_viewed_at, 3.days.ago)
+ @topic_1.created_at = 1.day.ago
+ @topic_2.created_at = 1.day.ago
+ @topic_3.created_at = 1.day.ago
+ @topic_4.created_at = 4.days.ago
+ end
+
+ it "calls out new topics since last visit" do
+ visit forum_path(forum)
+ new_topics = Nokogiri::HTML(page.body).css(".topics tbody tr super")
+ new_topics.size.should eq(3)
+ end
+
+ it "doesn't call out a topic that has been viewed" do
+ visit forum_path(forum)
+ visit forum_topic_path(forum, @topic_1)
+ visit forum_path(forum)
+ new_topics = Nokogiri::HTML(page.body).css(".topics tbody tr super")
+ new_topics.size.should eq(2)
+ end
+ end
end
end
end
Something went wrong with that request. Please try again.