From d19045fc5b53e06813ad804bd3c79d4e24f63977 Mon Sep 17 00:00:00 2001 From: mutukuian Date: Mon, 13 May 2024 23:00:39 +0300 Subject: [PATCH] details screen navigation and UI refinement --- .../data/remote/dto/ShipDetailDto.kt | 2 +- .../domain/model/ShipDetail.kt | 1 + .../ship_details_screen/ShipDetailScreen.kt | 152 +++++++++++------- .../ships_screen/ShipListScreen.kt | 6 +- 4 files changed, 101 insertions(+), 60 deletions(-) diff --git a/app/src/main/java/com/example/kocelainterview/data/remote/dto/ShipDetailDto.kt b/app/src/main/java/com/example/kocelainterview/data/remote/dto/ShipDetailDto.kt index e3ed664..5eca6ec 100644 --- a/app/src/main/java/com/example/kocelainterview/data/remote/dto/ShipDetailDto.kt +++ b/app/src/main/java/com/example/kocelainterview/data/remote/dto/ShipDetailDto.kt @@ -27,5 +27,5 @@ data class ShipDetailDto( ) fun ShipDetailDto.toShipDetail():ShipDetail{ - return ShipDetail(active, home_port, ship_id, ship_name, ship_type, weight_kg, year_built) + return ShipDetail(active, home_port, ship_id, ship_name, ship_type,image, weight_kg, year_built) } \ No newline at end of file diff --git a/app/src/main/java/com/example/kocelainterview/domain/model/ShipDetail.kt b/app/src/main/java/com/example/kocelainterview/domain/model/ShipDetail.kt index d9cfc72..553c3be 100644 --- a/app/src/main/java/com/example/kocelainterview/domain/model/ShipDetail.kt +++ b/app/src/main/java/com/example/kocelainterview/domain/model/ShipDetail.kt @@ -2,6 +2,7 @@ package com.example.kocelainterview.domain.model data class ShipDetail( val active: Boolean, + val image: String, val home_port: String, val ship_id: String, val ship_name: String, diff --git a/app/src/main/java/com/example/kocelainterview/presentation/ship_details_screen/ShipDetailScreen.kt b/app/src/main/java/com/example/kocelainterview/presentation/ship_details_screen/ShipDetailScreen.kt index 9f3112b..e49141c 100644 --- a/app/src/main/java/com/example/kocelainterview/presentation/ship_details_screen/ShipDetailScreen.kt +++ b/app/src/main/java/com/example/kocelainterview/presentation/ship_details_screen/ShipDetailScreen.kt @@ -1,101 +1,139 @@ package com.example.kocelainterview.presentation.ship_details_screen -import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material3.Card import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import coil.compose.rememberAsyncImagePainter +import com.example.kocelainterview.domain.model.ShipDetail @Composable fun ShipDetailScreen( viewModel: ShipDetailViewModel = hiltViewModel() ) { - val state = viewModel.state.value - Box (modifier = Modifier.fillMaxSize()){ - state.ship?.let { shipDetail -> - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(20.dp) - ) { - item{ - Row ( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ){ - Text( - text = "$shipDetail.ship_name. $shipDetail.weight_kg ($shipDetail.year_built)", - style = MaterialTheme.typography.bodyMedium, - modifier = Modifier.weight(8f) - ) - Text( - text = if (shipDetail.active) "active" else "inactive", - color = if (shipDetail.active) Color.Green else Color.Red, - fontStyle = FontStyle.Italic, - textAlign = TextAlign.End, - style = MaterialTheme.typography.bodyMedium, - modifier = Modifier - .align(Alignment.CenterVertically) - .weight(2f) - ) - Spacer(modifier = Modifier.height(15.dp)) - Text( - text = "More Details", - style = MaterialTheme.typography.bodyMedium - ) - Spacer(modifier = Modifier.height(15.dp)) - Text( - text = "$shipDetail.ship_type " , - fontStyle = FontStyle.Italic, - style = MaterialTheme.typography.bodyMedium, - ) - Spacer(modifier = Modifier.height(4.dp)) - Text( - text = "$shipDetail.home_port", - fontStyle = FontStyle.Italic, - style = MaterialTheme.typography.bodyMedium - ) - } - - } + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp) + ) { + Text(text = "Ships Details", style = MaterialTheme.typography.bodyMedium) + Spacer(modifier = Modifier.height(24.dp)) + LazyColumn { + if (state.isLoading) { + item { + CircularProgressIndicator( + modifier = Modifier + .fillMaxSize() + .wrapContentSize(align = Alignment.Center) + ) + } + } + state.ship?.let { shipDetail -> + item { + ShipDetailImageCard(shipDetail = shipDetail) + } } } - if (state.error.isNotBlank()){ + if (state.error.isNotBlank()) { Text( - text =state.error, + text = state.error, color = Color.Red, textAlign = TextAlign.Center, modifier = Modifier .fillMaxWidth() .padding(horizontal = 20.dp) - .align(Alignment.Center) + .align(Alignment.CenterHorizontally) ) } - if (state.isLoading){ - CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) + } + +} + + +@Composable +fun ShipDetailImageCard(shipDetail: ShipDetail) { + val imagePainter = rememberAsyncImagePainter(model = shipDetail.image) + Card( + shape = MaterialTheme.shapes.medium, + modifier = Modifier.padding(16.dp) + + ) { + Box { + + Image( + painter = imagePainter, + contentDescription = null, + modifier = Modifier + .fillMaxWidth() + .height(200.dp), + contentScale = ContentScale.FillBounds + ) + + Surface( + color = MaterialTheme.colorScheme.onSurface.copy(alpha = .3f), + modifier = Modifier + .align( + Alignment.BottomCenter + ), + contentColor = MaterialTheme.colorScheme.surface + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + ) { + + //Text(text = "Ship: ${shipDetail.ship_name}") + + Text(text = "Home Port: ${shipDetail.home_port}") + + Text( + text = if (shipDetail.active) "Active" else "Inactive", + color = if (shipDetail.active) Color.Green else Color.Red, + style = MaterialTheme.typography.bodyLarge + ) + + + //Text(text = "Ship Type: ${shipDetail.ship_type}") + + + Text(text = "Year Built: ${shipDetail.year_built}") + + } + } + } + + } -} \ No newline at end of file + + +} + diff --git a/app/src/main/java/com/example/kocelainterview/presentation/ships_screen/ShipListScreen.kt b/app/src/main/java/com/example/kocelainterview/presentation/ships_screen/ShipListScreen.kt index 0a288d2..27972c5 100644 --- a/app/src/main/java/com/example/kocelainterview/presentation/ships_screen/ShipListScreen.kt +++ b/app/src/main/java/com/example/kocelainterview/presentation/ships_screen/ShipListScreen.kt @@ -58,7 +58,8 @@ fun ShipListScreen( Column(modifier = Modifier .fillMaxSize() - .padding(16.dp)) { + .padding(16.dp)) + { Text(text = "Ships List", style = MaterialTheme.typography.bodyMedium) @@ -116,7 +117,8 @@ fun ShipImageCard(ships: Ship,onItemClick:(Ship)->Unit){ val imagePainter = rememberAsyncImagePainter(model = ships.image) Card( shape = MaterialTheme.shapes.medium, - modifier = Modifier.padding(16.dp) + modifier = Modifier + .padding(16.dp) .clickable { onItemClick(ships) } ) { Box{