# nisanray/mediatubepro architecture

> Architecture diagram of the GitHub repository nisanray/mediatubepro, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/nisanray/mediatubepro
- Repository: https://github.com/nisanray/mediatubepro

## Overview

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: [`lib/data/repositories/download_repository_impl.dart`](https://github.com/nisanray/mediatubepro/blob/master/lib/data/repositories/download_repository_impl.dart) (Download repo), [`lib/presentation/pages/main_layout.dart`](https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/main_layout.dart) (Main layout), [`lib/presentation/controllers/downloader_controller.dart`](https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/controllers/downloader_controller.dart) (Downloader ctrl), [`lib/domain/repositories/download_repository.dart`](https://github.com/nisanray/mediatubepro/blob/master/lib/domain/repositories/download_repository.dart) (Download contract)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_platform["Platform shells"]
end

subgraph group_app["Flutter app"]
  node_main(("App entry<br/>flutter entry<br/>[main.dart]"))
  node_core["Core<br/>shared foundation"]
  node_routes["Routes<br/>navigation map"]
  node_download_task["Download task<br/>entity<br/>[download_task.dart]"]
  node_history_entry["History entry<br/>entity<br/>[history_entry.dart]"]
  node_download_repo_contract["Download contract<br/>repository contract"]
  node_settings_repo_contract["Settings contract<br/>repository contract"]
  node_start_download{{"Start download<br/>use case"}}
  node_cancel_download{{"Cancel download<br/>use case"}}
  node_get_history{{"Get history<br/>use case"}}
  node_binary_locator["Binary locator<br/>env utility"]
end

subgraph group_storage["Local data"]
  node_download_repo[("Download repo<br/>repository impl")]
  node_playlist_tracker["Playlist tracker<br/>queue tracker"]
  node_yt_dlp["yt-dlp bridge<br/>process datasource"]
  node_history_store[("History store<br/>local datasource")]
  node_settings_store[("Settings store<br/>local datasource")]
end

subgraph group_ui["UI shell"]
  node_presentation["Presentation<br/>ui layer"]
  node_main_layout["Main layout<br/>desktop shell<br/>[main_layout.dart]"]
  node_downloader_page["Downloader<br/>screen"]
  node_download_details["Details view<br/>screen"]
  node_history_page["History<br/>screen<br/>[history_page.dart]"]
  node_logs_page["Logs<br/>screen<br/>[logs_page.dart]"]
  node_settings_page["Settings<br/>screen<br/>[settings_page.dart]"]
  node_downloader_controller{{"Downloader ctrl<br/>state controller"}}
  node_history_controller{{"History ctrl<br/>state controller"}}
  node_logs_controller{{"Logs ctrl<br/>state controller"}}
  node_settings_controller{{"Settings ctrl<br/>state controller"}}
end

node_main -->|"uses"| node_routes
node_main -->|"boots"| node_presentation
node_presentation -->|"contains"| node_main_layout
node_main_layout -->|"hosts"| node_downloader_page
node_main_layout -->|"hosts"| node_history_page
node_main_layout -->|"hosts"| node_logs_page
node_main_layout -->|"hosts"| node_settings_page
node_downloader_page -->|"binds"| node_downloader_controller
node_download_details -->|"shares"| node_downloader_controller
node_history_page -->|"binds"| node_history_controller
node_logs_page -->|"binds"| node_logs_controller
node_settings_page -->|"binds"| node_settings_controller
node_downloader_controller -->|"calls"| node_start_download
node_downloader_controller -->|"calls"| node_cancel_download
node_history_controller -->|"calls"| node_get_history
node_start_download -->|"depends on"| node_download_repo_contract
node_cancel_download -->|"depends on"| node_download_repo_contract
node_get_history -->|"depends on"| node_download_repo_contract
node_download_repo -->|"implements"| node_download_repo_contract
node_download_repo -->|"launches"| node_yt_dlp
node_download_repo -->|"uses"| node_playlist_tracker
node_download_repo -->|"writes"| node_history_store
node_settings_controller -->|"depends on"| node_settings_repo_contract
node_settings_store -->|"implements"| node_settings_repo_contract
node_binary_locator -->|"resolves"| node_yt_dlp
node_binary_locator -->|"uses"| node_settings_store
node_core -->|"contains"| node_binary_locator
node_download_repo -->|"produces"| node_download_task
node_history_store -->|"stores"| node_history_entry
node_download_repo -->|"maps to"| node_history_entry

click node_main "https://github.com/nisanray/mediatubepro/blob/master/lib/main.dart"
click node_core "https://github.com/nisanray/mediatubepro/tree/master/lib/core"
click node_routes "https://github.com/nisanray/mediatubepro/tree/master/lib/routes"
click node_presentation "https://github.com/nisanray/mediatubepro/tree/master/lib/presentation"
click node_main_layout "https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/main_layout.dart"
click node_downloader_page "https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/downloader/downloader_page.dart"
click node_download_details "https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/downloader/download_details_page.dart"
click node_history_page "https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/history/history_page.dart"
click node_logs_page "https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/logs/logs_page.dart"
click node_settings_page "https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/settings/settings_page.dart"
click node_downloader_controller "https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/controllers/downloader_controller.dart"
click node_history_controller "https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/controllers/history_controller.dart"
click node_logs_controller "https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/controllers/logs_controller.dart"
click node_settings_controller "https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/controllers/settings_controller.dart"
click node_download_repo "https://github.com/nisanray/mediatubepro/blob/master/lib/data/repositories/download_repository_impl.dart"
click node_playlist_tracker "https://github.com/nisanray/mediatubepro/blob/master/lib/data/repositories/playlist_task_tracker.dart"
click node_yt_dlp "https://github.com/nisanray/mediatubepro/blob/master/lib/data/datasources/process/ytdlp_datasource.dart"
click node_history_store "https://github.com/nisanray/mediatubepro/blob/master/lib/data/datasources/local/history_datasource.dart"
click node_settings_store "https://github.com/nisanray/mediatubepro/blob/master/lib/data/datasources/local/settings_datasource.dart"
click node_download_task "https://github.com/nisanray/mediatubepro/blob/master/lib/domain/entities/download_task.dart"
click node_history_entry "https://github.com/nisanray/mediatubepro/blob/master/lib/domain/entities/history_entry.dart"
click node_download_repo_contract "https://github.com/nisanray/mediatubepro/blob/master/lib/domain/repositories/download_repository.dart"
click node_settings_repo_contract "https://github.com/nisanray/mediatubepro/blob/master/lib/domain/repositories/settings_repository.dart"
click node_start_download "https://github.com/nisanray/mediatubepro/blob/master/lib/domain/usecases/start_download_usecase.dart"
click node_cancel_download "https://github.com/nisanray/mediatubepro/blob/master/lib/domain/usecases/cancel_download_usecase.dart"
click node_get_history "https://github.com/nisanray/mediatubepro/blob/master/lib/domain/usecases/get_history_usecase.dart"
click node_binary_locator "https://github.com/nisanray/mediatubepro/blob/master/lib/core/utils/binary_locator.dart"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main,node_core,node_routes,node_download_task,node_history_entry,node_download_repo_contract,node_settings_repo_contract,node_start_download,node_cancel_download,node_get_history,node_binary_locator toneAmber
class node_download_repo,node_playlist_tracker,node_yt_dlp,node_history_store,node_settings_store toneMint
class node_presentation,node_main_layout,node_downloader_page,node_download_details,node_history_page,node_logs_page,node_settings_page,node_downloader_controller,node_history_controller,node_logs_controller,node_settings_controller toneRose
```

## Components

### Flutter app

Shared Dart application layers and runtime entrypoints.

- [App entry](https://github.com/nisanray/mediatubepro/blob/master/lib/main.dart): flutter entry · Bootstraps the app and wiring for shared runtime initialization. · `lib/main.dart`
- [Core](https://github.com/nisanray/mediatubepro/tree/master/lib/core): shared foundation · App-wide constants, theme, utilities, and error types. · `lib/core`
- [Routes](https://github.com/nisanray/mediatubepro/tree/master/lib/routes): navigation map · Named routes and page registration for app navigation. · `lib/routes`
- [Download task](https://github.com/nisanray/mediatubepro/blob/master/lib/domain/entities/download_task.dart): entity · Domain model for an active or queued download. · `lib/domain/entities/download_task.dart`
- [History entry](https://github.com/nisanray/mediatubepro/blob/master/lib/domain/entities/history_entry.dart): entity · Domain model for a completed download record. · `lib/domain/entities/history_entry.dart`
- [Download contract](https://github.com/nisanray/mediatubepro/blob/master/lib/domain/repositories/download_repository.dart): repository contract · Domain boundary for download queue and task operations. · `lib/domain/repositories/download_repository.dart`
- [Settings contract](https://github.com/nisanray/mediatubepro/blob/master/lib/domain/repositories/settings_repository.dart): repository contract · Domain boundary for app settings persistence. · `lib/domain/repositories/settings_repository.dart`
- [Start download](https://github.com/nisanray/mediatubepro/blob/master/lib/domain/usecases/start_download_usecase.dart): use case · Triggers download execution from a URL or playlist. · `lib/domain/usecases/start_download_usecase.dart`
- [Cancel download](https://github.com/nisanray/mediatubepro/blob/master/lib/domain/usecases/cancel_download_usecase.dart): use case · Stops an active task and updates queue state. · `lib/domain/usecases/cancel_download_usecase.dart`
- [Get history](https://github.com/nisanray/mediatubepro/blob/master/lib/domain/usecases/get_history_usecase.dart): use case · Retrieves completed downloads for the history surface. · `lib/domain/usecases/get_history_usecase.dart`
- [Binary locator](https://github.com/nisanray/mediatubepro/blob/master/lib/core/utils/binary_locator.dart): env utility · Resolves local executable paths and bundled binary fallbacks. · `lib/core/utils/binary_locator.dart`

### Local data

Process integration and local persistence boundaries.

- [Download repo](https://github.com/nisanray/mediatubepro/blob/master/lib/data/repositories/download_repository_impl.dart): repository impl · Concrete download orchestration and queue management implementation. · `lib/data/repositories/download_repository_impl.dart`
- [Playlist tracker](https://github.com/nisanray/mediatubepro/blob/master/lib/data/repositories/playlist_task_tracker.dart): queue tracker · Expands playlists and tracks item-level progress. · `lib/data/repositories/playlist_task_tracker.dart`
- [yt-dlp bridge](https://github.com/nisanray/mediatubepro/blob/master/lib/data/datasources/process/ytdlp_datasource.dart): process datasource · Subprocess boundary for extraction, progress, completion, and failure events. · `lib/data/datasources/process/ytdlp_datasource.dart`
- [History store](https://github.com/nisanray/mediatubepro/blob/master/lib/data/datasources/local/history_datasource.dart): local datasource · Persists completed download records for later search and display. · `lib/data/datasources/local/history_datasource.dart`
- [Settings store](https://github.com/nisanray/mediatubepro/blob/master/lib/data/datasources/local/settings_datasource.dart): local datasource · 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](https://github.com/nisanray/mediatubepro/tree/master/lib/presentation): ui layer · Screens, controllers, bindings, and desktop layout widgets. · `lib/presentation`
- [Main layout](https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/main_layout.dart): desktop shell · Primary application frame with sidebar, top bar, and right panel. · `lib/presentation/pages/main_layout.dart`
- [Downloader](https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/downloader/downloader_page.dart): screen · Main download workspace for adding URLs and monitoring tasks. · `lib/presentation/pages/downloader/downloader_page.dart`
- [Details view](https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/downloader/download_details_page.dart): screen · Per-task detail surface with actions like retry, pause, and cancel. · `lib/presentation/pages/downloader/download_details_page.dart`
- [History](https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/history/history_page.dart): screen · Searchable list of completed downloads and metadata. · `lib/presentation/pages/history/history_page.dart`
- [Logs](https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/logs/logs_page.dart): screen · Runtime diagnostics and process failure visibility. · `lib/presentation/pages/logs/logs_page.dart`
- [Settings](https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/pages/settings/settings_page.dart): screen · User preferences for tools, paths, and behavior. · `lib/presentation/pages/settings/settings_page.dart`
- [Downloader ctrl](https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/controllers/downloader_controller.dart): state controller · Coordinates queue state, item actions, playlist handling, and downloads. · `lib/presentation/controllers/downloader_controller.dart`
- [History ctrl](https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/controllers/history_controller.dart): state controller · Loads and filters completed download history. · `lib/presentation/controllers/history_controller.dart`
- [Logs ctrl](https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/controllers/logs_controller.dart): state controller · Collects and exposes process and runtime logs. · `lib/presentation/controllers/logs_controller.dart`
- [Settings ctrl](https://github.com/nisanray/mediatubepro/blob/master/lib/presentation/controllers/settings_controller.dart): state controller · Owns settings state and persistence interactions. · `lib/presentation/controllers/settings_controller.dart`

## Connections

- 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.
