Fix: Resolve list selection crash & update to minimal flat app icon

- ListDetailViewModel & Screen: set listId safely via setListId() avoiding SavedStateHandle null crashes
- Navigation: pass listId = key.listId explicitly into ListDetailScreen
- App Icon: replace 3D icon with a clean, minimal flat line-art shopping bag & checkmark icon suited for Samsung One UI & stock Android adaptive icon masks
- ADB reinstall & launch verified 
This commit is contained in:
Tronax 2026-08-05 20:27:38 +02:00
parent b9f10b1a2e
commit 04e5c55c2a
Signed by: Tronax
SSH key fingerprint: SHA256:2pKKXDZucWvaF/GzXNz0FY53EAO1YDLN80bqS+TTz/o
15 changed files with 23 additions and 7 deletions

View file

@ -37,6 +37,7 @@ fun MainNavigation(sessionManager: SessionManager) {
} }
entry<ListDetailNavKey> { key -> entry<ListDetailNavKey> { key ->
ListDetailScreen( ListDetailScreen(
listId = key.listId,
onBack = { backStack.removeLastOrNull() } onBack = { backStack.removeLastOrNull() }
) )
} }

View file

@ -29,10 +29,15 @@ import com.example.mitbringsl.data.local.entity.ItemEntity
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ListDetailScreen( fun ListDetailScreen(
listId: String,
onBack: () -> Unit, onBack: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
viewModel: ListDetailViewModel = hiltViewModel(), viewModel: ListDetailViewModel = hiltViewModel(),
) { ) {
LaunchedEffect(listId) {
viewModel.setListId(listId)
}
val items by viewModel.items.collectAsStateWithLifecycle() val items by viewModel.items.collectAsStateWithLifecycle()
val query by viewModel.query.collectAsStateWithLifecycle() val query by viewModel.query.collectAsStateWithLifecycle()
val suggestions by viewModel.suggestions.collectAsStateWithLifecycle() val suggestions by viewModel.suggestions.collectAsStateWithLifecycle()

View file

@ -1,34 +1,43 @@
package com.example.mitbringsl.ui.detail package com.example.mitbringsl.ui.detail
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.mitbringsl.data.local.entity.ItemEntity import com.example.mitbringsl.data.local.entity.ItemEntity
import com.example.mitbringsl.data.remote.api.MitbringslApi import com.example.mitbringsl.data.remote.api.MitbringslApi
import com.example.mitbringsl.data.repository.ShoppingRepository import com.example.mitbringsl.data.repository.ShoppingRepository
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
@OptIn(FlowPreview::class) @OptIn(FlowPreview::class, ExperimentalCoroutinesApi::class)
@HiltViewModel @HiltViewModel
class ListDetailViewModel @Inject constructor( class ListDetailViewModel @Inject constructor(
private val repository: ShoppingRepository, private val repository: ShoppingRepository,
private val api: MitbringslApi, private val api: MitbringslApi,
savedStateHandle: SavedStateHandle,
) : ViewModel() { ) : ViewModel() {
val listId: String = checkNotNull(savedStateHandle["listId"]) private val _listId = MutableStateFlow<String?>(null)
val items: StateFlow<List<ItemEntity>> = repository.observeItems(listId) val items: StateFlow<List<ItemEntity>> = _listId
.filterNotNull()
.flatMapLatest { id -> repository.observeItems(id) }
.stateIn( .stateIn(
scope = viewModelScope, scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000), started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList() initialValue = emptyList()
) )
fun setListId(id: String) {
if (_listId.value != id) {
_listId.value = id
}
}
val currentListId: String get() = _listId.value ?: ""
private val _query = MutableStateFlow("") private val _query = MutableStateFlow("")
val query: StateFlow<String> = _query.asStateFlow() val query: StateFlow<String> = _query.asStateFlow()
@ -61,10 +70,11 @@ class ListDetailViewModel @Inject constructor(
} }
fun addItem(name: String, quantity: String? = null) { fun addItem(name: String, quantity: String? = null) {
val targetListId = _listId.value ?: return
if (name.isBlank()) return if (name.isBlank()) return
val qty = quantity?.trim()?.takeIf { it.isNotEmpty() } val qty = quantity?.trim()?.takeIf { it.isNotEmpty() }
viewModelScope.launch { viewModelScope.launch {
repository.addItem(listId, name.trim(), qty) repository.addItem(targetListId, name.trim(), qty)
_query.value = "" _query.value = ""
_suggestions.value = emptyList() _suggestions.value = emptyList()
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 220 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Before After
Before After

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="ic_launcher_background_color">#1B1B2F</color> <color name="ic_launcher_background_color">#151829</color>
</resources> </resources>