Skip to content

Commit c572ac8

Browse files
authored
Merge pull request #64 from amatsuda/threads
messages#index with thread view
2 parents 8a29b98 + 8e9efb7 commit c572ac8

File tree

15 files changed

+166
-25
lines changed

15 files changed

+166
-25
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,6 @@
3535
/config/master.key
3636

3737
/coverage
38+
39+
/app/assets/builds/*
40+
!/app/assets/builds/.keep

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ gem "turbo-rails"
2424
# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
2525
gem "stimulus-rails"
2626

27+
gem 'tailwindcss-rails'
28+
2729
# Use Redis adapter to run Action Cable in production
2830
# gem "redis", ">= 4.0.1"
2931

Gemfile.lock

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,16 @@ GEM
296296
stimulus-rails (1.3.4)
297297
railties (>= 6.0.0)
298298
stringio (3.1.7)
299+
tailwindcss-rails (4.3.0)
300+
railties (>= 7.0.0)
301+
tailwindcss-ruby (~> 4.0)
302+
tailwindcss-ruby (4.1.13)
303+
tailwindcss-ruby (4.1.13-aarch64-linux-gnu)
304+
tailwindcss-ruby (4.1.13-aarch64-linux-musl)
305+
tailwindcss-ruby (4.1.13-arm64-darwin)
306+
tailwindcss-ruby (4.1.13-x86_64-darwin)
307+
tailwindcss-ruby (4.1.13-x86_64-linux-gnu)
308+
tailwindcss-ruby (4.1.13-x86_64-linux-musl)
299309
thor (1.4.0)
300310
timeout (0.4.3)
301311
tsort (0.2.0)
@@ -353,6 +363,7 @@ DEPENDENCIES
353363
simplecov
354364
sprockets-rails
355365
stimulus-rails
366+
tailwindcss-rails
356367
turbo-rails
357368
tzinfo-data
358369
web-console

Procfile.dev

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
web: bin/rails server
2+
css: bin/rails tailwindcss:watch

app/assets/builds/.keep

Whitespace-only changes.

app/assets/config/manifest.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
//= link_tree ../images
22
//= link_directory ../stylesheets .css
3+
//= link_tree ../builds
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "tailwindcss";

app/controllers/messages_controller.rb

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ class MessagesController < ApplicationController
55
def index
66
if (list_name = params[:list_name])
77
@list = List.find_by_name list_name
8-
@messages = Message.where(list_id: @list.id).order(:id)
8+
9+
messages = Message.with_recursive(parent_and_children: [Message.where(list_id: @list.id, parent_id: nil).order(:id).limit(100), Message.joins('inner join parent_and_children on messages.parent_id = parent_and_children.id')])
10+
.joins('inner join parent_and_children on parent_and_children.id = messages.id')
11+
@messages = compose_tree(messages)
912
elsif (query = params[:q])
1013
search query
1114

@@ -47,4 +50,17 @@ def search(query)
4750
message_where = Message.where('body %> ? AND list_id IN (?)', query, list_ids).order(Arel.sql('body <-> ?', query))
4851
@messages = message_where.offset(page * PER_PAGE).limit(PER_PAGE)
4952
end
53+
54+
def compose_tree(messages)
55+
[].tap do |ret|
56+
messages.each do |m|
57+
if m.parent_id && (parent = messages.detect { it.id == m.parent_id })
58+
(parent.children ||= []) << m
59+
else
60+
ret << m
61+
end
62+
end
63+
ret.sort_by!(&:id)
64+
end
65+
end
5066
end

app/models/message.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ class Message < ApplicationRecord
1010
# https://blade.ruby-lang.org/ruby-talk/410000 is not.
1111
self.skip_time_zone_conversion_for_attributes = [:published_at]
1212

13+
attr_accessor :children
14+
1315
class << self
1416
def from_mail(mail, list, list_seq)
1517
body = Kconv.toutf8 mail.body.raw_source
@@ -33,13 +35,13 @@ def from_mail(mail, list, list_seq)
3335

3436
# mail.in_reply_to returns strange Array object in some cases (?), so let's use the raw value
3537
parent_message_id_header = extract_message_id_from_in_reply_to(mail.header[:in_reply_to]&.value)
36-
parent_message_id = Message.where(message_id_header: parent_message_id_header).pick(:id) if parent_message_id_header
38+
parent_message_id = Message.where(list_id: list.id, message_id_header: parent_message_id_header).pick(:id) if parent_message_id_header
3739
if !parent_message_id && (String === mail.references)
38-
parent_message_id = Message.where(message_id_header: mail.references).pick(:id)
40+
parent_message_id = Message.where(list_id: list.id, message_id_header: mail.references).pick(:id)
3941
end
4042
if !parent_message_id && (Array === mail.references)
4143
mail.references.compact.each do |ref|
42-
break if (parent_message_id = Message.where(message_id_header: ref).pick(:id))
44+
break if (parent_message_id = Message.where(list_id: list.id, message_id_header: ref).pick(:id))
4345
end
4446
end
4547

@@ -85,6 +87,10 @@ def from_string(str)
8587
end
8688
end
8789

90+
def count_recursively(count = 0)
91+
count + 1 + (children&.sum(&:count_recursively) || 0)
92+
end
93+
8894
def reload_from_s3(s3_client = Aws::S3::Client.new(region: BLADE_BUCKET_REGION))
8995
m = Message.from_s3(List.find_by_id(self.list_id).name, self.list_seq, s3_client)
9096

app/views/layouts/application.html.erb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,22 @@
1111
<meta name="viewport" content="width=device-width,initial-scale=1">
1212
<%= csrf_meta_tags %>
1313
<%= csp_meta_tag %>
14+
<%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %>
1415

1516
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
1617
</head>
1718

18-
<body>
19-
<%= yield %>
19+
<body class="bg-gray-50">
20+
<header class="bg-white shadow-sm border-b border-gray-200">
21+
<div class="container mx-auto px-4 py-4">
22+
<h1 class="text-2xl font-bold text-gray-900">
23+
<%= link_to "blade.ruby-lang.org", root_path, class: "hover:text-red-600 transition-colors" %>
24+
</h1>
25+
</div>
26+
</header>
27+
28+
<main class="container mx-auto px-4 py-8">
29+
<%= yield %>
30+
</main>
2031
</body>
2132
</html>

0 commit comments

Comments
 (0)