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:
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">