Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions app/controllers/messages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@ def index(list_name: nil, yyyymm: nil, q: nil, page: nil)
if list_name
@list = List.find_by_name list_name

@yyyymms = Message.where(list_id: @list).order('yyyymm').pluck(Arel.sql "distinct to_char(published_at, 'YYYYMM') as yyyymm")
@yyyymm = yyyymm || @yyyymms.last

root_query = Message.where(list_id: @list, parent_id: nil).where("to_char(published_at, 'YYYYMM') = ?", @yyyymm).order(:id)
messages = Message.with_recursive(parent_and_children: [root_query, Message.joins('inner join parent_and_children on messages.parent_id = parent_and_children.id')])
.joins('inner join parent_and_children on parent_and_children.id = messages.id')

@messages = compose_tree(messages)
render_threads yyyymm: yyyymm
elsif q
search q, page

Expand All @@ -29,10 +22,28 @@ def index(list_name: nil, yyyymm: nil, q: nil, page: nil)
def show(list_name:, list_seq:)
@list = List.find_by_name(list_name)
@message = Message.find_by!(list_id: @list, list_seq: list_seq)

# If this is a turbo frame request, just render the message
return if turbo_frame_request?

render_threads yyyymm: @message.published_at.strftime('%Y%m')
end

private

def render_threads(yyyymm: nil)
@yyyymms = Message.where(list_id: @list).order('yyyymm').pluck(Arel.sql "distinct to_char(published_at, 'YYYYMM') as yyyymm")
@yyyymm = yyyymm || @yyyymms.last

root_query = Message.where(list_id: @list, parent_id: nil).where("to_char(published_at, 'YYYYMM') = ?", @yyyymm).order(:id)
messages = Message.with_recursive(parent_and_children: [root_query, Message.joins('inner join parent_and_children on messages.parent_id = parent_and_children.id')])
.joins('inner join parent_and_children on parent_and_children.id = messages.id')

@messages = compose_tree(messages)

render :index
end

def get_list_ids(params)
list_ids = []
['ruby-talk', 'ruby-core', 'ruby-list', 'ruby-dev'].each do |name|
Expand Down
10 changes: 10 additions & 0 deletions app/javascript/controllers/message_list_controller.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
connect() {
// Scroll to selected message on page load, with a delay to ensure threads are expanded
setTimeout(() => {
const selected = this.element.querySelector('.message-selected')
if (selected) {
selected.scrollIntoView({behavior: 'smooth', block: 'center'})
}
}, 100)
}

select(event) {
// Remove highlight from previously selected message
const previousSelected = this.element.querySelector('.message-selected')
Expand Down
12 changes: 10 additions & 2 deletions app/javascript/controllers/thread_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,17 @@ export default class extends Controller {
static targets = ["children", "icon"]

connect() {
// Initially hide children
// Initially hide children unless one is selected
if (this.hasChildrenTarget) {
this.childrenTarget.classList.add("hidden")
const hasSelectedChild = this.childrenTarget.querySelector('.message-selected')
if (hasSelectedChild) {
// Keep expanded and rotate icon
if (this.hasIconTarget) {
this.iconTarget.classList.add("rotate-90")
}
} else {
this.childrenTarget.classList.add("hidden")
}
}
}

Expand Down
5 changes: 3 additions & 2 deletions app/views/messages/_thread.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<div class="thread-message" style="margin-left: <%= depth * 6 %>px;" <% if (depth == 0) && message.children&.any? %>data-controller="thread"<% end %>>
<% selected = defined?(@message) && @message&.id == message.id %>
<% if depth == 0 %>
<%= link_to [list, message], class: 'message-item block bg-white dark:bg-gray-800 rounded-lg shadow-md border border-gray-200 dark:border-gray-700 overflow-hidden hover:shadow-lg transition-shadow', data: {turbo_frame: 'message_content', turbo_action: 'advance', action: 'click->message-list#select'} do %>
<%= link_to [list, message], class: "message-item block bg-white dark:bg-gray-800 rounded-lg shadow-md border border-gray-200 dark:border-gray-700 overflow-hidden hover:shadow-lg transition-shadow#{' message-selected' if selected}", data: {turbo_frame: 'message_content', turbo_action: 'advance', action: 'click->message-list#select'} do %>
<div class="p-5">
<div class="flex items-start justify-between gap-4">
<div class="flex-1 min-w-0">
Expand Down Expand Up @@ -35,7 +36,7 @@
</div>
<% end %>
<% else %>
<%= link_to [list, message], class: 'message-item block py-2 border-l-2 border-gray-200 dark:border-gray-700 pl-4 hover:border-red-400 dark:hover:border-red-500 transition-colors', data: {turbo_frame: 'message_content', turbo_action: 'advance', action: 'click->message-list#select'} do %>
<%= link_to [list, message], class: "message-item block py-2 border-l-2 border-gray-200 dark:border-gray-700 pl-4 hover:border-red-400 dark:hover:border-red-500 transition-colors#{' message-selected' if selected}", data: {turbo_frame: 'message_content', turbo_action: 'advance', action: 'click->message-list#select'} do %>
<div class="flex items-start gap-2 text-sm">
<svg class="w-4 h-4 text-gray-400 dark:text-gray-500 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6"></path>
Expand Down
18 changes: 11 additions & 7 deletions app/views/messages/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,18 @@

<div class="col-span-3 overflow-y-auto">
<%= turbo_frame_tag "message_content", class: "block" do %>
<div class="flex items-center justify-center h-full text-gray-400 dark:text-gray-500">
<div class="text-center">
<svg class="w-16 h-16 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>
</svg>
<p>Select a message to view</p>
<% if @message %>
<%= render @message %>
<% else %>
<div class="flex items-center justify-center h-full text-gray-400 dark:text-gray-500">
<div class="text-center">
<svg class="w-16 h-16 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>
</svg>
<p>Select a message to view</p>
</div>
</div>
</div>
<% end %>
<% end %>
</div>
</div>