From 8419d21c4cc0a4fa434aeb8159bc2277e24e280f Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sat, 25 Oct 2025 01:50:45 +0900 Subject: [PATCH 1/4] Preview line for each message --- app/decorators/message_decorator.rb | 4 ++++ app/views/messages/_thread.html.erb | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/app/decorators/message_decorator.rb b/app/decorators/message_decorator.rb index 51f008c..4632b55 100644 --- a/app/decorators/message_decorator.rb +++ b/app/decorators/message_decorator.rb @@ -4,4 +4,8 @@ module MessageDecorator def from super&.gsub(/@[a-zA-Z.\-]+/, '@...') end + + def first_line + body.lines.first&.strip + end end diff --git a/app/views/messages/_thread.html.erb b/app/views/messages/_thread.html.erb index 1655865..1f22870 100644 --- a/app/views/messages/_thread.html.erb +++ b/app/views/messages/_thread.html.erb @@ -14,6 +14,9 @@ <%= link_to without_list_prefix(message.subject), "/#{list.name}/#{message.list_seq}", data: {turbo_frame: 'message_content'} %> — <%= message.from %> + <% if message.body.present? %> +

<%= message.first_line %>

+ <% end %>
@@ -37,6 +40,9 @@ [#<%= message.list_seq %>] <%= without_list_prefix(message.subject) %> <% end %> — <%= message.from %> + <% if message.body.present? %> +

<%= message.first_line %>

+ <% end %>
From 4264e07d2b21067b920e6d5073b018306e609ab0 Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sat, 25 Oct 2025 02:14:26 +0900 Subject: [PATCH 2/4] Highlight the selected message on the left pane --- app/assets/stylesheets/application.css | 10 ++++++++++ .../controllers/message_list_controller.js | 17 +++++++++++++++++ app/views/messages/_thread.html.erb | 15 +++++++-------- app/views/messages/index.html.erb | 2 +- 4 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 app/javascript/controllers/message_list_controller.js diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 288b9ab..f6ae8a9 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -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; + } +} diff --git a/app/javascript/controllers/message_list_controller.js b/app/javascript/controllers/message_list_controller.js new file mode 100644 index 0000000..06c9253 --- /dev/null +++ b/app/javascript/controllers/message_list_controller.js @@ -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') + } + } +} diff --git a/app/views/messages/_thread.html.erb b/app/views/messages/_thread.html.erb index 1f22870..92b9029 100644 --- a/app/views/messages/_thread.html.erb +++ b/app/views/messages/_thread.html.erb @@ -1,6 +1,6 @@
data-controller="thread"<% end %>> <% if depth == 0 %> -
+ <%= 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', action: 'click->message-list#select'} do %>
@@ -10,8 +10,7 @@ <% end %> - [#<%= message.list_seq %>] - <%= link_to without_list_prefix(message.subject), "/#{list.name}/#{message.list_seq}", data: {turbo_frame: 'message_content'} %> + [#<%= message.list_seq %>] <%= without_list_prefix(message.subject) %> — <%= message.from %> <% if message.body.present? %> @@ -28,24 +27,24 @@
-
+ <% end %> <% else %> -
+ <%= 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', action: 'click->message-list#select'} do %>
- <%= 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 %> + [#<%= message.list_seq %>] <%= without_list_prefix(message.subject) %> - <% end %> + — <%= message.from %> <% if message.body.present? %>

<%= message.first_line %>

<% end %>
-
+ <% end %> <% end %> <% if message.children&.any? %> diff --git a/app/views/messages/index.html.erb b/app/views/messages/index.html.erb index 7990fe0..e5b2ecb 100644 --- a/app/views/messages/index.html.erb +++ b/app/views/messages/index.html.erb @@ -11,7 +11,7 @@

Mailing list archive

-
+
<%= render partial: 'thread', collection: @messages, as: :message, locals: {list: @list, depth: 0} %>
From 7f735cbadd5b1bfa26771e7449c84c7343e8b902 Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sat, 25 Oct 2025 02:22:27 +0900 Subject: [PATCH 3/4] Show each message's published date --- app/decorators/message_decorator.rb | 4 ++++ app/views/messages/_thread.html.erb | 7 +++++++ test/fixtures/messages.yml | 2 ++ 3 files changed, 13 insertions(+) diff --git a/app/decorators/message_decorator.rb b/app/decorators/message_decorator.rb index 4632b55..01fad73 100644 --- a/app/decorators/message_decorator.rb +++ b/app/decorators/message_decorator.rb @@ -8,4 +8,8 @@ def from def first_line body.lines.first&.strip end + + def published_date + published_at.strftime('%Y/%m/%d') + end end diff --git a/app/views/messages/_thread.html.erb b/app/views/messages/_thread.html.erb index 92b9029..a527f2e 100644 --- a/app/views/messages/_thread.html.erb +++ b/app/views/messages/_thread.html.erb @@ -23,6 +23,12 @@ <%= count = message.count_recursively %> <%= count == 1 ? 'message' : 'messages' %> + + + + + <%= message.published_date %> +
@@ -39,6 +45,7 @@ [#<%= message.list_seq %>] <%= without_list_prefix(message.subject) %> — <%= message.from %> + <%= message.published_date %> <% if message.body.present? %>

<%= message.first_line %>

<% end %> diff --git a/test/fixtures/messages.yml b/test/fixtures/messages.yml index 426b835..853db18 100644 --- a/test/fixtures/messages.yml +++ b/test/fixtures/messages.yml @@ -6,6 +6,7 @@ message1: body: Body1 list_id: 1 list_seq: 123 + published_at: 1995-12-21 05:44:05 message2: subject: Mail2 @@ -13,3 +14,4 @@ message2: body: Body2 list_id: 2 list_seq: 234 + published_at: 1997-07-28 14:51:40 From d8b58b2ae8fa0f9c8604b56dd818247aa315343b Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sat, 25 Oct 2025 02:47:00 +0900 Subject: [PATCH 4/4] Advance the browser address bar URL to the chosen message --- app/views/messages/_thread.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/messages/_thread.html.erb b/app/views/messages/_thread.html.erb index a527f2e..64c8f5e 100644 --- a/app/views/messages/_thread.html.erb +++ b/app/views/messages/_thread.html.erb @@ -1,6 +1,6 @@
data-controller="thread"<% end %>> <% if depth == 0 %> - <%= 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', action: 'click->message-list#select'} do %> + <%= 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 %>
@@ -35,7 +35,7 @@
<% end %> <% else %> - <%= 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', action: 'click->message-list#select'} do %> + <%= 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 %>