diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 69f0bd7..8fa2101 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -51,6 +51,7 @@ android { "proguard-rules.pro" ) buildConfigField("boolean", "ECOSYSTEM_FLAG", "false") + signingConfig = signingConfigs.getByName("debug") } } compileOptions { diff --git a/app/src/main/java/com/cornellappdev/transit/ui/components/home/AddFavoritesButton.kt b/app/src/main/java/com/cornellappdev/transit/ui/components/home/AddFavoritesButton.kt new file mode 100644 index 0000000..f2f1072 --- /dev/null +++ b/app/src/main/java/com/cornellappdev/transit/ui/components/home/AddFavoritesButton.kt @@ -0,0 +1,65 @@ +package com.cornellappdev.transit.ui.components.home + +import android.R.attr.text +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.cornellappdev.transit.R +import com.cornellappdev.transit.ui.theme.SecondaryText +import com.cornellappdev.transit.ui.theme.robotoFamily + +@Composable +fun AddFavoritesButton( + onAddFavoritesClick: () -> Unit, + modifier: Modifier = Modifier +) { + Button( + onClick = onAddFavoritesClick, + colors = ButtonDefaults.buttonColors( + containerColor = Color.White, + contentColor = Color.Black + ), + modifier = modifier + .fillMaxWidth() + .height(40.dp) + ) { + + Icon( + painter = painterResource(R.drawable.ic_addition), + contentDescription = "Add Favorite", + tint = SecondaryText, + ) + + Spacer(modifier = Modifier.width(8.dp)) + + Text( + text = "Add Favorites", + fontFamily = robotoFamily, + fontWeight = FontWeight.SemiBold, + fontSize = 16.sp, + color = SecondaryText + ) + } +} + +@Preview +@Composable +private fun AddFavoritesButtonPreview() { + AddFavoritesButton( + onAddFavoritesClick = {}, + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/transit/ui/components/home/AddFavoritesSearchSheet.kt b/app/src/main/java/com/cornellappdev/transit/ui/components/home/AddFavoritesSearchSheet.kt index 67832ac..af3e149 100644 --- a/app/src/main/java/com/cornellappdev/transit/ui/components/home/AddFavoritesSearchSheet.kt +++ b/app/src/main/java/com/cornellappdev/transit/ui/components/home/AddFavoritesSearchSheet.kt @@ -67,8 +67,8 @@ fun AddFavoritesSearchSheet( Column( modifier = Modifier - .fillMaxHeight(0.92f) .fillMaxWidth() + .fillMaxHeight(0.92f) ) { Column( modifier = Modifier diff --git a/app/src/main/java/com/cornellappdev/transit/ui/components/home/BottomSheetFilterItem.kt b/app/src/main/java/com/cornellappdev/transit/ui/components/home/BottomSheetFilterItem.kt index bfeb077..f710cc1 100644 --- a/app/src/main/java/com/cornellappdev/transit/ui/components/home/BottomSheetFilterItem.kt +++ b/app/src/main/java/com/cornellappdev/transit/ui/components/home/BottomSheetFilterItem.kt @@ -15,13 +15,14 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.cornellappdev.transit.R +import com.cornellappdev.transit.ui.theme.MetadataGray +import com.cornellappdev.transit.ui.theme.PrimaryText import com.cornellappdev.transit.ui.theme.Style /** @@ -62,7 +63,7 @@ fun BottomSheetFilterItem( } Text( label, - color = Color.Black, + color = if (isActive) PrimaryText else MetadataGray, textAlign = TextAlign.Center, modifier = Modifier .align(Alignment.CenterHorizontally) diff --git a/app/src/main/java/com/cornellappdev/transit/ui/components/home/BottomSheetLocationCard.kt b/app/src/main/java/com/cornellappdev/transit/ui/components/home/BottomSheetLocationCard.kt index 03292a7..ba663b6 100644 --- a/app/src/main/java/com/cornellappdev/transit/ui/components/home/BottomSheetLocationCard.kt +++ b/app/src/main/java/com/cornellappdev/transit/ui/components/home/BottomSheetLocationCard.kt @@ -30,7 +30,6 @@ fun BottomSheetLocationCard( ) { Column( modifier = Modifier - .padding(horizontal = 24.dp, vertical = 10.dp) .clickable { onClick() } diff --git a/app/src/main/java/com/cornellappdev/transit/ui/components/home/EcosystemBottomSheetContent.kt b/app/src/main/java/com/cornellappdev/transit/ui/components/home/EcosystemBottomSheetContent.kt index d1eae12..316db37 100644 --- a/app/src/main/java/com/cornellappdev/transit/ui/components/home/EcosystemBottomSheetContent.kt +++ b/app/src/main/java/com/cornellappdev/transit/ui/components/home/EcosystemBottomSheetContent.kt @@ -3,8 +3,10 @@ package com.cornellappdev.transit.ui.components.home import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row +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.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope @@ -51,7 +53,8 @@ fun EcosystemBottomSheetContent( modifier: Modifier = Modifier, navigateToPlace: (Place) -> Unit, onDetailsClick: (DetailedEcosystemPlace) -> Unit, - onFavoriteStarClick: (Place) -> Unit + onFavoriteStarClick: (Place) -> Unit, + onAddFavoritesClick: () -> Unit, ) { Column(modifier = modifier) { Row( @@ -91,7 +94,8 @@ fun EcosystemBottomSheetContent( favorites = favorites, navigateToPlace = navigateToPlace, onDetailsClick = onDetailsClick, - onFavoriteStarClick = onFavoriteStarClick + onFavoriteStarClick = onFavoriteStarClick, + onAddFavoritesClick = onAddFavoritesClick ) } } @@ -104,15 +108,16 @@ private fun BottomSheetFilteredContent( favorites: Set, navigateToPlace: (Place) -> Unit, onDetailsClick: (DetailedEcosystemPlace) -> Unit, - onFavoriteStarClick: (Place) -> Unit + onFavoriteStarClick: (Place) -> Unit, + onAddFavoritesClick: () -> Unit ) { LazyColumn( - contentPadding = PaddingValues(bottom = 90.dp), + contentPadding = PaddingValues(start = 24.dp, end = 24.dp, top = 20.dp, bottom = 90.dp), modifier = Modifier.fillMaxSize() ) { when (currentFilter) { FilterState.FAVORITES -> { - favoriteList(favorites, navigateToPlace) + favoriteList(favorites, navigateToPlace, onAddFavoritesClick) } FilterState.PRINTERS -> { @@ -151,8 +156,13 @@ private fun BottomSheetFilteredContent( */ private fun LazyListScope.favoriteList( favorites: Set, - navigateToPlace: (Place) -> Unit + navigateToPlace: (Place) -> Unit, + onAddFavoritesClick: () -> Unit ) { + item { + AddFavoritesButton(onAddFavoritesClick = onAddFavoritesClick) + Spacer(Modifier.height(20.dp)) + } items(favorites.toList()) { BottomSheetLocationCard( title = it.name, @@ -160,6 +170,7 @@ private fun LazyListScope.favoriteList( ) { //TODO: Eatery } + Spacer(Modifier.height(10.dp)) } } @@ -185,7 +196,9 @@ private fun LazyListScope.gymList( ) { //TODO: Eatery } + Spacer(Modifier.height(10.dp)) } + } } } @@ -214,7 +227,9 @@ private fun LazyListScope.printerList( it.toPlace() ) } + Spacer(Modifier.height(10.dp)) } + } } } @@ -256,6 +271,7 @@ private fun LazyListScope.eateryList( ) { onDetailsClick(it) } + Spacer(Modifier.height(10.dp)) } } } @@ -291,6 +307,7 @@ private fun LazyListScope.libraryList( ) { navigateToDetails(it) } + Spacer(Modifier.height(10.dp)) } } } @@ -319,6 +336,7 @@ private fun PreviewEcosystemBottomSheet() { modifier = Modifier, navigateToPlace = {}, onDetailsClick = {}, - onFavoriteStarClick = {} + onFavoriteStarClick = {}, + onAddFavoritesClick = {} ) } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/transit/ui/screens/HomeScreen.kt b/app/src/main/java/com/cornellappdev/transit/ui/screens/HomeScreen.kt index a90a3b4..fa59363 100644 --- a/app/src/main/java/com/cornellappdev/transit/ui/screens/HomeScreen.kt +++ b/app/src/main/java/com/cornellappdev/transit/ui/screens/HomeScreen.kt @@ -28,6 +28,7 @@ import androidx.compose.material3.BottomSheetScaffold import androidx.compose.material3.DockedSearchBar import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon +import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.SearchBarDefaults import androidx.compose.material3.SheetState import androidx.compose.material3.SheetValue @@ -35,6 +36,7 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.rememberBottomSheetScaffoldState +import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -53,6 +55,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavController import com.cornellappdev.transit.R import com.cornellappdev.transit.models.Place @@ -82,6 +85,8 @@ import com.google.maps.android.compose.GoogleMap import com.google.maps.android.compose.MapProperties import com.google.maps.android.compose.MapUiSettings import com.google.maps.android.compose.rememberCameraPositionState +import io.morfly.compose.bottomsheet.material3.BottomSheetScaffold +import io.morfly.compose.bottomsheet.material3.rememberBottomSheetScaffoldState import io.morfly.compose.bottomsheet.material3.rememberBottomSheetState import io.morfly.compose.bottomsheet.material3.sheetVisibleHeightDp import kotlinx.coroutines.launch @@ -125,6 +130,12 @@ fun HomeScreen( homeViewModel.instantiateLocation(context) } + val showAddFavoritesSheet by homeViewModel.showAddFavoritesSheet.collectAsStateWithLifecycle() + + val addFavoritesSheetState = rememberModalBottomSheetState( + skipPartiallyExpanded = true + ) + //SheetState for FavoritesBottomSheet val favoritesSheetState = rememberBottomSheetScaffoldState( @@ -138,20 +149,6 @@ fun HomeScreen( } ) - //sheetState for AddFavorites BottomSheet - val addSheetState = rememberBottomSheetScaffoldState( - bottomSheetState = remember { - SheetState( - skipPartiallyExpanded = true, - initialValue = SheetValue.Hidden, - density = localDensity, - confirmValueChange = { - homeViewModel.onAddQueryChange("") - true - } - ) - } - ) // Filter sheet state // Using advanced-bottomsheet-compose from https://github.com/Morfly/advanced-bottomsheet-compose @@ -170,7 +167,7 @@ fun HomeScreen( // Filter scaffold state val filterScaffoldState = - io.morfly.compose.bottomsheet.material3.rememberBottomSheetScaffoldState(filterSheetState) + rememberBottomSheetScaffoldState(filterSheetState) // Main search bar flow val searchBarValue = homeViewModel.searchBarUiState.collectAsState().value @@ -263,9 +260,7 @@ fun HomeScreen( navController.navigate("settings") }, onFavoriteAdd = { - scope.launch { - addSheetState.bottomSheetState.expand() - } + homeViewModel.toggleAddFavoritesSheet(true) }, onRecentClear = { homeViewModel.clearRecents() @@ -294,7 +289,7 @@ fun HomeScreen( ) } - io.morfly.compose.bottomsheet.material3.BottomSheetScaffold( + BottomSheetScaffold( scaffoldState = filterScaffoldState, sheetSwipeEnabled = true, sheetContainerColor = DetailsHeaderGray, @@ -341,7 +336,11 @@ fun HomeScreen( onDetailsClick = { ecosystemSheetState = EcosystemSheetState.Details(it) }, - onFavoriteStarClick = favoritesViewModel::toggleFavorite + onFavoriteStarClick = favoritesViewModel::toggleFavorite, + onAddFavoritesClick = { + homeViewModel.toggleAddFavoritesSheet(true) + } + ) } } @@ -367,14 +366,9 @@ fun HomeScreen( "Edit" } }, addOnClick = { - scope.launch { - if (!favoritesSheetState.bottomSheetState.hasExpandedState) { - favoritesSheetState.bottomSheetState.expand() - } - if (editState) { - editState = false - } - addSheetState.bottomSheetState.expand() + homeViewModel.toggleAddFavoritesSheet(true) + if (editState) { + editState = false } }, removeOnClick = { @@ -394,43 +388,47 @@ fun HomeScreen( } // AddFavorites BottomSheet - BottomSheetScaffold( - sheetShape = RoundedCornerShape(16.dp), - scaffoldState = addSheetState, - sheetContainerColor = Color.White, - sheetPeekHeight = 0.dp, - sheetContent = { + if (showAddFavoritesSheet) { + ModalBottomSheet( + onDismissRequest = { + homeViewModel.toggleAddFavoritesSheet(false) + homeViewModel.onAddQueryChange("") + }, + sheetState = addFavoritesSheetState, + shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), + containerColor = Color.White + ) { AddFavoritesSearchSheet( addSearchBarValue = addSearchBarValue, placeQueryResponse = placeQueryResponse, cancelOnClick = { - scope.launch { - addSheetState.bottomSheetState.hide() - homeViewModel.onAddQueryChange("") - } + homeViewModel.toggleAddFavoritesSheet(false) + homeViewModel.onAddQueryChange("") }, onItemClick = { - scope.launch { - if (!favoritesViewModel.isFavorite(it)) { - addSheetState.bottomSheetState.hide() - homeViewModel.clearAddQuery() - favoritesViewModel.addFavorite(it) - } else { - Toast.makeText( - context, - "${it.name} is already favorited!", - Toast.LENGTH_SHORT - ) - .show() - } + if (!favoritesViewModel.isFavorite(it)) { + homeViewModel.clearAddQuery() + favoritesViewModel.addFavorite(it) + Toast.makeText( + context, + "${it.name} was successfully added to your favorites list!", + Toast.LENGTH_SHORT + ) + .show() + } else { + Toast.makeText( + context, + "${it.name} is already favorited!", + Toast.LENGTH_SHORT + ) + .show() } }, onQueryChange = homeViewModel::onAddQueryChange, onClearChange = homeViewModel::clearAddQuery ) - }, - content = {} - ) + } + } } /** diff --git a/app/src/main/java/com/cornellappdev/transit/ui/viewmodels/HomeViewModel.kt b/app/src/main/java/com/cornellappdev/transit/ui/viewmodels/HomeViewModel.kt index 2c7c9e7..3b9aaea 100644 --- a/app/src/main/java/com/cornellappdev/transit/ui/viewmodels/HomeViewModel.kt +++ b/app/src/main/java/com/cornellappdev/transit/ui/viewmodels/HomeViewModel.kt @@ -114,6 +114,14 @@ class HomeViewModel @Inject constructor( ) ) + private val _showAddFavoritesSheet = MutableStateFlow(false) + val showAddFavoritesSheet: StateFlow = _showAddFavoritesSheet.asStateFlow() + + fun toggleAddFavoritesSheet(show: Boolean) { + _showAddFavoritesSheet.value = show + } + + init { userPreferenceRepository.favoritesFlow.onEach { if (_searchBarUiState.value is SearchBarUIState.RecentAndFavorites) { diff --git a/app/src/main/res/drawable/ic_addition.xml b/app/src/main/res/drawable/ic_addition.xml new file mode 100644 index 0000000..90e883e --- /dev/null +++ b/app/src/main/res/drawable/ic_addition.xml @@ -0,0 +1,9 @@ + + +