diff --git a/.idea/compiler.xml b/.idea/compiler.xml index fb7f4a8..b589d56 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..0fc3113 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index bdd9278..9f71c83 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,7 @@ - + diff --git a/app/build.gradle b/app/build.gradle index b2abf39..867ebad 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -65,10 +65,12 @@ dependencies { // ViewModel implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1" implementation("androidx.lifecycle:lifecycle-runtime-compose:2.6.1") + implementation("androidx.compose.runtime:runtime-livedata:1.4.2") + implementation 'androidx.core:core-ktx:1.10.0' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1' - implementation 'androidx.activity:activity-compose:1.7.0' + implementation 'androidx.activity:activity-compose:1.7.1' implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" implementation 'androidx.compose.material3:material3:1.0.1' diff --git a/app/src/main/java/com/mitchelbv/thuis_c/MainActivity.kt b/app/src/main/java/com/mitchelbv/thuis_c/MainActivity.kt index 72f0483..1d6fc36 100644 --- a/app/src/main/java/com/mitchelbv/thuis_c/MainActivity.kt +++ b/app/src/main/java/com/mitchelbv/thuis_c/MainActivity.kt @@ -17,6 +17,7 @@ import com.mitchelbv.thuis_c.ui.theme.ThuisTheme import com.mitchelbv.thuis_c.views.feyenoord.MatchesScreen import com.mitchelbv.thuis_c.views.freezer.FreezerScreen import com.mitchelbv.thuis_c.views.freezer.item_list.FreezerItemListScreen +import com.mitchelbv.thuis_c.views.freezer.item_list.edit_item.FreezerItemEditScreen import com.mitchelbv.thuis_c.views.home.HomeScreen import com.mitchelbv.thuis_c.views.recipe.RecipeScreen @@ -88,6 +89,7 @@ class MainActivity : ComponentActivity() { ) } + // Items list composable(route = "${FreezerItemListDestination.route}/{freezer_id}", arguments = listOf( navArgument("freezer_id") { this.type = NavType.IntType @@ -95,10 +97,21 @@ class MainActivity : ComponentActivity() { }) ) { FreezerItemListScreen( - onEditItem = { + onEditItem = {freezerItem -> // I want onEditItem to open a modal dialog, so not sure if this is needed here... + navController.navigate("${FreezerItemDetail.route}/${freezerItem}") }) } + + // Edit items + composable(route = "${FreezerItemDetail.route}/{freezer_id}", arguments = listOf( + navArgument("freezer_id") { + this.type = NavType.IntType + this.nullable = false + } + )) { + FreezerItemEditScreen() + } } } } diff --git a/app/src/main/java/com/mitchelbv/thuis_c/network/thuis/ThuisService.kt b/app/src/main/java/com/mitchelbv/thuis_c/network/thuis/ThuisService.kt index 8b1afb0..a783c0d 100644 --- a/app/src/main/java/com/mitchelbv/thuis_c/network/thuis/ThuisService.kt +++ b/app/src/main/java/com/mitchelbv/thuis_c/network/thuis/ThuisService.kt @@ -44,7 +44,7 @@ interface ThuisService { suspend fun getFreezerItems(): FreezerItems @GET("api/FreezerItem/{id}") - suspend fun getFreezerItem(id: Int): FreezerItem + suspend fun getFreezerItem(@Path("id") id: Int): FreezerItem @GET("api/FreezerItem/InFreezer/{id}") suspend fun getFreezerItemsInFreezer(@Path("id") id: Int): List diff --git a/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/FreezerItemListView.kt b/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/FreezerItemListView.kt index 9623544..3c60e55 100644 --- a/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/FreezerItemListView.kt +++ b/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/FreezerItemListView.kt @@ -5,6 +5,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.material3.* import androidx.compose.runtime.* +import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Alignment import androidx.compose.ui.res.stringResource import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -20,7 +21,9 @@ fun FreezerItemListScreen( onEditItem: (Int) -> Unit ) { val freezerItemListUiState by freezerItemListViewModel.uiState.collectAsStateWithLifecycle() - freezerItemListUiState.items.forEach { freezerItem -> + val itemObserver = freezerItemListUiState.items.observeAsState() + + itemObserver.value?.forEach { freezerItem -> FreezerItemElement(freezerItem = freezerItem, arrowPressed = { item_id: Int, newAmount: Int -> freezerItemListViewModel.UpdateItemAmount( item_id, @@ -28,26 +31,8 @@ fun FreezerItemListScreen( ) }, onEditItem = onEditItem) } -// FreezerItemList( -// freezerItemListUiState.items, -// arrowPressed = { kaas: Int, baas: Int -> -// freezerItemListViewModel.UpdateItemAmount( -// kaas, -// baas -// ) -// }, -// onEditItem = onEditItem -// ) -} + FloatingActionButton(onClick = { /*TODO*/ }) { -@Composable -fun FreezerItemList( - freezerItems: List, - arrowPressed: (Int, Int) -> Unit, - onEditItem: (Int) -> Unit -) { - freezerItems.forEach { freezerItem -> - FreezerItemElement(freezerItem, arrowPressed = arrowPressed, onEditItem = onEditItem) } } @@ -90,19 +75,3 @@ fun FreezerItemElement( } ) } - -//@Preview -//@Composable -//fun FreezerItemElementPreview() { -// val freezerItem = FreezerItem( -// freezerItemId = 1, -// item = "Kip", -// amount = 5, -// drawer = 1, -// dateTimeAdded = "now", -// freezerId = 1 -// ) -// FreezerItemElement(freezerItem = freezerItem) -// FreezerItemElement(freezerItem = freezerItem) -// FreezerItemElement(freezerItem = freezerItem) -//} \ No newline at end of file diff --git a/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/FreezerItemListViewModel.kt b/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/FreezerItemListViewModel.kt index 05baefe..d8b24b0 100644 --- a/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/FreezerItemListViewModel.kt +++ b/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/FreezerItemListViewModel.kt @@ -15,8 +15,7 @@ import java.net.ConnectException import java.net.SocketTimeoutException data class FreezerItemListUiState( - var items: List = listOf(), -// val items: MutableLiveData> = MutableLiveData>(), + val items: MutableLiveData> = MutableLiveData>(), var error: String = "" ) @@ -33,7 +32,7 @@ class FreezerItemListViewModel(savedStateHandle: SavedStateHandle) : ViewModel() try { val apiResponse = ThuisRetrofitHelper.thuis.getFreezerItemsInFreezer(id = freezer_id) - _uiState.value = FreezerItemListUiState(apiResponse) + _uiState.value = FreezerItemListUiState(MutableLiveData(apiResponse)) } catch (e: ConnectException) { // _uiState.value = FreezerItemListUiState(listOf(FreezerItem(item = ))) @@ -46,16 +45,16 @@ class FreezerItemListViewModel(savedStateHandle: SavedStateHandle) : ViewModel() fun UpdateItemAmount(item_id: Int, newAmount: Int) { viewModelScope.launch(Dispatchers.IO) { try { - val itemList = _uiState.value.items.toMutableList() + val itemList = _uiState.value.items.value!!.toMutableList() val indexFreezerItem = - itemList.indexOf(uiState.value.items.find { a -> a.freezerItemId == item_id }) + itemList.indexOf(uiState.value.items.value!!.find { a -> a.freezerItemId == item_id }) val freezerItemToUpdate = itemList[indexFreezerItem] freezerItemToUpdate.amount = newAmount // itemList[indexFreezerItem] = freezerItemToUpdate val apiResponse = ThuisRetrofitHelper.thuis.putFreezerItem(item_id, freezerItemToUpdate) _uiState.update { currentState -> - currentState.copy(items = apiResponse) + currentState.copy(items = MutableLiveData(apiResponse)) } } catch (e: HttpException) { // TODO Display a snackbar... diff --git a/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/edit_item/FreezerItemEdit.kt b/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/edit_item/FreezerItemEdit.kt new file mode 100644 index 0000000..602dc82 --- /dev/null +++ b/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/edit_item/FreezerItemEdit.kt @@ -0,0 +1,77 @@ +package com.mitchelbv.thuis_c.views.freezer.item_list.edit_item + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.core.text.isDigitsOnly +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.lifecycle.viewmodel.compose.viewModel +import com.mitchelbv.thuis_c.R +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.item_list.FreezerItemListViewModel + +@Composable +fun FreezerItemEditScreen( + freezerItemEditViewModel: FreezerItemEditViewModel = viewModel() +) { + val freezerItemUiState by freezerItemEditViewModel.uiState.collectAsStateWithLifecycle() + + freezerItemUiState.item?.let { BuildEditView(freezerItem = it) } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun BuildEditView(freezerItem: FreezerItem) { + var itemText by rememberSaveable() { + mutableStateOf(freezerItem.item) + } + Column(verticalArrangement = Arrangement.SpaceBetween) { + TextField( + label = { Text(stringResource(id = R.string.freezer_item_edit_description)) }, +// value = "${freezerItem.item}", + value = "${itemText}", + onValueChange = { + freezerItem.item = it + itemText = it + }) + TextField( + label = { Text(stringResource(id = R.string.freezer_item_edit_amount)) }, + value = "${freezerItem.amount}", + onValueChange = { value -> + if (value.isDigitsOnly()) { + freezerItem.amount = value.toInt() + } + }, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) + ) + TextField( + label = { Text(stringResource(id = R.string.freezer_item_edit_drawer)) }, + value = "${freezerItem.drawer}", + onValueChange = {}) + } +} + +@Preview +@Composable +fun EditViewPreview() { + val test = FreezerItem(freezerItemId = 1, item = "Kip", 5, 5, "12-01-01", 1) + BuildEditView(freezerItem = test) +} \ No newline at end of file diff --git a/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/edit_item/FreezerItemEditViewModel.kt b/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/edit_item/FreezerItemEditViewModel.kt new file mode 100644 index 0000000..458cc9a --- /dev/null +++ b/app/src/main/java/com/mitchelbv/thuis_c/views/freezer/item_list/edit_item/FreezerItemEditViewModel.kt @@ -0,0 +1,44 @@ +package com.mitchelbv.thuis_c.views.freezer.item_list.edit_item + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.mitchelbv.thuis_c.network.thuis.ThuisRetrofitHelper +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.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import java.net.ConnectException + +data class FreezerItemEditUiState( + val item: FreezerItem? = null, + var error: String = "" +) + +class FreezerItemEditViewModel(savedStateHandle: SavedStateHandle) : ViewModel() { + private val _uiState = MutableStateFlow(FreezerItemEditUiState()) + val uiState: StateFlow = _uiState.asStateFlow() + + init { + savedStateHandle.get("freezer_id")?.let { fillEditBoxes(it) } + } + + fun fillEditBoxes(freezer_id: Int) { + viewModelScope.launch(Dispatchers.IO) { + try { + val apiResponse = + ThuisRetrofitHelper.thuis.getFreezerItem(id = freezer_id) + _uiState.value = FreezerItemEditUiState(item = apiResponse) + + } catch (e: ConnectException) { +// _uiState.value = FreezerItemListUiState(listOf(FreezerItem(item = ))) + _uiState.value = FreezerItemEditUiState(error = "Oeps") + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ba3d918..e2bb918 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,8 +8,14 @@ Cards Freezers + No freezer(s) Edit freezer items Drawer + + + Description + Amount + Drawer \ No newline at end of file diff --git a/build.gradle b/build.gradle index 55316c8..1af5111 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,10 @@ buildscript { ext { - compose_version = '1.4.1' + compose_version = '1.4.2' } }// Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id 'com.android.application' version '7.4.2' apply false - id 'com.android.library' version '7.4.2' apply false + id 'com.android.application' version '8.0.0' apply false + id 'com.android.library' version '8.0.0' apply false id 'org.jetbrains.kotlin.android' version '1.8.10' apply false } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 3c5031e..f2b979f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,4 +20,7 @@ kotlin.code.style=official # Enables namespacing of each library's R class so that its R class includes only the # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true \ No newline at end of file +android.nonTransitiveRClass=true +android.defaults.buildfeatures.buildconfig=true +android.nonFinalResIds=false +org.gradle.unsafe.configuration-cache=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9269099..5455ed8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Mon Oct 31 14:59:45 CET 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME