diff --git a/app/controllers/forem/forums_controller.rb b/app/controllers/forem/forums_controller.rb
index 96e392bd6..4237ac953 100644
--- a/app/controllers/forem/forums_controller.rb
+++ b/app/controllers/forem/forums_controller.rb
@@ -10,6 +10,7 @@ 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
diff --git a/app/helpers/forem/topics_helper.rb b/app/helpers/forem/topics_helper.rb
index 9356b496d..5f85595db 100644
--- a/app/helpers/forem/topics_helper.rb
+++ b/app/helpers/forem/topics_helper.rb
@@ -7,12 +7,11 @@ def link_to_latest_post(post)
def new_since_last_view_text(topic)
if forem_user
- # hasn't been viewed and was created within 15 minutes of last forum view
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.viewed_at) < 15.minutes
+ if topic_view.nil? && topic.created_at > forum_view.past_viewed_at
content_tag :super, "New"
end
end
diff --git a/app/models/forem/concerns/viewable.rb b/app/models/forem/concerns/viewable.rb
index 796c36936..b5875d0dc 100644
--- a/app/models/forem/concerns/viewable.rb
+++ b/app/models/forem/concerns/viewable.rb
@@ -18,6 +18,14 @@ 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
diff --git a/app/models/forem/view.rb b/app/models/forem/view.rb
index 69a60dec8..615b99848 100644
--- a/app/models/forem/view.rb
+++ b/app/models/forem/view.rb
@@ -1,5 +1,7 @@
module Forem
class View < ActiveRecord::Base
+ before_create :set_viewed_at_to_now
+
belongs_to :viewable, :polymorphic => true
belongs_to :user, :class_name => Forem.user_class.to_s
@@ -9,5 +11,11 @@ class View < ActiveRecord::Base
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
diff --git a/app/views/forem/topics/_topic.html.erb b/app/views/forem/topics/_topic.html.erb
index 261044296..cc88ef602 100644
--- a/app/views/forem/topics/_topic.html.erb
+++ b/app/views/forem/topics/_topic.html.erb
@@ -21,5 +21,5 @@
<%= link_to_latest_post(topic.posts.by_created_at.last) -%>
<%= topic.posts.count %> |
- <%= topic.views.sum(:count) %> |
+ <%= topic.views_count %> |
diff --git a/db/migrate/20120302152918_add_forem_view_fields.rb b/db/migrate/20120302152918_add_forem_view_fields.rb
new file mode 100644
index 000000000..7f7a052fb
--- /dev/null
+++ b/db/migrate/20120302152918_add_forem_view_fields.rb
@@ -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
diff --git a/spec/requests/2 b/spec/requests/2
new file mode 100644
index 000000000..9da3efccf
--- /dev/null
+++ b/spec/requests/2
@@ -0,0 +1,71 @@
+require 'spec_helper'
+
+describe "forums" do
+ let!(:forum) { FactoryGirl.create(:forum) }
+
+ it "listing all" do
+ visit forums_path
+ within(".forum") do
+ page.should have_content("Welcome to Forem!")
+ within(".description") do
+ page.should have_content("A placeholder forum.")
+ end
+ end
+ end
+
+ context "visiting a forum" do
+ before do
+ @topic_1 = FactoryGirl.create(:topic, :subject => "Unpinned", :forum => forum)
+ @topic_2 = FactoryGirl.create(:topic, :subject => "Most Recent", :forum => forum)
+ FactoryGirl.create(:post, :topic => @topic_2, :created_at => Time.now + 30.seconds)
+ @topic_3 = FactoryGirl.create(:topic, :subject => "PINNED!", :forum => forum, :pinned => true)
+ @topic_4 = FactoryGirl.create(:topic, :subject => "HIDDEN!", :forum => forum, :hidden => true)
+ visit forum_path(forum)
+ end
+
+ it "lists pinned topics first" do
+ # TODO: cleaner way to get at topic subjects on the page?
+ topic_subjects = Nokogiri::HTML(page.body).css(".topics tbody tr .subject").map(&:text)
+ topic_subjects.should == ["PINNED!", "Most Recent", "Unpinned"]
+ end
+
+ it "does not show hidden topics" do
+ # TODO: cleaner way to get at topic subjects on the page?
+ topic_subjects = Nokogiri::HTML(page.body).css(".topics tbody tr .subject").map(&:text)
+ topic_subjects.include?("HIDDEN!").should be_false
+ end
+
+ context "when logged in" do
+ before do
+ @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)
+ ::Forem::View.last.update_attribute(:updated_at, 1.minute.ago)
+ visit forum_path(forum)
+ topic_subjects = Nokogiri::HTML(page.body).css(".topics tbody tr .new_posts")
+ topic_subjects.should_not be_empty
+ end
+
+ it "calls out new topics since last visit" do
+ forum.topics.clear
+ forum.register_view_by(@user)
+ forum.view_for(@user).update_attribute(:updated_at, 3.days.ago)
+
+ new_topic = FactoryGirl.create(:topic, :subject => "New Since Visit", :forum => forum, :created_at=>1.day.ago)
+ old_topic = FactoryGirl.create(:topic, :subject => "Already Viewed", :forum => forum, :created_at=>4.day.ago)
+
+ visit forum_path(forum)
+ new_topics = Nokogiri::HTML(page.body).css(".topics tbody tr super")
+ new_topics.size.should eq(1) # should include the one just created
+
+ visit forum_topic_path(forum, topic)
+
+ visit forum_path(forum)
+ new_topics = Nokogiri::HTML(page.body).css(".topics tbody tr super")
+ new_topics.size.should eq(3) # should include the one just created
+ end
+ end
+ end
+end
diff --git a/spec/requests/forums_spec.rb b/spec/requests/forums_spec.rb
index 4e0812540..38f0e55a3 100644
--- a/spec/requests/forums_spec.rb
+++ b/spec/requests/forums_spec.rb
@@ -48,14 +48,29 @@
topic_subjects.should_not be_empty
end
- it "calls out new topics since last visit" do
- forum.register_view_by(@user)
- forum.view_for(@user).update_attribute(:updated_at, 3.days.ago)
- FactoryGirl.create(:topic, :subject => "New Since Visit", :forum => forum, :created_at=>1.day.ago)
+ 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
- visit forum_path(forum)
- new_topics = Nokogiri::HTML(page.body).css(".topics tbody tr super")
- new_topics.size.should eq(4) # should include the one just created
+ 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