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
10 changes: 10 additions & 0 deletions app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,13 @@
*= require_tree .
*= require_self
*/

.message-selected {
background-color: oklch(98.5% 0.002 247.839) !important;
}

@media (prefers-color-scheme: dark) {
.message-selected {
background-color: oklch(40% 0.08 247.839) !important;
}
}
8 changes: 8 additions & 0 deletions app/decorators/message_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,12 @@ module MessageDecorator
def from
super&.gsub(/@[a-zA-Z.\-]+/, '@...')
end

def first_line
body.lines.first&.strip
end

def published_date
published_at.strftime('%Y/%m/%d')
end
end
17 changes: 17 additions & 0 deletions app/javascript/controllers/message_list_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
select(event) {
// Remove highlight from previously selected message
const previousSelected = this.element.querySelector('.message-selected')
if (previousSelected) {
previousSelected.classList.remove('message-selected')
}

// Add highlight to clicked message
const messageElement = event.currentTarget
if (messageElement) {
messageElement.classList.add('message-selected')
}
}
}
28 changes: 20 additions & 8 deletions app/views/messages/_thread.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="thread-message" style="margin-left: <%= depth * 6 %>px;" <% if (depth == 0) && message.children&.any? %>data-controller="thread"<% end %>>
<% if depth == 0 %>
<div class="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">
<%= link_to "/#{list.name}/#{message.list_seq}", 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 %>
<div class="p-5">
<div class="flex items-start justify-between gap-4">
<div class="flex-1 min-w-0">
Expand All @@ -10,36 +10,48 @@
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
<% end %>
<span class="px-0.5">[#<%= message.list_seq %>]</span>
<%= link_to without_list_prefix(message.subject), "/#{list.name}/#{message.list_seq}", data: {turbo_frame: 'message_content'} %>
<span class="px-0.5">[#<%= message.list_seq %>] <%= without_list_prefix(message.subject) %></span>
<span class="text-sm text-gray-500 dark:text-gray-400 font-normal ml-2">— <%= message.from %></span>
</h2>
<% if message.body.present? %>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-2 line-clamp-1"><%= message.first_line %></p>
<% end %>
<div class="flex items-center gap-3 text-sm text-gray-600 dark:text-gray-400">
<span class="inline-flex items-center gap-1">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"></path>
</svg>
<%= count = message.count_recursively %> <%= count == 1 ? 'message' : 'messages' %>
</span>
<span class="inline-flex items-center gap-1">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<%= message.published_date %>
</span>
</div>
</div>
</div>
</div>
</div>
<% end %>
<% else %>
<div class="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">
<%= link_to "/#{list.name}/#{message.list_seq}", 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 %>
<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>
</svg>
<div class="flex-1 min-w-0">
<%= link_to "/#{list.name}/#{message.list_seq}", class: 'text-gray-900 dark:text-gray-100 hover:text-red-600 dark:hover:text-red-400 transition-colors', data: {turbo_frame: 'message_content'} do %>
<span class="text-gray-900 dark:text-gray-100 hover:text-red-600 dark:hover:text-red-400 transition-colors">
<span class="px-0.5">[#<%= message.list_seq %>] <%= without_list_prefix(message.subject) %></span>
<% end %>
</span>
<span class="text-gray-500 dark:text-gray-400">— <%= message.from %></span>
<span class="text-gray-500 dark:text-gray-400 ml-2"><%= message.published_date %></span>
<% if message.body.present? %>
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1 line-clamp-1"><%= message.first_line %></p>
<% end %>
</div>
</div>
</div>
<% end %>
<% end %>

<% if message.children&.any? %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/messages/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<p class="text-gray-600 dark:text-gray-400 mt-2">Mailing list archive</p>
</div>

<div class="grid grid-cols-4 gap-6" style="height: calc(100vh - 16rem);">
<div class="grid grid-cols-4 gap-6" style="height: calc(100vh - 16rem);" data-controller="message-list">
<div class="col-span-1 overflow-y-auto space-y-6">
<%= render partial: 'thread', collection: @messages, as: :message, locals: {list: @list, depth: 0} %>
</div>
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/messages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ message1:
body: Body1
list_id: 1
list_seq: 123
published_at: 1995-12-21 05:44:05

message2:
subject: Mail2
from: From2
body: Body2
list_id: 2
list_seq: 234
published_at: 1997-07-28 14:51:40