From 843888c0871722a4018c2a21c352fa775b83844e Mon Sep 17 00:00:00 2001 From: moozzi Date: Tue, 25 Aug 2026 13:30:30 +0200 Subject: [PATCH 1/2] Mark activities as read only when you click on it Rigth now all activities are being marked as `read` when we visit `/activities`. This patch changes it so activity is marked as `read` only when we click on it or when we use `Mark all read` button. --- app/controllers/activities_controller.rb | 24 +++++++++++++++++------- app/views/activities/index.html.slim | 4 ++-- config/routes.rb | 1 + 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/app/controllers/activities_controller.rb b/app/controllers/activities_controller.rb index 0ca020e4..b49852d2 100644 --- a/app/controllers/activities_controller.rb +++ b/app/controllers/activities_controller.rb @@ -10,7 +10,6 @@ def index .includes(subject: [ :topic, { message: :sender } ]) .order(created_at: :desc) .limit(100) - mark_shown_as_read!(@activities) @unread_count = base_scope.unread.count end @@ -19,8 +18,25 @@ def mark_all_read redirect_to activities_path, notice: "Marked all as read" end + def read + activity = base_scope.find(params[:id]) + activity.mark_read! if activity.read_at.nil? + redirect_to path_for_subject(activity.subject) + end + private + def path_for_subject(subject) + case subject + when Note + topic_path(subject.topic, anchor: subject.message_id ? helpers.message_dom_id(subject.message) : "thread-notes") + when Message + topic_path(subject.topic, anchor: helpers.message_dom_id(subject)) + else + activities_path + end + end + def base_scope current_user.activities.visible end @@ -36,10 +52,4 @@ def apply_query(scope) Activity.from("(#{note_query.to_sql} UNION #{message_query.to_sql}) AS activities") end - - def mark_shown_as_read!(activities) - unread_ids = activities.select { |a| a.read_at.nil? }.map(&:id) - return if unread_ids.empty? - Activity.where(id: unread_ids).update_all(read_at: Time.current) - end end diff --git a/app/views/activities/index.html.slim b/app/views/activities/index.html.slim index 42769fd9..014c950c 100644 --- a/app/views/activities/index.html.slim +++ b/app/views/activities/index.html.slim @@ -24,7 +24,7 @@ - if subject.is_a?(Note) .activity-body .activity-title - = link_to(subject.topic.title, topic_path(subject.topic, anchor: subject.message_id ? message_dom_id(subject.message) : "thread-notes")) + = link_to subject.topic.title, read_activity_path(activity), data: { turbo_method: :post } .activity-snippet = truncate(subject.body, length: 160) - if subject.note_tags.any? .activity-tags @@ -36,7 +36,7 @@ - elsif subject.is_a?(Message) .activity-body .activity-title - = link_to(subject.topic.title, topic_path(subject.topic, anchor: message_dom_id(subject))) + = link_to subject.topic.title, read_activity_path(activity), data: { turbo_method: :post } .activity-snippet strong> = subject.subject = truncate(subject.body, length: 140) diff --git a/config/routes.rb b/config/routes.rb index c7bb766f..d1499b25 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -100,6 +100,7 @@ end resources :activities, only: [ :index ] do post :mark_all_read, on: :collection + post :read, on: :member end resources :notes, only: [ :create, :update, :destroy ] resources :note_mentions, only: [ :destroy ] From bbebbebab83c886fb34a5954b9d1687f6aa5ba6e Mon Sep 17 00:00:00 2001 From: moozzi Date: Wed, 2 Sep 2026 14:37:57 +0200 Subject: [PATCH 2/2] Use `GET` instead of `POST` and mark all related activities on read --- app/controllers/activities_controller.rb | 3 ++- app/models/activity.rb | 4 ++++ app/views/activities/index.html.slim | 4 ++-- config/routes.rb | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/controllers/activities_controller.rb b/app/controllers/activities_controller.rb index b49852d2..f8f01724 100644 --- a/app/controllers/activities_controller.rb +++ b/app/controllers/activities_controller.rb @@ -20,7 +20,8 @@ def mark_all_read def read activity = base_scope.find(params[:id]) - activity.mark_read! if activity.read_at.nil? + related_activities = base_scope.where(subject: activity.subject) + related_activities.mark_all_as_read! redirect_to path_for_subject(activity.subject) end diff --git a/app/models/activity.rb b/app/models/activity.rb index b01dee3b..52e7377f 100644 --- a/app/models/activity.rb +++ b/app/models/activity.rb @@ -8,4 +8,8 @@ class Activity < ApplicationRecord def mark_read! update!(read_at: Time.current) end + + def self.mark_all_as_read! + self.where(read_at: nil).update_all(read_at: Time.current) + end end diff --git a/app/views/activities/index.html.slim b/app/views/activities/index.html.slim index 014c950c..6edb2c06 100644 --- a/app/views/activities/index.html.slim +++ b/app/views/activities/index.html.slim @@ -24,7 +24,7 @@ - if subject.is_a?(Note) .activity-body .activity-title - = link_to subject.topic.title, read_activity_path(activity), data: { turbo_method: :post } + = link_to subject.topic.title, read_activity_path(activity) .activity-snippet = truncate(subject.body, length: 160) - if subject.note_tags.any? .activity-tags @@ -36,7 +36,7 @@ - elsif subject.is_a?(Message) .activity-body .activity-title - = link_to subject.topic.title, read_activity_path(activity), data: { turbo_method: :post } + = link_to subject.topic.title, read_activity_path(activity) .activity-snippet strong> = subject.subject = truncate(subject.body, length: 140) diff --git a/config/routes.rb b/config/routes.rb index d1499b25..d76bdf96 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -100,7 +100,7 @@ end resources :activities, only: [ :index ] do post :mark_all_read, on: :collection - post :read, on: :member + get :read, on: :member end resources :notes, only: [ :create, :update, :destroy ] resources :note_mentions, only: [ :destroy ]