diff --git a/frontend.html b/frontend.html
index 2375a3d..9d2b1d1 100644
--- a/frontend.html
+++ b/frontend.html
@@ -51,7 +51,7 @@
padding: 10px;
}
.play-btn:hover { color: rgba(255, 255, 255, 1); transform: scale(1.1); }
-/q .hidden { display: none; }
+ .hidden { display: none; }
#sidebar {
position: fixed;
top: 0;
@@ -72,6 +72,7 @@
display: block;
padding: 4px 8px;
border-radius: 4px;
+ text-wrap-mode: nowrap;
}
#sidebar a:hover {
background: #3a3a3a;
@@ -185,6 +186,7 @@
}
} else if (e.key.toLowerCase() === 'i') {
document.getElementById('sidebar').classList.toggle('hidden');
+ document.getElementById('sidebar-toggle').classList.toggle('collapsed');
}
});
diff --git a/main.py b/main.py
index a9f8275..69516fc 100644
--- a/main.py
+++ b/main.py
@@ -705,7 +705,7 @@ def _render_folder_index_html(
current_order: str | None = None,
current_delay: int | None = None,
) -> str:
- """Render a folder index sidebar showing the full tree from root.
+ """Render a folder index sidebar showing only the current folder's contents.
Args:
current_path: The currently viewed file path (for highlighting).
@@ -716,6 +716,30 @@ def _render_folder_index_html(
HTML string for the folder index sidebar.
"""
all_paths = _collect_zip_paths()
+
+ # Determine the folder to display:
+ # - None/"" → root
+ # - ends with "/" → that folder
+ # - file path → parent folder
+ if not current_path:
+ folder_prefix = ""
+ elif current_path.endswith("/"):
+ folder_prefix = current_path
+ else:
+ # current_path is a file — show its parent folder
+ slash_idx = current_path.rfind("/")
+ folder_prefix = current_path[: slash_idx + 1] if slash_idx >= 0 else ""
+
+ folders: set[str] = set()
+ files: set[str] = set()
+ for p in all_paths:
+ if p.startswith(folder_prefix):
+ remainder = p[len(folder_prefix) :]
+ if "/" in remainder:
+ folders.add(remainder.split("/", 1)[0])
+ else:
+ files.add(remainder)
+
lines: list[str] = []
# Breadcrumb
@@ -729,63 +753,40 @@ def _render_folder_index_html(
lines.append(f'{part}')
lines.append("")
- def _render_folder(folder_prefix: str, depth: int = 0) -> list[str]:
- """Recursively render a folder's contents."""
- result: list[str] = []
- indent = " " * depth
- prefix = folder_prefix or ""
+ href_params = ""
+ if current_order is not None and current_delay is not None:
+ href_params = f"?order={current_order}&delay={current_delay}"
- folders: set[str] = set()
- files: set[str] = set()
- for p in all_paths:
- if p.startswith(prefix):
- remainder = p[len(prefix) :]
- if "/" in remainder:
- folders.add(remainder.split("/", 1)[0])
- else:
- files.add(remainder)
+ for folder in sorted(folders):
+ folder_path = f"{folder_prefix}{folder}/" if folder_prefix else f"{folder}/"
+ lines.append(
+ f'
"
+ )
- for folder in sorted(folders):
- folder_path = f"{prefix}{folder}/" if prefix else f"{folder}/"
- result.append(
- f'"
- )
- result.extend(_render_folder(folder_path, depth + 1))
+ for file in sorted(files):
+ file_path = f"{folder_prefix}{file}" if folder_prefix else file
+ is_current = file_path == current_path
+ cls = "index-item file current" if is_current else "index-item file"
+ lines.append(
+ f'"
+ )
- for file in sorted(files):
- file_path = f"{prefix}{file}" if prefix else file
- is_current = file_path == current_path
- cls = "index-item file current" if is_current else "index-item file"
- href_params = ""
- if current_order is not None and current_delay is not None:
- href_params = f"?order={current_order}&delay={current_delay}"
- result.append(
- f'"
- )
-
- return result
-
- lines.extend(_render_folder(""))
return "\n".join(lines)
def _render_folder_index_page(
path: str,
- folders: list[str],
- files: list[str],
current_order: str | None = None,
current_delay: int | None = None,
) -> HTMLResponse:
- """Render a folder index page showing subfolders and files.
+ """Render a folder index page showing the current folder's contents.
Args:
path: The folder path (e.g., 'folder/').
- folders: List of subfolder names.
- files: List of file names.
current_order: Current navigation order.
current_delay: Current navigation delay.
@@ -797,8 +798,10 @@ def _render_folder_index_page(
template = string.Template(content)
- # Build folder index sidebar HTML using recursive tree renderer
- folder_path = path.rstrip("/") or None
+ # Build folder index sidebar HTML showing current folder contents
+ folder_path = path.rstrip("/")
+ if folder_path:
+ folder_path += "/"
folder_index_html = _render_folder_index_html(
current_path=folder_path,
current_order=current_order,
@@ -856,8 +859,6 @@ async def navigate_page(
raise HTTPException(status_code=404, detail="File not found")
return _render_folder_index_page(
path if path else "/",
- folders,
- files,
current_order=order,
current_delay=delay,
)
diff --git a/tests/test_navigate.py b/tests/test_navigate.py
index 167f43b..4449534 100644
--- a/tests/test_navigate.py
+++ b/tests/test_navigate.py
@@ -115,14 +115,17 @@ class TestNavigatePage:
assert "/navigate/folder/deep.txt" in response.text
assert "/navigate/folder/image.png" in response.text
- async def test_subfolder_index_shows_full_tree(
+ async def test_subfolder_index_shows_only_current_folder(
self, client_zip_navigate: AsyncClient
) -> None:
- """Subfolder index sidebar shows full tree from root."""
+ """Subfolder index shows only that folder's contents, not the full tree."""
response = await client_zip_navigate.get("/navigate/folder/")
assert response.status_code == 200
- # Should still show root-level items in the tree
- assert "/navigate/top.txt" in response.text
+ # Should show folder's own files
+ assert "/navigate/folder/deep.txt" in response.text
+ assert "/navigate/folder/image.png" in response.text
+ # Should NOT show root-level items
+ assert "/navigate/top.txt" not in response.text
async def test_file_page_has_sidebar(
self, client_zip_navigate: AsyncClient