How phnem/vetro works
Purpose and runtime
Vetro is a local-first Android media-library app for collecting anime, manga/manhwa, films, and series; tracking progress; streaming/downloading video; and reading manga. The primary runtime is Kotlin on Android API 26+, using Jetpack Compose, Koin, SQLDelight, WorkManager, Ktor/Apollo GraphQL, and Media3/ExoPlayer. The app module is app/; reusable network/database/design modules are core/.
Application composition and entry points
VetroApplication initializes application-level dependencies; MainActivity hosts the Compose/navigation UI. Navigation routes separate collection screens from dedicated streaming, local-player, and manga-reader activities.
• app/src/main/java/com/example/myapplication/VetroApplication.kt
• app/src/main/java/com/example/myapplication/MainActivity.kt
• app/src/main/java/com/example/myapplication/ui/navigation/NavGraph.kt
Collection core: local persistence and domain operations
The collection is authoritative locally: SQLDelight schemas store titles, airing/progress, settings, attachments, and sync state. Repository/data-source abstractions feed domain use cases for add/edit, search/import, title normalization, and settings repair/migration. UI ViewModels expose immutable state and dispatch actions through this boundary.
• app/src/main/sqldelight/com/example/myapplication/data/local/Anime.sq
• app/src/main/java/com/example/myapplication/data/local/SQLDelightDatabaseFactory.kt
• app/src/main/java/com/example/myapplication/domain/addedit/SaveAnimeUseCase.kt
Collection UI, discovery, and intelligence
Compose feature screens are organized around home/library, details, add/edit, settings, and image inspection. Recommendations derive genre affinity, scoring, and optional cover visual similarity from local collection data; stats can use cached or BYOK AI-generated explanations. AI credentials, provider routing, and Gemini client integrations remain optional.
• app/src/main/java/com/example/myapplication/ui/home/HomeViewModel.kt
• app/src/main/java/com/example/myapplication/domain/recommendations/RecommendationEngine.kt
• app/src/main/java/com/example/myapplication/data/ai/AiLlmFallbackRouter.kt
Catalog, metadata, and background enrichment
The network core integrates AniList GraphQL plus Kitsu, Shikimori, AniLibria, trace.moe, and GitHub release endpoints. Enrichment coordinates title/metadata/web-link gaps and maintenance through WorkManager, with throttling and a user-facing pause gate for interactive media work. Episode/update workers refresh persisted catalog state and trigger notifications.
• core/network/src/main/java/com/example/myapplication/network/AniListRemoteDataSource.kt
• app/src/main/java/com/example/myapplication/domain/enrichment/CollectionEnrichmentCoordinator.kt
• app/src/main/java/com/example/myapplication/worker/AnimeUpdateWorker.kt
Streaming and offline video pipeline
Details UI requests season/episode resolution, which queries and ranks provider adapters (Kodik, JutSu, AnimeGo, AniLibria, etc.) through the source engine. The stream player consumes resolved playback sources, persists episode progress, applies recovery/diagnostics policies, and supports auto-advance. Downloads use HLS segment retrieval, validation, optional FFmpeg remuxing, and background jobs; local playback separately scans device folders and resolves skip segments, including AniSkip.
• app/src/main/java/com/example/myapplication/media/source/SourceEngine.kt
• app/src/main/java/com/example/myapplication/media/ui/StreamWatchViewModel.kt
• app/src/main/java/com/example/myapplication/media/download/MediaDownloadWorker.kt
Manga acquisition and reading
A manga source engine adapts MangaDex and Remanga. Chapter discovery/page resolution feeds cache/download stores and WorkManager download execution. Reader activities/view models render paged or vertical layouts, prefetch pages, and persist reading position/preferences independently of video progress.
• app/src/main/java/com/example/myapplication/manga/source/MangaSourceEngine.kt
• app/src/main/java/com/example/myapplication/manga/download/MangaDownloadWorker.kt
• app/src/main/java/com/example/myapplication/manga/ui/MangaReaderViewModel.kt
Optional cloud synchronization boundary
Supabase sync is optional and does not replace local persistence. Coordinators synchronize collection/progress, API-key metadata, and attachments, with passphrase/crypto management and safe logging. Supabase Edge Functions mint Cloudflare R2 presigned upload/download URLs and delete remote attachments; database schema/RLS live in Supabase migrations.
• app/src/main/java/com/example/myapplication/sync/supabase/SupabaseSyncCoordinator.kt
• supabase/functions/r2-presign-upload/index.ts
• supabase/migrations/20260625000000_initial_schema.sql
Main entry points: SQLDelightDatabaseFactory.kt Local collection store · SourceEngine.kt Video source engine · SupabaseSyncCoordinator.kt Supabase sync · NavGraph.kt Navigation graph
Components 21
Android app
Local-first collection, media, and reader runtime.
- Vetro application
app/src/main/java/com/example/myapplication/VetroApplication.kt - Main Compose UI
app/src/main/java/com/example/myapplication/MainActivity.kt - Navigation graph · Routes collection screens and dedicated media activities.
app/src/main/java/com/example/myapplication/ui/navigation/NavGraph.kt - Collection ViewModels · Home, library, details, add/edit, and settings state.
app/src/main/java/com/example/myapplication/ui/home/HomeViewModel.kt - Collection domain · Add/edit, import, normalization, and settings repair.
app/src/main/java/com/example/myapplication/domain/addedit/SaveAnimeUseCase.kt - Local collection store · Authoritative titles, progress, settings, attachments, and sync state.
app/src/main/java/com/example/myapplication/data/local/SQLDelightDatabaseFactory.kt - Collection schema
app/src/main/sqldelight/com/example/myapplication/data/local/Anime.sq - Recommendations · Genre, score, and optional cover-similarity recommendations.
app/src/main/java/com/example/myapplication/domain/recommendations/RecommendationEngine.kt - Optional AI router · Provides cached or generated stats explanations.
app/src/main/java/com/example/myapplication/data/ai/AiLlmFallbackRouter.kt - Catalog network · AniList plus metadata, image, and release providers.
core/network/src/main/java/com/example/myapplication/network/AniListRemoteDataSource.kt - Video source engine · Ranks streaming providers and resolves seasons and episodes.
app/src/main/java/com/example/myapplication/media/source/SourceEngine.kt - Stream player · Consumes sources, tracks progress, recovers playback, and auto-advances.
app/src/main/java/com/example/myapplication/media/ui/StreamWatchViewModel.kt - Manga source engine · Adapts MangaDex and Remanga.
app/src/main/java/com/example/myapplication/manga/source/MangaSourceEngine.kt - Manga reader · Renders pages, prefetches, and persists reader position.
app/src/main/java/com/example/myapplication/manga/ui/MangaReaderViewModel.kt
Background pipelines
Scheduled enrichment and offline acquisition.
- Enrichment coordinator · Fills metadata and link gaps with throttling and pause controls.
app/src/main/java/com/example/myapplication/domain/enrichment/CollectionEnrichmentCoordinator.kt - Episode update worker · Refreshes catalog state and triggers notifications.
app/src/main/java/com/example/myapplication/worker/AnimeUpdateWorker.kt - Video download worker · Retrieves and validates HLS segments with optional remuxing.
app/src/main/java/com/example/myapplication/media/download/MediaDownloadWorker.kt - Manga download worker · Caches chapter pages in background.
app/src/main/java/com/example/myapplication/manga/download/MangaDownloadWorker.kt
Optional cloud sync
Sync augments but does not replace local data.
- Supabase sync · Synchronizes collection, progress, key metadata, and attachments.
app/src/main/java/com/example/myapplication/sync/supabase/SupabaseSyncCoordinator.kt - Supabase schema and RLS
supabase/migrations/20260625000000_initial_schema.sql - R2 presign function · Mints attachment transfer URLs and deletes remote attachments.
supabase/functions/r2-presign-upload/index.ts
Connections 24
- Vetro application → Main Compose UI: starts
- Vetro application → Local collection store: initializes
- Main Compose UI → Navigation graph: hosts
- Navigation graph → Collection ViewModels: routes to
- Collection ViewModels → Collection domain: dispatches actions
- Collection domain → Local collection store: reads and writes
- Collection schema → Local collection store: defines
- Collection ViewModels → Recommendations: requests
- Recommendations → Local collection store: analyzes
- Optional AI router → Recommendations: explains stats
- Enrichment coordinator → Catalog network: queries
- Enrichment coordinator → Local collection store: persists gaps
- Episode update worker → Enrichment coordinator: runs
- Navigation graph → Video source engine: opens streaming
- Video source engine → Catalog network: uses provider metadata
- Stream player → Video source engine: consumes resolved source
- Stream player → Local collection store: persists progress
- Video download worker → Video source engine: downloads resolved streams
- Manga reader → Manga source engine: resolves chapters and pages
- Manga reader → Local collection store: persists reading state
- Manga download worker → Manga source engine: downloads pages
- Supabase sync → Local collection store: synchronizes
- Supabase sync → Supabase schema and RLS: syncs with
- Supabase sync → R2 presign function: transfers attachments