Show popular fetch phases in nav indicator and Downloads page
- Phase 1 (crawling) now creates the task immediately so Downloads shows it - Phase label updates to 'Enriching view counts' when phase 2 starts - Nav bar DownloadIndicator also polls /channels/tasks and shows spinning indicator + progress % for background tasks (not just file downloads) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import { Outlet, NavLink, Link, useLocation } from "react-router-dom";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useAuth } from "../hooks/useAuth";
|
||||
import SearchBar from "./SearchBar";
|
||||
import { getDownloads, getChannels } from "../api";
|
||||
import { getDownloads, getChannels, getActiveTasks } from "../api";
|
||||
|
||||
function BottomNav({ newCount }) {
|
||||
const tabs = [
|
||||
@@ -73,7 +73,7 @@ function BottomNav({ newCount }) {
|
||||
}
|
||||
|
||||
function DownloadIndicator() {
|
||||
const { data } = useQuery({
|
||||
const { data: downloads } = useQuery({
|
||||
queryKey: ["downloads"],
|
||||
queryFn: () => getDownloads().then((r) => r.data),
|
||||
refetchInterval: (query) => {
|
||||
@@ -84,27 +84,48 @@ function DownloadIndicator() {
|
||||
},
|
||||
});
|
||||
|
||||
const active = (data ?? []).filter(
|
||||
const { data: tasks = [] } = useQuery({
|
||||
queryKey: ["active-tasks"],
|
||||
queryFn: () => getActiveTasks().then((r) => r.data),
|
||||
refetchInterval: (query) => (query.state.data?.length > 0 ? 2000 : 10_000),
|
||||
});
|
||||
|
||||
const activeDownloads = (downloads ?? []).filter(
|
||||
(d) => d.status === "pending" || d.status === "downloading"
|
||||
);
|
||||
if (!active.length) return null;
|
||||
|
||||
const top = active[0];
|
||||
const pct = top.progress_percent ?? 0;
|
||||
if (!activeDownloads.length && !tasks.length) return null;
|
||||
|
||||
const totalActive = activeDownloads.length + tasks.length;
|
||||
|
||||
// Show download progress if there are active downloads, otherwise show task phase
|
||||
let label;
|
||||
if (activeDownloads.length) {
|
||||
const pct = activeDownloads[0].progress_percent ?? 0;
|
||||
label = <span className="font-mono tabular-nums text-[11px]">{pct.toFixed(0)}%</span>;
|
||||
} else {
|
||||
const task = tasks[0];
|
||||
const pct = task.total > 0 ? Math.round((task.done / task.total) * 100) : null;
|
||||
label = (
|
||||
<span className="text-[11px] max-w-[80px] truncate hidden sm:inline">
|
||||
{pct !== null ? `${pct}%` : task.phase || "…"}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
to="/downloads"
|
||||
className="flex items-center gap-1.5 px-2 py-1 rounded-lg bg-zinc-800 hover:bg-zinc-700 transition-colors text-xs text-zinc-300 shrink-0"
|
||||
title={`${active.length} download${active.length > 1 ? "s" : ""} in progress`}
|
||||
title={`${totalActive} task${totalActive > 1 ? "s" : ""} in progress`}
|
||||
>
|
||||
<svg className="w-3 h-3 animate-spin text-zinc-400 shrink-0" fill="none" viewBox="0 0 24 24">
|
||||
<circle className="opacity-20" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="3" />
|
||||
<path className="opacity-80" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" />
|
||||
</svg>
|
||||
<span className="font-mono tabular-nums text-[11px]">{pct.toFixed(0)}%</span>
|
||||
{active.length > 1 && (
|
||||
<span className="hidden sm:inline text-zinc-500">+{active.length - 1}</span>
|
||||
{label}
|
||||
{totalActive > 1 && (
|
||||
<span className="hidden sm:inline text-zinc-500">+{totalActive - 1}</span>
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
|
||||
@@ -141,9 +141,12 @@ export default function DownloadsPage() {
|
||||
const pct = task.total > 0 ? (task.done / task.total) * 100 : 0;
|
||||
return (
|
||||
<div key={task.id} className="bg-zinc-900 rounded-xl p-4">
|
||||
<p className="text-sm font-medium text-zinc-100 mb-0.5">{task.label}</p>
|
||||
<div className="flex items-center justify-between mb-1">
|
||||
<p className="text-sm font-medium text-zinc-100">{task.label}</p>
|
||||
<span className="text-xs text-zinc-400 tabular-nums">{task.done}/{task.total}</span>
|
||||
<span className="text-xs text-zinc-400">{task.phase || "Running…"}</span>
|
||||
{task.total > 0 && (
|
||||
<span className="text-xs text-zinc-400 tabular-nums">{task.done}/{task.total}</span>
|
||||
)}
|
||||
</div>
|
||||
<ProgressBar pct={pct} />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user