2024-01-23 13:41:46 +01:00
|
|
|
## Module structure
|
|
|
|
|
2024-03-18 13:51:51 +01:00
|
|
|
The project has different kinds of modules and, depending on the group a module belongs to, there are some rules about
|
|
|
|
which other modules it can depend on.
|
2024-01-23 13:41:46 +01:00
|
|
|
|
|
|
|
Here is a description of the dependency flow:
|
|
|
|
|
2024-03-18 13:51:51 +01:00
|
|
|
- `:androidApp` which is the KMP equivalent of `:app` module in Android-only projects) include `:shared` and can
|
|
|
|
include `:core` modules (e.g. for navigation);
|
|
|
|
- `:shared` is the heart of the KMP application and it virtually includes every other Gradle module as a dependency (it
|
|
|
|
contains in the `DiHelper.kt` files the setup of the DI, so it basically needs to see all Koin modules);
|
|
|
|
- `:feature` modules are included by :shared and include :domain, :core and :unit modules, but they DO not include other
|
|
|
|
each other nor any top level module; some unit modules are used just by one feature (e.g. `:unit:postlist` is used
|
|
|
|
only by `:feature:home`) in some other cases multiple features use the same unit (e.g. `:unit:zoomableimage` is used
|
|
|
|
by both `:feature:home`, `:feature:search`, `:feature:profile` and `:feature:inbox`);
|
|
|
|
- `:domain` modules can be used by feature and unit modules and can only include core modules; only exception
|
|
|
|
is `:domain:inbox` which is a thin layer on top of `:domain:lemmy` so it depends on it (for inbox related functions);
|
|
|
|
- `:unit` modules are included by feature modules (and `:shared`) and sometimes by other unit modules in case of highly
|
|
|
|
reusable parts of the app; the only notable violation to this rule is `:core:commonui:detailopener-impl` which is a
|
|
|
|
special module because it is only included by `:shared` (which does the binding between `:detailopener-api`
|
|
|
|
and `:detailopener-impl`) and it includes some unit modules but the fact of a unit module included by a core module in
|
|
|
|
general should never happen (instead, the reverse is perfectly ok);
|
2024-02-18 10:04:03 +01:00
|
|
|
- `:core` modules can sometimes include each other (but without cycles, e.g. `:core:markdown`
|
2024-03-18 13:51:51 +01:00
|
|
|
includes `:core:commonui:components` / `:core:utils` because it is a mid-level module and something similar happens
|
|
|
|
with `:core:persistecnce` which uses `:core:preferences` / `:core:appearance`) and nothing else; they are in turn
|
|
|
|
used by all the other types of modules.
|
2024-01-23 13:41:46 +01:00
|
|
|
|
2024-02-14 08:52:43 +01:00
|
|
|
### Top-level modules
|
2024-01-23 13:41:46 +01:00
|
|
|
|
2024-03-18 13:51:51 +01:00
|
|
|
The main module (Android-specific) is `:androidApp`, which contains the Application subclass (`MainApplication`) and the
|
|
|
|
main activity (`MainActivity`). The latter in its `onCreate(Bundle?)` invokes the `MainView` Composable function which
|
|
|
|
in turns calls `App`, the main entry point of the multiplatform application which is defined in the `:shared` module.
|
2024-01-23 13:41:46 +01:00
|
|
|
|
2024-03-18 13:51:51 +01:00
|
|
|
`:shared` is the top module of the multiplatform application, which includes all the other modules and is not included
|
|
|
|
by anything (except `:androidApp`). In its `commonMain` source set, this module contains `App`, the application entry
|
|
|
|
point, the definition on the `MainScreen` (and its ViewModel) hosting the main navigation with the bottom tab bar.
|
|
|
|
Another important part of this module resides in the platform specific source sets (`androidMain` and `iosMain`
|
|
|
|
respectively) where two `DiHelper.kt` files (one for each platform) can be found, which contain the setup of the root of
|
|
|
|
the project's dependency injection in a platform specific way, an initialization function on iOS and a Koin module for
|
|
|
|
Android (which is included in `MainApplication`).
|
2024-01-23 13:41:46 +01:00
|
|
|
|
|
|
|
### Feature modules
|
|
|
|
|
2024-03-18 13:51:51 +01:00
|
|
|
These modules correspond to the main functions of the application, i.e. the sections of the main bottom navigation. In
|
|
|
|
particular:
|
2024-01-23 13:41:46 +01:00
|
|
|
|
|
|
|
- `:feature:home` contains the post list tab;
|
|
|
|
- `:feature:search` contains the Explore tab;
|
|
|
|
- `:feature:inbox` contains the Inbox tab;
|
|
|
|
- `:feature:profile` contains the Profile tab;
|
|
|
|
- `:feature:settings` contains the Settings tab.
|
|
|
|
|
|
|
|
### Domain modules
|
|
|
|
|
|
|
|
These are purely business logic modules that can be reused to provide application main parts:
|
|
|
|
|
2024-03-18 13:51:51 +01:00
|
|
|
- `:domain:identity` contains the repositories and use cases that are related to user identity, authorization and API
|
|
|
|
configuration;
|
2024-01-23 13:41:46 +01:00
|
|
|
- `:domain:lemmy` contains all the Lemmy API interaction logic and is divided into two submodules:
|
2024-03-18 13:51:51 +01:00
|
|
|
- `:data` contains all the domain models for Lemmy entities (posts, comments, communities, users, etc);
|
2024-05-14 19:52:45 +02:00
|
|
|
- `:pagination` contains the pagination utilities for posts within feeds or comments as well as the navigation logic
|
|
|
|
that allows to navigate to previous/next post within a list with automatic pagination;
|
2024-03-18 13:51:51 +01:00
|
|
|
- `:repository` contains the repositories that access Lemmy APIs (through the :core:api module) and are used
|
2024-05-14 19:52:45 +02:00
|
|
|
to manage the entities contained in the `:data` module;
|
2024-03-18 13:51:51 +01:00
|
|
|
- `:domain:inbox` contains some uses cases needed to interact with the replies, mentions and private messages
|
|
|
|
repositories and coordinate the interaction between inbox-related app components.
|
2024-01-23 13:41:46 +01:00
|
|
|
|
|
|
|
### Unit modules
|
|
|
|
|
2024-03-18 13:51:51 +01:00
|
|
|
These modules are the building blocks that are used to create user-visible parts of the application, i.e. the various
|
|
|
|
screens, some of which are reusable in multiple points (e.g. the user detail, community detail or post detail, but also
|
|
|
|
report/post/comment creation forms, etc.). In some cases even a dialog or a bottom-sheet can become a "unit", especially
|
|
|
|
if it is used in multiple points or contains a little more than pure UI (e.g. some presentation logic); simple pure-UI
|
|
|
|
dialogs and sheets are located in the `:core:commonui:modals` module instead (but are being progressively converted to
|
|
|
|
separate units).
|
2024-01-23 13:41:46 +01:00
|
|
|
|
|
|
|
Here is a list of the main unit modules and their purpose:
|
|
|
|
|
|
|
|
- `:unit:about` contains the About this app dialog
|
|
|
|
- `:unit:accountsettings` contains the screen of the remote account settings (web preferences)
|
|
|
|
- `:unit:ban` contains the modal bottom sheet used to ban a user from a community
|
|
|
|
- `:unit:chat` contains the chat conversation screen
|
|
|
|
- `:unit:choosecolor` contains the dialogs and bottom sheets used for theme/color selection
|
|
|
|
- `:unit:choosefont` contains the bottom sheets used for font selection
|
|
|
|
- `:unit:communitydetail` contains the community detail screen
|
|
|
|
- `:unit:communityinfo` contains the community info bottom sheet accessible from community detail
|
|
|
|
- `:unit:configureswipeactions` contains the screen and bottom sheets to configure swipe actions
|
2024-02-25 11:10:10 +01:00
|
|
|
- `:unit:configurecontentview` contains the screen used to configure post and comment appearance
|
2024-01-23 13:41:46 +01:00
|
|
|
- `:unit:createcomment` contains the create comment form
|
|
|
|
- `:unit:createpost` contains the create post form
|
2024-02-25 11:10:10 +01:00
|
|
|
- `:unit:drafts` contains the screen uses to display post and comment drafts
|
2024-01-23 13:41:46 +01:00
|
|
|
- `:unit:drawer` contains the navigation drawer
|
2024-05-14 19:52:45 +02:00
|
|
|
- `:unit:filteredcontents` contains the screen to access moderated contents, liked/disliked items and bookmarks
|
2024-01-23 13:41:46 +01:00
|
|
|
- `:unit:instanceinfo` contains the instance info bottom sheet with the list of communities
|
|
|
|
- `:unit:login` contains the login modal bottom sheet
|
|
|
|
- `:unit:manageaccounts` contains the modal bottom sheet used to change account
|
|
|
|
- `:unit:manageban` contains the ban management screen
|
|
|
|
- `:unit:managesubscriptions` contains the subscription management screen
|
|
|
|
- `:unit:mentions` contains the mentions section of the Inbox tab
|
|
|
|
- `:unit:messages` contains the private messages section of the Inbox tab
|
2024-05-14 19:52:45 +02:00
|
|
|
- `:unit:moderatewithreason` contains the modal bottom sheet for moderation actions that require a reason (remove,
|
|
|
|
purge, report, hide)
|
2024-01-23 13:41:46 +01:00
|
|
|
- `:unit:modlog` contains the moderation log screen
|
|
|
|
- `:unit:multicommunity` contains the multi-community detail and multi-community editor screens
|
|
|
|
- `:unit:myaccount` contains the profile logged section of the Profile tab
|
|
|
|
- `:unit:postdetail` contains the post detail screen
|
|
|
|
- `:unit:postlist` contains the post list (home) screen
|
|
|
|
- `:unit:rawcontent` contains the "Raw content" dialog with the custom (Android) text toolbar
|
|
|
|
- `:unit:replies` contains the replies section of the Inbox tab
|
|
|
|
- `:unit:reportlist` contains the report list screen (for moderators)
|
|
|
|
- `:unit:selectcommunity` contains the dialog used to select communities (for cross-posts)
|
|
|
|
- `:unit:selectinstance` contains the bottom sheet used to change instance in anonymous mode
|
|
|
|
- `:unit:userdetail` contains the user detail screen
|
|
|
|
- `:unit:userinfo` contains the user information bottom sheet accessible from user detail
|
|
|
|
- `:unit:web` contains the internal WebView screen
|
|
|
|
- `:unit:zoomableimage` contains the image detail screen used to display full-screen images.
|
|
|
|
|
|
|
|
### Core modules
|
|
|
|
|
2024-03-18 13:51:51 +01:00
|
|
|
These are the foundational blocks containing the design system and various reusable utilities that are called throughout
|
|
|
|
the whole project. Here is a short description of them:
|
|
|
|
|
|
|
|
- `:core:api` contains the Ktorfit services used to interact with Lemmy APIs and all the data transfer objects (DTOs)
|
|
|
|
used to send and receive data from the APIs;
|
|
|
|
- `:core:appearance` contains the look and feel repository which exposes the information about the current theme as
|
|
|
|
observable states and allows to change them;
|
|
|
|
- `:core:architecture` contains the building blocks for the Model-View-Intent architecture used in all the screens of
|
|
|
|
the application;
|
|
|
|
- `:core:commonui` contains a series of submodules that are used to define UI components used in the app and reusable
|
|
|
|
UI blocks:
|
2024-01-23 13:41:46 +01:00
|
|
|
- `:components`: a collection of components that represent graphical widgets
|
2024-03-18 13:51:51 +01:00
|
|
|
- `:detailopener-api` : a utility module used to expose an API to centralize content opening (post detail,
|
|
|
|
community, detail, user detail, comment creation and post creation)
|
|
|
|
- `:detailopener-impl`: implementation of the detail opener, this is an exception to the module architecture because
|
|
|
|
it is a core module which includes unit modules so the important thing is
|
2024-01-23 13:41:46 +01:00
|
|
|
that no one **ever** include this module except for `:shared`;
|
2024-03-18 13:51:51 +01:00
|
|
|
- `:lemmyui`: graphical components used to represent Lemmy UI (posts, comments, inbox items, etc.) and reusable
|
|
|
|
subcomponents such as different types of headers, footers, cards, etc.
|
|
|
|
- `:modals`: definition of modal bottom sheets and dialogs that have no presentation logic. This module was
|
|
|
|
historically much bigger and over time components were migrated to separate units
|
2024-01-23 13:41:46 +01:00
|
|
|
modules;
|
2024-02-18 10:04:03 +01:00
|
|
|
- `:core:markdown` contains Markdown rendering logic;
|
2024-03-18 13:51:51 +01:00
|
|
|
- `core:l10n` contains all the localization messages and the `L10nManager` interface which acts as a wrapper around
|
|
|
|
Lyricist to load the internationalized messages;
|
|
|
|
- `:core:navigation` contains the navigation manager used for stack navigation, bottom sheet navigation and a
|
|
|
|
coordinator for the events originated by the navigation drawer;
|
|
|
|
- `:core:notifications` contains the `NotificationCenter` contract and implementation as well as the event definition,
|
|
|
|
this is used as an event bus throughout the whole project;
|
|
|
|
- `:core:persistence` contains the local database (primary storage) management logic as well as SQLDelight definitions
|
|
|
|
of entities and migrations, plus all the local data sources that are used
|
2024-01-23 13:41:46 +01:00
|
|
|
to access the database;
|
2024-03-18 13:51:51 +01:00
|
|
|
- `:core:preferences` contains the shared preferences/user defaults (secondary storage) and relies on the
|
|
|
|
multiplatform-settings library to offer a temporary key-value store;
|
|
|
|
- `:core:resources` is a wrapper around the resource loading (fonts and images mainly) which used to rely on an external
|
|
|
|
library and now used the built-in resource management of Compose;
|
|
|
|
- `:core:utils`: contains a series of helper and utility functions/classes that are used in the project but were not big
|
|
|
|
enough to be converted to separate domain/core modules on their own.
|
2024-01-23 13:41:46 +01:00
|
|
|
|
|
|
|
On second thoughts:
|
|
|
|
|
2024-03-18 13:51:51 +01:00
|
|
|
- `:core:commonui` has still too much in it, especially `:modals` packages should become unit modules;
|
|
|
|
- `:core:persistence` belongs more to domain modules, e.g. `:domain:accounts`/`:domain:settings` but it is implemented
|
|
|
|
as a core module because is is strongly tied to SQLDelight and its generated code which provides the named queries to
|
|
|
|
fetch/save data to the local DB.
|