Quiblo wiki

Architecture

Module reference

Every Gradle module, what belongs in it, and what must not.

# Applications

ModuleHolds
:appThe phone assembly: the activity, the navigation graph, the Koin module list, the manifest.
:app-tvThe television assembly, and all of its UI. The TV screens live here rather than in :feature-tv:* modules — there is one consumer, and a module per screen would be structure without benefit.

# Core

ModuleHolds
:core:modelDomain types: Channel, Category, Programme, Source, Profile, Episode, SeriesDetails, VodDetails, TitleMetadata, HistoryEntry, and the settings enums. No Android dependency at all.
:core:dataRepositories — the seam between storage, sources and ViewModels. ChannelRepository, CategoryRepository, GuideRepository, SourceRepository, SearchRepository, ProfileRepository, WatchHistoryRepository, TitleMetadataRepository, TitleMetadataScanner, ChannelLogoRepository, backup.
:core:databaseRoom: entities, DAOs, migrations, and the exported schema JSON that migrations are checked against.
:core:datastorePreferences, and the encrypted credential store. Credentials live here and never in the database.
:core:mediaThe player, behind PlayerController. The only module that knows ExoPlayer exists.
:core:networkThe OkHttp client and its configuration.
:core:commonSmall shared utilities. Deliberately thin — a large "common" module is a sign the layering has failed.

# Source

ModuleHolds
:source:apiThe contract: MediaSource, plus the capability interfaces VodSource and SeriesSource, and the result and error types.
:source:m3uThe M3U/M3U8 parser. Pure JVM, no Android — which is why it is the best-tested module in the project.
:source:xtreamThe Xtream Codes client, the rate limiter and the block gate. Also pure JVM.
:source:tmdbThe optional film and series information client, its own rate limiter, and the three-way TmdbAnswer.
:source:iptvorgThe optional channel-logo reference list.

Capabilities are separate interfaces on purpose. An M3U source is a MediaSource and nothing more; asking one for a film's plot is a compile-time impossibility rather than a runtime null.

# Feature

:feature:browse, :feature:live, :feature:vod, :feature:series, :feature:player, :feature:favorites, :feature:sources, :feature:settings.

Each holds a ViewModel and the phone's composables for one area. The television depends on these modules for their ViewModels and Koin wiring and supplies its own composables.

:feature:browse is the interesting one: BrowseViewModel is parameterised by a feed — a kind plus a favourites flag — so Live, Movies, Series and Favourites are one implementation rather than four. They differ in what they show, not in how they behave.

Search lives there too, and is the exception that proves the parameterisation: it deliberately is not a feed, because it is the one question that ignores the kind the feed is parameterised by.