Files
jacuzzi/frontend/js/main.js
Simon 138c3224de Add modern UI enhancements over the classic redesign
Layered progressive polish on the warm classic + brass theme:
- Card entrance animation on first mount (virtualizer-aware)
- Cursor-tracking brass spotlight border on cards
- Thumbnail skeleton shimmer until the poster paints
- Hover video preview after a short dwell (only when formats resolved)
- View Transition + blurred-poster ambient backdrop on player open
- Favorite heart pop + expanding ring on add
- ⌘K command palette (search, theme, density, reels, source/channel)
- Scroll-progress bar + back-to-top FAB
- Grid density toggle (comfortable/compact)
- Reels HUD: serif title, brass scrubber, muted-state pulse

All new motion respects prefers-reduced-motion; no JS/HTML structure
changes to the core grid/feed. New glue lives in frontend/js/enhance.js.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 08:25:37 +00:00

53 lines
1.7 KiB
JavaScript

window.App = window.App || {};
(function() {
// App bootstrap: initialize storage, render UI, and load the first page.
async function initApp() {
await App.storage.ensureDefaults();
App.ui.applyTheme();
App.ui.applyPreferredQuality();
App.ui.applyFeedEndBehavior();
App.ui.applyDensity();
App.ui.renderMenu();
App.favorites.renderBar();
App.ui.bindGlobalHandlers();
App.videos.observeSentinel();
const loadMoreBtn = document.getElementById('load-more-btn');
if (loadMoreBtn) {
loadMoreBtn.onclick = () => {
App.videos.loadVideos();
};
}
const errorToastClose = document.getElementById('error-toast-close');
if (errorToastClose) {
errorToastClose.onclick = () => {
const toast = document.getElementById('error-toast');
if (toast) toast.classList.remove('show');
};
}
window.addEventListener('resize', () => {
App.videos.ensureViewportFilled();
});
await App.videos.loadVideos();
App.favorites.syncButtons();
// The UI above is rendered entirely from the last known status cached in
// localStorage, so startup never blocks on (or breaks because of) a slow
// or failing status endpoint. Now fetch fresh status in the background and
// reconcile the UI with whatever comes back.
App.storage.refreshServerStatusInBackground();
// Watch for frontend deploys and seamlessly reload/hot-swap changed assets.
if (App.version && App.version.start) {
App.version.start();
}
}
initApp();
})();