From ba0bf2d73132b094ed9d4e3c58cfe7a0d5146d38 Mon Sep 17 00:00:00 2001 From: lelo Date: Mon, 21 Apr 2025 14:08:23 +0200 Subject: [PATCH] add thumbnails in frontend --- app.py | 14 +++-- static/app.css | 23 +++++++ static/app.js | 164 ++++++++++++++++++++++++++----------------------- 3 files changed, 119 insertions(+), 82 deletions(-) diff --git a/app.py b/app.py index 6a26442..e5af1eb 100755 --- a/app.py +++ b/app.py @@ -100,6 +100,8 @@ def list_directory_contents(directory, subpath): music_exts = ('.mp3',) image_exts = ('.jpg', '.jpeg', '.png', '.gif', '.bmp') + blocked_filenames = ['Thumbs.db'] + try: with os.scandir(directory) as it: # Sorting by name if required. @@ -107,6 +109,10 @@ def list_directory_contents(directory, subpath): # Skip hidden files and directories. if entry.name.startswith('.'): continue + + # Skip blocked_filenames + if entry.name in blocked_filenames: + continue if entry.is_dir(follow_symlinks=False): if entry.name in ["Transkription", "@eaDir"]: @@ -287,7 +293,7 @@ def serve_file(subpath): img = ImageOps.exif_transpose(orig) variants = { orig_key: (1920, 1920), - small_key: ( 192, 192), + small_key: ( 480, 480), } for key, size in variants.items(): thumb = img.copy() @@ -295,10 +301,8 @@ def serve_file(subpath): if thumb.mode in ("RGBA", "P"): thumb = thumb.convert("RGB") bio = io.BytesIO() - save_kwargs = {'format': 'JPEG', 'quality': 85} - if exif_bytes: - save_kwargs['exif'] = exif_bytes - thumb.save(bio, **save_kwargs) + # don’t pass exif_bytes here + thumb.save(bio, format='JPEG', quality=85) bio.seek(0) cache.set(key, bio, read=True) # Read back the variant we need diff --git a/static/app.css b/static/app.css index 5d05515..8309ec6 100644 --- a/static/app.css +++ b/static/app.css @@ -236,4 +236,27 @@ footer { transition: opacity 1s ease; opacity: 0; cursor: auto; +} + +.images-grid { + display: grid; + /* make each column exactly 150px wide */ + grid-template-columns: repeat(auto-fill, 150px); + /* force every row exactly 150px tall */ + grid-auto-rows: 150px; + gap: 14px; +} + +.image-item { + /* ensure the thumbnail can’t overflow its cell */ + overflow: hidden; +} + +.thumbnail { + /* fill the full cell */ + width: 100%; + height: 100%; + /* crop/scale to cover without stretching */ + object-fit: cover; + border-radius: 4px; } \ No newline at end of file diff --git a/static/app.js b/static/app.js index c73bfcd..2f6b086 100644 --- a/static/app.js +++ b/static/app.js @@ -34,8 +34,7 @@ function paintFile() { } function renderContent(data) { - - // Render breadcrumbs, directories (grid view when appropriate), and files. + // Render breadcrumbs let breadcrumbHTML = ''; data.breadcrumbs.forEach((crumb, index) => { breadcrumbHTML += `${crumb.name}`; @@ -45,102 +44,113 @@ function renderContent(data) { }); document.getElementById('breadcrumbs').innerHTML = breadcrumbHTML; + // Check for image-only directory (no subdirectories, at least one file, all images) + const isImageOnly = data.directories.length === 0 + && data.files.length > 0 + && data.files.every(file => file.file_type === 'image'); - // Render directories. let contentHTML = ''; - if (data.directories.length > 0) { - contentHTML += '