summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKen D'Ambrosio <ken@jots.org>2026-05-11 05:43:28 +0000
committerKen D'Ambrosio <ken@jots.org>2026-05-11 05:43:28 +0000
commit35a72d21075c9d2331ee4388fe34fe6efd5b65fc (patch)
treea7d00b185f1f77c658cbc05ca663a381bfbcc7db
parent9f586a8db100c586b33f425f7699355bca43f8b4 (diff)
Limit slideshow to filtered albums when search filter is active
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
-rw-r--r--app.rb15
-rw-r--r--public/js/album.js47
-rw-r--r--views/album.erb7
3 files changed, 43 insertions, 26 deletions
diff --git a/app.rb b/app.rb
index e23ae38..9b636fe 100644
--- a/app.rb
+++ b/app.rb
@@ -250,8 +250,16 @@ get '/slideshow/*' do
slideshow_view(params[:splat].first.chomp('/'))
end
-def all_media_entries
- dirs = [MEDIA_ROOT] + Dir.glob("#{MEDIA_ROOT}/**/*/").sort
+def all_media_entries(top_dirs: nil)
+ dirs = if top_dirs
+ top_dirs.flat_map do |name|
+ full = File.expand_path(name, MEDIA_ROOT)
+ next [] unless full.start_with?("#{MEDIA_ROOT}/") && File.directory?(full)
+ [full] + Dir.glob("#{full}/**/*/").sort
+ end
+ else
+ [MEDIA_ROOT] + Dir.glob("#{MEDIA_ROOT}/**/*/").sort
+ end
dirs.flat_map do |dir|
rel = dir.delete_prefix(MEDIA_ROOT).delete_prefix('/')
data = load_album(dir)
@@ -271,7 +279,8 @@ def slideshow_view(rel)
@rel = rel
@title = data['title'] || (rel.empty? ? 'Albums' : File.basename(dir))
@entries = if rel.empty?
- all_media_entries
+ top_dirs = params[:dirs]&.split(',')&.map(&:strip)&.reject(&:empty?)
+ all_media_entries(top_dirs: top_dirs&.any? ? top_dirs : nil)
else
album_files(dir, data)
.select { |e| %i[image video].include?(e[:type]) }
diff --git a/public/js/album.js b/public/js/album.js
index dd54ed2..689edee 100644
--- a/public/js/album.js
+++ b/public/js/album.js
@@ -115,32 +115,39 @@ window.addEventListener('DOMContentLoaded', () => {
}
});
-// Album search filter
+// Album search filter + slideshow link (kept together so filter state feeds the link)
(function () {
const input = document.getElementById('album-search');
- if (!input) return;
- input.addEventListener('input', () => {
- const q = input.value.trim().toLowerCase();
- document.querySelectorAll('#album-grid .album-card').forEach(card => {
- const label = (card.querySelector('.album-label')?.textContent || '').toLowerCase();
- card.style.display = !q || label.includes(q) ? '' : 'none';
- });
- });
-})();
+ const link = document.getElementById('ss-launch');
-// Slideshow launch options (Shuffle / Full screen checkboxes next to the button)
-(function () {
- const link = document.getElementById('ss-launch');
- if (!link) return;
- const base = link.dataset.base;
- function update() {
+ function updateSsLink() {
+ if (!link) return;
const p = [];
- if (document.getElementById('ss-opt-shuffle').checked) p.push('shuffle=1');
- if (document.getElementById('ss-opt-fullscreen').checked) p.push('fullscreen=1');
- link.href = base + (p.length ? '?' + p.join('&') : '');
+ if (document.getElementById('ss-opt-shuffle')?.checked) p.push('shuffle=1');
+ if (document.getElementById('ss-opt-fullscreen')?.checked) p.push('fullscreen=1');
+ if (input && input.value.trim()) {
+ const visible = [...document.querySelectorAll('#album-grid .album-card')]
+ .filter(c => c.style.display !== 'none')
+ .map(c => c.dataset.rel)
+ .filter(Boolean);
+ if (visible.length) p.push('dirs=' + visible.map(encodeURIComponent).join(','));
+ }
+ link.href = link.dataset.base + (p.length ? '?' + p.join('&') : '');
}
+
+ if (input) {
+ input.addEventListener('input', () => {
+ const q = input.value.trim().toLowerCase();
+ document.querySelectorAll('#album-grid .album-card').forEach(card => {
+ const label = (card.querySelector('.album-label')?.textContent || '').toLowerCase();
+ card.style.display = !q || label.includes(q) ? '' : 'none';
+ });
+ updateSsLink();
+ });
+ }
+
['ss-opt-shuffle', 'ss-opt-fullscreen'].forEach(id =>
- document.getElementById(id).addEventListener('change', update)
+ document.getElementById(id)?.addEventListener('change', updateSsLink)
);
})();
diff --git a/views/album.erb b/views/album.erb
index c99ec3c..b44971e 100644
--- a/views/album.erb
+++ b/views/album.erb
@@ -27,8 +27,9 @@
<% end %>
<div class="grid" id="album-grid">
<% @albums.each do |a| %>
- <% href = @rel.empty? ? "/browse/#{a[:name]}" : "/browse/#{@rel}/#{a[:name]}" %>
- <a href="<%= href %>" class="card album-card">
+ <% a_rel = @rel.empty? ? a[:name] : "#{@rel}/#{a[:name]}" %>
+ <% href = "/browse/#{a_rel}" %>
+ <a href="<%= href %>" class="card album-card" data-rel="<%= a_rel %>">
<div class="thumb-wrap">
<% cover_rel = @rel.empty? ? "#{a[:name]}/#{a[:cover]}" : "#{@rel}/#{a[:name]}/#{a[:cover]}" %>
<% if a[:cover] %>
@@ -105,4 +106,4 @@ const ENTRIES = <%= @entries.map { |e|
e.merge(src: "/media/#{file_rel}")
}.to_json %>;
</script>
-<script src="/js/album.js?v=3"></script>
+<script src="/js/album.js?v=4"></script>