tagliatelle

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit c67e546756dc1240a8c3c6fc89e17609799bdf4c
parent 373bb6ff78f9f43ddc715ed1226f3230ec018847
Author: breadcat <breadcat@users.noreply.github.com>
Date:   Fri,  6 Feb 2026 22:06:23 +0000

Apply rotation logic to images as well as videos

Also improve JS a little

Diffstat:
Mstatic/style.css | 3+++
Mstatic/timestamps.js | 43+++++++++++++++++++++++++++----------------
Mtemplates/file.html | 4++++
3 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/static/style.css b/static/style.css @@ -80,6 +80,9 @@ pre#text-viewer {white-space:pre-wrap; overflow:auto; background:#111; color:#ee img.file-content-image {max-width:400px} +/* media containers */ +.media-container img, .media-container video { transition: transform 0.2s ease; display: block; margin: auto; } + /* pagination */ .pagination .disabled,.pagination a{border-radius:4px;padding:.5rem 1rem} .pagination{display:flex;justify-content:center;align-items:center;gap:1rem;margin:2rem 0;padding:1rem} diff --git a/static/timestamps.js b/static/timestamps.js @@ -11,6 +11,8 @@ function makeTimestampsClickable(containerId, videoId, imageId) { const container = document.getElementById(containerId); const video = document.getElementById(videoId); const image = document.getElementById(imageId); + const videoContainer = document.getElementById('videoContainer'); + const imageContainer = document.getElementById('imageContainer'); // Regex for timestamps: [h:mm:ss] or [mm:ss] or [ss] const timestampRegex = /\[(\d{1,2}(?::\d{2}){0,2})\]/g; @@ -18,16 +20,14 @@ function makeTimestampsClickable(containerId, videoId, imageId) { const rotateRegex = /\[rotate(0|90|180|270)\]/g; // Replace timestamps - container.innerHTML = container.innerHTML.replace(timestampRegex, (match, ts) => { - const seconds = parseTimestamp(ts); - return `<a href="#" class="timestamp" data-time="${seconds}">${match}</a>`; + container.innerHTML = container.innerHTML + .replace(timestampRegex, (match, ts) => { + const seconds = parseTimestamp(ts); + return `<a href="#" class="timestamp" data-time="${seconds}">${match}</a>`; + }) + .replace(rotateRegex, (match, angle) => { + return `<a href="#" class="rotate" data-angle="${angle}">${match}</a>`; }); - - // Replace rotations - container.innerHTML = container.innerHTML.replace(rotateRegex, (match, angle) => { - return `<a href="#" class="rotate" data-angle="${angle}">${match}</a>`; - }); - // Handle clicks container.addEventListener("click", e => { if (e.target.classList.contains("timestamp")) { @@ -40,16 +40,27 @@ function makeTimestampsClickable(containerId, videoId, imageId) { } else if (e.target.classList.contains("rotate")) { e.preventDefault(); const angle = Number(e.target.dataset.angle); - // Apply rotation to whichever element exists - const target = video || image; - if (target) { - target.style.transform = `rotate(${angle}deg)`; - target.style.transformOrigin = "center center"; - } - } + + if (video) { + applyRotation(video, angle); + } else if (image) { + applyRotation(image, angle); + } + } }); } +function applyRotation(element, angle) { + element.style.transform = `rotate(${angle}deg)`; + element.style.transformOrigin = "center center"; + + if (angle === 90 || angle === 270) { + element.style.maxWidth = "none"; + } else { + element.style.maxWidth = "100%"; + } +} + // Run it document.addEventListener("DOMContentLoaded", () => { makeTimestampsClickable("current-description", "videoPlayer", "imageViewer"); diff --git a/templates/file.html b/templates/file.html @@ -59,7 +59,9 @@ <div class="file-content"> {{if hasAnySuffix .Data.File.Filename ".jpg" ".jpeg" ".png" ".gif" ".webp"}} + <div id="imageContainer" class="media-container"> <a href="/uploads/{{.Data.EscapedFilename}}" target="_blank"><img src="/uploads/{{.Data.EscapedFilename}}" id="imageViewer" class="file-content-image"></a><br> + </div> <script src="/static/timestamps.js" defer></script> {{else if hasAnySuffix .Data.File.Filename ".cbz"}} <div class="cbz-preview"> @@ -71,9 +73,11 @@ </div> </div> {{else if hasAnySuffix .Data.File.Filename ".mp4" ".webm" ".mov" ".m4v"}} + <div id="videoContainer" class="media-container"> <video id="videoPlayer" controls loop muted width="600"> <source src="/uploads/{{.Data.EscapedFilename}}"> </video><br> + </div> <script src="/static/timestamps.js" defer></script> {{else if hasAnySuffix .Data.File.Filename ".txt" ".md"}} <div id="text-viewer-container">