Add TypeScript migration, image resizing, media upload UX, and multimedia support
All checks were successful
Deploy to NAS / deploy (push) Successful in 2m20s
All checks were successful
Deploy to NAS / deploy (push) Successful in 2m20s
- Migrate static JS to TypeScript (static-ts/ → compiled to internal/api/static/) - Add image resizing on upload: JPEG/PNG/WebP scaled to max 1920px at quality 80 - Extract shared upload logic into upload.go (saveUpload, saveResizedImage, saveResizedWebP) - Add POST /media endpoint for drag-drop/paste media uploads with markdown ref return - Add background music player with video/audio coordination (autoplay.ts) - Add global nav, public feed, hashtags, visibility, Markdown rendering for entries - Add Dockerfile stage for TypeScript compilation (static-ts-builder) - Add goldmark, disintegration/imaging, golang.org/x/image dependencies Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
103
backend/internal/api/static/autoplay.js
Normal file
103
backend/internal/api/static/autoplay.js
Normal file
@@ -0,0 +1,103 @@
|
||||
"use strict";
|
||||
(function () {
|
||||
'use strict';
|
||||
/* ── Background player ───────────────────────────────────── */
|
||||
const bgAudio = new Audio();
|
||||
let bgPlaying = false;
|
||||
let bgBar = null;
|
||||
let bgTitle = null;
|
||||
let bgPlayBtn = null;
|
||||
function createBgBar() {
|
||||
var _a;
|
||||
if (bgBar)
|
||||
return;
|
||||
bgBar = document.createElement('div');
|
||||
bgBar.id = 'bg-bar';
|
||||
bgBar.innerHTML =
|
||||
'<span id="bg-title"></span>' +
|
||||
'<button id="bg-play" aria-label="Abspielen">▶</button>' +
|
||||
'<button id="bg-close" aria-label="Schließen">✕</button>';
|
||||
document.body.appendChild(bgBar);
|
||||
bgTitle = document.getElementById('bg-title');
|
||||
bgPlayBtn = document.getElementById('bg-play');
|
||||
bgPlayBtn.addEventListener('click', function () {
|
||||
if (bgAudio.paused)
|
||||
void bgAudio.play();
|
||||
else
|
||||
bgAudio.pause();
|
||||
});
|
||||
(_a = document.getElementById('bg-close')) === null || _a === void 0 ? void 0 : _a.addEventListener('click', function () {
|
||||
bgAudio.pause();
|
||||
if (bgBar)
|
||||
bgBar.style.display = 'none';
|
||||
});
|
||||
bgAudio.addEventListener('play', function () { if (bgPlayBtn)
|
||||
bgPlayBtn.textContent = '⏸'; });
|
||||
bgAudio.addEventListener('pause', function () { if (bgPlayBtn)
|
||||
bgPlayBtn.textContent = '▶'; });
|
||||
bgAudio.addEventListener('ended', function () { if (bgPlayBtn)
|
||||
bgPlayBtn.textContent = '▶'; });
|
||||
}
|
||||
function sendToBg(src, title) {
|
||||
createBgBar();
|
||||
if (bgBar)
|
||||
bgBar.style.display = 'flex';
|
||||
bgAudio.src = src;
|
||||
if (bgTitle)
|
||||
bgTitle.textContent = title;
|
||||
void bgAudio.play();
|
||||
}
|
||||
// Attach "♪" button to every inline audio player
|
||||
document.querySelectorAll('audio.media-audio').forEach(function (a) {
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'btn-bg-music';
|
||||
btn.textContent = '♪ Hintergrundmusik';
|
||||
btn.type = 'button';
|
||||
const title = a.title || a.src.split('/').pop() || a.src;
|
||||
btn.addEventListener('click', function () { sendToBg(a.src, title); });
|
||||
a.insertAdjacentElement('afterend', btn);
|
||||
});
|
||||
/* ── Video autoplay + coordination ──────────────────────── */
|
||||
const obs = new IntersectionObserver(function (entries) {
|
||||
entries.forEach(function (e) {
|
||||
const v = e.target;
|
||||
if (e.isIntersecting) {
|
||||
void v.play();
|
||||
}
|
||||
else {
|
||||
v.pause();
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.3 });
|
||||
document.querySelectorAll('video.media-embed').forEach(function (v) {
|
||||
v.muted = true;
|
||||
v.loop = true;
|
||||
v.setAttribute('playsinline', '');
|
||||
obs.observe(v);
|
||||
// User unmutes → pause background music
|
||||
v.addEventListener('volumechange', function () {
|
||||
if (!v.muted && !v.paused) {
|
||||
bgPlaying = !bgAudio.paused;
|
||||
bgAudio.pause();
|
||||
}
|
||||
// Video muted again → resume background
|
||||
if (v.muted && bgPlaying) {
|
||||
void bgAudio.play();
|
||||
bgPlaying = false;
|
||||
}
|
||||
});
|
||||
// Video pauses or ends → resume background if it was playing
|
||||
v.addEventListener('pause', function () {
|
||||
if (bgPlaying) {
|
||||
void bgAudio.play();
|
||||
bgPlaying = false;
|
||||
}
|
||||
});
|
||||
v.addEventListener('ended', function () {
|
||||
if (bgPlaying) {
|
||||
void bgAudio.play();
|
||||
bgPlaying = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user