204 lines
8.2 KiB
Markdown
204 lines
8.2 KiB
Markdown
<div align="center">
|
|
|
|
# Jellybloom
|
|
|
|
**A desktop media client for Jellyfin that actually feels good to use.**
|
|
|
|
Built for people who run their own servers. No cloud, no accounts, no subscriptions, no gatekeepers between you and your library.
|
|
|
|
<br>
|
|
|
|
<img src="https://img.shields.io/badge/version-0.1.0-6B8AFF?style=flat-square&labelColor=282C33" alt="Version">
|
|
<img src="https://img.shields.io/badge/platform-Windows-6B8AFF?style=flat-square&labelColor=282C33" alt="Platform">
|
|
<img src="https://img.shields.io/badge/React-19-61DAFB?style=flat-square&logo=react&logoColor=white" alt="React">
|
|
<img src="https://img.shields.io/badge/Tauri-v2-24C8D8?style=flat-square&logo=tauri&logoColor=white" alt="Tauri">
|
|
<img src="https://img.shields.io/badge/license-CC0_Public_Domain-6B8AFF?style=flat-square&labelColor=282C33" alt="License">
|
|
|
|
</div>
|
|
|
|
<br>
|
|
|
|
## 🏴 Why Jellybloom?
|
|
|
|
You already run a Jellyfin server. You already own the media. So why does using it still feel like using a web app designed by committee?
|
|
|
|
Jellybloom is a ground-up desktop client for Windows. It talks directly to your Jellyfin server and makes browsing, discovering, and watching actually pleasant. Fast, dense, responsive, and fully under your control.
|
|
|
|
No cloud dependencies. No data collection. No feature gates. No one profits from your watch history except you.
|
|
|
|
<br>
|
|
|
|
## ✨ What it does
|
|
|
|
### 📺 Browse
|
|
|
|
- **Home shelves** - curate your own rows or let the app suggest based on what you watch
|
|
- **Virtualized poster grid** - smooth scrolling with thousands of items
|
|
- **Unified fuzzy search** - titles, people, collections. Saved searches stick around
|
|
- **Quick look** - right-click any poster for a peek without losing your scroll position
|
|
- **Notification bell** - new episodes and movies, deduplicated by series so a full-season drop does not flood you
|
|
|
|
### 🎬 The player
|
|
|
|
- **Native subtitle rendering** - ASS/SSA via libass-wasm, plus SRT, VTT, and plain text
|
|
- **Subtitle search** - find and download from OpenSubtitles without leaving the player
|
|
- **Subtitle styling** - size, font, outline, color, background opacity, positioning
|
|
- **Bookmarks** - drop a pin with a note, shown as dots on the scrubber
|
|
- **A-B loop** - for study, reference, or that one perfect joke
|
|
- **Chapters and trickplay thumbnails** - jump around, hover the scrubber to see where you are
|
|
- **Speed control** - 0.5x to 3x
|
|
- **Picture filter** - brightness, contrast, saturation, hue, gamma for bad encodes
|
|
- **Audio graph** - compressor and parametric EQ for quiet or loud mixes
|
|
- **Audio passthrough** - let your receiver handle decoding
|
|
- **Quality and track menus** - switch streams on the fly
|
|
- **Resume prompt** - asks first so you do not spoil the cold open
|
|
- **End card** - next episode or related title as the credits roll
|
|
- **Mini player** - pop out to a floating window
|
|
- **Sleep timer** - fades out after your chosen duration
|
|
- **"Still watching?"** - gently checks in after a few episodes
|
|
- **Downloads** - save for offline playback
|
|
- **Cast** - send to another Jellyfin session on your network
|
|
- **SyncPlay** - watch together with friends, playback stays locked
|
|
- **Trakt.tv scrobbling** - optional, device-code auth, no redirects
|
|
- **Customizable keyboard shortcuts** - rebind everything
|
|
|
|
### 📄 Detail pages
|
|
|
|
- **Hero** - backdrop, poster, logo overlay, ratings, action buttons
|
|
- **Cast and crew** - clickable filmographies with in-library matches highlighted
|
|
- **Composer block** - because the score matters
|
|
- **Awards** - from Wikidata
|
|
- **Filming locations** - mapped with Leaflet
|
|
- **Reception** - aggregates IMDb, TMDB, Rotten Tomatoes, Metacritic, and your own ratings
|
|
- **Reviews, trailers, trivia, tech specs** - from TMDB, YouTube, Wikipedia
|
|
- **Collection strip** - franchise entries
|
|
- **Series status** - air days, next episode, season count, production state
|
|
- **Anime filler detection** - flags filler and mixed-canon episodes
|
|
- **Versions selector** - pick between multiple files for one title
|
|
- **Watch timeline** - your personal history from the diary
|
|
- **Personal section** - your ratings, rewatch counts, notes. Stays local
|
|
- **Diary** - log watches with date, rating, rewatch flag. Export to Markdown, JSON, or Letterboxd CSV
|
|
- **Request button** - ask Radarr or Sonarr for missing titles without leaving the page
|
|
|
|
### 🔭 Discover
|
|
|
|
Find things you do not already own. Needs a free TMDB API key.
|
|
|
|
- **Tonight hero** - personalized spotlight based on your top genre
|
|
- **Spotlight hero** - trending pick of the day
|
|
- **Mood chips** - ten vibes that resolve to a filtered row
|
|
- **Roulette** - spin for a random highly-rated title
|
|
- **Decade strips** - the 90s, the 80s, etc.
|
|
- **Canonical lists** - top rated, cult classics, upcoming
|
|
- **On this day** - titles that premiered today
|
|
- **Library gap finder** - highest-rated missing titles in genres you already watch
|
|
- **Browse grid** - by genre, language, studio, network. Inline expansion
|
|
- **Advanced filters** - year range, rating, vote count, sort order
|
|
|
|
### 👤 Profile and stats
|
|
|
|
- Watch streak, genre breakdown, year-in-review
|
|
- Personally top-rated titles, recent diary entries
|
|
|
|
### ⚙️ Settings
|
|
|
|
- Multiple Jellyfin servers with live dashboard
|
|
- Playback, audio, subtitle, and display preferences
|
|
- Home page and detail page section toggles
|
|
- TMDB, Fanart.tv, Trakt.tv, Sonarr, Radarr configuration
|
|
- Personal data management, privacy controls, full keyboard rebinds
|
|
|
|
<br>
|
|
|
|
## ♿ Accessibility
|
|
|
|
Jellybloom targets WCAG 2.2 AAA conformance because a media client that only works for some people is not really a media client.
|
|
|
|
| Area | Details |
|
|
|:-----|:--------|
|
|
| **Semantic HTML** | Proper landmarks, ARIA roles for menus, dialogs, tabs, and status regions |
|
|
| **Full keyboard navigation** | Every interactive element reachable and operable without a mouse |
|
|
| **Focus management** | Visible focus indicators on all controls, focus traps in modals with restore on close |
|
|
| **High contrast** | All themes meet AAA contrast ratios (7:1+ for normal text) |
|
|
| **Reduced motion** | Respects prefers-reduced-motion - all animations disabled when active |
|
|
| **Screen readers** | ARIA live regions for dynamic content, proper labels on icon-only buttons |
|
|
| **Touch targets** | All interactive controls meet 24x24px minimum |
|
|
|
|
<br>
|
|
|
|
## 📦 Getting started
|
|
|
|
### Prerequisites
|
|
|
|
- Windows 10 or later
|
|
- WebView2 Runtime (pre-installed on Windows 10/11)
|
|
- Node.js 18+
|
|
- Rust (latest stable)
|
|
- Tauri v2 prerequisites
|
|
|
|
### Development
|
|
|
|
```bash
|
|
git clone https://git.lashman.live/lashman/jellybloom.git
|
|
cd jellybloom
|
|
npm install
|
|
```
|
|
|
|
```bash
|
|
npm run dev # browser dev
|
|
npm run tauri:dev # desktop dev
|
|
npm run build # production web build
|
|
npm run tauri:build # production desktop build
|
|
```
|
|
|
|
<br>
|
|
|
|
## 🔧 Technology stack
|
|
|
|
| | Layer | Technology |
|
|
|:--|:--|:--|
|
|
| **Runtime** | Desktop shell | [Tauri v2](https://tauri.app/) |
|
|
| **Frontend** | UI framework | React 19, TypeScript, Vite |
|
|
| **Styling** | CSS | Tailwind CSS 4 |
|
|
| **State** | Management | Zustand |
|
|
| **Data** | Fetching and caching | TanStack Query |
|
|
| **Lists** | Virtualization | TanStack Virtual |
|
|
| **Playback** | Media engine | Vidstack, hls.js |
|
|
| **Subtitles** | Rendering | libass-wasm |
|
|
| **Animation** | Transitions | Framer Motion |
|
|
| **Maps** | Locations | Leaflet |
|
|
| **Search** | Fuzzy matching | Fuse.js |
|
|
| **Primitives** | Accessibility | Radix UI |
|
|
|
|
<br>
|
|
|
|
## 🗂️ Project structure
|
|
|
|
```
|
|
jellybloom/
|
|
├── src/
|
|
│ ├── api/ API clients (Jellyfin, TMDB, Fanart, etc.)
|
|
│ ├── components/ UI components (player, detail, discover, layout)
|
|
│ ├── hooks/ Data hooks and player logic
|
|
│ ├── lib/ Utilities, formatters, device profile
|
|
│ ├── pages/ Route pages
|
|
│ ├── stores/ Zustand stores
|
|
│ └── types/ TypeScript declarations
|
|
├── src-tauri/ Rust backend
|
|
│ ├── src/
|
|
│ ├── capabilities/
|
|
│ └── icons/
|
|
├── public/ Static assets
|
|
├── package.json
|
|
├── vite.config.ts
|
|
└── tsconfig.json
|
|
```
|
|
|
|
<br>
|
|
|
|
## 📜 License
|
|
|
|
Dedicated to the public domain under [CC0 1.0 Universal](LICENSE).
|
|
|
|
No copyright, no restrictions, no permission needed. Take it, use it, change it, share it. The culture belongs to everyone.
|