Basic item editing implemented.

This commit is contained in:
KaasKop-
2023-04-23 16:07:23 +02:00
parent 159d96f7f3
commit e401b3e34b
6 changed files with 178 additions and 46 deletions

View File

@@ -99,18 +99,18 @@ class MainActivity : ComponentActivity() {
FreezerItemListScreen( FreezerItemListScreen(
onEditItem = {freezerItem -> onEditItem = {freezerItem ->
// I want onEditItem to open a modal dialog, so not sure if this is needed here... // I want onEditItem to open a modal dialog, so not sure if this is needed here...
navController.navigate("${FreezerItemDetail.route}/${freezerItem}") navController.navigate("${FreezerItemDetailDestination.route}/${freezerItem}")
}) })
} }
// Edit items // Edit items
composable(route = "${FreezerItemDetail.route}/{freezer_id}", arguments = listOf( composable(route = "${FreezerItemDetailDestination.route}/{freezer_id}", arguments = listOf(
navArgument("freezer_id") { navArgument("freezer_id") {
this.type = NavType.IntType this.type = NavType.IntType
this.nullable = false this.nullable = false
} }
)) { )) {
FreezerItemEditScreen() FreezerItemEditScreen { navController.popBackStack() }
} }
} }
} }

View File

@@ -41,7 +41,7 @@ object FreezerItemListDestination : ThuisDestination {
override val route = "freezer_item_list" override val route = "freezer_item_list"
} }
object FreezerItemDetail : ThuisDestination { object FreezerItemDetailDestination : ThuisDestination {
override val icon = Icons.Default.DateRange override val icon = Icons.Default.DateRange
override val destinationName = R.string.home_card_freezer override val destinationName = R.string.home_card_freezer
override val route = "freezer_item_detail" override val route = "freezer_item_detail"

View File

@@ -8,6 +8,7 @@ import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.window.Dialog
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.mitchelbv.thuis_c.R import com.mitchelbv.thuis_c.R
@@ -31,9 +32,9 @@ fun FreezerItemListScreen(
) )
}, onEditItem = onEditItem) }, onEditItem = onEditItem)
} }
FloatingActionButton(onClick = { /*TODO*/ }) { // FloatingActionButton(onClick = { /*TODO*/ }) {
//
} // }
} }
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)

View File

@@ -1,20 +1,14 @@
package com.mitchelbv.thuis_c.views.freezer.item_list.edit_item package com.mitchelbv.thuis_c.views.freezer.item_list.edit_item
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.*
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
@@ -24,54 +18,160 @@ import androidx.core.text.isDigitsOnly
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.mitchelbv.thuis_c.R import com.mitchelbv.thuis_c.R
import com.mitchelbv.thuis_c.network.thuis.responses.Freezer
import com.mitchelbv.thuis_c.network.thuis.responses.FreezerItem import com.mitchelbv.thuis_c.network.thuis.responses.FreezerItem
import com.mitchelbv.thuis_c.views.freezer.item_list.FreezerItemElement import com.mitchelbv.thuis_c.views.freezer.freezerUiState
import com.mitchelbv.thuis_c.views.freezer.item_list.FreezerItemListViewModel
@Composable @Composable
fun FreezerItemEditScreen( fun FreezerItemEditScreen(
freezerItemEditViewModel: FreezerItemEditViewModel = viewModel() freezerItemEditViewModel: FreezerItemEditViewModel = viewModel(),
previousScreen: () -> Unit
) { ) {
val freezerItemUiState by freezerItemEditViewModel.uiState.collectAsStateWithLifecycle() val freezerItemUiState by freezerItemEditViewModel.uiState.collectAsStateWithLifecycle()
freezerItemUiState.item?.let { BuildEditView(freezerItem = it) } if (freezerItemUiState.item != null && freezerItemUiState.freezers != null) {
BuildEditView(
freezerItem = freezerItemUiState.item!!,
freezerList = freezerItemUiState.freezers!!,
savePressed = { freezerItemEditViewModel.UpdateFreezerItem(it) },
returnScreen = previousScreen,
modifier = Modifier
)
}
} }
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun BuildEditView(freezerItem: FreezerItem) { fun BuildEditView(
var itemText by rememberSaveable() { freezerItem: FreezerItem,
mutableStateOf(freezerItem.item) freezerList: List<Freezer>,
savePressed: (FreezerItem) -> Unit,
returnScreen: () -> Unit,
modifier: Modifier
) {
var expanded by remember {
mutableStateOf(false)
} }
Column(verticalArrangement = Arrangement.SpaceBetween) {
var freezerItemLifeCycle by remember {
mutableStateOf(freezerItem)
}
var freezerItemAmount by remember {
mutableStateOf("${freezerItem.amount}")
}
var freezerItemDrawer by remember {
mutableStateOf("${freezerItem.drawer}")
}
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top,
modifier = modifier
.fillMaxSize()
.padding(16.dp)
) {
TextField( TextField(
label = { Text(stringResource(id = R.string.freezer_item_edit_description)) }, label = { Text(stringResource(id = R.string.freezer_item_edit_description)) },
// value = "${freezerItem.item}", value = "${freezerItemLifeCycle.item}",
value = "${itemText}", onValueChange = { value ->
onValueChange = { freezerItemLifeCycle = freezerItemLifeCycle.copy(item = value)
freezerItem.item = it },
itemText = it maxLines = 2,
}) modifier = modifier.fillMaxWidth()
)
Spacer(modifier = modifier.height(15.dp))
TextField( TextField(
label = { Text(stringResource(id = R.string.freezer_item_edit_amount)) }, label = { Text(stringResource(id = R.string.freezer_item_edit_amount)) },
value = "${freezerItem.amount}", value = freezerItemAmount,
onValueChange = { value -> onValueChange = { value ->
if (value.isDigitsOnly()) { if (value.isBlank()) {
freezerItem.amount = value.toInt() freezerItemAmount = ""
}
if (value.isDigitsOnly() && value.isNotBlank()) {
freezerItemAmount = value
freezerItemLifeCycle = freezerItemLifeCycle.copy(amount = value.toInt())
} }
}, },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
maxLines = 1,
modifier = modifier.fillMaxWidth()
) )
Spacer(modifier = modifier.height(15.dp))
TextField( TextField(
label = { Text(stringResource(id = R.string.freezer_item_edit_drawer)) }, label = { Text(stringResource(id = R.string.freezer_item_edit_drawer)) },
value = "${freezerItem.drawer}", value = freezerItemDrawer,
onValueChange = {}) onValueChange = { value ->
if (value.isBlank()) {
freezerItemDrawer = ""
}
if (value.isDigitsOnly() && value.isNotBlank()) {
freezerItemDrawer = value
freezerItemLifeCycle = freezerItemLifeCycle.copy(drawer = value.toInt())
}
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
maxLines = 1,
modifier = modifier.fillMaxWidth()
)
Spacer(modifier = modifier.height(15.dp))
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = !expanded },
modifier = modifier.fillMaxWidth()
) {
TextField(
label = { Text(stringResource(id = R.string.freezer_item_edit_freezer)) },
value = "${freezerList[freezerItemLifeCycle.freezerId?.minus(1)!!].name}",
onValueChange = {},
readOnly = true,
modifier = modifier
.menuAnchor()
.fillMaxWidth(),
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
maxLines = 1,
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = modifier.fillMaxWidth()
) {
freezerList.forEach { freezer ->
DropdownMenuItem(
text = { freezer.name?.let { Text(it) } },
onClick = {
freezerItemLifeCycle =
freezerItemLifeCycle.copy(freezerId = freezer.freezerId)
expanded = !expanded
})
}
}
}
Spacer(modifier = modifier.height(15.dp))
Row(modifier = modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
Button(onClick = {
// Save and return to overview
returnScreen()
savePressed(freezerItemLifeCycle)
}) {
Text(stringResource(id = R.string.com_save))
}
OutlinedButton(onClick = {
// Cancel all changes and return to last view
returnScreen()
}) {
Text(stringResource(id = R.string.com_cancel))
}
}
} }
} }
@Preview @Preview(showBackground = true)
@Composable @Composable
fun EditViewPreview() { fun EditViewPreview() {
val test = FreezerItem(freezerItemId = 1, item = "Kip", 5, 5, "12-01-01", 1) val test = FreezerItem(freezerItemId = 1, item = "Kip", 5, 5, "12-01-01", 1)
BuildEditView(freezerItem = test) val kaas = listOf(
Freezer(freezerId = 1, amountInFreezer = 5, name = "Keuken"),
Freezer(freezerId = 2, amountInFreezer = 5, name = "Berging")
)
BuildEditView(freezerItem = test, kaas, {}, {}, Modifier)
} }

View File

@@ -1,12 +1,12 @@
package com.mitchelbv.thuis_c.views.freezer.item_list.edit_item package com.mitchelbv.thuis_c.views.freezer.item_list.edit_item
import androidx.lifecycle.MutableLiveData import android.util.Log
import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.mitchelbv.thuis_c.network.thuis.ThuisRetrofitHelper import com.mitchelbv.thuis_c.network.thuis.ThuisRetrofitHelper
import com.mitchelbv.thuis_c.network.thuis.responses.Freezer
import com.mitchelbv.thuis_c.network.thuis.responses.FreezerItem import com.mitchelbv.thuis_c.network.thuis.responses.FreezerItem
import com.mitchelbv.thuis_c.views.freezer.item_list.FreezerItemListUiState
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@@ -16,6 +16,9 @@ import java.net.ConnectException
data class FreezerItemEditUiState( data class FreezerItemEditUiState(
val item: FreezerItem? = null, val item: FreezerItem? = null,
var freezerItemAmount: String? = null,
var freezerItemDrawer: String? = null,
val freezers: List<Freezer>? = null,
var error: String = "" var error: String = ""
) )
@@ -24,15 +27,23 @@ class FreezerItemEditViewModel(savedStateHandle: SavedStateHandle) : ViewModel()
val uiState: StateFlow<FreezerItemEditUiState> = _uiState.asStateFlow() val uiState: StateFlow<FreezerItemEditUiState> = _uiState.asStateFlow()
init { init {
savedStateHandle.get<Int>("freezer_id")?.let { fillEditBoxes(it) } savedStateHandle.get<Int>("freezer_id")?.let { PopulateUiState(it) }
} }
fun fillEditBoxes(freezer_id: Int) { fun PopulateUiState(freezer_id: Int) {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
try { try {
val apiResponse = val getFreezers = ThuisRetrofitHelper.thuis.getFreezers()
if (freezer_id == 0) {
// This is when creating a new frezer item
_uiState.value =
FreezerItemEditUiState(item = FreezerItem(), freezers = getFreezers)
return@launch
}
val getFreezerItems =
ThuisRetrofitHelper.thuis.getFreezerItem(id = freezer_id) ThuisRetrofitHelper.thuis.getFreezerItem(id = freezer_id)
_uiState.value = FreezerItemEditUiState(item = apiResponse) _uiState.value =
FreezerItemEditUiState(item = getFreezerItems, freezers = getFreezers)
} catch (e: ConnectException) { } catch (e: ConnectException) {
// _uiState.value = FreezerItemListUiState(listOf(FreezerItem(item = ))) // _uiState.value = FreezerItemListUiState(listOf(FreezerItem(item = )))
@@ -41,4 +52,18 @@ class FreezerItemEditViewModel(savedStateHandle: SavedStateHandle) : ViewModel()
} }
} }
fun UpdateFreezerItem(freezerItem: FreezerItem) {
Log.d("TESTINGGG", "hello ${freezerItem.item}")
viewModelScope.launch(Dispatchers.IO) {
try {
val putFreezerItem = ThuisRetrofitHelper.thuis.putFreezerItem(
id = freezerItem.freezerItemId!!,
freezerItem = freezerItem
)
} catch (e: ConnectException) {
// Not sure yet..
}
}
}
} }

View File

@@ -1,6 +1,11 @@
<resources> <resources>
<string name="app_name">Thuis</string> <string name="app_name">Thuis</string>
<!-- Common errors -->
<string name="com_connection_error">Connection error, try again later.</string>
<string name="com_save">Save</string>
<string name="com_cancel">Cancel</string>
<string name="nav_matches">Matches</string> <string name="nav_matches">Matches</string>
<string name="nav_recipes">Recipes</string> <string name="nav_recipes">Recipes</string>
<string name="nav_home">Home</string> <string name="nav_home">Home</string>
@@ -18,4 +23,5 @@
<string name="freezer_item_edit_description">Description</string> <string name="freezer_item_edit_description">Description</string>
<string name="freezer_item_edit_amount">Amount</string> <string name="freezer_item_edit_amount">Amount</string>
<string name="freezer_item_edit_drawer">Drawer</string> <string name="freezer_item_edit_drawer">Drawer</string>
<string name="freezer_item_edit_freezer">Freezer</string>
</resources> </resources>