No description
Find a file
2026-04-06 09:51:47 +08:00
fastlane chore: Bump build to 9 (1.1.0) 2026-03-11 09:53:51 +08:00
Flixarr feat: Improve push notifications with episode titles, deep linking, and profile-aware navigation 2026-04-06 09:51:39 +08:00
Flixarr.xcodeproj chore: Bump version to 1.2.0 2026-03-17 23:13:02 +08:00
FlixarrTests fix: Fix 7 failing unit tests 2026-03-06 19:14:10 +08:00
FlixarrWidgets chore: Remove all sangarr/managarr references 2026-02-08 22:25:30 +08:00
NotificationServer feat: Improve push notifications with episode titles, deep linking, and profile-aware navigation 2026-04-06 09:51:39 +08:00
.gitignore feat: Add ntfy push notification support via Sonarr/Radarr API 2026-03-15 22:48:57 +08:00
AccentColor.swift feat: Add Calendar Widget (Phase 2.3) 2026-01-20 23:08:01 +08:00
add_diagnostics_view_to_xcode.rb refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
add_files_to_xcode.rb refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
add_model_files_to_xcode.rb refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
add_poster_cache_to_xcode.rb refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
add_service_files_to_xcode.rb refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
add_test_files_to_xcode.rb refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
APP_STORE_CHECKLIST.md docs: Remove personal references and update contact information 2026-02-07 22:52:12 +08:00
APP_STORE_METADATA.md docs: Remove personal references and update contact information 2026-02-07 22:52:12 +08:00
APP_STORE_METADATA.txt docs: Add complete App Store submission metadata 2026-02-08 23:14:17 +08:00
APP_STORE_REVIEWER_CREDENTIALS.txt chore: Prepare for App Store submission with test credentials 2026-02-08 08:20:31 +08:00
APP_STORE_SUBMISSION_INFO.txt docs: Add App Store submission information with live privacy URL 2026-02-07 23:02:43 +08:00
APP_STORE_SUBMISSION_SAFE.txt docs: Add safe App Store submission version based on reviewer feedback 2026-02-07 23:10:30 +08:00
capture-screenshots.sh fix: Remove Netflix branding from user-facing UI strings and add iPad 13" screenshot option 2026-02-25 00:07:57 +08:00
CLAUDE.md chore: Prohibit Claude co-author attribution in commit messages 2026-03-01 00:53:56 +08:00
CONTINUATION_NOTES.md docs: Add comprehensive session continuation notes 2026-02-08 23:18:20 +08:00
CRITICAL_ACTIONS_BEFORE_SUBMIT.md docs: Add critical action checklist for safe App Store submission 2026-02-07 23:11:17 +08:00
feral-setup-info.txt chore: Prepare for App Store submission with test credentials 2026-02-08 08:20:31 +08:00
FERAL_SETUP_COMPLETE.md chore: Prepare for App Store submission with test credentials 2026-02-08 08:20:31 +08:00
FERAL_SETUP_GUIDE.md docs: Add Feral Hosting cleanup and test server setup guide 2026-02-07 23:23:50 +08:00
FILTER_IMPLEMENTATION_PLAN.md feat: Implement comprehensive filtering and sorting for Series and Movies 2026-02-28 12:57:55 +08:00
fix_poster_cache_path.rb refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
FlixarrLogo.svg refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
Gemfile chore: Add Fastlane setup with release lane 2026-03-06 13:41:12 +08:00
Gemfile.lock chore: Add Fastlane setup with release lane 2026-03-06 13:41:12 +08:00
IMPLEMENTATION_PLAN.md feat: Add ntfy push notification support via Sonarr/Radarr API 2026-03-15 22:48:57 +08:00
MULTI-PROFILE-PLAN.md Added plan for multi profile plan 2026-01-25 22:12:02 +08:00
NETFLIX-GENRE.md refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
PHASE3_COMPLETE.md refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
PHASE4_COMPLETE.md refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
PHASE4_IMPLEMENTATION_DETAILS.md refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
PHASE7_COMPLETION.md refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
PHASE8_COMPLETION.md refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
PHASE9_COMPLETION.md refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
PHASE_3.1_INVESTIGATION.md docs: Complete Phase 3.1 push notifications investigation 2026-01-18 22:53:48 +00:00
PHASES_7_8_SUMMARY.md refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
PLEX_CONNECTION_DESIGN.md refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
POSTER_CACHE_OPTIMIZATION.md refactor: Complete rebrand from Sangarr to Flixarr 2026-01-25 00:08:21 +08:00
privacy.html docs: Remove personal references and update contact information 2026-02-07 22:52:12 +08:00
PRIVACY_HOSTING_GUIDE.md docs: Remove personal references and update contact information 2026-02-07 22:52:12 +08:00
PRIVACY_POLICY.md docs: Remove personal references and update contact information 2026-02-07 22:52:12 +08:00
PUSH_NOTIFICATIONS_PLAN.md feat: Replace ntfy with native iOS push notifications via Cloudflare Worker 2026-03-16 23:43:24 +08:00
README.md docs: Update documentation to reflect current project state 2026-02-25 00:07:56 +08:00
ROADMAP.md docs: Mark 1.2.3 iCloud Settings Sync as complete in roadmap 2026-03-01 00:53:56 +08:00
SUBMISSION_CHECKLIST.md docs: Add comprehensive App Store submission checklist 2026-02-08 23:15:06 +08:00
USER_GUIDE_COMPOSITE_GENRES.md feat: Add Netflix-like composite genres with ML-assisted discovery 2026-01-23 10:29:56 +08:00

Flixarr

A native iOS app for managing your Sonarr (TV series) and Radarr (movies) instances with integrated Plex playback support.

Features

Home Dashboard

  • At-a-Glance Overview: Comprehensive dashboard showing library statistics, system status, and quick actions
  • Statistics Cards: Total series/movies, episodes, upcoming content, and Plex connection status
  • Continue Watching: Resume your in-progress content with visual progress bars
  • AI Recommendations: Personalized suggestions based on your viewing habits
  • Composite Genres: Netflix-style intelligent genre categories combining language, country, and traditional genres
  • Recently Added to Plex: View the 10 most recent items added to your Plex library with direct playback
  • Upcoming Content: Horizontal scrolling cards showing next releases
  • Quick Actions: Fast access to add content, view calendar, and check activity
  • System Status: Real-time monitoring of Sonarr, Radarr, and Plex connection states

Core Management

  • Dual Service Support: Manage both Sonarr (TV series) and Radarr (movies) from a single app
  • Modern List Views: Card-based layouts with gradient icons, metadata pills, and status badges
  • Browse Libraries: View all your series and movies with posters, metadata, and statistics
  • Search & Add Content: Modern search cards with quality profile and root folder selection
  • Delete Content: Remove series or movies from your library with optional file deletion
  • Activity Queue: Monitor active downloads with gradient progress bars and status indicators

Plex Integration

  • Recently Added Section: See what's new in Plex with direct playback from home screen
  • Continue Watching: Resume playback from where you left off with progress tracking
  • AI-Powered Recommendations: Personalized content suggestions based on watch history and preferences
  • Multi-Server Support: Connect to multiple Plex servers with automatic discovery via Plex.tv
  • Advanced Connection Management: Intelligent connection probing, caching, and automatic failover
  • Connection Diagnostics: Built-in diagnostics view to troubleshoot connection issues
  • Connection Types: Supports both Plex.Direct and custom domain connections
  • Content Availability: Automatic detection of content availability in your Plex library
  • Fullscreen Browser Playback: Stream content with fullscreen Plex web player and improved controls (default)
  • Multiple Playback Options: Choose between browser, Plex app, or in-app AVPlayer
  • Context Menus: Long-press for playback options on any Plex-available content
  • Watch Progress: View watch progress indicators for tracked content
  • Episode Navigation: Previous/next episode buttons in video player for binge-watching
  • Profile Support: Maintains Plex profile authentication and PIN protection
  • Enhanced Authentication: Seamless token-based authentication for web playback
  • TMDB & TVDB Integration: Enhanced metadata fetching from TheMovieDB and TheTVDB

Multi-Profile Support

  • Multiple Configurations: Create and manage multiple server profiles with isolated settings
  • Profile Switching: Quick switching between different Sonarr/Radarr/Plex configurations
  • Profile Editor: Dedicated editor for creating and managing profiles
  • Profile Picker: Easy-to-use profile selection interface
  • Isolated Settings: Each profile maintains its own API keys, URLs, and preferences

Composite Genres (Netflix-Style)

  • Intelligent Categorization: Automatically generates genre combinations like "Korean Thriller", "Japanese Anime", "Chinese Romance Drama"
  • Multi-Dimensional Matching: Combines language, country, and traditional genres for precise categorization
  • Rule-Based + ML: Uses both rule-based logic and ML clustering for comprehensive genre generation
  • Auto-Refresh: Configurable auto-refresh period (15 minutes to 1 day) with manual refresh option
  • Interactive Cards: Tap movies to play directly, tap series to see Netflix-style episode selector
  • Episode Selector: Season picker with episode thumbnails, summaries, and playback integration
  • Genre Explanations: Long-press any item to see why it was included in that genre
  • Accent Color Theming: Genre cards follow the app's accent color for consistent design
  • Smart Filtering: Only shows genres with at least 3 matching items and high confidence scores

Video Player

  • In-App Playback: Native AVPlayer-based video playback
  • Episode Navigation: Previous/next episode buttons for seamless binge-watching
  • Progress Tracking: Automatic position saving and resume support
  • Subtitle Support: Change subtitles during playback (may require restart)
  • Audio Session Management: Proper audio category handling for background playback
  • Fullscreen Mode: Automatic orientation lock in landscape for immersive viewing
  • Watch History: Automatic recording for AI recommendations
  • Series Context: Understands series/season/episode context for navigation

Continue Watching

  • Progress Tracking: Automatically tracks playback position for all content
  • Resume Playback: Pick up exactly where you left off
  • Visual Progress Bars: See progress at a glance on content cards
  • Cross-Session Sync: Progress persists across app launches
  • Series & Movies: Works for both TV episodes and movies
  • In-App Tracking: Tracks playback from VideoPlayerView

AI-Powered Recommendations

  • Personalized Suggestions: Content recommendations based on your watch history
  • Genre-Based Matching: Suggests similar content from your library
  • Watch History Analysis: Learns from your viewing patterns
  • Confidence Scores: Shows how well each recommendation matches your preferences
  • Real-Time Updates: Recommendations refresh as you watch more content
  • Privacy-Focused: All processing happens locally on device

Manual Import

  • Failed Download Recovery: Manually import files when automatic import fails
  • File Selection: View and select files with quality, episode/movie info, and rejection reasons
  • Smart Auto-Selection: Automatically selects files without rejections
  • Retry Logic: Automatic retry with delays for directory scanning
  • Status Indicators: Clear status display showing "Download completed" and "• Importing" states

Calendar & Navigation

  • Unified Calendar: View upcoming episodes and movie releases in a monthly calendar
  • Modern Calendar Design: Better day cell styling with gradient icons for events
  • Tab Navigation: Tap calendar items to navigate to series/movies with automatic tab switching
  • Date Selection: Filter calendar items by selected date
  • Calendar Widget: iOS Home Screen widget showing upcoming releases

Queue Management

  • Real-Time Status: View download progress with gradient progress bars
  • Queue Actions: Remove items, blocklist releases, or trigger manual retry
  • Import Status: Visual indicators for import failures with manual import button
  • Multi-Source Display: Combined view of Sonarr and Radarr queue items sorted by date
  • Modern Cards: Status badges, metadata pills, and gradient progress visualization
  • File Renaming: Preview and rename files before import with RenamePreviewSheet

Storage Management

  • Directory Browser: Modern card-based directory picker with visual hierarchy
  • Path Display: View current storage path for each series/movie
  • Root Folder Selection: Choose storage location when adding new content
  • Breadcrumb Navigation: Clear parent directory navigation

Modern Design System

  • Gradient Icons: Color-coded icons for TV (cyan/blue) and Movies (indigo/purple)
  • Status Badges: Capsule-shaped indicators for monitoring, download, and connection states
  • Metadata Pills: Small pills displaying year, network, quality, and other metadata
  • Progress Bars: Custom gradient-filled progress indicators
  • Card Layouts: Consistent card-based design with shadows and rounded corners
  • Loading States: Modern loading indicators with descriptive messages
  • Empty States: Friendly empty state views with gradient icons
  • Animations: Smooth transitions respecting accessibility preferences

Accessibility & Polish

  • VoiceOver Support: Comprehensive accessibility labels and hints
  • Dynamic Type: Scalable fonts supporting user preferences
  • Reduced Motion: All animations respect accessibility settings
  • High Contrast: Color-coded elements with sufficient contrast
  • Touch Targets: Appropriately sized interactive elements

iOS Integration

  • Siri Shortcuts: Add series/movies, check queue, and search via Siri
  • Spotlight Search: Search your library directly from iOS Spotlight
  • Home Screen Widget: Upcoming releases widget for quick access
  • Accent Colors: Customize app appearance with 9 color options
  • Dark Mode: Full support for light, dark, and automatic appearance modes

User Interface

  • Native SwiftUI: Modern, native iOS interface built with SwiftUI
  • Responsive Layout: Optimized for all iPhone screen sizes
  • Pull to Refresh: Refresh content with simple pull-down gesture
  • Quick Search: Fast search within series and movie lists
  • Tab Navigation: Organized into Home, Series, Movies, Calendar, Activity, Status, Settings, and Support tabs

Requirements

  • iOS 17.0 or later
  • Xcode 15.0 or later (for building from source)
  • Sonarr v3 API or Radarr v3 API
  • (Optional) Plex Media Server for playback integration

Getting Started

Installation

  1. Clone or download this repository
  2. Open Flixarr.xcodeproj in Xcode
  3. Select your target device or simulator
  4. Build and run the project (⌘R)

Configuration

Sonarr Setup

  1. Open the app and go to the Settings tab
  2. Scroll to the Sonarr section
  3. Enter your Sonarr server URL (e.g., http://192.168.1.100:8989)
  4. Enter your API key (found in Sonarr: Settings → General → Security → API Key)
  5. Tap Test Connection to verify the settings

Radarr Setup

  1. In the Settings tab, scroll to the Radarr section
  2. Enter your Radarr server URL (e.g., http://192.168.1.100:7878)
  3. Enter your API key (found in Radarr: Settings → General → Security → API Key)
  4. Tap Test Connection to verify the settings

Plex Setup (Optional)

  1. In the Settings tab, scroll to the Plex section
  2. Tap Sign in with Plex
  3. Complete the OAuth authentication flow in Safari
  4. Select your Plex server from the available servers list (Plex.Direct connections recommended)
  5. The app will automatically check content availability
  6. (Optional) Configure playback preference: Browser (default), Plex App, In-App Player, or Auto

Project Structure

Flixarr/
├── FlixarrApp.swift                 # App entry point with service initialization
├── ContentView.swift                # Main tab view with navigation coordination
├── Models/
│   ├── Series.swift                 # Series data model (Sonarr)
│   ├── Episode.swift                # Episode data model (Sonarr)
│   ├── Movie.swift                  # Movie data model (Radarr)
│   ├── CalendarItem.swift           # Unified calendar item model
│   ├── MediaItem.swift              # Unified Plex media snapshot
│   ├── MediaFeatures.swift          # Feature vectors for ML processing
│   ├── CompositeGenre.swift         # Composite genre definition
│   ├── CompositeGenreMembership.swift # Item-genre relationship tracking
│   ├── Profile.swift                # Multi-profile configuration model
│   ├── Recommendation.swift         # AI recommendation model
│   ├── RecentlyWatched.swift        # Watch history tracking model
│   ├── PlexConnection.swift         # Plex connection configuration
│   ├── CachedConnection.swift       # Cached connection data
│   ├── ConnectionScore.swift        # Connection quality scoring
│   ├── NetworkIdentifier.swift      # Network identification model
│   ├── TMDBMedia.swift              # TheMovieDB metadata model
│   ├── TVDBMedia.swift              # TheTVDB metadata model
│   ├── AccentColor.swift            # Accent color preferences
│   └── AppearanceMode.swift         # Theme preferences
├── Services/
│   ├── SonarrService.swift          # Sonarr API client with queue & manual import
│   ├── RadarrService.swift          # Radarr API client with queue & manual import
│   ├── PlexService.swift            # Plex API client with OAuth
│   ├── PlexNotificationService.swift # Recently added to Plex matching
│   ├── PlexMediaItemFetcher.swift   # Plex library metadata fetcher
│   ├── PlexWebView.swift            # Plex OAuth & web playback views
│   ├── PlexConnectionManager.swift  # Plex connection orchestration
│   ├── PlexConnectionProber.swift   # Connection health checking
│   ├── PlexConnectionSelector.swift # Intelligent connection selection
│   ├── PlexConnectionCache.swift    # Connection caching service
│   ├── CompositeGenreService.swift  # Composite genre orchestration
│   ├── GenreRuleEngine.swift        # Rule-based genre generation
│   ├── MLProcessor.swift            # ML clustering for genre suggestions
│   ├── CacheService.swift           # Local caching with TTL
│   ├── CalendarCacheService.swift   # Dedicated calendar caching
│   ├── PosterCacheService.swift     # Poster image caching
│   ├── ExternalMediaCacheService.swift # External media caching
│   ├── PlaybackCoordinator.swift    # Playback routing logic
│   ├── ContinueWatchingService.swift # Watch progress tracking
│   ├── RecommendationService.swift  # AI-powered recommendations
│   ├── SeriesWatchStateService.swift # Series watch state tracking
│   ├── ProfileManager.swift         # Multi-profile management
│   ├── MediaItemResolver.swift      # Media item resolution logic
│   ├── TMDBService.swift            # TheMovieDB API client
│   ├── TVDBService.swift            # TheTVDB API client
│   ├── EncryptionService.swift      # Settings encryption for sync
│   ├── SharedDataManager.swift      # App group data sharing
│   └── SpotlightService.swift       # Spotlight search indexing
├── Intents/
│   ├── AppShortcuts.swift           # Siri Shortcuts definitions
│   ├── AddSeriesIntent.swift        # Add series via Siri
│   ├── AddMovieIntent.swift         # Add movie via Siri
│   ├── CheckQueueIntent.swift       # Check queue via Siri
│   ├── SearchMediaIntent.swift      # Search content via Siri
│   └── IntentModels.swift           # Intent data models
├── Views/
│   ├── HomeView.swift               # Dashboard with stats, genres, recently added
│   ├── GenreMediaCard.swift         # Composite genre media cards
│   ├── GenreExplanationSheet.swift  # Genre membership explanation
│   ├── PlexSeriesEpisodeSheet.swift # Netflix-style episode selector
│   ├── ContinueWatchingCard.swift   # Continue watching media cards
│   ├── RecommendationCard.swift     # AI recommendation cards
│   ├── RecommendationSection.swift  # Recommendation section layout
│   ├── PlexRecentlyAddedCard.swift  # Recently added Plex content cards
│   ├── ProfileEditorView.swift      # Multi-profile editor
│   ├── ProfilePickerSheet.swift     # Profile selection sheet
│   ├── SeriesListView.swift         # Modern series list with cards
│   ├── SeriesDetailView.swift       # Series details with modern UI
│   ├── SeriesAddConfigView.swift    # Series configuration with modern UI
│   ├── MovieListView.swift          # Modern movie list with cards
│   ├── MovieDetailView.swift        # Movie details with modern UI
│   ├── MovieAddConfigView.swift     # Movie configuration with modern UI
│   ├── AddSeriesView.swift          # Modern search and add series
│   ├── AddMovieView.swift           # Modern search and add movies
│   ├── CalendarView.swift           # Modern monthly calendar view
│   ├── ManualImportView.swift       # Manual import file selection
│   ├── RenamePreviewSheet.swift     # File rename preview interface
│   ├── PlexConnectionDiagnosticsView.swift # Plex connection troubleshooting
│   ├── SettingsView.swift           # Modern settings with gradient icons
│   ├── ShortcutsSettingsView.swift  # Siri Shortcuts configuration
│   ├── ServerStatusView.swift       # Server status with modern cards
│   ├── DirectoryBrowserView.swift   # Modern directory picker
│   ├── VideoPlayerView.swift        # In-app video playback with episode navigation
│   └── SupportView.swift            # Support/donation information
├── Styles/
│   ├── ModernComponents.swift       # Modern UI components (badges, pills, icons)
│   ├── DesignSystem.swift           # Design constants (spacing, colors, gradients)
│   ├── ButtonStyles.swift           # Standardized button styles
│   ├── ContainerStyles.swift        # Card and container styles
│   ├── AnimationStyles.swift        # Animation modifiers
│   ├── FeedbackStyles.swift         # Error and success feedback
│   └── ProgressViewStyles.swift     # Progress view configurations
├── Widgets/
│   └── CalendarWidget.swift         # Home Screen widget for upcoming content
└── Assets.xcassets/                 # App assets and icons

API Integration

Sonarr v3 API

  • GET /api/v3/series - Fetch all series
  • GET /api/v3/series/{id} - Fetch series details
  • POST /api/v3/series - Add new series
  • DELETE /api/v3/series/{id} - Remove series
  • GET /api/v3/episode - Fetch episodes for a series
  • GET /api/v3/calendar - Fetch upcoming episodes
  • GET /api/v3/queue - Fetch download queue
  • DELETE /api/v3/queue/{id} - Remove from queue
  • POST /api/v3/queue/grab/{id} - Retry download
  • GET /api/v3/manualimport - Fetch files for manual import
  • POST /api/v3/command - Execute commands (manual import, rescan, etc.)
  • GET /api/v3/rootfolder - Fetch available root folders
  • GET /api/v3/qualityprofile - Fetch quality profiles
  • GET /api/v3/series/lookup - Search for series
  • GET /api/v3/filesystem - Browse directory structure

Radarr v3 API

  • GET /api/v3/movie - Fetch all movies
  • POST /api/v3/movie - Add new movie
  • DELETE /api/v3/movie/{id} - Remove movie
  • GET /api/v3/calendar - Fetch upcoming movie releases
  • GET /api/v3/queue - Fetch download queue
  • DELETE /api/v3/queue/{id} - Remove from queue
  • POST /api/v3/queue/grab/{id} - Retry download
  • GET /api/v3/manualimport - Fetch files for manual import
  • POST /api/v3/command - Execute manual import command
  • GET /api/v3/rootfolder - Fetch available root folders
  • GET /api/v3/qualityprofile - Fetch quality profiles
  • GET /api/v3/movie/lookup - Search for movies
  • GET /api/v3/filesystem - Browse directory structure

Plex API

  • POST /pins - Initiate OAuth PIN authentication
  • GET /pins/{id} - Poll for authentication completion
  • GET /pms/resources - Discover available Plex servers
  • GET /library/sections - Fetch library sections
  • GET /library/sections/{id}/all - Fetch all library content with metadata
  • GET /library/metadata/{ratingKey} - Fetch show/season metadata
  • GET /library/metadata/{ratingKey}/children - Fetch episodes for a season
  • GET /video/:/transcode/universal/start.m3u8 - Get HLS stream URL

TMDB API (TheMovieDB)

  • Enhanced metadata fetching for movies and TV shows
  • Poster and backdrop image retrieval
  • Cast and crew information
  • External ID mapping (IMDB, TVDB)

TVDB API (TheTVDB)

  • TV series metadata enrichment
  • Episode information and air dates
  • Series artwork and banners
  • External ID cross-referencing

Data Storage

UserDefaults Keys

  • Sonarr: sonarr_url, sonarr_api_key
  • Radarr: radarr_url, radarr_api_key
  • Plex: plex_token, plex_username, plex_client_id, plex_selected_server, plex_server_url
  • Composite Genres: composite_genres_enabled, composite_genre_refresh_hours, composite_genre_last_generation
  • Profiles: active_profile_id, profiles_list
  • Recommendations: recommendation_enabled, recommendation_refresh_interval
  • Continue Watching: continue_watching_enabled
  • External Services: tmdb_api_key, tvdb_api_key
  • Theme: appearance_mode (system/light/dark), accent_color

Local Cache

  • Series/Movies: 5-minute TTL
  • Episodes: 10-minute TTL
  • Queue: 30-second TTL
  • Calendar: 5-minute TTL (CalendarCacheService)
  • Composite Genres: 24-hour TTL
  • Media Items/Features: 24-hour TTL
  • Posters/Images: Permanent cache with LRU eviction (PosterCacheService)
  • Plex Connections: Smart caching with probing (PlexConnectionCache)
  • Continue Watching: Session-based cache
  • Recommendations: 6-hour TTL
  • External Media: 24-hour TTL (ExternalMediaCacheService)
  • Files stored in Documents/Cache/ directory

Architecture

State Management

  • @StateObject + @EnvironmentObject Pattern: Services are created as @StateObject in FlixarrApp and injected via @EnvironmentObject
  • ObservableObject Services: Core services include:
    • Media Management: SonarrService, RadarrService
    • Plex Integration: PlexService, PlexNotificationService, PlexConnectionManager
    • Recommendations: RecommendationService, ContinueWatchingService
    • Genres: CompositeGenreService
    • Profiles: ProfileManager
    • External APIs: TMDBService, TVDBService
  • async/await: All network operations use Swift's modern concurrency
  • MainActor: UI updates properly dispatched to main thread

Service Layer

Each service is an ObservableObject that:

  • Manages authentication state (API keys/tokens in UserDefaults)
  • Publishes data arrays (@Published var series, @Published var movies)
  • Publishes loading state (@Published var isLoading)
  • Publishes error messages (@Published var errorMessage)
  • Uses custom URLSession with appropriate timeouts
  • Updates UI state safely via await MainActor.run { }
  • Implements caching with TTL for performance

Design System

  • ModernComponents: Reusable UI components (GradientIcon, StatusBadge, MetadataPill, etc.)
  • Consistent Spacing: Standardized spacing scale (xs, sm, md, lg, xl, xxl, xxxl)
  • Color Palette: Brand colors for TV (cyan/blue) and Movies (indigo/purple)
  • Gradients: Custom gradient definitions for visual polish
  • Animations: Smooth transitions respecting accessibility preferences

Navigation

  • NavigationCoordinator: Coordinates tab switching and deep linking
  • Tab-Based Navigation: Main content organized in 8 tabs (Home, Series, Movies, Calendar, Activity, Status, Settings, Support)
  • Deep Linking: Calendar items can navigate to series/movies with automatic tab switching
  • Spotlight Integration: Content searchable from iOS Spotlight
  • Siri Shortcuts: Voice-activated actions for common tasks

Manual Import Feature

How It Works

  1. Queue item shows import failure with manual import button (green import icon)
  2. Tap button to open ManualImportView
  3. App fetches available files with metadata (quality, episodes/movie, rejections)
  4. Files without rejections are auto-selected
  5. Review and modify selection as needed
  6. Tap "Import" to queue the manual import command
  7. Queue refreshes automatically after import

API Flow

1. GET /api/v3/manualimport?downloadId=X&folder=Y&filterExistingFiles=false
   → Returns list of files with metadata

2. POST /api/v3/command
   Body: {
     "name": "ManualImport",
     "files": [
       {
         "path": "/path/to/file.mkv",
         "seriesId": 152,          // or movieId for Radarr
         "episodeIds": [15780],
         "quality": { ... },
         "languages": [ ... ],
         "releaseGroup": "...",
         "downloadId": "..."
       }
     ],
     "importMode": "auto"
   }
   → Queues import command, returns 201 Created

State Management

  • Uses ManualImportInfo struct with .sheet(item:) to ensure proper state capture
  • Avoids SwiftUI timing issues with reliable data passing
  • Implements retry logic for directory scanning delays

Composite Genres Feature

How It Works

  1. Fetches all media items from Plex with comprehensive metadata (language, country, genres, studios)
  2. Generates feature vectors from each item for ML processing
  3. Uses dual-method genre generation:
    • Rule-Based Engine: Deterministic combinations (e.g., "Korean" + "Drama" → "Korean Drama")
    • ML Clustering: K-means clustering on feature vectors for pattern discovery
  4. Merges and filters genres (minimum 3 items, confidence thresholds)
  5. Creates memberships linking items to genres with explanations
  6. Caches results with 24-hour TTL for performance

Genre Components

Each composite genre combines:

  • Language: Chinese, Korean, Japanese, English, Spanish, French
  • Country: China, South Korea, Japan, US, UK, France
  • Primary Genre: Action, Drama, Comedy, Horror, Thriller, Romance, Sci-Fi, Animation
  • Secondary Genres: Additional genre modifiers for precision

User Controls

  • Enable/Disable: Toggle in Settings → Composite Genres
  • Auto-Refresh: Configurable period (15 minutes to 1 day)
  • Manual Refresh: Force immediate regeneration
  • Server Change: Automatically refreshes when Plex server changes

API Flow

1. GET /library/sections → Fetch all Plex library sections
2. GET /library/sections/{id}/all → Fetch all items with metadata
3. Generate MediaItems → Convert Plex data to unified format
4. Generate Features → Extract multi-dimensional features
5. GenreRuleEngine → Rule-based genre generation
6. MLProcessor → ML-assisted clustering
7. Merge & Filter → Combine and quality check
8. Create Memberships → Link items to genres with explanations

Advanced Plex Connection Management

PlexConnectionManager

Flixarr uses an intelligent connection management system for reliable Plex server access:

Features:

  • Connection Probing: Actively tests all available connection methods (direct, relay, local)
  • Quality Scoring: Ranks connections based on latency, bandwidth, and reliability
  • Automatic Failover: Seamlessly switches to backup connections if primary fails
  • Smart Caching: Remembers successful connections for faster future access
  • Network Awareness: Adapts to network changes (WiFi, cellular, VPN)
  • Connection Diagnostics: Built-in troubleshooting view for connection issues

Components:

  • PlexConnectionManager: Orchestrates connection lifecycle and selection
  • PlexConnectionProber: Tests connection health and measures performance
  • PlexConnectionSelector: Chooses optimal connection based on scoring algorithm
  • PlexConnectionCache: Caches successful connections with TTL

Connection Priority:

  1. Local network (direct IP)
  2. Plex.Direct (secure relay)
  3. Custom domains
  4. Plex relay (fallback)

Diagnostics View: Access via Settings → Plex → Connection Diagnostics to:

  • View all available connections
  • See real-time connection scores
  • Test individual connections
  • View detailed error messages
  • Force connection refresh

Security

  • API keys stored in UserDefaults (consider iOS Keychain for production)
  • Plex OAuth tokens stored securely in UserDefaults
  • HTTPS enforced by default (NSAppTransportSecurity allows local HTTP exceptions)
  • No credentials transmitted; uses Plex OAuth PIN flow
  • Encryption key for settings sync stored in iOS Keychain (never syncs to iCloud)

Building & Testing

Build Commands

# Build for simulator
xcodebuild -project Flixarr.xcodeproj -scheme Flixarr -sdk iphonesimulator build

# Build for specific device
xcodebuild -project Flixarr.xcodeproj -scheme Flixarr -configuration Debug \
  -destination 'platform=iOS Simulator,name=iPhone 15' build

# Clean build
xcodebuild -project Flixarr.xcodeproj -scheme Flixarr clean

Testing

# List available simulators
xcrun simctl list devices available

# Install and launch
xcrun simctl install booted path/to/Flixarr.app
xcrun simctl launch booted com.sangarr.app

# Monitor logs
log stream --predicate 'processImagePath contains "Flixarr"' --level debug

iOS Integration Features

Siri Shortcuts

Flixarr supports the following Siri Shortcuts:

  • Add Movie: Voice-activated movie search and addition
  • Add Series: Voice-activated series search and addition
  • Check Queue: Quick queue status check
  • Search for Movie/Series: Voice search functionality
  • All series and movies in your library are indexed in iOS Spotlight
  • Search directly from home screen to quickly access content
  • Tapping search results opens the app to the specific item

Home Screen Widget

  • Calendar Widget: Shows upcoming releases on your home screen
  • Updates automatically to keep you informed of new content
  • Available in multiple widget sizes

Customization

  • 9 Accent Colors: Personalize the app with your preferred color scheme
  • Appearance Modes: Light, Dark, or System automatic
  • Playback Preferences: Configure default playback method (Browser, Plex App, In-App)

Known Limitations

  • Manual import requires both downloadId and folder path from queue item
  • First manual import load may require 10+ seconds for server directory scanning
  • Recently Added to Plex requires at least one service (Sonarr or Radarr) to be configured
  • Composite Genres require Plex to be configured and at least 3 items per genre
  • Cache invalidation is time-based (TTL), not event-based
  • Genre generation accuracy depends on Plex metadata quality (language, country, genres)
  • AI Recommendations require sufficient watch history (minimum 5 watched items)
  • Continue Watching only tracks playback within the app (not external Plex clients)
  • Profile switching requires app restart to fully apply all settings
  • TMDB/TVDB integration requires valid API keys (optional feature)

Plex Playback

Browser is Default: The app uses in-app browser playback by default instead of the native Plex app due to known issues with Plex's iOS app deep linking.

Plex App Deep Linking Issues (as of v2025.31.1):

  • Navigation Failure: The plex:// URL scheme opens the Plex app but navigates to the home screen instead of the specific content
  • Managed Profiles with PINs: When Plex profiles have PIN protection enabled, deep links cause an infinite PIN loop:
    • App accepts the PIN
    • Attempts to play content
    • Loses profile context
    • Requests PIN again → repeat
  • No Profile Context: The deep link URL scheme doesn't support passing profile authentication or user context

Recommended Solution:

  • Keep default playback set to "Browser" in Settings → Playback Preference
  • The in-app browser provides:
    • Reliable playback every time
    • Full Plex web interface with all features
    • Proper authentication with profile context
    • No PIN issues
    • True fullscreen with tap-to-show overlay controls

Plex App Option:

  • You can still try using the Plex app by changing Settings → Playback Preference to "Always Plex App"
  • Or use the context menu (long-press Play button) → "Open in Plex App"
  • Note: This may not work reliably due to the issues above

Future Enhancements

See IMPLEMENTATION_PLAN.md for detailed roadmap. Planned features include:

  • Push Notifications: Real-time notifications for downloads and Plex availability (Phase 3.2)
  • Additional Widgets: Continue watching and recommendations widgets (Phase 3.3)
  • Enhanced Plex Integration: Watch history sync with external Plex clients, auto-play when ready (Phase 3.4)
  • Dynamic Type Support: Full support for iOS Dynamic Type accessibility
  • Series/Movie Rescan: Manual rescan functionality for library updates
  • Advanced Recommendation Tuning: User-adjustable recommendation preferences and filters

Contributing

This is a personal project for managing media servers. Feel free to fork and customize for your own use.

License

This project is provided as-is for personal use.