Add scheduled sync, disk space awareness, and subtitle downloads
- auto-sync daemon: background thread checks every hour and syncs followed channels for users with sync_interval_hours set (6/12/24h options) - disk stats: /api/stats now returns total/used/free/download bytes; Stats page shows a disk usage bar - subtitles: subtitle_langs setting (e.g. "en,sv") passed through all download paths; yt-dlp writes .srt files alongside the video - Settings page: sync interval dropdown + subtitle languages input Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,14 @@ function fmt(seconds) {
|
||||
return `${h}h ${m}m`;
|
||||
}
|
||||
|
||||
function fmtBytes(bytes) {
|
||||
if (!bytes) return "0 B";
|
||||
const units = ["B", "KB", "MB", "GB", "TB"];
|
||||
let i = 0, v = bytes;
|
||||
while (v >= 1024 && i < units.length - 1) { v /= 1024; i++; }
|
||||
return `${v.toFixed(i === 0 ? 0 : 1)} ${units[i]}`;
|
||||
}
|
||||
|
||||
function StatCard({ label, value, sub }) {
|
||||
return (
|
||||
<div className="bg-zinc-900 rounded-2xl p-4 flex flex-col gap-1">
|
||||
@@ -170,6 +178,29 @@ export default function Stats() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Disk usage */}
|
||||
{data.disk?.total_bytes && (
|
||||
<div className="bg-zinc-900 rounded-2xl p-5 flex flex-col gap-3">
|
||||
<h2 className="text-xs font-semibold text-zinc-500 uppercase tracking-wider">Disk usage</h2>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-zinc-400">Downloads</span>
|
||||
<span className="text-zinc-300 font-mono">{fmtBytes(data.disk.download_bytes)}</span>
|
||||
</div>
|
||||
<div className="h-2 bg-zinc-800 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-accent/70 rounded-full transition-all"
|
||||
style={{ width: `${Math.min((data.disk.used_bytes / data.disk.total_bytes) * 100, 100)}%` }}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-between text-[11px] text-zinc-600">
|
||||
<span>{fmtBytes(data.disk.used_bytes)} used</span>
|
||||
<span>{fmtBytes(data.disk.free_bytes)} free · {fmtBytes(data.disk.total_bytes)} total</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Taste profile */}
|
||||
{topTags.length > 0 && (
|
||||
<div className="bg-zinc-900 rounded-2xl p-5 flex flex-col gap-3">
|
||||
|
||||
Reference in New Issue
Block a user