qbit_manage/web-ui/js/utils/toast.js
bobokun 9ee3527853
v4.5.3 (#900)
# Requirements Updated
- "retrying==1.4.2",


# New Features
- **Web UI**: Implement dynamic schedule management via web UI/API
- **Share Limits**: Add limit upload speed when share limits are reached
(New config option: `upload_speed_on_limit_reached`) (Fixes #731, #737,
#703)
- **Share Limits**: Add min/max torrent size filters (New config option:
`min_torrent_size` / `max_torrent_size`) (Fixes #472)
- **Remove Unregistered**: Add grace period for unregistered torrent
removal (New config option: `rem_unregistered_grace_minutes`) (Fixes
#898)
- **Scheduler (Web API)**: Implement dynamic schedule management via web
API

# Improvements
- **Mover Script**: Allow granular control with pause, resume and move
args
- **web UI**: When saving, don’t delete config comments and empty lines
(Fixes #890)

# Bug Fixes
- Fix Error acquiring lock: cannot assign to field '_last_run_start'
(Fixes #895)
- Fix remove_orphaned not working correctly with `remote_dir` and
reporting 0 files removed
- fix(web-ui): prevent XSS vulnerabilities and prototype pollution
- Potential fix for code scanning alert no. 13: Client-side cross-site
scripting (#896)



**Full Changelog**:
https://github.com/StuffAnThings/qbit_manage/compare/v4.5.2...v4.5.3

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-08-08 20:57:06 -04:00

77 lines
2.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Toast Utility Module
* Manages the display of toast notifications.
*/
import { get, show, hide } from './dom.js';
import { CLOSE_ICON_SVG } from './icons.js';
const TOAST_CONTAINER_ID = 'toast-container';
/**
* Displays a toast notification.
* @param {string} message - The message to display in the toast.
* @param {'success'|'error'|'warning'|'info'} [type='info'] - The type of toast (for styling).
* @param {number} [duration=5000] - How long the toast should be visible in milliseconds.
*/
export function showToast(message, type = 'info', duration = 5000) {
const container = get(TOAST_CONTAINER_ID);
if (!container) {
console.warn('Toast container not found. Cannot display toast message.');
return;
}
const toast = document.createElement('div');
toast.className = `toast toast-${type}`;
const icons = {
success: '✓',
error: '✕',
warning: '⚠',
info: '',
undo: '↶',
redo: '↷'
};
// Build static structure with innerHTML, then set message via textContent
toast.innerHTML = `
<div class="toast-icon">${icons[type] || icons.info}</div>
<div class="toast-content">
<div class="toast-message"></div>
</div>
<button class="btn btn-icon btn-close-icon toast-close">
${CLOSE_ICON_SVG}
</button>
`;
// Insert message safely without relying on HTML escaping
const msgNode = toast.querySelector('.toast-message');
if (msgNode) {
msgNode.textContent = message == null ? '' : String(message);
}
container.appendChild(toast);
// Show toast (add 'show' class to trigger transition)
setTimeout(() => {
toast.classList.add('show');
}, 100);
// Auto-hide toast
const hideToast = () => {
toast.classList.remove('show');
// Remove from DOM after transition
toast.addEventListener('transitionend', () => {
if (toast.parentElement) {
toast.remove();
}
}, { once: true });
};
setTimeout(hideToast, duration);
// Close button event
const closeButton = toast.querySelector('.toast-close');
if (closeButton) {
closeButton.addEventListener('click', hideToast);
}
}