Skip to content

Commit

Permalink
Androapp 6259 mobile UI adapt showcase app for release (#280)
Browse files Browse the repository at this point in the history
* Add `ColumnComponentItemContainer` and update `ColumnComponentContainer`

* Update `NoComponentSelectedScreen` design and add onClick param

* Update action input group components showcase

* Update group drop down

* Update badge component showcase

* Fix Group components drop down

* Fix lint error for action input group components

* Update basic text input group components showcase

* Update button group components showcase

* Update no group components showcase

* Update option group components showcase

* Fix `InputDropdown` modifier

* Update bottom sheet group components showcase

* Fix action input dropdown items label

* Update list card and card details component showcase

* Rename ColumnComponentContainer to ColumnScreenContainer and ColumnComponentItemContainer to ColumnContainerComponent

* Update status bar colour of the app

* Update snapshot test

* Fix lint error

* Fix background colour for group and component dropdown

* Improve the usability

---------

Co-authored-by: Siddharth Agarwal <[email protected]>
  • Loading branch information
siddh1004 and Siddharth Agarwal authored Aug 9, 2024
1 parent 573b2c0 commit 776a588
Show file tree
Hide file tree
Showing 100 changed files with 3,704 additions and 3,812 deletions.
20 changes: 20 additions & 0 deletions android/src/main/java/org/hisp/dhis/android/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@ package org.hisp.dhis.android
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.core.view.WindowCompat
import org.hisp.dhis.common.App

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val res = LocalContext.current.resources
SetStatusBarColor()
App(
imageBitmapLoader = {
BitmapFactory.decodeResource(
Expand All @@ -27,3 +32,18 @@ class MainActivity : AppCompatActivity() {
}
}
}

@Composable
fun SetStatusBarColor() {
val context = LocalContext.current
val window = (context as? ComponentActivity)?.window

SideEffect {
window?.let {
WindowCompat.getInsetsController(it, it.decorView).apply {
isAppearanceLightStatusBars = true
}
it.statusBarColor = 0xFFE2F2FF.toInt()
}
}
}
87 changes: 54 additions & 33 deletions common/src/commonMain/kotlin/org/hisp/dhis/common/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import org.hisp.dhis.common.screens.Components
import org.hisp.dhis.common.screens.Groups
import org.hisp.dhis.common.screens.NoComponentSelectedScreen
import org.hisp.dhis.common.screens.actionInputs.ActionInputsScreen
import org.hisp.dhis.common.screens.basicTextInputs.BasicTextInputsScreen
Expand All @@ -31,8 +33,11 @@ import org.hisp.dhis.common.screens.toggleableInputs.ToggleableInputsScreen
import org.hisp.dhis.mobile.ui.designsystem.component.DropdownItem
import org.hisp.dhis.mobile.ui.designsystem.component.InputDropDown
import org.hisp.dhis.mobile.ui.designsystem.component.InputShellState
import org.hisp.dhis.mobile.ui.designsystem.component.InputStyle
import org.hisp.dhis.mobile.ui.designsystem.theme.DHIS2Theme
import org.hisp.dhis.mobile.ui.designsystem.theme.Shape
import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing
import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor

@Composable
fun App(imageBitmapLoader: (() -> ImageBitmap)? = null) {
Expand All @@ -45,50 +50,66 @@ fun App(imageBitmapLoader: (() -> ImageBitmap)? = null) {
fun Main(
imageBitmapLoader: (() -> ImageBitmap)?,
) {
val currentScreen = remember { mutableStateOf(Components.CARDS) }
val currentScreen = remember { mutableStateOf(Groups.NO_GROUP_SELECTED) }
var isComponentSelected by remember { mutableStateOf(false) }

Column(
verticalArrangement = Arrangement.spacedBy(Spacing.Spacing16),
modifier = Modifier
.background(Color.White)
.padding(Spacing.Spacing16),
.background(SurfaceColor.Container),
) {
val screenDropdownItemList = mutableListOf<DropdownItem>()
Components.entries.forEach {
Groups.entries.forEach {
screenDropdownItemList.add(DropdownItem(it.label))
}

InputDropDown(
"Components",
dropdownItems = screenDropdownItemList.toList(),
onItemSelected = { currentScreen.value = getCurrentScreen(it.label) },
onResetButtonClicked = { currentScreen.value = Components.NO_COMPONENT_SELECTED },
state = InputShellState.UNFOCUSED,
selectedItem = DropdownItem(currentScreen.value.label),
)
if (isComponentSelected) {
InputDropDown(
modifier = Modifier.padding(
start = Spacing.Spacing16,
end = Spacing.Spacing16,
top = Spacing.Spacing16,
),
title = "Group",
dropdownItems = screenDropdownItemList.toList(),
onItemSelected = { currentScreen.value = getCurrentScreen(it.label) },
onResetButtonClicked = { currentScreen.value = Groups.NO_GROUP_SELECTED },
state = InputShellState.UNFOCUSED,
expanded = true,
selectedItem = DropdownItem(currentScreen.value.label),
inputStyle = InputStyle.DataInputStyle().apply { backGroundColor = SurfaceColor.SurfaceBright },
)

when (currentScreen.value) {
Components.ACTION_INPUTS -> ActionInputsScreen()
Components.BADGES -> BadgesScreen()
Components.BASIC_TEXT_INPUTS -> BasicTextInputsScreen()
Components.BOTTOM_SHEETS -> BottomSheetsScreen()
Components.BUTTONS -> ButtonsScreen()
Components.CARDS -> CardsScreen()
Components.CHIPS -> ChipsScreen()
Components.INDICATOR -> IndicatorScreen()
Components.LEGEND -> LegendScreen()
Components.METADATA_AVATAR -> MetadataAvatarScreen()
Components.PROGRESS_INDICATOR -> ProgressScreen()
Components.PARAMETER_SELECTOR -> ParameterSelectorScreen()
Components.SECTIONS -> SectionScreen()
Components.TOGGLEABLE_INPUTS -> ToggleableInputsScreen(imageBitmapLoader)
Components.TAGS -> TagsScreen()
Components.SEARCH_BAR -> SearchBarScreen()
Components.NO_COMPONENT_SELECTED -> NoComponentSelectedScreen()
when (currentScreen.value) {
Groups.ACTION_INPUTS -> ActionInputsScreen()
Groups.BADGES -> BadgesScreen()
Groups.BASIC_TEXT_INPUTS -> BasicTextInputsScreen()
Groups.BOTTOM_SHEETS -> BottomSheetsScreen()
Groups.BUTTONS -> ButtonsScreen()
Groups.CARDS -> CardsScreen()
Groups.CHIPS -> ChipsScreen()
Groups.INDICATOR -> IndicatorScreen()
Groups.LEGEND -> LegendScreen()
Groups.METADATA_AVATAR -> MetadataAvatarScreen()
Groups.PROGRESS_INDICATOR -> ProgressScreen()
Groups.PARAMETER_SELECTOR -> ParameterSelectorScreen()
Groups.SECTIONS -> SectionScreen()
Groups.TOGGLEABLE_INPUTS -> ToggleableInputsScreen(imageBitmapLoader)
Groups.TAGS -> TagsScreen()
Groups.SEARCH_BAR -> SearchBarScreen()
Groups.NO_GROUP_SELECTED -> NoComponentSelectedScreen()
}
} else {
NoComponentSelectedScreen(
modifier = Modifier
.background(Color.White, Shape.NoRounding),
) {
isComponentSelected = !isComponentSelected
}
}
}
}

fun getCurrentScreen(label: String): Components {
return Components.entries.firstOrNull { it.label == label } ?: Components.ACTION_INPUTS
fun getCurrentScreen(label: String): Groups {
return Groups.entries.firstOrNull { it.label == label } ?: Groups.ACTION_INPUTS
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.hisp.dhis.common.screens

enum class Components(val label: String) {
enum class Groups(val label: String) {
ACTION_INPUTS("Action inputs"),
BASIC_TEXT_INPUTS("Basic text Inputs"),
BOTTOM_SHEETS("Bottom sheet components"),
Expand All @@ -17,5 +17,5 @@ enum class Components(val label: String) {
METADATA_AVATAR("Metadata Avatar"),
INDICATOR("Indicators"),
PARAMETER_SELECTOR("Parameter selector"),
NO_COMPONENT_SELECTED("No component selected"),
NO_GROUP_SELECTED("No group selected"),
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,58 @@
package org.hisp.dhis.common.screens

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Category
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import org.hisp.dhis.mobile.ui.designsystem.component.Button
import org.hisp.dhis.mobile.ui.designsystem.component.ButtonStyle
import org.hisp.dhis.mobile.ui.designsystem.component.ColumnScreenContainer
import org.hisp.dhis.mobile.ui.designsystem.component.Title
import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing
import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor
import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor

@Composable
fun NoComponentSelectedScreen() {
Column(
modifier = Modifier.fillMaxSize(),
fun NoComponentSelectedScreen(
modifier: Modifier = Modifier,
onClick: (() -> Unit)? = null,
) {
ColumnScreenContainer(
modifier = modifier,
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(Modifier.size(Spacing.Spacing160))
Spacer(Modifier.size(Spacing.Spacing120))
Icon(
modifier = Modifier.size(Spacing.Spacing80),
modifier = Modifier.size(Spacing.Spacing48),
imageVector = Icons.Outlined.Category,
tint = SurfaceColor.ContainerHighest,
contentDescription = "Please choose an option",
)
Spacer(Modifier.size(Spacing.Spacing16))

Title("Please select a component", textColor = TextColor.OnSurfaceLight)

if (onClick != null) {
Spacer(Modifier.size(Spacing.Spacing24))

Button(
enabled = true,
style = ButtonStyle.KEYBOARDKEY,
text = "Select component",
icon = {
Icon(
imageVector = Icons.Outlined.Category,
contentDescription = "Please choose an option",
)
},
onClick = onClick,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,24 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import org.hisp.dhis.common.screens.NoComponentSelectedScreen
import org.hisp.dhis.common.screens.components.GroupComponentDropDown
import org.hisp.dhis.mobile.ui.designsystem.component.DropdownItem
import org.hisp.dhis.mobile.ui.designsystem.component.InputDropDown
import org.hisp.dhis.mobile.ui.designsystem.component.InputShellState

@Composable
fun ActionInputsScreen() {
val currentScreen = remember { mutableStateOf(ActionInputs.INPUT_AGE) }
val currentScreen = remember { mutableStateOf(ActionInputs.NO_COMPONENT_SELECTED) }

val screenDropdownItemList = mutableListOf<DropdownItem>()
ActionInputs.entries.forEach {
if (it != ActionInputs.NO_COMPONENT_SELECTED) {
screenDropdownItemList.add(DropdownItem(it.label))
}
}
InputDropDown(
"Display",
GroupComponentDropDown(
dropdownItems = screenDropdownItemList.toList(),
onItemSelected = { currentScreen.value = getCurrentScreen(it.label) },
onResetButtonClicked = { currentScreen.value = ActionInputs.NO_COMPONENT_SELECTED },
selectedItem = DropdownItem(currentScreen.value.label),
state = InputShellState.UNFOCUSED,
)
when (currentScreen.value) {
ActionInputs.INPUT_QR_CODE -> InputQRCodeScreen()
Expand All @@ -46,20 +43,20 @@ fun ActionInputsScreen() {
}

enum class ActionInputs(val label: String) {
LOGIN("Login"),
INPUT_AGE("Input Age"),
INPUT_BARCODE("Input Barcode"),
INPUT_COORDINATE("Input Coordinate"),
INPUT_DATE_TIME("Input Date Time"),
INPUT_EMAIL("Input Email"),
INPUT_FILE_RESOURCE("Input File Resource"),
INPUT_IMAGE("Input Image"),
INPUT_LINK("Input Link"),
INPUT_ORG_UNIT("Input Org. Unit"),
INPUT_PHONE_NUMBER("Input Phone Number"),
INPUT_POLYGON("Input Polygon"),
INPUT_QR_CODE("Input QR code"),
INPUT_SIGNATURE("Input Signature"),
LOGIN("Login component"),
INPUT_AGE("Input Age component"),
INPUT_BARCODE("Input Barcode component"),
INPUT_COORDINATE("Input Coordinate component"),
INPUT_DATE_TIME("Input Date Time component"),
INPUT_EMAIL("Input Email component"),
INPUT_FILE_RESOURCE("Input File Resource component"),
INPUT_IMAGE("Input Image component"),
INPUT_LINK("Input Link component"),
INPUT_ORG_UNIT("Input Org. Unit component"),
INPUT_PHONE_NUMBER("Input Phone Number component"),
INPUT_POLYGON("Input Polygon component"),
INPUT_QR_CODE("Input QR code component"),
INPUT_SIGNATURE("Input Signature component"),
NO_COMPONENT_SELECTED("No component selected"),
}

Expand Down
Loading

0 comments on commit 776a588

Please sign in to comment.