Open thePlebDev opened 8 months ago
5)
If there are multiple parts inside another part. Consider making it a builder
6)
Builders are NOT`allowed inside of builders
7)
if you have compound part
composable, consider merging it with a builder
8)
the implementations should contain no business logic. It should be strictly a wrapper class that is exposed to the public9)
When refactoring first break things down into parts. This will be easier to see where the waste is(unwanted code or code reuses)
10)
breaking down into parts means try to organize by Column, Row, Box and other organizational composable
11)
If a composable contains multiple parts
it is a good candidate for a builder
12)
once everything has been broken down into parts. Then look for builders and finally implementations
13)
Implementations can contain other implementations
14)
one level of nesting with builders, consider merging the two together. Multiple levels of nested builders, consider making taking the multiple nested builders into their own implementation
1) When documenting implementations, the first sentence should tell the user when builder they are using:
- MainScaffoldComponent is the implementation of [Builder.ScaffoldBuilder].
2) Builders should declare where they are being used in the first sentence:
- ScaffoldBuilder is used inside of [MainScaffoldComponent].
3) Since parts can contain multiple parts, the first sentence should contain a declaration of how many parts it contains:
- CustomTopBar contains 0 other parts
or - CustomTopBar contains 2 other parts, [CustomText] and [CustomRow]
- If their are multiple instances of the same part. They may be counted as 1 part
4) Using KDoc, the proper way to write the documentation when a part contains multiple parts is this:
/**
* - LiveChannelRowItem contains 2 extra parts:
* 1) [ImageWithViewCount]
* 2) [StreamTitleWithInfo]
* */
5) Using KDoc, the top level object should start with a declaration of how many implementations it has, followed by a short description:
/**
* - Contains 1 implementation:
* 1) [MainScaffoldComponent]
*
* - ScaffoldComponents represents all the UI composables that create the scaffold experience inside the HomeView.
*
*
* */
6) The encompassing object declaration can be named anything. However the inner object declarations should always be called: Builders
and Parts
:
object MainChat{
private object Builders{
// all the builders
}
private object Parts{
// all the Parts
}
}
Do not link to the same identifier inside documentation
:
/**
* [Item] is ...
*/
class Item
- instead do this:
/**
- The [Item] is called a `self-referential link` and These links are not actionable, as they will take the user to the same element they are already reading
15)
There are now 2 types of implementations:
1) normal top level implementations.
These are the normal top level implementations that can be used anywhere in the code base.
2) private top level implementation
These type of implementations are private and are only used inside of other implementations. These are only used when implementations are getting so complex that a nested implementation is needed. In my code base you can see an example with the EnhancedChatSettingsBox
composable function
16)
parts can not use Builders. If you have a part that uses a builder, it is now a private top level implementation
17)
Builders should not have the world Builder
in their name.
Builders.AdvancedChatBuilder
to this: Builders.AdvancedChat
1) really is a pain when trying to update something that currently exists. You need to update the code, then the documentation and depending on what you are updating, you will also have to update where this code is used.
18)
PBI and sometimes C architectureParts, Builders, Implementations and sometimes Constants architecture
When there are constants used inside of your composable functions, if you deem it neccessary, create another object declaration
called Constants
and places your constants with in that object declaration:
object AutoMod{
private object Constants{
val discriminationList = listOf<TitleSubTitle>(
TitleSubTitle("Disability","Demonstrating hatred or prejudice based on perceived or actual mental or physical abilities"),
TitleSubTitle("Sexuality, sex, or gender","Demonstrating hatred or prejudice based on sexual identity, sexual orientation, gender identity, or gender expression"),
TitleSubTitle("Misogyny","Demonstrating hatred or prejudice against women, including sexual objectification"),
TitleSubTitle("Race, ethnicity, or religion","Demonstrating hatred or prejudice based on race, ethnicity, or religion"),
)
val hostilityList = listOf<TitleSubTitle>(
TitleSubTitle("Aggression","Threatening, inciting, or promoting violence or other harm"),
TitleSubTitle("Bullying","Demonstrating hatred or prejudice based on sexual identity, sexual orientation, gender identity, or gender expression"),
)
val profanityList = listOf<TitleSubTitle>(
TitleSubTitle("Swearing","Swear words, &*^!#@%*"),
)
}
}
PRIVATE
declaration as to avoid accidental bugs when changing the constants constants19)
Combined parts before single partsParts
declaration, Parts made up of multiple parts come before parts that are not made up of multiple partsexample:
@Composable
fun AutoModRow(
title:String,
titleList: List<TitleSubTitle>
){
var expandedState by remember {
mutableStateOf(false)
}
Column(modifier = Modifier
.fillMaxWidth()
.padding(15.dp)) {
ClickableRow(
changeExpandedState = {
expandedState = !expandedState
},
title =title
)
ConditionalRows(
expandedState, titleList
)
}
}
@Composable
fun DropDownRow(
selectedText:String,
expandMenu:() ->Unit
){
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = { expandMenu() })
.background(Color.Gray),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
){
Icon(
imageVector = Icons.Default.ArrowDropDown,
contentDescription = stringResource(R.string.close_icon_description),
tint = Color.White,
modifier = Modifier.padding(end = 5.dp)
)
Text(
selectedText,
)
Icon(
imageVector = Icons.Default.ArrowDropDown,
contentDescription = stringResource(R.string.close_icon_description),
tint = Color.White,
modifier = Modifier.padding(end = 5.dp)
)
}
}
- This rule dictates that in the file, `AutoModRow` should be placed before `DropDownRow`
20)
Constants Should live inside the ViewModel
Proposed change
Why is this important
Anything top level can be used anywhere in the code base How to determine where the composable should go:
1)
if it uses the slot layout then it is abuilder
2)
if it does not use the slot layout and is only used inside of this declaration then it is apart
3)
parts
are allowed to be made up of multipleparts
4)
if it does not contain a slot layout and is used elsewhere in the code base, then it goes at the top level and is considered animplementation
Additional context