- Docker deployment ready
- Content aggregation and filtering
- User authentication
- Polling service for updates
🤖 Generated with Claude Code
122 lines
3.3 KiB
JavaScript
122 lines
3.3 KiB
JavaScript
// Modern Card UI Theme Interactions
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
// Enhanced hover effects
|
|
function initializeCardHoverEffects() {
|
|
const cards = document.querySelectorAll('.card-surface, .list-card, .comment-surface');
|
|
|
|
cards.forEach(card => {
|
|
card.addEventListener('mouseenter', function() {
|
|
// Subtle scale effect on hover
|
|
this.style.transform = 'translateY(-2px)';
|
|
this.style.boxShadow = '0 6px 20px rgba(0, 0, 0, 0.15)';
|
|
});
|
|
|
|
card.addEventListener('mouseleave', function() {
|
|
// Reset transform
|
|
this.style.transform = '';
|
|
this.style.boxShadow = '';
|
|
});
|
|
});
|
|
}
|
|
|
|
// Lazy loading for performance
|
|
function initializeLazyLoading() {
|
|
if ('IntersectionObserver' in window) {
|
|
const options = {
|
|
root: null,
|
|
rootMargin: '50px',
|
|
threshold: 0.1
|
|
};
|
|
|
|
const observer = new IntersectionObserver((entries, observer) => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
// Add visible class for animations
|
|
entry.target.classList.add('visible');
|
|
|
|
// Unobserve after animation
|
|
observer.unobserve(entry.target);
|
|
}
|
|
});
|
|
}, options);
|
|
|
|
// Observe all cards and comments
|
|
document.querySelectorAll('.post-card, .comment-card').forEach(card => {
|
|
observer.observe(card);
|
|
});
|
|
}
|
|
}
|
|
|
|
// Improved comment thread visibility
|
|
function initializeCommentThreading() {
|
|
const toggleButtons = document.querySelectorAll('.comment-toggle');
|
|
|
|
toggleButtons.forEach(button => {
|
|
button.addEventListener('click', function() {
|
|
const comment = this.closest('.comment-card');
|
|
const replies = comment.querySelector('.comment-replies');
|
|
|
|
if (replies) {
|
|
replies.classList.toggle('collapsed');
|
|
this.textContent = replies.classList.contains('collapsed') ? '+' : '-';
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Add CSS classes for JavaScript-enhanced features
|
|
function initializeThemeFeatures() {
|
|
document.documentElement.classList.add('js-enabled');
|
|
|
|
// Add platform-specific classes to body
|
|
const platformElements = document.querySelectorAll('[data-platform]');
|
|
const platforms = new Set();
|
|
|
|
platformElements.forEach(el => {
|
|
platforms.add(el.dataset.platform);
|
|
});
|
|
|
|
platforms.forEach(platform => {
|
|
document.body.classList.add(`has-${platform}`);
|
|
});
|
|
}
|
|
|
|
// Keyboard navigation for accessibility
|
|
function initializeKeyboardNavigation() {
|
|
const cards = document.querySelectorAll('.post-card, .comment-card');
|
|
|
|
cards.forEach(card => {
|
|
card.setAttribute('tabindex', '0');
|
|
|
|
card.addEventListener('keydown', function(e) {
|
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
e.preventDefault();
|
|
const link = this.querySelector('a');
|
|
if (link) {
|
|
link.click();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Initialize all features when DOM is ready
|
|
function initializeTheme() {
|
|
initializeThemeFeatures();
|
|
initializeCardHoverEffects();
|
|
initializeLazyLoading();
|
|
initializeCommentThreading();
|
|
initializeKeyboardNavigation();
|
|
}
|
|
|
|
// Run initialization after DOM load
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', initializeTheme);
|
|
} else {
|
|
initializeTheme();
|
|
}
|
|
})();
|