Use toast notifications over JavaScript alerts (#37)
Implement UI toast notifications
This commit is contained in:
committed by
GitHub
parent
99b4a3152d
commit
1b9b7e203e
@@ -268,9 +268,9 @@
|
||||
|
||||
if (!response.ok) throw new Error(await response.text());
|
||||
|
||||
alert('Configuration saved successfully!');
|
||||
createToast('Configuration saved successfully!');
|
||||
} catch (error) {
|
||||
alert(`Error saving configuration: ${error.message}`);
|
||||
createToast(`Error saving configuration: ${error.message}`, 'error');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -68,11 +68,11 @@
|
||||
.filter(url => url.length > 0);
|
||||
|
||||
if (urls.length === 0) {
|
||||
alert('Please submit at least one torrent');
|
||||
createToast('Please submit at least one torrent', 'warning');
|
||||
return;
|
||||
}
|
||||
if (urls.length >= 100) {
|
||||
alert('Please submit less than 100 torrents at a time');
|
||||
createToast('Please submit less than 100 torrents at a time', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -92,12 +92,16 @@
|
||||
const result = await response.json();
|
||||
if (!response.ok) throw new Error(result.error || 'Unknown error');
|
||||
if (result.errors && result.errors.length > 0) {
|
||||
alert(`Added ${result.results.length} torrents with ${result.errors.length} errors:\n${result.errors.join('\n')}`);
|
||||
if (result.results.length > 0) {
|
||||
createToast(`Added ${result.results.length} torrents with ${result.errors.length} errors:\n${result.errors.join('\n')}`, 'warning');
|
||||
} else {
|
||||
createToast(`Failed to add torrents:\n${result.errors.join('\n')}`, 'error');
|
||||
}
|
||||
} else {
|
||||
alert(`Successfully added ${result.results.length} torrents!`);
|
||||
createToast(`Successfully added ${result.results.length} torrents!`);
|
||||
}
|
||||
} catch (error) {
|
||||
alert(`Error adding downloads: ${error.message}`);
|
||||
createToast(`Error adding downloads: ${error.message}`, 'error');
|
||||
} finally {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = originalText;
|
||||
|
||||
@@ -170,9 +170,10 @@
|
||||
method: 'DELETE'
|
||||
});
|
||||
await loadTorrents();
|
||||
createToast('Torrent deleted successfully');
|
||||
} catch (error) {
|
||||
console.error('Error deleting torrent:', error);
|
||||
alert('Failed to delete torrent');
|
||||
createToast('Failed to delete torrent', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,9 +186,10 @@
|
||||
);
|
||||
await Promise.all(deletePromises);
|
||||
await loadTorrents();
|
||||
createToast('Selected torrents deleted successfully');
|
||||
} catch (error) {
|
||||
console.error('Error deleting torrents:', error);
|
||||
alert('Failed to delete some torrents');
|
||||
createToast('Failed to delete some torrents' , 'error');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,9 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="toast-container position-fixed bottom-0 end-0 p-3">
|
||||
<!-- Toast messages will be created dynamically here -->
|
||||
</div>
|
||||
<nav class="navbar navbar-expand-lg navbar-light mb-4">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="/">
|
||||
@@ -115,6 +118,52 @@
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||
<script>
|
||||
/**
|
||||
* Create a toast message
|
||||
* @param {string} message - The message to display
|
||||
* @param {string} [type='success'] - The type of toast (success, warning, error)
|
||||
*/
|
||||
const createToast = (message, type = 'success') => {
|
||||
type = ['success', 'warning', 'error'].includes(type) ? type : 'success';
|
||||
|
||||
const toastTimeouts = {
|
||||
success: 5000,
|
||||
warning: 10000,
|
||||
error: 15000
|
||||
}
|
||||
|
||||
const toastContainer = document.querySelector('.toast-container');
|
||||
const toastId = `toast-${Date.now()}`;
|
||||
|
||||
const toastHtml = `
|
||||
<div id="${toastId}" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header ${type === 'error' ? 'bg-danger text-white' : type === 'warning' ? 'bg-warning text-dark' : 'bg-success text-white'}">
|
||||
<strong class="me-auto">
|
||||
${type === 'error' ? 'Error' : type === 'warning' ? 'Warning' : 'Success'}
|
||||
</strong>
|
||||
<button type="button" class="btn-close ${type === 'warning' ? '' : 'btn-close-white'}" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
${message.replace(/\n/g, '<br>')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
toastContainer.insertAdjacentHTML('beforeend', toastHtml);
|
||||
|
||||
const toastElement = document.getElementById(toastId);
|
||||
const toast = new bootstrap.Toast(toastElement, {
|
||||
autohide: true,
|
||||
delay: toastTimeouts[type]
|
||||
});
|
||||
|
||||
toast.show();
|
||||
|
||||
toastElement.addEventListener('hidden.bs.toast', () => {
|
||||
toastElement.remove();
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
fetch('/internal/version')
|
||||
.then(response => response.json())
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
let mediaIds = document.getElementById('mediaIds').value.split(',').map(id => id.trim());
|
||||
let arr = document.getElementById('arrSelect').value;
|
||||
if (!arr) {
|
||||
alert('Please select an Arr instance');
|
||||
createToast('Please select an Arr instance', 'warning');
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = originalText;
|
||||
return;
|
||||
@@ -81,9 +81,9 @@
|
||||
});
|
||||
|
||||
if (!response.ok) throw new Error(await response.text());
|
||||
alert('Repair process initiated successfully!');
|
||||
createToast('Repair process initiated successfully!');
|
||||
} catch (error) {
|
||||
alert(`Error starting repair: ${error.message}`);
|
||||
createToast(`Error starting repair: ${error.message}`, 'error');
|
||||
} finally {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = originalText;
|
||||
|
||||
Reference in New Issue
Block a user