mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-15 23:59:08 +00:00
Fixes missing dependencies in useMemo and useCallback hooks to prevent stale closures and potential bugs. Adds null/undefined guards before navigation in music components to prevent crashes when attempting to navigate with missing IDs. Corrects query key from "company" to "genre" in genre page to ensure proper cache invalidation. Updates Jellyseerr references to Seerr throughout documentation and error messages for consistency. Improves type safety by adding error rejection handling in SeerrApi and memoizing components to optimize re-renders.
4.6 KiB
4.6 KiB
CLAUDE.md
@.claude/learned-facts.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Streamyfin is a cross-platform Jellyfin video streaming client built with Expo (React Native). It supports mobile (iOS/Android) and TV platforms, with features including offline downloads, Chromecast support, and Seerr integration.
Development Commands
CRITICAL: Always use bun for package management. Never use npm, yarn, or npx.
# Setup
bun i && bun run submodule-reload
# Development builds
bun run prebuild # Mobile prebuild
bun run ios # Run iOS
bun run android # Run Android
# TV builds (suffix with :tv)
bun run prebuild:tv
bun run ios:tv
bun run android:tv
# Code quality
bun run typecheck # TypeScript check
bun run check # BiomeJS check
bun run lint # BiomeJS lint + fix
bun run format # BiomeJS format
bun run test # Run all checks (typecheck, lint, format, doctor)
# iOS-specific
bun run ios:install-metal-toolchain # Fix "missing Metal Toolchain" build errors
Tech Stack
- Runtime: Bun
- Framework: React Native (Expo SDK 54)
- Language: TypeScript (strict mode)
- State Management: Jotai (global state atoms) + React Query (server state)
- API: Jellyfin SDK (
@jellyfin/sdk) - Navigation: Expo Router (file-based)
- Linting/Formatting: BiomeJS
- Storage: react-native-mmkv
Architecture
File Structure
app/- Expo Router screens with file-based routingcomponents/- Reusable UI componentsproviders/- React Context providershooks/- Custom React hooksutils/- Utilities including Jotai atomsmodules/- Native modules (vlc-player, mpv-player, background-downloader)translations/- i18n translation files
Key Patterns
State Management:
- Global state uses Jotai atoms in
utils/atoms/ settingsAtominutils/atoms/settings.tsfor app settingsapiAtomanduserAtominproviders/JellyfinProvider.tsxfor auth state- Server state uses React Query with
@tanstack/react-query
Jellyfin API Access:
- Use
apiAtomfromJellyfinProviderfor authenticated API calls - Access user via
userAtom - Use Jellyfin SDK utilities from
@jellyfin/sdk/lib/utils/api
Navigation:
- File-based routing in
app/directory - Tab navigation:
(home),(search),(favorites),(libraries),(watchlists) - Shared routes use parenthesized groups like
(home,libraries,search,favorites,watchlists) - IMPORTANT: Always use
useAppRouterfrom@/hooks/useAppRouterinstead ofuseRouterfromexpo-router. This custom hook automatically handles offline mode state preservation across navigation:// ✅ Correct import useRouter from "@/hooks/useAppRouter"; const router = useRouter(); // ❌ Never use this import { useRouter } from "expo-router"; import { router } from "expo-router";
Offline Mode:
- Use
OfflineModeProviderfrom@/providers/OfflineModeProviderto wrap pages that support offline content - Use
useOfflineMode()hook to check if current context is offline - The
useAppRouterhook automatically injectsoffline=trueparam when navigating within an offline context
Providers (wrapping order in app/_layout.tsx):
- JotaiProvider
- QueryClientProvider
- JellyfinProvider (auth, API)
- NetworkStatusProvider
- PlaySettingsProvider
- WebSocketProvider
- DownloadProvider
- MusicPlayerProvider
Native Modules
Located in modules/:
vlc-player- VLC video player integrationmpv-player- MPV video player integration (iOS)background-downloader- Background download functionalitysf-player- Swift player module
Path Aliases
Use @/ prefix for imports (configured in tsconfig.json):
import { useSettings } from "@/utils/atoms/settings";
import { apiAtom } from "@/providers/JellyfinProvider";
Coding Standards
- Use TypeScript for all files (no .js)
- Use functional React components with hooks
- Use Jotai atoms for global state, React Query for server state
- Follow BiomeJS formatting rules (2-space indent, semicolons, LF line endings)
- Handle both mobile and TV navigation patterns
- Use existing atoms, hooks, and utilities before creating new ones
- Use Conventional Commits:
feat(scope):,fix(scope):,chore(scope):
Platform Considerations
- TV version uses
:tvsuffix for scripts - Platform checks:
Platform.isTV,Platform.OS === "android"or"ios" - Some features disabled on TV (e.g., notifications, Chromecast)