From c5ec42b2f42e285a95610f1b9b9efba4beef3d7e Mon Sep 17 00:00:00 2001 From: Ken D'Ambrosio Date: Thu, 18 Jun 2026 21:58:04 +0000 Subject: Rename global search to "Album Search" and group results by album Photo search was returning every individual matching photo, which was overkill for what's meant to be a quick way to find an album. /search now groups matches by album (cover thumbnail + match count) instead of listing each photo, and is relabeled "Album Search" throughout the UI. Co-Authored-By: Claude Sonnet 4.6 --- app.rb | 23 +++++++++++++++++------ public/css/style.css | 5 ----- views/layout.erb | 2 +- views/search.erb | 33 ++++++++++++--------------------- 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/app.rb b/app.rb index 7d6489a..c5f533b 100644 --- a/app.rb +++ b/app.rb @@ -556,15 +556,26 @@ end get '/search' do q = params[:q].to_s.strip - @title = q.empty? ? 'Search' : "Search: #{q}" + @title = q.empty? ? 'Album Search' : "Album Search: #{q}" @search_query = q unless q.empty? - ast = search_parse(q) - index = search_index - all = index.select { |d| (admin? || d[:visible]) && eval_search(ast, d[:text]) } - @total = all.length - @results = all.first(300) + ast = search_parse(q) + index = search_index + matched = index.select { |d| (admin? || d[:visible]) && eval_search(ast, d[:text]) } + + by_dir = matched.each_with_object({}) { |d, h| (h[d[:dir_rel]] ||= []) << d } + @results = by_dir.map do |dir_rel, docs| + dir = dir_rel.empty? ? MEDIA_ROOT : File.join(MEDIA_ROOT, dir_rel) + data = load_album(dir) + { + dir_rel: dir_rel, + title: data['title'] || (dir_rel.empty? ? '(root)' : File.basename(dir_rel)), + cover: album_cover(dir, data), + count: docs.length, + } + end + @total = @results.length end erb :search diff --git a/public/css/style.css b/public/css/style.css index 09de0b3..03d869f 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -389,11 +389,6 @@ legend { padding: 0 8px; color: var(--text-dim); font-size: .85rem; } .search-input:focus { border-color: var(--accent); outline: none; } .search-hint { font-size: .8rem; color: var(--text-dim); margin: 0 0 18px; } .search-hint code { background: var(--bg3); padding: 1px 5px; border-radius: 3px; font-size: .85em; } -.search-card .card-meta { padding: 6px 8px 8px; } -.search-album-path { font-size: .72rem; color: var(--text-dim); margin-top: 3px; - overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } -.search-album-path a { color: var(--text-dim); } -.search-album-path a:hover { color: var(--accent); } /* ── Responsive ────────────────────────────────────────────────────────── */ @media (max-width: 600px) { diff --git a/views/layout.erb b/views/layout.erb index 6a85482..17a5983 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -22,7 +22,7 @@