fix: Gitea Traefik routing and connection pool optimization
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled

- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
This commit is contained in:
2025-11-09 14:46:15 +01:00
parent 85c369e846
commit 36ef2a1e2c
1366 changed files with 104925 additions and 28719 deletions

View File

@@ -0,0 +1,211 @@
/**
* Scroll Animation
*
* Handles various scroll-based animations: fade-in, zoom-in, parallax, sticky-fade, sticky-steps
*/
import { Logger } from '../../core/logger.js';
/**
* ScrollAnimation - Individual scroll animation
*/
export class ScrollAnimation {
constructor(element, config = {}) {
this.element = element;
this.config = {
type: config.type || 'fade-in',
offset: config.offset || 0.85,
delay: config.delay || 0,
once: config.once !== false,
speed: config.speed || 0.5,
fadeStart: config.fadeStart || 0,
fadeEnd: config.fadeEnd || 1,
steps: config.steps || 3,
...config
};
this.triggered = false;
this.needsUpdate = true;
// Initialize based on type
this.init();
}
/**
* Initialize animation
*/
init() {
switch (this.config.type) {
case 'fade-in':
case 'zoom-in':
this.initFadeIn();
break;
case 'parallax':
this.initParallax();
break;
case 'sticky-fade':
this.initStickyFade();
break;
case 'sticky-steps':
this.initStickySteps();
break;
}
}
/**
* Initialize fade-in animation
*/
initFadeIn() {
this.element.style.opacity = '0';
this.element.style.transition = `opacity 0.6s ease, transform 0.6s ease`;
this.element.style.transitionDelay = `${this.config.delay}s`;
if (this.config.type === 'zoom-in') {
this.element.style.transform = 'scale(0.9)';
}
}
/**
* Initialize parallax animation
*/
initParallax() {
// Parallax doesn't need initial setup
this.needsUpdate = true;
}
/**
* Initialize sticky fade animation
*/
initStickyFade() {
this.element.style.position = 'sticky';
this.element.style.top = '0';
}
/**
* Initialize sticky steps animation
*/
initStickySteps() {
this.element.style.position = 'sticky';
this.element.style.top = '0';
}
/**
* Enter animation (element enters viewport)
*/
enter() {
if (this.triggered && this.config.once) {
return;
}
this.triggered = true;
switch (this.config.type) {
case 'fade-in':
this.element.style.opacity = '1';
this.element.classList.add('visible', 'entered');
break;
case 'zoom-in':
this.element.style.opacity = '1';
this.element.style.transform = 'scale(1)';
this.element.classList.add('visible', 'entered');
break;
}
}
/**
* Exit animation (element exits viewport)
*/
exit() {
if (this.config.once) {
return;
}
this.triggered = false;
switch (this.config.type) {
case 'fade-in':
this.element.style.opacity = '0';
this.element.classList.remove('visible', 'entered');
break;
case 'zoom-in':
this.element.style.opacity = '0';
this.element.style.transform = 'scale(0.9)';
this.element.classList.remove('visible', 'entered');
break;
}
}
/**
* Update animation (for scroll-based animations)
*/
update() {
const rect = this.element.getBoundingClientRect();
const viewportHeight = window.innerHeight;
const scrollY = window.scrollY;
switch (this.config.type) {
case 'parallax':
this.updateParallax(rect, scrollY);
break;
case 'sticky-fade':
this.updateStickyFade(rect, viewportHeight);
break;
case 'sticky-steps':
this.updateStickySteps(rect, viewportHeight, scrollY);
break;
}
}
/**
* Update parallax animation
*/
updateParallax(rect, scrollY) {
const elementTop = rect.top + scrollY;
const scrolled = scrollY - elementTop;
const translateY = scrolled * this.config.speed;
this.element.style.transform = `translateY(${translateY}px)`;
}
/**
* Update sticky fade animation
*/
updateStickyFade(rect, viewportHeight) {
const progress = Math.max(0, Math.min(1, (viewportHeight - rect.top) / viewportHeight));
const opacity = this.config.fadeStart + (this.config.fadeEnd - this.config.fadeStart) * progress;
this.element.style.opacity = opacity.toString();
}
/**
* Update sticky steps animation
*/
updateStickySteps(rect, viewportHeight, scrollY) {
const elementTop = rect.top + scrollY - viewportHeight;
const scrollProgress = Math.max(0, Math.min(1, scrollY / (rect.height + viewportHeight)));
const step = Math.floor(scrollProgress * this.config.steps);
this.element.setAttribute('data-step', step.toString());
this.element.classList.remove('step-0', 'step-1', 'step-2', 'step-3', 'step-4', 'step-5');
this.element.classList.add(`step-${step}`);
}
/**
* Destroy animation
*/
destroy() {
// Reset styles
this.element.style.opacity = '';
this.element.style.transform = '';
this.element.style.transition = '';
this.element.style.transitionDelay = '';
this.element.style.position = '';
this.element.style.top = '';
// Remove classes
this.element.classList.remove('visible', 'entered');
this.triggered = false;
}
}