Content Library
Watch Videos
In-depth theology, apologetics, and church history from Warren McGrew.
const { useState, useEffect } = React; // ── Config ──────────────────────────────────────────────────────────────── const _API = { key: ['AIzaSyCSGJzK6KrsujWb', 'LUQkhYsVoHt_oemMLDg'].join(''), channels: { main: { handle: 'IdolKiller', label: 'Idol Killer' }, music: { handle: 'IdolKiller2', label: 'Idol Killer 2' }, // pending }, base: 'https://www.googleapis.com/youtube/v3', }; const CACHE_TTL = 20 * 60 * 1000; function cacheKey(handle) { return `ik_feed_handle_${handle}`; } function getCache(handle) { try { const raw = localStorage.getItem(cacheKey(handle)); if (!raw) return null; const { ts, videos } = JSON.parse(raw); if (Date.now() - ts > CACHE_TTL) return null; return { videos }; } catch { return null; } } function setCache(handle, videos) { try { localStorage.setItem(cacheKey(handle), JSON.stringify({ ts: Date.now(), videos })); } catch {} } function clearChannelCache(handle) { // Clear old ID-based caches too try { localStorage.removeItem(cacheKey(handle)); localStorage.removeItem('ik_feed_UCjZ83CJKuU03jmeeKRP4wiw'); localStorage.removeItem('ik_feed_UCh8NcWbRDzwszrgvZ6nmVcw'); localStorage.removeItem('ik_videos_v2'); localStorage.removeItem('ik_videos_cache'); } catch {} } // ── Step 1: resolve handle → uploads playlist ID ───────────────────────── async function fetchUploadsPlaylistId(handle) { const url = `${_API.base}/channels?part=contentDetails&forHandle=${encodeURIComponent(handle)}&key=${_API.key}`; const res = await fetch(url); if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error(err.error?.message || `HTTP ${res.status}`); } const data = await res.json(); const uploadsId = data.items?.[0]?.contentDetails?.relatedPlaylists?.uploads; if (!uploadsId) throw new Error(`Could not resolve uploads playlist for @${handle}`); return uploadsId; } // ── Step 2: playlistItems.list → all videos ────────────────────────────── async function fetchPlaylistVideos(playlistId, onProgress) { const BASE = `${_API.base}/playlistItems`; let videos = []; let pageToken = ''; let pages = 0; do { const url = `${BASE}?part=snippet&playlistId=${playlistId}&maxResults=50&key=${_API.key}${pageToken ? '&pageToken=' + pageToken : ''}`; const res = await fetch(url); if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error(err.error?.message || `HTTP ${res.status}`); } const data = await res.json(); pageToken = data.nextPageToken || ''; pages++; const batch = (data.items || []) .filter(item => { const t = item.snippet?.title || ''; return t !== 'Private video' && t !== 'Deleted video'; }) .map(item => { const s = item.snippet; const videoId = s.resourceId?.videoId || ''; const thumbs = s.thumbnails || {}; const thumb = (thumbs.maxres || thumbs.high || thumbs.medium || thumbs.default || {}).url || `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`; return { id: videoId, title: s.title || '', date: s.publishedAt || '', description: s.description || '', thumb, category: classifyVideo(s.title, s.description || ''), }; }); videos = videos.concat(batch); if (onProgress) onProgress(videos.length); } while (pageToken && pages < 40); return videos; } // ── Combined: handle → videos (with cache) ───────────────────────────── async function fetchChannelVideos(handle, onProgress) { const cached = getCache(handle); if (cached) { if (onProgress) onProgress(cached.videos.length); return cached; } const playlistId = await fetchUploadsPlaylistId(handle); const videos = await fetchPlaylistVideos(playlistId, onProgress); setCache(handle, videos); return { videos }; } // ── Classifier ──────────────────────────────────────────────────────────── const CATEGORIES = ['All', 'Calvinism', 'Original Sin', 'Atonement', 'Molinism', 'Dynamic Omniscience', 'Debates & Responses', 'Church History', 'Theology']; function classifyVideo(title, description) { const t = (title + ' ' + (description || '')).toLowerCase(); if (/calvin|tulip|predestination|reformed|total depravity|irresistible grace|limited atonement|perseverance of/.test(t)) return 'Calvinism'; if (/original sin|inherited sin|adam.s sin|federal head/.test(t)) return 'Original Sin'; if (/atonement|penal sub|ransom|propitiation|expiation/.test(t)) return 'Atonement'; if (/molinis|middle knowledge|counterfactual|luis de molina/.test(t)) return 'Molinism'; if (/omniscience|open theism|foreknow|dynamic omniscience|greg boyd|open view/.test(t)) return 'Dynamic Omniscience'; if (/\bdebate\b|respond|reply|refut| vs |against|rebuttal|james white|response to/.test(t)) return 'Debates & Responses'; if (/church history|church father|origen|augustine|early church|patristic|irenaeus|tertullian|clement|justin martyr|chrysostom/.test(t)) return 'Church History'; return 'Theology'; } // ── Status bar ──────────────────────────────────────────────────────────── function StatusBar({ count, loading, progress, error, onRefresh }) { if (error) return (
{eyebrow}
{progress > 0 ? `${progress} videos loaded…` : 'Fetching from YouTube…'}
No videos found{searchQuery ? ` for "${searchQuery}"` : ` in ${activeCategory}`}
Content Library
In-depth theology, apologetics, and church history from Warren McGrew.