diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/location/LocationItem.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/location/LocationItem.kt index 6fe2aeb4..76f22496 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/location/LocationItem.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/location/LocationItem.kt @@ -18,6 +18,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -29,18 +30,24 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.rounded.ArrowBack import androidx.compose.material.icons.automirrored.rounded.NavigateNext +import androidx.compose.material.icons.automirrored.rounded.OpenInNew import androidx.compose.material.icons.rounded.BugReport +import androidx.compose.material.icons.rounded.Edit import androidx.compose.material.icons.rounded.Language -import androidx.compose.material.icons.rounded.Map import androidx.compose.material.icons.rounded.Navigation import androidx.compose.material.icons.rounded.Phone import androidx.compose.material.icons.rounded.Star import androidx.compose.material.icons.rounded.StarOutline +import androidx.compose.material.icons.rounded.Visibility +import androidx.compose.material.icons.rounded.VisibilityOff +import androidx.compose.material.icons.rounded.WifiOff import androidx.compose.material3.AssistChip import androidx.compose.material3.AssistChipDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedCard +import androidx.compose.material3.SnackbarDuration +import androidx.compose.material3.SnackbarResult import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState @@ -62,10 +69,13 @@ import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.roundToIntRect import androidx.compose.ui.unit.times +import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.lifecycle.lifecycleScope import de.mm20.launcher2.i18n.R import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.search.Location +import de.mm20.launcher2.search.LocationCategory import de.mm20.launcher2.search.OpeningHours import de.mm20.launcher2.search.OpeningSchedule import de.mm20.launcher2.ui.component.DefaultToolbarAction @@ -77,10 +87,13 @@ import de.mm20.launcher2.ui.ktx.metersToLocalizedString import de.mm20.launcher2.ui.ktx.toPixels import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM import de.mm20.launcher2.ui.launcher.search.listItemViewModel +import de.mm20.launcher2.ui.launcher.sheets.LocalBottomSheetManager import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled import de.mm20.launcher2.ui.locals.LocalGridSettings +import de.mm20.launcher2.ui.locals.LocalSnackbarHostState import de.mm20.launcher2.ui.modifier.scale import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.launch import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.time.format.FormatStyle @@ -170,7 +183,7 @@ fun LocationItem( if (category != null || formattedDistance != null) { Text( when { - category != null && formattedDistance != null -> "${category} • ${formattedDistance}" + category != null && formattedDistance != null -> "${stringResource(category.labelRes)} • ${formattedDistance}" category != null -> category.toString() formattedDistance != null -> formattedDistance else -> "" @@ -268,7 +281,7 @@ fun LocationItem( if (category != null || formattedDistance != null) { Text( when { - category != null && formattedDistance != null -> "${category} • ${formattedDistance}" + category != null && formattedDistance != null -> "${stringResource(category.labelRes)} • ${formattedDistance}" category != null -> category.toString() formattedDistance != null -> formattedDistance else -> "" @@ -291,7 +304,8 @@ fun LocationItem( //TODO: add rating to location if (showMap && false) { RatingBar(0.66f) - } else { + } + if (!showMap) { Compass( targetHeading = targetHeading, modifier = Modifier @@ -540,16 +554,23 @@ fun LocationItem( toolbarActions.add(favAction) } - if (!showMap) { - toolbarActions += DefaultToolbarAction( - label = stringResource(id = R.string.menu_map), - icon = Icons.Rounded.Map - ) { - viewModel.launch(context) - } - + toolbarActions += DefaultToolbarAction( + label = stringResource(id = R.string.menu_map), + icon = Icons.AutoMirrored.Rounded.OpenInNew, + ) { + viewModel.launch(context) } + val sheetManager = LocalBottomSheetManager.current + val lifecycleOwner = LocalLifecycleOwner.current + val snackbarHostState = LocalSnackbarHostState.current + + toolbarActions.add(DefaultToolbarAction( + label = stringResource(de.mm20.launcher2.ui.R.string.menu_customize), + icon = Icons.Rounded.Edit, + action = { sheetManager.showCustomizeSearchableModal(location) } + )) + location.fixMeUrl?.let { @@ -565,6 +586,41 @@ fun LocationItem( } } + val isHidden by viewModel.isHidden.collectAsState(false) + val hideAction = if (isHidden) { + DefaultToolbarAction( + label = stringResource(R.string.menu_unhide), + icon = Icons.Rounded.Visibility, + action = { + viewModel.unhide() + onBack() + } + ) + } else { + DefaultToolbarAction( + label = stringResource(R.string.menu_hide), + icon = Icons.Rounded.VisibilityOff, + action = { + viewModel.hide() + onBack() + lifecycleOwner.lifecycleScope.launch { + val result = snackbarHostState.showSnackbar( + message = context.getString( + R.string.msg_item_hidden, + location.labelOverride ?: location.label + ), + actionLabel = context.getString(R.string.action_undo), + duration = SnackbarDuration.Short, + ) + if (result == SnackbarResult.ActionPerformed) { + viewModel.unhide() + } + } + + }) + } + toolbarActions.add(hideAction) + Toolbar( modifier = Modifier.fillMaxWidth(), leftActions = listOf(DefaultToolbarAction( @@ -681,4 +737,81 @@ private fun OpeningSchedule.getNextOpeningHours(): OpeningHours { .find { now.dayOfWeek < it.dayOfWeek || now.dayOfWeek == it.dayOfWeek && now.toLocalTime() < it.startTime } ?: sortedSchedule.first() -} \ No newline at end of file +} + +private val LocationCategory.labelRes + get() = when(this) { + LocationCategory.ART -> R.string.poi_category_art + LocationCategory.BANK -> R.string.poi_category_bank + LocationCategory.BAR -> R.string.poi_category_bar + LocationCategory.BEAUTY -> R.string.poi_category_beauty + LocationCategory.BICYCLE -> R.string.poi_category_bicycle + LocationCategory.RESTAURANT -> R.string.poi_category_restaurant + LocationCategory.FAST_FOOD -> R.string.poi_category_fast_food + LocationCategory.CAFE -> R.string.poi_category_coffee_shop + LocationCategory.HOTEL -> R.string.poi_category_hotel + LocationCategory.SUPERMARKET -> R.string.poi_category_supermarket + LocationCategory.OTHER -> R.string.poi_category_other + LocationCategory.SCHOOL -> R.string.poi_category_school + LocationCategory.PARKING -> R.string.poi_category_parking + LocationCategory.FUEL -> R.string.poi_category_fuel + LocationCategory.TOILETS -> R.string.poi_category_toilets + LocationCategory.PHARMACY -> R.string.poi_category_pharmacy + LocationCategory.HOSPITAL -> R.string.poi_category_hospital + LocationCategory.POST_OFFICE -> R.string.poi_category_post_office + LocationCategory.PUB -> R.string.poi_category_pub + LocationCategory.GRAVE_YARD -> R.string.poi_category_grave_yard + LocationCategory.DOCTORS -> R.string.poi_category_doctors + LocationCategory.POLICE -> R.string.poi_category_police + LocationCategory.DENTIST -> R.string.poi_category_dentist + LocationCategory.LIBRARY -> R.string.poi_category_library + LocationCategory.COLLEGE -> R.string.poi_category_college + LocationCategory.ICE_CREAM -> R.string.poi_category_ice_cream + LocationCategory.THEATER -> R.string.poi_category_theater + LocationCategory.PUBLIC_BUILDING -> R.string.poi_category_public_building + LocationCategory.CINEMA -> R.string.poi_category_cinema + LocationCategory.NIGHTCLUB -> R.string.poi_category_nightclub + LocationCategory.BIERGARTEN -> R.string.poi_category_biergarten + LocationCategory.CLINIC -> R.string.poi_category_clinic + LocationCategory.UNIVERSITY -> R.string.poi_category_university + LocationCategory.DEPARTMENT_STORE -> R.string.poi_category_department_store + LocationCategory.CLOTHES -> R.string.poi_category_clothes + LocationCategory.CONVENIENCE -> R.string.poi_category_convenience + LocationCategory.HAIRDRESSER -> R.string.poi_category_hairdresser + LocationCategory.CAR_REPAIR -> R.string.poi_category_car_repair + LocationCategory.BOOKS -> R.string.poi_category_books + LocationCategory.BAKERY -> R.string.poi_category_bakery + LocationCategory.CAR -> R.string.poi_category_car + LocationCategory.MOBILE_PHONE -> R.string.poi_category_mobile_phone + LocationCategory.FURNITURE -> R.string.poi_category_furniture + LocationCategory.ALCOHOL -> R.string.poi_category_alcohol + LocationCategory.FLORIST -> R.string.poi_category_florist + LocationCategory.HARDWARE -> R.string.poi_category_hardware + LocationCategory.ELECTRONICS -> R.string.poi_category_electronics + LocationCategory.SHOES -> R.string.poi_category_shoes + LocationCategory.MALL -> R.string.poi_category_mall + LocationCategory.OPTICIAN -> R.string.poi_category_optician + LocationCategory.JEWELRY -> R.string.poi_category_jewelry + LocationCategory.GIFT -> R.string.poi_category_gift + LocationCategory.LAUNDRY -> R.string.poi_category_laundry + LocationCategory.COMPUTER -> R.string.poi_category_computer + LocationCategory.TOBACCO -> R.string.poi_category_tobacco + LocationCategory.WINE -> R.string.poi_category_wine + LocationCategory.PHOTO -> R.string.poi_category_photo + LocationCategory.COFFEE_SHOP -> R.string.poi_category_coffee_shop + LocationCategory.SOCCER -> R.string.poi_category_soccer + LocationCategory.BASKETBALL -> R.string.poi_category_basketball + LocationCategory.TENNIS -> R.string.poi_category_tennis + LocationCategory.FITNESS -> R.string.poi_category_fitness + LocationCategory.TRAM_STOP -> R.string.poi_category_tram_stop + LocationCategory.RAILWAY_STATION -> R.string.poi_category_railway_station + LocationCategory.BUS_STATION -> R.string.poi_category_bus_station + LocationCategory.ATM -> R.string.poi_category_atm + LocationCategory.KIOSK -> R.string.poi_category_kiosk + LocationCategory.BUS_STOP -> R.string.poi_category_bus_stop + LocationCategory.MUSEUM -> R.string.poi_category_museum + LocationCategory.PARCEL_LOCKER -> R.string.poi_category_parcel_locker + LocationCategory.CHEMIST -> R.string.poi_category_chemist + LocationCategory.TRAVEL_AGENCY -> R.string.poi_category_travel_agency + LocationCategory.FITNESS_CENTER -> R.string.poi_category_fitness_center + } \ No newline at end of file diff --git a/core/base/src/main/java/de/mm20/launcher2/search/Location.kt b/core/base/src/main/java/de/mm20/launcher2/search/Location.kt index 72be196d..7297707f 100644 --- a/core/base/src/main/java/de/mm20/launcher2/search/Location.kt +++ b/core/base/src/main/java/de/mm20/launcher2/search/Location.kt @@ -80,7 +80,7 @@ interface Location : SavableSearchable { LocationCategory.LIBRARY, LocationCategory.BOOKS -> R.drawable.ic_location_library to R.color.brown LocationCategory.COLLEGE, LocationCategory.UNIVERSITY -> R.drawable.ic_location_college to R.color.purple LocationCategory.ICE_CREAM -> R.drawable.ic_location_ice_cream to R.color.pink - LocationCategory.THEATRE -> R.drawable.ic_location_theatre to R.color.purple + LocationCategory.THEATER -> R.drawable.ic_location_theatre to R.color.purple LocationCategory.PUBLIC_BUILDING -> R.drawable.ic_location_public_building to R.color.bluegrey LocationCategory.CINEMA -> R.drawable.ic_location_cinema to R.color.purple LocationCategory.NIGHTCLUB -> R.drawable.ic_location_nightclub to R.color.purple @@ -111,9 +111,9 @@ interface Location : SavableSearchable { LocationCategory.SOCCER -> R.drawable.ic_location_soccer to R.color.green LocationCategory.BASKETBALL -> R.drawable.ic_location_basketball to R.color.orange LocationCategory.TENNIS -> R.drawable.ic_location_tennis to R.color.orange - LocationCategory.FITNESS, LocationCategory.FITNESS_CENTRE -> R.drawable.ic_location_fitness to R.color.orange + LocationCategory.FITNESS, LocationCategory.FITNESS_CENTER -> R.drawable.ic_location_fitness to R.color.orange LocationCategory.TRAM_STOP -> R.drawable.ic_location_tram_stop to R.color.blue - LocationCategory.RAILWAY_STOP -> R.drawable.ic_location_railway_stop to R.color.lightblue + LocationCategory.RAILWAY_STATION -> R.drawable.ic_location_railway_stop to R.color.lightblue LocationCategory.BUS_STATION, LocationCategory.BUS_STOP -> R.drawable.ic_location_bus_station to R.color.blue LocationCategory.ATM -> R.drawable.ic_location_atm to R.color.green LocationCategory.ART -> R.drawable.ic_location_art to R.color.deeporange @@ -175,7 +175,7 @@ enum class LocationCategory { LIBRARY, COLLEGE, ICE_CREAM, - THEATRE, + THEATER, PUBLIC_BUILDING, CINEMA, NIGHTCLUB, @@ -215,7 +215,7 @@ enum class LocationCategory { TENNIS, FITNESS, TRAM_STOP, - RAILWAY_STOP, + RAILWAY_STATION, BUS_STATION, ATM, ART, @@ -225,7 +225,7 @@ enum class LocationCategory { PARCEL_LOCKER, CHEMIST, TRAVEL_AGENCY, - FITNESS_CENTRE + FITNESS_CENTER } data class OpeningHours( diff --git a/core/i18n/src/main/res/values/strings.xml b/core/i18n/src/main/res/values/strings.xml index 64583d99..aaef8b3e 100644 --- a/core/i18n/src/main/res/values/strings.xml +++ b/core/i18n/src/main/res/values/strings.xml @@ -930,4 +930,78 @@ Customize filter bar Customize which items are included in the filter bar The current filter enables online results by default. Your search queries might unintentionally be sent to external web services. For privacy reasons, this is not recommended. + + Restaurant + Fast food + Bar + Cafe + Hotel + Supermarket + Place of interest + School + Parking + Gas station + Restroom + Pharmacy + Hospital + Post office + Pub + Graveyard + Doctors + Police + Dentist + Library + College + Ice cream parlor + Theater + Public building + Cinema + Nightclub + Biergarten + Clinic + University + Department store + Apparel store + Convenience store + Hairdresser + Car repair + Beauty salon + Bookstore + Bakery + Car service + Cell phone store + Furniture store + Liquor store + Flower shop + Hardware store + Electronics store + Shoe store + Mall + Optometrist + Jewelry store + Gift shop + Bicycle store + Laundry + Computer store + Tobacco store + Wine store + Photo shop + Coffee Shop + Bank + Soccer + Basketball + Tennis + Fitness + Tram stop + Railway station + Bus station + ATM + Art store + Kiosk + Bus stop + Museum + Parcel locker + Drug store + Travel agency + Fitness center \ No newline at end of file