diff --git a/app/assets/stylesheets/application/utilities.css b/app/assets/stylesheets/application/utilities.css index 0e72774c..b8883017 100644 --- a/app/assets/stylesheets/application/utilities.css +++ b/app/assets/stylesheets/application/utilities.css @@ -30,6 +30,7 @@ .txt-tight-lines { line-height: 1.2; } .txt-normal { font-weight: 400; font-style: normal; } .txt-medium { font-weight: 500; } +.fw-800 { font-weight: 800; } .txt-nowrap { white-space: nowrap; } .inline { display: inline } diff --git a/app/models/rooms/thread.rb b/app/models/rooms/thread.rb index 5fdf1041..2de90e9b 100644 --- a/app/models/rooms/thread.rb +++ b/app/models/rooms/thread.rb @@ -9,4 +9,39 @@ def default_involvement(user: nil) "invisible" end end + + # Check if a user is participating in this thread + # A user participates if they: + # - Created the parent message (the original message being threaded) + # - Created the thread (first commenter) + # - Have a visible membership (not "invisible" involvement) + # - Were mentioned in the thread (which gives them "mentions" involvement) + def participating?(user) + return false unless user + + user_id = user.id + + # Parent message creator is always a participant + return true if parent_message&.creator_id == user_id + + # Thread creator is always a participant + return true if creator_id == user_id + + # Check if user has a visible membership (not "invisible") + membership = memberships.active.find_by(user_id: user_id) + return false unless membership + + # User is participating if they have a visible involvement (not "invisible") + membership.involved_in_invisible? ? false : true + end + + # Check if a participating user has unread messages in this thread + def unread_for_participating?(user) + return false unless user + + membership = memberships.active.find_by(user_id: user.id) + return false unless membership + + membership.unread? + end end diff --git a/app/views/messages/_threads.html.erb b/app/views/messages/_threads.html.erb index 7900a85a..e9f731f7 100644 --- a/app/views/messages/_threads.html.erb +++ b/app/views/messages/_threads.html.erb @@ -11,6 +11,8 @@ <% participants = User.where(id: participant_users).index_by(&:id) %> <% ordered_participants = participant_users.map { |id| participants[id] }.compact %> <% reply_count = thread.messages_count || thread.messages.active.count %> + <% is_participating = thread.participating?(Current.user) %> + <% has_unread = is_participating && thread.unread_for_participating?(Current.user) %> <%= link_to room_path(thread), class: "thread__link flex-inline align-center gap", data: { turbo_frame: "_top", updated_at: thread.last_active_at.iso8601 } do %>