feat: 50 channels, daily 3AM cron sync, countdown timer, remove manual button

This commit is contained in:
Gan, Jimmy
2026-06-24 02:35:22 +08:00
parent 1c4f9dc713
commit 8ce359764f
3 changed files with 24 additions and 13 deletions
+1 -1
View File
@@ -51,7 +51,7 @@ async def fetch_subscriptions():
# Step 2: For each channel, get latest videos
new_count = 0
async with aiosqlite.connect(DB_PATH) as db:
for cid in channel_ids[:20]:
for cid in channel_ids[:50]:
try:
req = youtube.search().list(
part="snippet",
+6 -7
View File
@@ -7,14 +7,13 @@ services:
dockerfile: Dockerfile
container_name: t-youtube
restart: unless-stopped
network_mode: host
ports:
- "8001:8000"
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY:-sk-Kq5JbgmnEEkdzTqNAQ6bV6nztQ0ngeHTHF9Vg8nUglQvrOlx}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- ANTHROPIC_BASE_URL=https://www.bytecatcode.org
- HTTP_PROXY=http://100.70.115.1:8118
- HTTPS_PROXY=http://100.70.115.1:8118
- NO_PROXY=localhost,127.0.0.1,100.0.0.0/8,192.168.0.0/16
- DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}
- DEEPSEEK_BASE_URL=https://api.deepseek.com
- DEEPSEEK_MODEL=deepseek-chat
- DB_DIR=/app/data
volumes:
- ./data:/app/data
- ./config:/app/config
+17 -5
View File
@@ -8,6 +8,7 @@
let isSyncing = $state(false);
let syncMessage = $state('');
let pendingCount = $state(0);
let nextSync = $state(localStorage.getItem('t-yt-next-sync') || '');
let theme = $state(localStorage.getItem('theme') || 'dark');
let summaryPanel = $state(null);
let notes = $state(JSON.parse(localStorage.getItem('t-yt-notes') || '{}'));
@@ -92,10 +93,25 @@
document.documentElement.className = theme;
loadVideos();
loadPendingCount();
updateSyncTimer();
window.addEventListener('keydown', handleKeydown);
return () => window.removeEventListener('keydown', handleKeydown);
});
function updateSyncTimer() {
const el = document.getElementById('sync-timer');
if (!el) return;
const now = new Date();
const next = new Date(now);
next.setHours(3, 0, 0, 0); // 3 AM daily
if (now > next) next.setDate(next.getDate() + 1);
const diff = next - now;
const h = Math.floor(diff / 3600000);
const m = Math.floor((diff % 3600000) / 60000);
el.textContent = `Next sync in ${h}h ${m}m`;
setTimeout(updateSyncTimer, 60000);
}
async function loadPendingCount() {
try {
const res = await fetch('/api/videos?status=pending&limit=1');
@@ -191,16 +207,12 @@
<span class="text-[10px] px-2 py-0.5 rounded font-semibold uppercase tracking-widest" style="background:var(--bg-tertiary);color:var(--text-muted)">text feed</span>
</div>
<div class="flex items-center space-x-3">
<button onclick={syncSubscriptions} disabled={isSyncing}
class="px-3 py-1.5 text-xs font-bold rounded-lg transition"
style="background:var(--accent);color:white">
{isSyncing ? 'Syncing...' : 'Sync'}
</button>
<button onclick={toggleTheme}
class="text-sm px-2 py-1 rounded transition" style="color:var(--text-muted)"
title="Toggle theme">
{theme === 'dark' ? '☀' : '☾'}
</button>
<span class="text-[10px]" style="color:var(--text-muted)" id="sync-timer"></span>
</div>
</header>