Update frontend with live progress timing and status transitions
This commit is contained in:
1 parent
42f050ae9a
commit
7609d70dd1
1 file changed
+31
-4
@@ -43,6 +43,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
let currentThread = null;
|
let currentThread = null;
|
||||||
let allHistory = [];
|
let allHistory = [];
|
||||||
|
let statusInterval = null;
|
||||||
|
|
||||||
// Initialize history
|
// Initialize history
|
||||||
fetchHistory();
|
fetchHistory();
|
||||||
@@ -86,14 +87,14 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
const mode = document.querySelector('input[name="rip-mode"]:checked').value;
|
const mode = document.querySelector('input[name="rip-mode"]:checked').value;
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
statusTitle.textContent = "Connecting to Threads...";
|
startProgressAnimation();
|
||||||
statusDesc.textContent = "Launching headless browser and resolving URL...";
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const startTime = performance.now();
|
||||||
const response = await fetch("/api/rip", {
|
const response = await fetch("/api/rip", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ url, mode, max_scrolls: 5 })
|
body: JSON.stringify({ url, mode, max_scrolls: 4 })
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
@@ -102,18 +103,44 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
const elapsed = ((performance.now() - startTime) / 1000).toFixed(1);
|
||||||
currentThread = data;
|
currentThread = data;
|
||||||
renderThread(data);
|
renderThread(data);
|
||||||
fetchHistory();
|
fetchHistory();
|
||||||
showToast("Thread successfully ripped & saved!");
|
showToast(`Thread ripped in ${elapsed}s!`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
showToast(`Error: ${err.message}`, true);
|
showToast(`Error: ${err.message}`, true);
|
||||||
} finally {
|
} finally {
|
||||||
|
stopProgressAnimation();
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startProgressAnimation() {
|
||||||
|
const steps = [
|
||||||
|
{ title: "Connecting to Threads...", desc: "Bypassing heavy assets and resolving redirects..." },
|
||||||
|
{ title: "Extracting continuation posts...", desc: "Tracking author replies and thread structure..." },
|
||||||
|
{ title: "Stitching post segments...", desc: "Generating Markdown, HTML, and Plain Text formats..." }
|
||||||
|
];
|
||||||
|
let stepIdx = 0;
|
||||||
|
statusTitle.textContent = steps[0].title;
|
||||||
|
statusDesc.textContent = steps[0].desc;
|
||||||
|
|
||||||
|
clearInterval(statusInterval);
|
||||||
|
statusInterval = setInterval(() => {
|
||||||
|
stepIdx++;
|
||||||
|
if (stepIdx < steps.length) {
|
||||||
|
statusTitle.textContent = steps[stepIdx].title;
|
||||||
|
statusDesc.textContent = steps[stepIdx].desc;
|
||||||
|
}
|
||||||
|
}, 1200);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopProgressAnimation() {
|
||||||
|
clearInterval(statusInterval);
|
||||||
|
}
|
||||||
|
|
||||||
function setLoading(isLoading) {
|
function setLoading(isLoading) {
|
||||||
const btnText = ripBtn.querySelector(".btn-text");
|
const btnText = ripBtn.querySelector(".btn-text");
|
||||||
const spinner = ripBtn.querySelector(".btn-spinner");
|
const spinner = ripBtn.querySelector(".btn-spinner");
|
||||||
|
|||||||
Reference in new issue
Block a user