diff --git a/frontend.html b/frontend.html index 9d2b1d1..a2a0e7d 100644 --- a/frontend.html +++ b/frontend.html @@ -14,16 +14,14 @@ overflow: hidden; zoom: 1; } - #img { + .media { max-width: 100%; max-height: 100%; width: 100%; height: 100%; cursor: pointer; - background-image: url($img_url); - background-size: contain; /* Important for proper scaling */ - background-position: center; - background-repeat: no-repeat; + object-fit: contain; + display: block; } .chevron { position: absolute; @@ -75,7 +73,7 @@ text-wrap-mode: nowrap; } #sidebar a:hover { - background: #3a3a3a; + background: #3a3a3a; color: #fff; } .breadcrumb { @@ -131,7 +129,7 @@
-
+ $media_element $play_button diff --git a/main.py b/main.py index 69516fc..d5109db 100644 --- a/main.py +++ b/main.py @@ -413,10 +413,27 @@ def _render_page( ) sidebar_class = "" + # Build the media element based on file type + img_url = "{root_path}/api/{file_hash}/data".format( + root_path=root_path, file_hash=navigation_data["file_hash"] + ) + content_type, _ = mimetypes.guess_type(file_path or "") + data_attrs = f'data-hash="{navigation_data["file_hash"]}"' + if navigate_enabled: + data_attrs += f' data-path="{file_path}"' + if content_type and content_type.startswith("video"): + media_element = ( + f'' + ) + else: + media_element = ( + f'' + ) + content = template.substitute( - img_url="{root_path}/api/{file_hash}/data".format( - root_path=root_path, file_hash=navigation_data["file_hash"] - ), + media_element=media_element, image_click_url=image_click_url or _get_random_hash(), next_url=next_url, prev_url=prev_url, @@ -809,7 +826,7 @@ def _render_folder_index_page( ) content = template.substitute( - img_url="#", + media_element="", image_click_url="#", next_url="#", prev_url="#", diff --git a/tests/conftest.py b/tests/conftest.py index cb7a6c1..bcbd2ac 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -53,6 +53,9 @@ def sample_files(tmp_path: Path) -> dict[str, Path]: files["image_file"] = tmp_path / "photo.jpg" files["image_file"].write_bytes(b"\xff\xd8\xff\xe0fake_jpeg_data") + files["video_file"] = tmp_path / "clip.mp4" + files["video_file"].write_bytes(b"\x00\x00\x00\x1cftypfake_mp4_data") + return files diff --git a/tests/test_file_indexer.py b/tests/test_file_indexer.py index 2f7f810..bd7c0a4 100644 --- a/tests/test_file_indexer.py +++ b/tests/test_file_indexer.py @@ -87,8 +87,8 @@ class TestIndex: """All files in the directory tree are indexed.""" indexer = FileIndexer(str(sample_files["root_file"].parent), salt="test") assert ( - len(indexer._file_mapping) == 4 - ) # root.txt, nested.txt, data.bin, photo.jpg + len(indexer._file_mapping) == 5 + ) # root.txt, nested.txt, data.bin, photo.jpg, clip.mp4 def test_hash_maps_to_correct_path(self, sample_files: dict[str, Path]) -> None: """Each hash maps to the correct file path.""" diff --git a/tests/test_media_elements.py b/tests/test_media_elements.py new file mode 100644 index 0000000..3c21242 --- /dev/null +++ b/tests/test_media_elements.py @@ -0,0 +1,219 @@ +"""Tests for media element rendering (images vs videos).""" + +from httpx import AsyncClient + +import main + + +class TestMediaElementRendering: + """Tests for GET /{file_hash} media element selection.""" + + async def test_image_file_renders_img_tag(self, client_dir: AsyncClient) -> None: + """Image files should render an element.""" + file_hash = None + for h, path in main.file_mapping.items(): + if path.endswith(".jpg"): + file_hash = h + break + + assert file_hash is not None + response = await client_dir.get(f"/{file_hash}") + assert response.status_code == 200 + assert " None: + """Video files should render a