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>
96 lines
3.4 KiB
TypeScript
96 lines
3.4 KiB
TypeScript
(function () {
|
|
'use strict';
|
|
|
|
/* ── Background player ───────────────────────────────────── */
|
|
const bgAudio = new Audio();
|
|
let bgPlaying = false;
|
|
let bgBar: HTMLElement | null = null;
|
|
let bgTitle: HTMLElement | null = null;
|
|
let bgPlayBtn: HTMLButtonElement | null = null;
|
|
|
|
function createBgBar(): void {
|
|
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') as HTMLButtonElement;
|
|
|
|
bgPlayBtn.addEventListener('click', function () {
|
|
if (bgAudio.paused) void bgAudio.play(); else bgAudio.pause();
|
|
});
|
|
document.getElementById('bg-close')?.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: string, title: string): void {
|
|
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<HTMLAudioElement>('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: IntersectionObserverEntry[]) {
|
|
entries.forEach(function (e) {
|
|
const v = e.target as HTMLVideoElement;
|
|
if (e.isIntersecting) {
|
|
void v.play();
|
|
} else {
|
|
v.pause();
|
|
}
|
|
});
|
|
}, { threshold: 0.3 });
|
|
|
|
document.querySelectorAll<HTMLVideoElement>('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; }
|
|
});
|
|
});
|
|
|
|
})();
|