Files
KoalaSync/website/app.js
T
MacBook 3e2e9ed7a5 feat: production-ready release v1.0.0
- Integrated 'Koala-Bridge' for seamless web-to-extension communication.
- Implemented dedicated, minimalist invitation page (join.html).
- Added brute-force protection and RAM-cleanup to the relay server.
- Removed external fonts and trackers from the landing page (Privacy First).
- Unified header/footer design across all website pages.
- Added MIT License and comprehensive legal documentation (Impressum/Datenschutz).
2026-04-21 08:46:28 +02:00

167 lines
7.7 KiB
JavaScript

// KoalaSync Landing Page Logic
document.addEventListener('DOMContentLoaded', () => {
// Scroll Reveal Logic
const revealElements = document.querySelectorAll('[data-reveal]');
const revealOnScroll = () => {
const windowHeight = window.innerHeight;
revealElements.forEach(el => {
const elementTop = el.getBoundingClientRect().top;
const revealPoint = 150;
if (elementTop < windowHeight - revealPoint) {
el.classList.add('revealed');
}
});
};
// Initial check
revealOnScroll();
// Scroll listener
window.addEventListener('scroll', revealOnScroll);
// Navbar scroll effect
const nav = document.querySelector('nav');
window.addEventListener('scroll', () => {
if (window.scrollY > 50) {
nav.style.padding = '0.75rem 0';
nav.style.background = 'rgba(15, 23, 42, 0.9)';
} else {
nav.style.padding = '1rem 0';
nav.style.background = 'rgba(30, 41, 59, 0.7)';
}
});
// Smooth scroll for anchors
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// Invite Detection & Bridge
const checkInvite = () => {
const isJoinPage = window.location.pathname.includes('join.html');
// Use a short timeout to let the bridge script initialize its dataset attribute
setTimeout(() => {
const isInstalled = document.documentElement.dataset.koalasyncInstalled === 'true';
if (window.location.hash.startsWith('#join:')) {
const parts = window.location.hash.split(':');
if (parts.length >= 3) {
const roomId = parts[1];
const password = parts[2];
if (isJoinPage) {
const displayRoom = document.getElementById('display-room-id');
const actions = document.getElementById('join-actions');
if (displayRoom) displayRoom.textContent = roomId;
if (actions) {
if (!isInstalled) {
actions.innerHTML = `
<a href="#" class="primary" style="text-align:center; text-decoration:none; display:block; padding: 1.2rem; background: var(--accent); color: white; border-radius: 12px; font-weight: 700;">GET IT ON CHROME WEBSTORE</a>
<a href="https://github.com/shik3i/KoalaSync" style="text-align:center; color:var(--accent); text-decoration:underline; font-size:0.85rem; margin-top:0.8rem; display:block; font-weight: 600;">Download via GitHub</a>
<p style="text-align:center; font-size:0.8rem; opacity:0.7; margin-top: 1.2rem; color: var(--text-muted);">The extension is required to join and sync videos.</p>
`;
} else {
actions.innerHTML = `
<button class="primary" id="webJoinBtn" style="padding: 1.2rem; width:100%; cursor: pointer;">JOIN ROOM NOW</button>
<p style="text-align:center; font-size:0.8rem; color:var(--success); margin-top: 0.8rem; font-weight: 600;">✅ Extension detected and ready.</p>
`;
}
}
} else {
// Fallback banner for index.html
if (!document.getElementById('koala-banner')) {
const banner = document.createElement('div');
banner.className = 'invite-banner';
banner.id = 'koala-banner';
banner.innerHTML = `
<div class="container" style="display:flex; justify-content:space-between; align-items:center;">
<span>🎫 Invitation for <b>${roomId}</b> detected!</span>
<a href="join.html${window.location.hash}" class="btn-banner">OPEN JOIN PAGE</a>
</div>
`;
document.body.prepend(banner);
}
}
// Global listener for Join Button
document.addEventListener('click', (e) => {
if (e.target && e.target.id === 'webJoinBtn') {
e.target.textContent = 'JOINING...';
e.target.disabled = true;
window.dispatchEvent(new CustomEvent('KOALASYNC_JOIN_REQUEST', {
detail: { roomId, password }
}));
}
});
}
}
}, 600); // 600ms delay to ensure bridge.js has set the dataset
};
// Listen for status from Extension
window.addEventListener('KOALASYNC_STATUS', (e) => {
const { success, message } = e.detail;
const isJoinPage = window.location.pathname.includes('join.html');
if (isJoinPage) {
const icon = document.getElementById('join-status-icon');
const title = document.getElementById('join-title');
const actions = document.getElementById('join-actions');
const desc = document.getElementById('join-desc');
if (success) {
if (icon) icon.textContent = '✅';
title.textContent = 'Erfolgreich!';
let count = 5;
const updateCountdown = () => {
desc.textContent = `Du bist dem Raum beigetreten. Dieser Tab schließt sich in ${count} Sekunden...`;
if (count <= 0) {
window.close();
desc.textContent = 'Beitritt erfolgreich! Du kannst diesen Tab jetzt manuell schließen.';
} else {
count--;
setTimeout(updateCountdown, 1000);
}
};
updateCountdown();
actions.innerHTML = '<button class="primary" onclick="window.close()" style="background:var(--success); width: 100%;">TAB JETZT SCHLIESSEN</button>';
} else {
if (icon) icon.textContent = '❌';
title.textContent = 'Fehler';
desc.textContent = `Beitritt fehlgeschlagen: ${message}`;
actions.innerHTML = '<button class="primary" onclick="location.reload()" style="width: 100%;">ERNEUT VERSUCHEN</button>';
}
} else {
const banner = document.getElementById('koala-banner');
if (banner) {
if (success) {
banner.style.background = 'var(--success)';
banner.innerHTML = '<div class="container">✅ Joined! This tab will close in 3s...</div>';
setTimeout(() => window.close(), 3000);
} else {
banner.style.background = 'var(--error)';
banner.innerHTML = `<div class="container">❌ Error: ${message}</div>`;
}
}
}
});
checkInvite();
});