formatters, device profile, media matching, subtitle utils, syncplay, trakt

This commit is contained in:
2026-03-24 10:48:59 +02:00
parent 292b3f42cf
commit 996a85de76
41 changed files with 4306 additions and 0 deletions
+69
View File
@@ -0,0 +1,69 @@
import type { ComponentType } from 'react'
import {
Sword, Swords, Palette, MoodHappy, MasksTheater, Mask, Wand, Ghost, Camera,
QuestionMark, Rocket, Bolt, Shield, HorseToy, News, Microphone, Ball,
Spy, Trophy, MoodKid, Heart, Music, Tv2 as Tv, Film, Backpack,
UserCheck, HomeHeart, Hourglass, Drone, Monument, Confetti, Flame,
Lock, Binoculars, ChefHat, Gavel, Stethoscope, Leaf, MoonStars, Plane,
} from './icons'
type IconType = ComponentType<{ size?: number; stroke?: number; className?: string }>
/**
* Maps a TMDB / Jellyfin genre name to a unique Tabler icon.
* Matches are case-insensitive. Order matters - more specific patterns
* (e.g. "tv movie", "action and adventure", "science fiction", "children")
* come before broader ones so the right icon wins.
*/
const map: Array<[RegExp, IconType]> = [
// Multi-word / compound matches first
[/^action.{0,4}adventure|action.+adventure/i, Swords],
[/^tv movie|television movie/i, Tv],
[/^game.?show/i, Trophy],
[/^talk.?show/i, Microphone],
[/^sci.?fi|science fiction/i, Rocket],
[/^children|kids/i, MoodKid],
// Single-word, alphabetised
[/^action/i, Sword],
[/^adult|erotic/i, Lock],
[/^adventure/i, Backpack],
[/^animation|animated/i, Palette],
[/^biography|biographic/i, UserCheck],
[/^comedy|sitcom/i, MoodHappy],
[/^crime/i, Spy],
[/^document/i, Camera],
[/^drama/i, MasksTheater],
[/^espionage/i, Binoculars],
[/^family/i, HomeHeart],
[/^fantasy/i, Wand],
[/^food|culinary|cooking/i, ChefHat],
[/^histor/i, Monument],
[/^holiday/i, Confetti],
[/^horror/i, Ghost],
[/^legal|law/i, Gavel],
[/^medical|hospital/i, Stethoscope],
[/^music/i, Music],
[/^myster/i, QuestionMark],
[/^natur|wildlife|environment/i, Leaf],
[/^news/i, News],
[/^realit/i, Drone],
[/^romance|romantic/i, Heart],
[/^short/i, Hourglass],
[/^soap/i, Mask],
[/^sport/i, Ball],
[/^supernatural|paranormal|occult/i, MoonStars],
[/^talk/i, Microphone],
[/^thriller|suspense/i, Bolt],
[/^travel/i, Plane],
[/^war/i, Shield],
[/^western/i, HorseToy],
]
export function iconForGenre(name: string | null | undefined): IconType {
if (!name) return Film
for (const [re, Icon] of map) {
if (re.test(name)) return Icon
}
return Flame
}