Skip to content

Commit 3206b94

Browse files
committed
In the actual thread view, the row background of a participant in the sidebar navigates to that person’s latest reply while the name (and avatar) remain profile links
Signed-off-by: Kai Wagner <kai.wagner@percona.com>
1 parent b3a28a9 commit 3206b94

5 files changed

Lines changed: 55 additions & 3 deletions

File tree

app/assets/stylesheets/components/messages.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
border: var(--border-width) solid var(--color-border);
1212
border-radius: var(--border-radius-lg);
1313
overflow: hidden;
14-
scroll-margin-top: 90px;
14+
scroll-margin-top: calc(var(--nav-height) + var(--spacing-4));
1515
}
1616

1717
.threaded .reply-message {
@@ -207,6 +207,7 @@
207207
height: 0;
208208
width: 0;
209209
overflow: hidden;
210+
scroll-margin-top: calc(var(--nav-height) + var(--spacing-4));
210211
}
211212

212213
& .inline-reference {

app/assets/stylesheets/layouts/topic-view.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@
104104
}
105105
}
106106

107+
.participant-row.is-clickable {
108+
cursor: pointer;
109+
}
110+
111+
.participant-row.is-clickable:focus-visible {
112+
outline: 2px solid var(--color-border-focus);
113+
outline-offset: 2px;
114+
}
115+
107116
.participant-left {
108117
display: flex;
109118
align-items: center;

app/controllers/topics_controller.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,14 @@ def set_topic
334334
end
335335

336336
def build_participants_sidebar_data(_messages_scope)
337+
latest_by_person = Message
338+
.where(topic_id: @topic.id)
339+
.select("DISTINCT ON (messages.sender_person_id) messages.sender_person_id, messages.id, messages.created_at")
340+
.order("messages.sender_person_id, messages.created_at DESC")
341+
latest_message_ids = latest_by_person.each_with_object({}) do |row, hash|
342+
hash[row.sender_person_id] = row.id
343+
end
344+
337345
participants = @topic.topic_participants
338346
.includes(person: [ :default_alias, :contributor_memberships ])
339347
.order(message_count: :desc, first_message_at: :asc)
@@ -347,7 +355,8 @@ def build_participants_sidebar_data(_messages_scope)
347355
person: tp.person,
348356
message_count: tp.message_count,
349357
first_at: tp.first_message_at,
350-
last_at: tp.last_message_at
358+
last_at: tp.last_message_at,
359+
last_message_id: latest_message_ids[tp.person_id]
351360
}
352361
end.compact
353362
end

app/helpers/topics_helper.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,20 @@ def participant_row_html(participant:, avatar_size: 40, tooltip: nil)
5151
end
5252
end
5353

54-
tag.div(class: "participant-row", title: tooltip) do
54+
last_message_id = participant[:last_message_id]
55+
row_classes = [ "participant-row" ]
56+
row_data = {}
57+
row_attrs = { title: tooltip }
58+
if last_message_id
59+
row_classes << "is-clickable"
60+
row_data[:controller] = "participant-row"
61+
row_data[:participant_row_url_value] = "#message-#{last_message_id}"
62+
row_data[:action] = "click->participant-row#navigate keydown->participant-row#keyNavigate"
63+
row_attrs[:role] = "link"
64+
row_attrs[:tabindex] = 0
65+
end
66+
67+
tag.div(class: row_classes.join(" "), data: row_data, **row_attrs) do
5568
safe_join([ left, memberships ].compact)
5669
end
5770
end
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Controller } from "@hotwired/stimulus"
2+
3+
export default class extends Controller {
4+
static values = { url: String }
5+
6+
navigate(event) {
7+
if (!this.hasUrlValue) return
8+
if (event.target.closest("a")) return
9+
window.location.assign(this.urlValue)
10+
}
11+
12+
keyNavigate(event) {
13+
if (!this.hasUrlValue) return
14+
if (event.target.closest("a")) return
15+
if (event.key === "Enter" || event.key === " ") {
16+
event.preventDefault()
17+
window.location.assign(this.urlValue)
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)