How nisanray/mediatubepro works
1. Overall shape: MediaTube Pro is a Flutter application with a desktop-first UI, but it still ships standard platform shells for Android, iOS, Linux, macOS, Windows, and web. The native folders are mostly thin launch/config wrappers; the app logic lives under lib/.
2. Layered architecture: The Dart code is split into core, domain, data, presentation, and routes. Dependency flow is intentionally inward: UI talks to controllers, controllers call use cases, use cases depend on repository interfaces, and the concrete repository implementations live in data/.
3. UI and navigation: lib/presentation contains the visible app surfaces: downloader, download details, history, logs, and settings. main_layout.dart plus the sidebar/topbar/right-sidebar widgets form the desktop shell, while lib/routes holds named route definitions used for GetX-style navigation.
4. Controller-driven state: Each major screen has a controller in lib/presentation/controllers. These controllers own reactive state such as queue items, filters, selected task details, logs, and settings values, and they coordinate user actions like retry, pause, cancel, open-folder, and search.
5. Use-case boundary: The domain layer models the app’s intent with DownloadTask and HistoryEntry, plus repository contracts and use cases such as start_download, cancel_download, and get_history. This keeps the business logic independent from process execution and storage details.
6. Download execution boundary: The main external integration is yt-dlp, launched from lib/data/datasources/process/ytdlp_datasource.dart. That datasource is the subprocess boundary where URL extraction, progress output, completion, and failures are translated into app events. ffmpeg is a required companion for merge/processing steps.
7. Local binary resolution: lib/core/utils/binary_locator.dart and config/constants files determine where the app finds executables. The repo expects local binaries under asset/bin/ as a bundled fallback, but settings can override the executable paths. This is a key architectural boundary because downloads cannot proceed without valid local tool paths.
8. Persistence and settings: lib/data/datasources/local/history_datasource.dart and settings_datasource.dart handle local storage of completed downloads and user preferences. Repository implementations adapt those records into domain entities and expose them to the rest of the app. The README indicates GetStorage is used for task/state persistence.
9. Queue and playlist management: download_repository_impl.dart and playlist_task_tracker.dart manage the reactive download queue, including playlist expansion and item-level tracking. This is why the UI can show per-item status, detail views, retry/cancel controls, and playlist child entries rather than treating each URL as a single opaque job.
10. History and diagnostics: Completed downloads are written into a searchable history view with metadata such as channel, thumbnail, and format. Separate logs screens capture runtime/process issues, which is important because most failures come from binary discovery, subprocess output, or merge problems rather than Flutter UI errors.
11. Shared foundation: lib/core contains app-wide constants, theme, typography, spacing, formatters, filename helpers, and exception types. These utilities keep UI styling and download metadata formatting consistent across screens.
12. Platform packages and tests: The native Android/iOS/desktop folders are standard Flutter host projects; they do not contain major business logic. The test/ folder focuses on wiring and behavior around download tasks, cancellation settings, details-page actions, and the logs controller, which matches the app’s architecture around task orchestration and local state.
Main entry points: download_repository_impl.dart Download repo · main_layout.dart Main layout · downloader_controller.dart Downloader ctrl · download_repository.dart Download contract
Components 27
Flutter app
Shared Dart application layers and runtime entrypoints.
- App entry · Bootstraps the app and wiring for shared runtime initialization.
lib/main.dart - Core · App-wide constants, theme, utilities, and error types.
lib/core - Routes · Named routes and page registration for app navigation.
lib/routes - Download task · Domain model for an active or queued download.
lib/domain/entities/download_task.dart - History entry · Domain model for a completed download record.
lib/domain/entities/history_entry.dart - Download contract · Domain boundary for download queue and task operations.
lib/domain/repositories/download_repository.dart - Settings contract · Domain boundary for app settings persistence.
lib/domain/repositories/settings_repository.dart - Start download · Triggers download execution from a URL or playlist.
lib/domain/usecases/start_download_usecase.dart - Cancel download · Stops an active task and updates queue state.
lib/domain/usecases/cancel_download_usecase.dart - Get history · Retrieves completed downloads for the history surface.
lib/domain/usecases/get_history_usecase.dart - Binary locator · Resolves local executable paths and bundled binary fallbacks.
lib/core/utils/binary_locator.dart
Local data
Process integration and local persistence boundaries.
- Download repo · Concrete download orchestration and queue management implementation.
lib/data/repositories/download_repository_impl.dart - Playlist tracker · Expands playlists and tracks item-level progress.
lib/data/repositories/playlist_task_tracker.dart - yt-dlp bridge · Subprocess boundary for extraction, progress, completion, and failure events.
lib/data/datasources/process/ytdlp_datasource.dart - History store · Persists completed download records for later search and display.
lib/data/datasources/local/history_datasource.dart - Settings store · Persists user preferences and app configuration.
lib/data/datasources/local/settings_datasource.dart
UI shell
Screens, layouts, and controllers that drive the desktop-first experience.
- Presentation · Screens, controllers, bindings, and desktop layout widgets.
lib/presentation - Main layout · Primary application frame with sidebar, top bar, and right panel.
lib/presentation/pages/main_layout.dart - Downloader · Main download workspace for adding URLs and monitoring tasks.
lib/presentation/pages/downloader/downloader_page.dart - Details view · Per-task detail surface with actions like retry, pause, and cancel.
lib/presentation/pages/downloader/download_details_page.dart - History · Searchable list of completed downloads and metadata.
lib/presentation/pages/history/history_page.dart - Logs · Runtime diagnostics and process failure visibility.
lib/presentation/pages/logs/logs_page.dart - Settings · User preferences for tools, paths, and behavior.
lib/presentation/pages/settings/settings_page.dart - Downloader ctrl · Coordinates queue state, item actions, playlist handling, and downloads.
lib/presentation/controllers/downloader_controller.dart - History ctrl · Loads and filters completed download history.
lib/presentation/controllers/history_controller.dart - Logs ctrl · Collects and exposes process and runtime logs.
lib/presentation/controllers/logs_controller.dart - Settings ctrl · Owns settings state and persistence interactions.
lib/presentation/controllers/settings_controller.dart
Connections 30
- App entry → Routes: uses · Registers navigation and startup destinations.
- App entry → Presentation: boots · Starts the Flutter UI and dependency wiring.
- Presentation → Main layout: contains · The shared layout frames the desktop-first app.
- Main layout → Downloader: hosts · Primary workspace shown inside the app shell.
- Main layout → History: hosts · History surface is routed inside the main frame.
- Main layout → Logs: hosts · Logs surface is routed inside the main frame.
- Main layout → Settings: hosts · Settings surface is routed inside the main frame.
- Downloader → Downloader ctrl: binds · Screen reacts to queue state and user actions.
- Details view → Downloader ctrl: shares · Detail actions operate on the same download state.
- History → History ctrl: binds · History screen queries and filters completed records.
- Logs → Logs ctrl: binds · Logs screen observes diagnostics state.
- Settings → Settings ctrl: binds · Settings screen edits persisted preferences.
- Downloader ctrl → Start download: calls · Starts new downloads from the UI.
- Downloader ctrl → Cancel download: calls · Cancels active tasks from actions and details views.
- History ctrl → Get history: calls · Loads completed download data for display.
- Start download → Download contract: depends on · Use case stays decoupled from implementation details.
- Cancel download → Download contract: depends on · Cancellation follows the repository boundary.
- Get history → Download contract: depends on · History retrieval is exposed through the domain repository.
- Download repo → Download contract: implements · Concrete queue orchestration fulfills the domain contract.
- Download repo → yt-dlp bridge: launches · Executes yt-dlp and translates process output.
- Download repo → Playlist tracker: uses · Tracks playlist expansion and child item progress.
- Download repo → History store: writes · Stores completed download records locally.
- Settings ctrl → Settings contract: depends on · Settings state is backed by a repository abstraction.
- Settings store → Settings contract: implements · Local settings persistence fulfills the contract.
- Binary locator → yt-dlp bridge: resolves · Determines where the subprocess executable can be found.
- Binary locator → Settings store: uses · Settings may override executable paths.
- Core → Binary locator: contains · Shared utilities and app-wide helpers.
- Download repo → Download task: produces · Queue operations work with domain task entities.
- History store → History entry: stores · Completed items are persisted as history entries.
- Download repo → History entry: maps to · Finished tasks become searchable history records.