Minimalist, full-screen ambient video player that surfaces random long‑form YouTube videos based on your saved keywords. It fetches results via a privacy-friendly Piped API, filters out Shorts, and auto-plays with an unobtrusive overlay for mute, play/pause, skip, and keyword management. Preferences persist in localStorage.
- Keyword-driven discovery: Add keywords; Portal fetches a random matching long-form video (excludes Shorts)
- Ambient playback: Auto-plays; automatically advances when a video ends
- Overlay controls: Mute/unmute, play/pause, skip, open settings
- Local persistence: Keywords are stored in
localStorage
- Preact + Vite
- Tailwind CSS v4 (with
tw-animate-cssand Geist font) - TanStack Query v5 for data fetching and caching
- ReactPlayer for playback
- @preact/signals for lightweight state
- shadcn/ui components (
Button,Input) and lucide-react icons
Prerequisites: Node 20+ (or Bun), pnpm/npm/yarn compatible.
Install dependencies:
# npm
npm install
# or pnpm
pnpm install
# or Bun (bun.lock present)
bun installRun the dev server:
npm run dev
# then open the printed localhost URLBuild for production and preview:
npm run build
npm run preview- Hover or tap to reveal the control overlay.
- Click the settings button to manage your keyword list.
- Click a keyword chip to remove it. New keywords are saved immediately.
- When a video ends, the next random match auto-plays.
- API: Uses
https://api.piped.private.coffee/searchfor discovery. To use a different Piped instance, update the endpoint insrc/app.tsx. - UI: Tailwind tokens and dark mode are defined in
src/index.css.
src/app.tsx: Main app UI, playback and keyword settingssrc/main.tsx: App bootstrap and TanStack Query providersrc/components/ui: Reusable UI primitives (shadcn/ui-style)src/index.css: Tailwind v4 setup and design tokens
- Shorts are filtered out via the
isShort === falsecheck. - Keywords persist under the key
portal-keywordsinlocalStorage.