diff --git a/devplacepy/static/css/attachments.css b/devplacepy/static/css/attachments.css index 4a180982..3f7fcd9e 100644 --- a/devplacepy/static/css/attachments.css +++ b/devplacepy/static/css/attachments.css @@ -29,6 +29,23 @@ max-height: 200px; } +.attachment-gallery.single .attachment-gallery-item:has(.gallery-thumb) { + width: 100%; + max-width: 100%; +} + +.attachment-gallery.single .attachment-gallery-item:has(.gallery-thumb):hover { + transform: none; + border-color: var(--border-light); +} + +.attachment-gallery.single .gallery-thumb { + width: 100%; + max-width: 100%; + max-height: 480px; + object-fit: contain; +} + .attachment-gallery-item:has(.non-image) { width: 120px; height: 120px; diff --git a/devplacepy/static/js/CLAUDE.md b/devplacepy/static/js/CLAUDE.md index f130c745..07a15f07 100644 --- a/devplacepy/static/js/CLAUDE.md +++ b/devplacepy/static/js/CLAUDE.md @@ -92,7 +92,11 @@ File validation: max 5MB, allowed extensions: `.png`, `.jpg`, `.jpeg`, `.gif`, ` **Ingesting a file from a URL.** `store_attachment_from_url(url, user_uid, filename=None)` (async, in `attachments.py`) is the remote counterpart to `store_attachment`: it downloads the URL on the server through `fetch_remote_file()` - SSRF-guarded (`_guard_public_url` resolves the host and refuses private/loopback/reserved/multicast addresses, mirroring the Devii fetch guard) and size-capped (streams, aborting once `_get_max_upload_bytes()` is exceeded) - resolves a filename from the URL path or the response `Content-Type` (`MIME_TO_EXT`), then calls `store_attachment()` so the bytes land in the **exact same** pipeline (validation, thumbnailing, DB row). It raises `RemoteFetchError(message, status)` which the route maps to an HTTP status. It is exposed at `POST /uploads/upload-url` (`UploadUrlForm{url, filename?}`, `require_user_api`) and as the Devii catalog action `attach_url` (handler `http`, `requires_auth=True`); both return the same record as `/uploads/upload`. The returned `uid` binds to a resource the same way as any upload - via `attachment_uids` at create/edit time - so attaching a remote image is just `attach_url` then `create_post`/`create_project`/etc. with that uid. Do not re-download remote files in a router; reuse this helper so the guard and size cap stay in one place. -`_row_to_attachment()` / `store_attachment()` expose `is_image` and `is_video` (derived from the mime prefix). The shared partial `templates/_attachment_display.html` branches image -> ``, video -> `