diff --git a/README.md b/README.md index a47cbb3..32327fe 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,153 @@ # Jellybloom -A desktop media client for Jellyfin. Built with React, TypeScript, Vite, and Tauri. +a desktop media client for Jellyfin, built because nobody should have to rent back their own culture from a server they already run -## What it does +## what it does -- Browse and play your Jellyfin library - movies, shows, music, live TV -- Discover new titles via TMDB integration with gap-finding against your library -- Watchlist sync with Trakt.tv -- Rich detail pages with cast, crew, awards, filming locations, and reviews -- Customizable player with subtitle search, bookmarks, chapter navigation, and audio passthrough -- Desktop-native feel via Tauri (Windows, macOS, Linux) +Jellybloom is a React + TypeScript + Vite + Tauri app that talks to your Jellyfin server and makes browsing, discovering, and watching actually pleasant. it is not a fork of jellyfin-web. it is not a skin. it is a complete reimagining of how a personal media library should feel - fast, dense, and yours. -## Dev +### browse + +- **movies, shows, music, playlists, live TV** - the usual stuff, but with a poster-grid that doesn't make your scroll wheel cry +- **unified search** - fuzzy matching across titles, people, and collections. saved searches stick around if you want them to +- **smart shelves** - curate your own rows on the home page (or let the app suggest some based on what you actually watch) +- **notification bell** - new episodes and movies land here, deduplicated by series so a full-season drop doesn't flood you +- **quick look** - right-click any poster for a peek without losing your scroll position + +### player + +the player is where most of the love went. it is built on **Vidstack** + **hls.js** with a custom chrome layer: + +- **subtitle rendering** - native ASS/SSA via **libass-wasm**, so styled fansubs look exactly like they're supposed to. also supports SRT, VTT, and plain text +- **subtitle search** - search and download from OpenSubtitles without leaving the player +- **subtitle styling** - size, font, outline, color, background opacity, positioning +- **bookmarks** - drop a pin at any moment with a note. bookmarks show up as dots on the scrubber +- **A-B loop** - loop a section for study, reference, or that one perfect joke +- **chapters** - jump between chapters from the scrubber or a side panel +- **trickplay thumbnails** - hover the scrubber to see exactly where you are +- **speed control** - 0.5x to 3x, because some shows deserve it and others really don't +- **picture filter** - brightness, contrast, saturation, hue, and gamma. useful for badly-encoded sources +- **audio graph** - a lightweight compressor + parametric EQ chain for when the mix is too quiet or too loud +- **audio passthrough** - let your receiver handle decoding when it can +- **quality menu** - switch streams on the fly (or let the server decide) +- **track menus** - pick audio and subtitle streams without leaving fullscreen +- **resume prompt** - picks up where you left off, but asks first so you don't spoil the cold open +- **up next / end card** - shows the next episode or related title as the credits roll +- **mini player** - pop out to a small floating window and keep watching while you do other things +- **sleep timer** - fades out after your chosen duration so you don't wake up three seasons later +- **"still watching?" prompt** - gently checks if you're still there after a few episodes (prevents runaway binge stats) +- **downloads** - save a movie or episode for offline playback. stored as a blob URL in the session +- **cast** - send playback to another Jellyfin session on your network +- **SyncPlay** - watch together with friends. join or create a group, and playback stays locked +- **Trakt.tv scrobbling** - optionally logs what you watch to Trakt (device-code auth, no redirect nonsense) +- **keyboard shortcuts** - fully customizable. every action in the player and app can be bound to whatever key combo you want + +### detail pages + +every title gets a rich detail page that pulls from multiple sources: + +- **hero** - backdrop, poster, logo overlay (from Jellyfin or TMDB), rating badges, action buttons +- **cast & crew** - click any person for their filmography, with in-library matches highlighted +- **crew grid** - directors, writers, producers, with job labels +- **composer block** - because the score matters and nobody else puts it front and center +- **awards** - pulled from Wikidata. Oscars, BAFTAs, Golden Globes, and more +- **filming locations** - mapped with Leaflet. see where it was shot +- **where to watch** - streaming availability by region, via TMDB +- **reception** - aggregate of every rating source available (IMDb, TMDB, Rotten Tomatoes, Metacritic, your own) +- **reviews** - pulled from TMDB +- **videos** - trailers and clips from YouTube +- **trivia** - production notes and keywords from Wikipedia +- **tech specs** - codec, container, resolution, audio channels, HDR format. media tech badge icons for Dolby Vision, Atmos, DTS:X, etc. +- **collection strip** - franchise entries with the current title highlighted +- **series status** - air days, next episode, season count, whether it's still in production +- **episode extras** - guest stars, production codes, absolute numbering +- **anime filler detection** - flags filler and mixed canon episodes based on a bundled dataset +- **versions selector** - when you have multiple files for one title, pick the one you want +- **watch timeline** - your personal history with this title, drawn from the diary +- **personal section** - your own rating, rewatch count, and notes. this data stays local +- **diary** - log watches with a date, rating, and rewatch flag. export to Markdown, JSON, or Letterboxd CSV +- **request button** - if you don't have it, request it from Radarr or Sonarr without leaving the page + +### discover + +the Discover page is for finding things you don't already own. it needs a TMDB API key (free) and respects your region and adult-content preference: + +- **tonight hero** - a personalized spotlight based on your top genre +- **spotlight hero** - trending pick of the day +- **mood chips** - ten vibes ("cosy," "chaotic," "melancholic") that resolve to a filtered row +- **roulette** - spin for a random highly-rated title from your chosen kind +- **decade strips** - "the 90s," "the 80s," etc. with interleaved movie and TV picks +- **canonical lists** - "top rated," "cult classics," "upcoming" +- **on this day** - titles that premiered on today's date +- **library gap finder** - shows the highest-rated missing titles in genres you already watch +- **browse grid** - explore by genre, language, studio, or network. each tile expands inline +- **advanced filters** - year range, rating, vote count, genre, watch region, sort order + +### profile & stats + +- **watch streak** - consecutive days with logged play activity +- **genre breakdown** - pie chart of what you actually watch +- **year in review** - hours watched, top genres, longest binge +- **top rated** - your personally highest-rated titles +- **recent diary** - last few logged watches + +### settings + +a lot of care went into making everything configurable without drowning you in toggles: + +- **server** - connect to one or many Jellyfin servers. switch between them without re-logging +- **server dashboard** - live stats: version, uptime, active streams, who's transcoding +- **playback** - autoplay, resume threshold, default audio language, subtitle language, subtitle size +- **audio & subtitles** - default behaviors, search preferences, styling defaults +- **display** - density (compact / comfortable), accent color, UI scale, reduced motion +- **home page** - toggle rows, pin smart shelves, hide adult content +- **detail page** - turn on/off sections you don't care about (trivia, filming locations, awards, etc.) +- **episodes** - default sort order, show/hide filler chips, absolute numbering +- **discovery** - region, hide adult, default filters +- **TMDB** - your own API key (optional built-in fallback) +- **Fanart.tv** - API key for richer artwork +- **Trakt.tv** - connect, sync watchlist, enable scrobbling +- **Sonarr & Radarr** - connect multiple instances (default + 4K tiers), set override rules per request +- **personal** - manage your ratings, rewatch counts, and diary +- **privacy** - clear caches, export data, delete everything +- **shortcuts** - rebind every keyboard action +- **about** - version, stack, acknowledgements + +### the little things + +- **sidebar pinning** - pin it open or let it auto-hide +- **window controls** - minimize, maximize, close. the whole app is a drag region except the buttons +- **offline banner** - gentle notice when the server is unreachable +- **toast system** - non-intrusive feedback for actions +- **error boundary** - catches crashes and shows a recoverable screen instead of a white page +- **reduced motion** - respects the system preference +- **density modes** - compact for power users, comfortable for everyone else + +## stack + +- **React 19** + **TypeScript** +- **Vite** + **Tailwind CSS** +- **Tauri 2** - desktop shell (Windows, macOS, Linux) +- **Zustand** - state management +- **TanStack Query** - data fetching and caching +- **TanStack Virtual** - virtualized lists +- **Vidstack** + **hls.js** - media playback +- **libass-wasm** - subtitle rendering +- **Framer Motion** - transitions and gestures +- **Leaflet** - maps +- **Fuse.js** - fuzzy search +- **Radix UI** - accessible primitives + +## dev ```bash npm install -npm run dev # browser dev +npm run dev # browser dev server npm run tauri:dev # desktop dev npm run build # production web build npm run tauri:build # production desktop build ``` -## Stack +## license -- React 19 + TypeScript -- Vite + Tailwind CSS -- Tauri 2 -- Zustand for state -- TanStack Query for data fetching -- Vidstack + hls.js for playback -- libass-wasm for subtitle rendering +CC0 - this code is a common resource. take it, modify it, run your own fork, or don't. no attribution required, no permission needed. the culture belongs to everyone.