mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-10 00:00:43 +01:00
chore: coding conventions section of CONTRIBUTING.md
This commit is contained in:
parent
1101dcce70
commit
619872435a
@ -341,8 +341,8 @@ libary which not only works great but also offers support for encryption.
|
|||||||
<dd>
|
<dd>
|
||||||
This project was a chance to experiment with <a href="https://github.com/cashapp/sqldelight">SQLDelight</a>
|
This project was a chance to experiment with <a href="https://github.com/cashapp/sqldelight">SQLDelight</a>
|
||||||
(in other multiplatform projects other libraries were tested like Exposed), whereas database encryption
|
(in other multiplatform projects other libraries were tested like Exposed), whereas database encryption
|
||||||
is obtained through [SQLCipher Android](https://www.zetetic.net/sqlcipher/sqlcipher-for-android/), formerly
|
is obtained through <a href="https://www.zetetic.net/sqlcipher/sqlcipher-for-android">SQLCipher Android</a>,
|
||||||
<a href="https://github.com/sqlcipher/android-database-sqlcipher">Android Database SQLCipher</a>.
|
formerly <a href="https://github.com/sqlcipher/android-database-sqlcipher">Android Database SQLCipher</a>.
|
||||||
</dd>
|
</dd>
|
||||||
<dt>Markdown rendering</dt>
|
<dt>Markdown rendering</dt>
|
||||||
<dd>
|
<dd>
|
||||||
@ -548,10 +548,98 @@ On second thoughts:
|
|||||||
|
|
||||||
### 6.1 Architectural patterns
|
### 6.1 Architectural patterns
|
||||||
|
|
||||||
|
#### 6.1.1 General principles
|
||||||
|
|
||||||
|
The project’s architecture is inspired from the Clean architecture principles. Modules are organized
|
||||||
|
in tiers and dependency flows goes from higher modules (top-level and feature modules) towards lower
|
||||||
|
order modules (unit modules for UI, domain modules for business logic) which in turn rely on core
|
||||||
|
modules for low-level operations; and that is a hierarchical structure on the vertical axis. Apart
|
||||||
|
from that, there is a split on the horizontal axis (i.e. different features for different sections
|
||||||
|
of the app). The intersection between these two axes determines the modularization strategy.
|
||||||
|
|
||||||
|
To summarize, if you are looking for something related to the app UI, have a look at `:feature:xxx`
|
||||||
|
or `:unit:xxx` (and possibly you will have to drill down to `:core:commonui:xxx`). If you are
|
||||||
|
searching for some piece of interaction with Lemmy APIs, have a look at `:domain:lemmy:xxx` (and
|
||||||
|
you’ll probably end up in `:core:api` for more low-level minutia), if you look for data access on
|
||||||
|
the local database have a look at `:core:persistence`, and so on. More on this here (Modularization
|
||||||
|
strategy).
|
||||||
|
|
||||||
|
#### 6.1.2 Model-View-Intent
|
||||||
|
|
||||||
|
Every part of the app which has some non trivial user-interaction follows the Model-View-Intent
|
||||||
|
architectural pattern. This means that there are two different components interacting with each
|
||||||
|
other:
|
||||||
|
|
||||||
|
- the View, represented by a `Screen` implementation
|
||||||
|
- the ViewModel, represented by a `ScreenModel` implementation
|
||||||
|
|
||||||
|
where the interfaces (Screen and ScreenModel) both come from the Voyager navigation library.
|
||||||
|
|
||||||
|
The **View** has the responsibility of drawing to screen the UI components that are needed to
|
||||||
|
represent a particular **state**, which is provided by the ViewModel they have a reference to (the
|
||||||
|
ViewModel being a state holder for this respect). The View has also the ability to collect user
|
||||||
|
input (or, rather, intentions as **intents**) and dispatch them to the ViewModel.
|
||||||
|
|
||||||
|
On its side, the **ViewModel** holds an observable state and has the ability to react to user
|
||||||
|
intents coming from the View, each of which implies some business logic operations which, in turn,
|
||||||
|
determine ultimately a state change, observed by the view. In some less frequent case, the ViewModel
|
||||||
|
can emit one-time events, that are unrelated to persistent state and can determine volatile *
|
||||||
|
*effects** in the View.
|
||||||
|
|
||||||
|
These concepts of a ViewModel having to deal with Intent, State and Effect are modelled in Kotlin in
|
||||||
|
the `:core:architecture` module which is included as a building block by all UI related features and
|
||||||
|
unit modules of the project. The `MviModel` interface defined here is a common supertype of all the
|
||||||
|
ScreenModel implementations.
|
||||||
|
|
||||||
|
In case some event needs to be propagated across different ViewModels, the event bus defined
|
||||||
|
in `:core:notification` is used.
|
||||||
|
|
||||||
### 6.2 Modularization strategy
|
### 6.2 Modularization strategy
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Here is a description of the dependency flow:
|
||||||
|
|
||||||
|
- `: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);
|
||||||
|
- the `:resources` module is at the bottom of the hierarchy and is included by any other module (but
|
||||||
|
does not depend on any);
|
||||||
|
- `: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);
|
||||||
|
- `:core` modules can sometimes include each other (but without cycles, e.g. `:core:md`
|
||||||
|
includes `:core:commonui:components` / `:core:utils` because it is a mid-level module and
|
||||||
|
something similar happens with :core:persistence which
|
||||||
|
uses `:core:preferences` / `:core:appearance`) and nothing else; they are in turn used by all the
|
||||||
|
other types of modules.
|
||||||
|
|
||||||
### 6.3 General Kotlin rules
|
### 6.3 General Kotlin rules
|
||||||
|
|
||||||
|
Please refer to [this page](https://kotlinlang.org/docs/coding-conventions.html) for the conventions
|
||||||
|
to apply to Kotlin code, most of which are already enforced by Android Studio inspections.
|
||||||
|
|
||||||
### 6.4 Compose rules
|
### 6.4 Compose rules
|
||||||
|
|
||||||
|
As far as Compose code is concerned, we take Google’s indications as a baseline:
|
||||||
|
|
||||||
|
- [general Compose API](https://android.googlesource.com/platform/frameworks/support/+/androidx-main/compose/docs/compose-api-guidelines.md)
|
||||||
|
- [Compose component API](https://android.googlesource.com/platform/frameworks/support/+/androidx-main/compose/docs/compose-component-api-guidelines.md)
|
||||||
|
|
||||||
### 6.5 Test structure
|
### 6.5 Test structure
|
||||||
|
|
||||||
|
TBD depending on experiment result.
|
Loading…
x
Reference in New Issue
Block a user