diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragment.kt index 79ecc675..381b1740 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragment.kt @@ -80,9 +80,9 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) { findNavController().popBackStack() } } - getNavResult>(R.id.nav_entries, "modes") { modes -> - viewModel.saveSelectedModes(modes) - } +// getNavResult>(R.id.nav_entries, "modes") { modes -> +// viewModel.saveSelectedModes(modes) +// } } private fun handleSatData(dataState: DataState>, entriesAdapter: EntriesAdapter) { diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragmentCompose.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragmentCompose.kt index 487b0b20..9c5f3b10 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragmentCompose.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesFragmentCompose.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource @@ -11,23 +12,27 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items -import androidx.compose.material.Card -import androidx.compose.material.Checkbox -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text +import androidx.compose.material.* +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.ArrowRight +import androidx.compose.material.icons.outlined.Close +import androidx.compose.material.icons.outlined.Search import androidx.compose.runtime.Composable import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.composed import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ViewCompositionStrategy +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.fragment.app.Fragment import androidx.lifecycle.viewmodel.compose.viewModel +import com.rtbishop.look4sat.R import com.rtbishop.look4sat.domain.model.DataState import com.rtbishop.look4sat.domain.model.SatItem import com.rtbishop.look4sat.presentation.theme.Look4SatTheme @@ -41,66 +46,124 @@ class EntriesFragmentCompose : Fragment() { ): View { return ComposeView(requireContext()).apply { setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) - setContent { - val entriesViewModel: EntriesViewModel = viewModel() - EntriesScreen(entriesViewModel) + setContent { Look4SatTheme { EntriesScreenView() } } + } + } + + @Composable + fun EntriesScreenView(viewModel: EntriesViewModel = viewModel()) { + val dataState = viewModel.satData.observeAsState(DataState.Loading) + Column(modifier = Modifier.padding(6.dp)) { + Card { SearchBar(setQuery = { newQuery -> viewModel.setQuery(newQuery) }) } + + Spacer(modifier = Modifier.height(6.dp)) + Card( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + ) { + LoadingOrList(state = dataState.value) { list, value -> + viewModel.updateSelection(list, value) + } + } + Spacer(modifier = Modifier.height(6.dp)) + EntryTypeBar(entryType = "All") + + } + } + + @Composable + fun EntryTypeBar(entryType: String, modifier: Modifier = Modifier) { + val icon = Icons.Outlined.ArrowRight + val text = "Selected type: $entryType" + Card { + Row(verticalAlignment = Alignment.CenterVertically) { +// Icon(painter = painterResource(id = R.drawable.ic_next), contentDescription = null) + Icon(imageVector = icon, contentDescription = null, modifier = modifier.size(48.dp)) + Text(text = text, maxLines = 1, modifier = modifier.fillMaxWidth()) } } } - @Preview(showBackground = true, widthDp = 400, heightDp = 720, showSystemUi = true) @Composable - private fun EntriesScreen(entriesViewModel: EntriesViewModel = viewModel()) { - Look4SatTheme { - val dataState = entriesViewModel.satData.observeAsState(DataState.Loading) - val onSelected: (List, Boolean) -> Unit = { list, value -> - entriesViewModel.updateSelection(list, value) + fun LoadingOrList(state: DataState>, onSelected: (List, Boolean) -> Unit) { + when (state) { + is DataState.Loading -> { + LoadingProgress() } - Card(modifier = Modifier.padding(6.dp)) { - when (val state = dataState.value) { - is DataState.Success -> { - Column(modifier = Modifier.fillMaxSize()) { - SearchBar() - EntriesList(dataState = state.data, onSelected) - } - } - else -> {} + is DataState.Success -> { + EntriesList(entries = state.data) { list, value -> onSelected(list, value) } + } + else -> { + LoadingProgress() + } + } + } + + @Composable + fun LoadingProgress() { + Row( + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically + ) { CircularProgressIndicator(modifier = Modifier.size(64.dp)) } + } + + @OptIn(ExperimentalFoundationApi::class) + @Composable + fun EntriesList(entries: List, onSelected: (List, Boolean) -> Unit) { + LazyVerticalGrid(columns = GridCells.Adaptive(200.dp)) { + items(items = entries, key = { item -> item.catnum }) { entry -> + EntryItem(entry, onSelected, Modifier.animateItemPlacement()) + } + } + } + + @Composable + fun EntryItem(entry: SatItem, onSelected: (List, Boolean) -> Unit, modifier: Modifier) { + Surface(color = MaterialTheme.colors.background, modifier = modifier) { + Surface(modifier = modifier.padding(bottom = 1.dp)) { + Row(verticalAlignment = Alignment.CenterVertically, + modifier = modifier + .background(MaterialTheme.colors.surface) + .onClick { onSelected(listOf(entry.catnum), entry.isSelected.not()) }) { + Checkbox( + checked = entry.isSelected, onCheckedChange = null, Modifier.padding(6.dp) + ) + Text(text = entry.name, maxLines = 1, overflow = TextOverflow.Ellipsis) } } } } @Composable - fun SearchBar() { - Card { - - } - } - - @Composable - fun EntriesList(dataState: List, onSelected: (List, Boolean) -> Unit) { - LazyVerticalGrid( - columns = GridCells.Fixed(2), - verticalArrangement = Arrangement.spacedBy(2.dp), - horizontalArrangement = Arrangement.spacedBy(2.dp), - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colors.background) - ) { items(dataState) { EntryItem(item = it, onSelected) } } - } - - @Composable - fun EntryItem(item: SatItem, onSelected: (List, Boolean) -> Unit) { - Row(verticalAlignment = Alignment.CenterVertically, + fun SearchBar(setQuery: (String) -> Unit) { + val currentQuery = rememberSaveable { mutableStateOf("") } + OutlinedTextField(value = currentQuery.value, onValueChange = { newValue -> + currentQuery.value = newValue + setQuery(newValue) + }, maxLines = 1, +// label = { Text(text = stringResource(id = R.string.entries_search_hint)) }, + placeholder = { Text(text = stringResource(id = R.string.entries_search_hint)) }, + leadingIcon = { + Icon(imageVector = Icons.Outlined.Search, contentDescription = null) + }, trailingIcon = { + Icon(imageVector = Icons.Outlined.Close, + contentDescription = null, + modifier = Modifier.onClick { + currentQuery.value = "" + setQuery("") + }) + }, + colors = TextFieldDefaults.outlinedTextFieldColors( + focusedBorderColor = MaterialTheme.colors.onBackground, + unfocusedBorderColor = MaterialTheme.colors.onBackground), modifier = Modifier + .fillMaxWidth() .background(MaterialTheme.colors.surface) - .noRippleClickable { onSelected(listOf(item.catnum), item.isSelected.not()) }) { - Checkbox(checked = item.isSelected, onCheckedChange = null, Modifier.padding(6.dp)) - Text(text = item.name, maxLines = 1, overflow = TextOverflow.Ellipsis) - } + ) } - private fun Modifier.noRippleClickable(onClick: () -> Unit): Modifier = composed { + private fun Modifier.onClick(onClick: () -> Unit): Modifier = composed { clickable(remember { MutableInteractionSource() }, null) { onClick() } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt index 658fcae1..52c27db8 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt @@ -34,20 +34,20 @@ class EntriesViewModel @Inject constructor( ) : ViewModel(), EntriesAdapter.EntriesClickListener { private val satType = MutableLiveData(String()) - private val transModes = MutableLiveData(settings.loadModesSelection()) +// private val transModes = MutableLiveData(settings.loadModesSelection()) private val currentQuery = MutableLiveData(String()) private val itemsFromRepo = liveData { - delay(125) + delay(250) emit(loadEntriesWithSelection()) } as MutableLiveData private val itemsWithType = satType.switchMap { type -> itemsFromRepo.map { items -> filterByType(items, type) } } - private val itemsWithModes = transModes.switchMap { modes -> - itemsWithType.map { items -> filterByModes(items, modes) } - } +// private val itemsWithModes = transModes.switchMap { modes -> +// itemsWithType.map { items -> filterByModes(items, modes) } +// } private val itemsWithQuery = currentQuery.switchMap { query -> - itemsWithModes.map { items -> filterByQuery(items, query) } + itemsWithType.map { items -> filterByQuery(items, query) } } val satData = itemsWithQuery.map { items -> DataState.Success(items) } val satTypes: List = settings.sourcesMap.keys.sorted() @@ -64,10 +64,10 @@ class EntriesViewModel @Inject constructor( } } - fun saveSelectedModes(modes: List) { - transModes.value = modes - settings.saveModesSelection(modes) - } +// fun saveSelectedModes(modes: List) { +// transModes.value = modes +// settings.saveModesSelection(modes) +// } fun setQuery(query: String) { currentQuery.value = query @@ -101,10 +101,10 @@ class EntriesViewModel @Inject constructor( return items.filter { item -> item.catnum in catnums } } - private fun filterByModes(items: List, modes: List): List { - if (modes.isEmpty()) return items - return items.filter { item -> item.modes.any { mode -> mode in modes } } - } +// private fun filterByModes(items: List, modes: List): List { +// if (modes.isEmpty()) return items +// return items.filter { item -> item.modes.any { mode -> mode in modes } } +// } private fun filterByQuery(items: List, query: String): List { if (query.isBlank()) return items diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Theme.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Theme.kt index 13e8fe3e..c33f5c69 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Theme.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Theme.kt @@ -20,7 +20,7 @@ private val LightColors = lightColors( surface = SurfaceGrey, onPrimary = TextWhite, onSecondary = TextBlack, - onBackground = TextWhite, + onBackground = TextGrey, onSurface = TextWhite ) @@ -32,6 +32,6 @@ private val DarkColors = darkColors( surface = SurfaceGrey, onPrimary = TextWhite, onSecondary = TextBlack, - onBackground = TextWhite, + onBackground = TextGrey, onSurface = TextWhite )