diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 093b80c4f0ef108962d4c1fd003bdbee8f40fe10..57894f2975b0c1d682fcaecaecfee7398ab11188 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -4,7 +4,7 @@ class CommentsController < ApplicationController before_action :set_comment, only: [:update, :destroy, :undelete, :show] before_action :set_thread, only: [:thread, :thread_rename, :thread_restrict, :thread_unrestrict, :thread_followers] before_action :check_privilege, only: [:update, :destroy, :undelete] - before_action :check_if_target_post_locked, only: [:create] + before_action :check_if_target_post_locked, only: [:create, :post_follow] before_action :check_if_parent_post_locked, only: [:update, :destroy] def create_thread @@ -40,9 +40,16 @@ class CommentsController < ApplicationController end if success + notification = "New comment thread on #{@comment.root.title}: #{@comment_thread.title}" unless @comment.post.user == current_user - @comment.post.user.create_notification("New comment thread on #{@comment.root.title}: #{@comment_thread.title}", - helpers.comment_link(@comment)) + @comment.post.user.create_notification(notification, helpers.comment_link(@comment)) + end + + ThreadFollower.where(post: @post).each do |tf| + unless tf.user == current_user || tf.user == @comment.post.user + tf.user.create_notification(notification, helpers.comment_link(@comment)) + end + ThreadFollower.create(user: tf.user, comment_thread: @comment_thread) end apply_pings pings @@ -245,6 +252,16 @@ class CommentsController < ApplicationController end end + def post_follow + @post = Post.find(params[:post_id]) + if CommentThread.post_followed?(@post, current_user) + ThreadFollower.where(post: @post, user: current_user).destroy_all + else + ThreadFollower.create(post: @post, user: current_user) + end + redirect_to post_path(@post) + end + def pingable thread = params[:id] == '-1' ? CommentThread.new(post_id: params[:post]) : CommentThread.find(params[:id]) ids = helpers.get_pingable(thread) diff --git a/app/models/comment_thread.rb b/app/models/comment_thread.rb index c4ec2b8e28372b081d690b4fc6eb61c2f4054793..39f5dcf5c81dff6caf17cedb3700eebb5e43882d 100644 --- a/app/models/comment_thread.rb +++ b/app/models/comment_thread.rb @@ -32,6 +32,10 @@ class CommentThread < ApplicationRecord post.can_access?(user) end + def self.post_followed?(post, user) + ThreadFollower.where(post: post, user: user).any? + end + private # Comment author and post author are automatically followed to the thread. Question author is NOT diff --git a/app/models/thread_follower.rb b/app/models/thread_follower.rb index 2f66a4842c2871d093a148a315316ed9bf7e12b2..426e1f39430bd6444c213aa78bd36365b73be9ce 100644 --- a/app/models/thread_follower.rb +++ b/app/models/thread_follower.rb @@ -1,4 +1,15 @@ class ThreadFollower < ApplicationRecord - belongs_to :comment_thread + belongs_to :comment_thread, optional: true + belongs_to :post, optional: true belongs_to :user + + validate :thread_or_post + + private + + def thread_or_post + if comment_thread.nil? && post.nil? + errors.add(:base, 'Must refer to either a comment thread or a post.') + end + end end diff --git a/app/views/posts/_expanded.html.erb b/app/views/posts/_expanded.html.erb index e4acfdacfae9734f1fe22ae3cea9bf5de85250ff..82733701ff6fe23351d0afc933a5368438a71292 100644 --- a/app/views/posts/_expanded.html.erb +++ b/app/views/posts/_expanded.html.erb @@ -455,6 +455,21 @@ <h4 class="has-margin-0"> <%= pluralize(public_count, 'comment thread') %> </h4> + <% if user_signed_in? %> + <p class="has-font-size-caption"> + <% if CommentThread.post_followed?(post, current_user) %> + <%= link_to follow_post_comments_path(post_id: post.id), method: :post, + title: 'Don\'t follow new comment threads on this post' do %> + <i class="fas fa-fw fa-minus"></i> unfollow new + <% end %> + <% else %> + <%= link_to follow_post_comments_path(post_id: post.id), method: :post, + title: 'Follow all new comment threads on this post' do %> + <i class="fas fa-fw fa-plus"></i> follow new + <% end %> + <% end %> + </p> + <% end %> <div class="post--comments-container"> <%= render 'comments/post', comment_threads: comment_threads.first(5) %> </div> diff --git a/config/routes.rb b/config/routes.rb index 694164c6de56abfc142cac41545eee02815b9a05..1619878ee6deb23be1a87ae8baa0a443e36fddaf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -210,6 +210,7 @@ Rails.application.routes.draw do post 'thread/:id/unrestrict', to: 'comments#thread_unrestrict', as: :unrestrict_comment_thread get 'thread/:id/followers', to: 'comments#thread_followers', as: :comment_thread_followers get 'post/:post_id', to: 'comments#post', as: :post_comments + post 'post/:post_id/follow', to: 'comments#post_follow', as: :follow_post_comments get ':id', to: 'comments#show', as: :comment get 'thread/:id', to: 'comments#thread', as: :comment_thread post ':id/edit', to: 'comments#update', as: :update_comment diff --git a/db/migrate/20220913183826_add_post_to_thread_followers.rb b/db/migrate/20220913183826_add_post_to_thread_followers.rb new file mode 100644 index 0000000000000000000000000000000000000000..e24e77b652fb4c73a5fef63cba4f0aba0be13ef8 --- /dev/null +++ b/db/migrate/20220913183826_add_post_to_thread_followers.rb @@ -0,0 +1,6 @@ +class AddPostToThreadFollowers < ActiveRecord::Migration[7.0] + def change + add_reference :thread_followers, :post, null: true, foreign_key: true + change_column_null :thread_followers, :comment_thread_id, true + end +end diff --git a/db/schema.rb b/db/schema.rb index ba718100ce390c0d37728cf0b27c304e798b7dd0..9cc021c6d809687d863c2571e039cb81160d2a2f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2022_09_03_174045) do +ActiveRecord::Schema[7.0].define(version: 2022_09_13_183826) do create_table "abilities", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.bigint "community_id" t.string "name" @@ -614,7 +614,9 @@ ActiveRecord::Schema[7.0].define(version: 2022_09_03_174045) do t.bigint "user_id" t.datetime "created_at", precision: nil, null: false t.datetime "updated_at", precision: nil, null: false + t.bigint "post_id" t.index ["comment_thread_id"], name: "index_thread_followers_on_comment_thread_id" + t.index ["post_id"], name: "index_thread_followers_on_post_id" t.index ["user_id"], name: "index_thread_followers_on_user_id" end @@ -761,6 +763,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_09_03_174045) do add_foreign_key "suggested_edits", "users", column: "decided_by_id" add_foreign_key "tags", "communities" add_foreign_key "tags", "tags", column: "parent_id" + add_foreign_key "thread_followers", "posts" add_foreign_key "user_abilities", "abilities" add_foreign_key "user_abilities", "community_users" add_foreign_key "users", "users", column: "deleted_by_id"