Show status of importing opml
This commit is contained in:
parent
c138940250
commit
059fd1a50d
@ -3,19 +3,76 @@
|
|||||||
background-color: var(--topbar-bg);
|
background-color: var(--topbar-bg);
|
||||||
color: white;
|
color: white;
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
display: flex;
|
display: grid;
|
||||||
justify-content: space-between;
|
grid-template-columns: auto 1fr auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hamburger-menu {
|
||||||
|
display: none;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--text-color);
|
||||||
|
font-size: 1.2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-feed-button {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--text-color);
|
||||||
|
font-size: 1.2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-status {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
color: var(--text-color);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-status i {
|
||||||
|
color: var(--primary-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-status.completed i {
|
||||||
|
animation: none;
|
||||||
|
color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-status-text {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeOut {
|
||||||
|
from { opacity: 1; }
|
||||||
|
to { opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-status.fade-out {
|
||||||
|
animation: fadeOut 0.5s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
.top-bar-title {
|
.top-bar-title {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: var(--primary-red);
|
color: var(--primary-red);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
grid-column: 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.feed-title-separator {
|
.feed-title-separator {
|
||||||
@ -23,6 +80,24 @@
|
|||||||
margin: 0 0.5rem;
|
margin: 0 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.hamburger-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-status {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-bar {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-bar-title {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* User menu styles */
|
/* User menu styles */
|
||||||
.user-menu {
|
.user-menu {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -87,25 +87,47 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
showStatusModal(result.message, false);
|
showJobStatus("Validating OPML file...");
|
||||||
if (result.job_id) {
|
if (result.job_id) {
|
||||||
pollJobStatus(result.job_id);
|
pollJobStatus(result.job_id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showStatusModal('OPML import failed: ' + result.message, true);
|
showError('OPML import failed: ' + result.message);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showStatusModal('Failed to import OPML file. Please try again.', true);
|
showError('Failed to import OPML file. Please try again.');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('OPML import failed:', error);
|
console.error('OPML import failed:', error);
|
||||||
showStatusModal('Failed to import OPML file. Please try again.', true);
|
showError('Failed to import OPML file. Please try again.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Clear the input so the same file can be selected again
|
// Clear the input so the same file can be selected again
|
||||||
e.target.value = '';
|
e.target.value = '';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function showJobStatus(message, isCompleted = false) {
|
||||||
|
const jobStatus = document.getElementById('jobStatus');
|
||||||
|
const jobStatusText = jobStatus.querySelector('.job-status-text');
|
||||||
|
|
||||||
|
jobStatus.style.display = 'flex';
|
||||||
|
jobStatusText.textContent = message;
|
||||||
|
|
||||||
|
if (isCompleted) {
|
||||||
|
jobStatus.classList.add('completed');
|
||||||
|
// Hide after 5 seconds
|
||||||
|
setTimeout(() => {
|
||||||
|
jobStatus.classList.add('fade-out');
|
||||||
|
setTimeout(() => {
|
||||||
|
jobStatus.style.display = 'none';
|
||||||
|
jobStatus.classList.remove('completed', 'fade-out');
|
||||||
|
}, 500);
|
||||||
|
}, 5000);
|
||||||
|
} else {
|
||||||
|
jobStatus.classList.remove('completed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function pollJobStatus(jobId) {
|
async function pollJobStatus(jobId) {
|
||||||
const maxAttempts = 30; // 30 attempts * 2 second delay = 1 minute maximum
|
const maxAttempts = 30; // 30 attempts * 2 second delay = 1 minute maximum
|
||||||
let attempts = 0;
|
let attempts = 0;
|
||||||
@ -116,15 +138,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const status = await response.json();
|
const status = await response.json();
|
||||||
if (status.status === 'completed') {
|
if (status.status === 'completed') {
|
||||||
showStatusModal(`Import completed. Successfully imported ${status.completed} feeds.`, false);
|
showJobStatus(`Import completed. Successfully imported ${status.completed} feeds.`, true);
|
||||||
handleFeeds();
|
handleFeeds();
|
||||||
return;
|
return;
|
||||||
} else if (status.status === 'in_progress') {
|
} else if (status.status === 'in_progress') {
|
||||||
showStatusModal(`Importing feeds... ${status.completed}/${status.total} completed`, false);
|
showJobStatus(`Importing feeds... ${status.completed}/${status.total} completed`);
|
||||||
if (attempts++ < maxAttempts) {
|
if (attempts++ < maxAttempts) {
|
||||||
setTimeout(poll, 2000); // Poll every 2 seconds
|
setTimeout(poll, 2000); // Poll every 2 seconds
|
||||||
} else {
|
} else {
|
||||||
showStatusModal('Import taking longer than expected. Check feeds list in a few minutes.', false);
|
showJobStatus('Import taking longer than expected. Check feeds list in a few minutes.', true);
|
||||||
setTimeout(handleFeeds, 5000);
|
setTimeout(handleFeeds, 5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,7 +155,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to poll job status:', error);
|
console.error('Failed to poll job status:', error);
|
||||||
showStatusModal('Failed to check import status. Please refresh the page.', true);
|
showError('Failed to check import status. Please refresh the page.');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,9 +66,15 @@
|
|||||||
<button class="hamburger-menu" id="hamburgerMenu">
|
<button class="hamburger-menu" id="hamburgerMenu">
|
||||||
<i class="fas fa-bars"></i>
|
<i class="fas fa-bars"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="add-feed-button" id="addFeedButton" title="Add Feed">
|
<div class="left-controls">
|
||||||
<i class="fas fa-plus"></i>
|
<button class="add-feed-button" id="addFeedButton" title="Add Feed">
|
||||||
</button>
|
<i class="fas fa-plus"></i>
|
||||||
|
</button>
|
||||||
|
<div class="job-status" id="jobStatus" style="display: none">
|
||||||
|
<i class="fas fa-sync fa-spin"></i>
|
||||||
|
<span class="job-status-text"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<h1 class="top-bar-title">RSS Reader</h1>
|
<h1 class="top-bar-title">RSS Reader</h1>
|
||||||
<div class="user-menu">
|
<div class="user-menu">
|
||||||
<button class="user-menu-button" id="userMenuButton">
|
<button class="user-menu-button" id="userMenuButton">
|
||||||
|
Loading…
Reference in New Issue
Block a user