Files
blog.pyaqa.ru/static/js/flash.js
Sergey Vanyushkin b1878e470f feat(ui): add error handling, flash messages and SEO optimization
- Add custom error pages (404, 403, 500) with user-friendly messages
- Add flash message system with signed cookies for security
- Add toast notifications with auto-dismiss and manual close
- Add comprehensive SEO meta tags (description, keywords, OG, Twitter)
- Add canonical URLs for SEO
- Update routes to use slug-based URLs (/posts/{slug} instead of /posts/{id})
- Add Open Graph and Twitter Card meta tags for social sharing
- Add favicon SVG
- Update all templates with proper meta tags and URLs
- Add error handlers registration in main.py
- Add flash middleware for request handling
- Install itsdangerous dependency
2026-05-02 16:23:57 +03:00

70 lines
1.8 KiB
JavaScript

/**
* Flash messages functionality for blog application.
*
* Handles auto-dismissal and manual closing of flash messages.
*/
(function() {
'use strict';
const AUTO_DISMISS_DELAY = 5000; // 5 seconds
function initFlashMessages() {
const flashMessages = document.querySelectorAll('[data-testid^="flash-message-"]');
flashMessages.forEach(function(message) {
const closeBtn = message.querySelector('[data-testid="flash-close"]');
// Manual close
if (closeBtn) {
closeBtn.addEventListener('click', function() {
dismissMessage(message);
});
}
// Auto dismiss after delay
setTimeout(function() {
dismissMessage(message);
}, AUTO_DISMISS_DELAY);
// Pause auto-dismiss on hover
message.addEventListener('mouseenter', function() {
message.classList.add('paused');
});
message.addEventListener('mouseleave', function() {
message.classList.remove('paused');
});
});
}
function dismissMessage(message) {
if (message.classList.contains('paused')) {
// Retry after a short delay if paused
setTimeout(function() {
dismissMessage(message);
}, 1000);
return;
}
message.classList.add('fade-out');
setTimeout(function() {
message.remove();
// Remove container if empty
const container = document.querySelector('[data-testid="flash-container"]');
if (container && container.children.length === 0) {
container.remove();
}
}, 300);
}
// Initialize on DOM ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initFlashMessages);
} else {
initFlashMessages();
}
})();