Only show the first 5 results of each category by default

This commit is contained in:
MM20 2024-05-19 18:19:34 +02:00
parent cc4fcf8f67
commit 72ab5dff39
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
10 changed files with 159 additions and 63 deletions

View File

@ -6,17 +6,13 @@ import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
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.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
@ -29,7 +25,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
@ -40,15 +35,11 @@ import de.mm20.launcher2.search.CalendarEvent
import de.mm20.launcher2.search.Contact
import de.mm20.launcher2.search.File
import de.mm20.launcher2.search.Location
import de.mm20.launcher2.search.SavableSearchable
import de.mm20.launcher2.search.Website
import de.mm20.launcher2.ui.component.LauncherCard
import de.mm20.launcher2.ui.component.PartialLauncherCard
import de.mm20.launcher2.ui.launcher.search.apps.AppResults
import de.mm20.launcher2.ui.launcher.search.calculator.CalculatorResults
import de.mm20.launcher2.ui.launcher.search.calendar.CalendarResults
import de.mm20.launcher2.ui.launcher.search.common.grid.GridItem
import de.mm20.launcher2.ui.launcher.search.common.list.ListItem
import de.mm20.launcher2.ui.launcher.search.contacts.ContactResults
import de.mm20.launcher2.ui.launcher.search.favorites.SearchFavorites
import de.mm20.launcher2.ui.launcher.search.favorites.SearchFavoritesVM
@ -56,17 +47,13 @@ import de.mm20.launcher2.ui.launcher.search.files.FileResults
import de.mm20.launcher2.ui.launcher.search.filters.SearchFilters
import de.mm20.launcher2.ui.launcher.search.location.LocationResults
import de.mm20.launcher2.ui.launcher.search.shortcut.ShortcutResults
import de.mm20.launcher2.ui.launcher.search.unitconverter.UnitConverterItem
import de.mm20.launcher2.ui.launcher.search.unitconverter.UnitConverterResults
import de.mm20.launcher2.ui.launcher.search.website.WebsiteItem
import de.mm20.launcher2.ui.launcher.search.website.WebsiteResults
import de.mm20.launcher2.ui.launcher.search.wikipedia.ArticleItem
import de.mm20.launcher2.ui.launcher.search.wikipedia.ArticleResults
import de.mm20.launcher2.ui.launcher.sheets.HiddenItemsSheet
import de.mm20.launcher2.ui.launcher.sheets.LocalBottomSheetManager
import de.mm20.launcher2.ui.locals.LocalCardStyle
import de.mm20.launcher2.ui.locals.LocalGridSettings
import kotlinx.collections.immutable.ImmutableList
@Composable
fun SearchColumn(
@ -112,7 +99,6 @@ fun SearchColumn(
val pinnedTags by favoritesVM.pinnedTags.collectAsState(emptyList())
val selectedTag by favoritesVM.selectedTag.collectAsState(null)
val tagsScrollState = rememberScrollState()
val favoritesEditButton by favoritesVM.showEditButton.collectAsState(false)
val favoritesTagsExpanded by favoritesVM.tagsExpanded.collectAsState(false)
@ -130,15 +116,15 @@ fun SearchColumn(
}
}
var expandedCategory: SearchCategory? by remember(isSearchEmpty) { mutableStateOf(null) }
val expandedCategory: SearchCategory? by viewModel.expandedCategory
var selectedContactIndex: Int by remember(contacts) { mutableIntStateOf(-1) }
var selectedFileIndex: Int by remember(files) { mutableIntStateOf(-1) }
var selectedCalendarIndex: Int by remember(events) { mutableIntStateOf(-1) }
var selectedLocationIndex: Int by remember(events) { mutableIntStateOf(-1) }
var selectedShortcutIndex: Int by remember(events) { mutableIntStateOf(-1) }
var selectedArticleIndex: Int by remember(events) { mutableIntStateOf(-1) }
var selectedWebsiteIndex: Int by remember(events) { mutableIntStateOf(-1) }
var selectedLocationIndex: Int by remember(locations) { mutableIntStateOf(-1) }
var selectedShortcutIndex: Int by remember(appShortcuts) { mutableIntStateOf(-1) }
var selectedArticleIndex: Int by remember(wikipedia) { mutableIntStateOf(-1) }
var selectedWebsiteIndex: Int by remember(website) { mutableIntStateOf(-1) }
val showFilters by viewModel.showFilters
@ -218,6 +204,10 @@ fun SearchColumn(
selectedIndex = selectedShortcutIndex,
onSelect = { selectedShortcutIndex = it },
highlightedItem = bestMatch as? AppShortcut,
truncate = expandedCategory != SearchCategory.Shortcuts,
onShowAll = {
viewModel.expandCategory(SearchCategory.Shortcuts)
},
)
UnitConverterResults(
@ -225,7 +215,7 @@ fun SearchColumn(
reverse = reverse,
truncate = expandedCategory != SearchCategory.UnitConverter,
onShowAll = {
expandedCategory = SearchCategory.UnitConverter
viewModel.expandCategory(SearchCategory.UnitConverter)
}
)
@ -247,6 +237,10 @@ fun SearchColumn(
selectedIndex = selectedCalendarIndex,
onSelect = { selectedCalendarIndex = it },
highlightedItem = bestMatch as? CalendarEvent,
truncate = expandedCategory != SearchCategory.Calendar,
onShowAll = {
viewModel.expandCategory(SearchCategory.Calendar)
}
)
ContactResults(
@ -262,6 +256,10 @@ fun SearchColumn(
selectedIndex = selectedContactIndex,
onSelect = { selectedContactIndex = it },
highlightedItem = bestMatch as? Contact,
truncate = expandedCategory != SearchCategory.Contacts,
onShowAll = {
viewModel.expandCategory(SearchCategory.Contacts)
},
)
LocationResults(
@ -277,6 +275,10 @@ fun SearchColumn(
selectedIndex = selectedLocationIndex,
onSelect = { selectedLocationIndex = it },
highlightedItem = bestMatch as? Location,
truncate = expandedCategory != SearchCategory.Location,
onShowAll = {
viewModel.expandCategory(SearchCategory.Location)
}
)
ArticleResults(
articles = wikipedia,
@ -306,6 +308,10 @@ fun SearchColumn(
selectedIndex = selectedFileIndex,
onSelect = {
selectedFileIndex = it
},
truncate = expandedCategory != SearchCategory.Files,
onShowAll = {
viewModel.expandCategory(SearchCategory.Files)
}
)
}
@ -344,15 +350,3 @@ fun LazyListScope.SingleResult(
}
}
enum class SearchCategory {
Apps,
Calculator,
Calendar,
Contacts,
Files,
UnitConverter,
Wikipedia,
Website,
Location,
Shortcut,
}

View File

@ -72,6 +72,8 @@ class SearchVM : ViewModel(), KoinComponent {
val searchQuery = mutableStateOf("")
val isSearchEmpty = mutableStateOf(true)
val expandedCategory = mutableStateOf<SearchCategory?>(null)
val locationResults = mutableStateOf<List<Location>>(emptyList())
val appResults = mutableStateOf<List<Application>>(emptyList())
val workAppResults = mutableStateOf<List<Application>>(emptyList())
@ -155,6 +157,22 @@ class SearchVM : ViewModel(), KoinComponent {
val filters = filters.value
if (filters.enabledCategories == 1) {
expandedCategory.value = when {
filters.apps -> SearchCategory.Apps
filters.events -> SearchCategory.Calendar
filters.contacts -> SearchCategory.Contacts
filters.files -> SearchCategory.Files
filters.websites -> SearchCategory.Website
filters.articles -> SearchCategory.Articles
filters.places -> SearchCategory.Location
filters.shortcuts -> SearchCategory.Shortcuts
else -> null
}
} else {
expandedCategory.value = null
}
if (isSearchEmpty.value)
bestMatch.value = null
try {
@ -367,4 +385,21 @@ class SearchVM : ViewModel(), KoinComponent {
fun disableAppShortcutSearch() {
shortcutSearchSettings.setEnabled(false)
}
fun expandCategory(category: SearchCategory) {
expandedCategory.value = category
}
}
enum class SearchCategory {
Apps,
Calculator,
Calendar,
Contacts,
Files,
UnitConverter,
Articles,
Website,
Location,
Shortcuts,
}

View File

@ -11,8 +11,10 @@ import androidx.compose.ui.unit.dp
import de.mm20.launcher2.search.CalendarEvent
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.MissingPermissionBanner
import de.mm20.launcher2.ui.launcher.search.common.ShowAllButton
import de.mm20.launcher2.ui.launcher.search.common.list.ListItem
import de.mm20.launcher2.ui.launcher.search.common.list.ListResults
import kotlin.math.min
fun LazyListScope.CalendarResults(
events: List<CalendarEvent>,
@ -23,9 +25,11 @@ fun LazyListScope.CalendarResults(
onSelect: (Int) -> Unit,
highlightedItem: CalendarEvent?,
reverse: Boolean,
truncate: Boolean,
onShowAll: () -> Unit,
) {
ListResults(
items = events,
items = events.subList(0, if (truncate) min(5, events.size) else events.size),
key = "calendar",
reverse = reverse,
selectedIndex = selectedIndex,
@ -54,6 +58,11 @@ fun LazyListScope.CalendarResults(
}
)
}
} else null,
after = if (truncate && events.size > 5) {
{
ShowAllButton(onShowAll = onShowAll)
}
} else null
)
}

View File

@ -0,0 +1,40 @@
package de.mm20.launcher2.ui.launcher.search.common
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.ArrowForward
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.ktx.TextButtonWithTrailingIconContentPadding
@Composable
fun ColumnScope.ShowAllButton(
onShowAll: () -> Unit,
) {
TextButton(
modifier = Modifier
.align(Alignment.End)
.padding(4.dp),
onClick = onShowAll,
contentPadding = ButtonDefaults.TextButtonWithTrailingIconContentPadding,
) {
Text(stringResource(R.string.unit_converter_show_all))
Icon(
Icons.AutoMirrored.Rounded.ArrowForward,
null,
modifier = Modifier
.padding(start = ButtonDefaults.IconSpacing)
.size(ButtonDefaults.IconSize)
)
}
}

View File

@ -29,9 +29,9 @@ import de.mm20.launcher2.ui.locals.LocalCardStyle
fun <T : SavableSearchable> LazyListScope.ListResults(
key: String,
items: List<T>,
itemContent: @Composable LazyItemScope.(T, Boolean, Int) -> Unit,
before: @Composable (LazyItemScope.() -> Unit)? = null,
after: @Composable (LazyItemScope.() -> Unit)? = null,
itemContent: @Composable ColumnScope.(T, Boolean, Int) -> Unit,
before: @Composable (ColumnScope.() -> Unit)? = null,
after: @Composable (ColumnScope.() -> Unit)? = null,
reverse: Boolean = false,
selectedIndex: Int = -1,
) {
@ -110,7 +110,6 @@ fun LazyItemScope.ListItemSurface(
val modifier = if (reverse) {
Modifier
.animateItem()
.padding(
bottom = if (!isFirst) padding else 0.dp,
top = if (!isLast) padding else 8.dp
@ -145,6 +144,7 @@ fun LazyItemScope.ListItemSurface(
Column(
modifier = modifier
.animateItem()
.fillMaxWidth()
.background(MaterialTheme.colorScheme.surface.copy(backgroundAlpha)),
verticalArrangement = if (reverse) Arrangement.BottomReversed else Arrangement.Top

View File

@ -11,8 +11,10 @@ import androidx.compose.ui.unit.dp
import de.mm20.launcher2.search.Contact
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.MissingPermissionBanner
import de.mm20.launcher2.ui.launcher.search.common.ShowAllButton
import de.mm20.launcher2.ui.launcher.search.common.list.ListItem
import de.mm20.launcher2.ui.launcher.search.common.list.ListResults
import kotlin.math.min
fun LazyListScope.ContactResults(
contacts: List<Contact>,
@ -23,9 +25,11 @@ fun LazyListScope.ContactResults(
onSelect: (Int) -> Unit,
highlightedItem: Contact?,
reverse: Boolean,
truncate: Boolean,
onShowAll: () -> Unit,
) {
ListResults(
items = contacts,
items = contacts.subList(0, if (truncate) min(5, contacts.size) else contacts.size),
key = "contact",
reverse = reverse,
selectedIndex = selectedIndex,
@ -35,7 +39,7 @@ fun LazyListScope.ContactResults(
.fillMaxWidth(),
item = contact,
showDetails = showDetails,
onShowDetails = { onSelect(if(it) index else -1) },
onShowDetails = { onSelect(if (it) index else -1) },
highlight = highlightedItem?.key == contact.key
)
},
@ -54,6 +58,11 @@ fun LazyListScope.ContactResults(
}
)
}
} else null,
after = if (truncate && contacts.size > 5) {
{
ShowAllButton(onShowAll = onShowAll)
}
} else null
)
}

View File

@ -11,8 +11,10 @@ import androidx.compose.ui.unit.dp
import de.mm20.launcher2.search.File
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.MissingPermissionBanner
import de.mm20.launcher2.ui.launcher.search.common.ShowAllButton
import de.mm20.launcher2.ui.launcher.search.common.list.ListItem
import de.mm20.launcher2.ui.launcher.search.common.list.ListResults
import kotlin.math.min
fun LazyListScope.FileResults(
files: List<File>,
@ -23,9 +25,11 @@ fun LazyListScope.FileResults(
onSelect: (Int) -> Unit,
highlightedItem: File? = null,
reverse: Boolean,
truncate: Boolean,
onShowAll: () -> Unit,
) {
ListResults(
items = files,
items = files.subList(0, if (truncate) min(5, files.size) else files.size),
key = "file",
reverse = reverse,
selectedIndex = selectedIndex,
@ -54,6 +58,11 @@ fun LazyListScope.FileResults(
}
)
}
} else null,
after = if (truncate && files.size > 5) {
{
ShowAllButton(onShowAll = onShowAll)
}
} else null
)
}

View File

@ -11,8 +11,10 @@ import androidx.compose.ui.unit.dp
import de.mm20.launcher2.search.Location
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.MissingPermissionBanner
import de.mm20.launcher2.ui.launcher.search.common.ShowAllButton
import de.mm20.launcher2.ui.launcher.search.common.list.ListItem
import de.mm20.launcher2.ui.launcher.search.common.list.ListResults
import kotlin.math.min
fun LazyListScope.LocationResults(
locations: List<Location>,
@ -23,9 +25,11 @@ fun LazyListScope.LocationResults(
onSelect: (Int) -> Unit,
highlightedItem: Location?,
reverse: Boolean,
truncate: Boolean,
onShowAll: () -> Unit,
) {
ListResults(
items = locations,
items = locations.subList(0, if (truncate) min(5, locations.size) else locations.size),
key = "location",
reverse = reverse,
selectedIndex = selectedIndex,
@ -54,6 +58,11 @@ fun LazyListScope.LocationResults(
}
)
}
} else null,
after = if (truncate && locations.size > 5) {
{
ShowAllButton(onShowAll = onShowAll)
}
} else null
)
}

View File

@ -11,8 +11,10 @@ import androidx.compose.ui.unit.dp
import de.mm20.launcher2.search.AppShortcut
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.MissingPermissionBanner
import de.mm20.launcher2.ui.launcher.search.common.ShowAllButton
import de.mm20.launcher2.ui.launcher.search.common.list.ListItem
import de.mm20.launcher2.ui.launcher.search.common.list.ListResults
import kotlin.math.min
fun LazyListScope.ShortcutResults(
shortcuts: List<AppShortcut>,
@ -23,9 +25,11 @@ fun LazyListScope.ShortcutResults(
onSelect: (Int) -> Unit,
highlightedItem: AppShortcut?,
reverse: Boolean,
truncate: Boolean,
onShowAll: () -> Unit,
) {
ListResults(
items = shortcuts,
items = shortcuts.subList(0, if (truncate) min(5, shortcuts.size) else shortcuts.size),
key = "shortcut",
reverse = reverse,
selectedIndex = selectedIndex,
@ -35,7 +39,7 @@ fun LazyListScope.ShortcutResults(
.fillMaxWidth(),
item = shortcut,
showDetails = showDetails,
onShowDetails = { onSelect(if(it) index else -1) },
onShowDetails = { onSelect(if (it) index else -1) },
highlight = highlightedItem?.key == shortcut.key
)
},
@ -54,6 +58,11 @@ fun LazyListScope.ShortcutResults(
}
)
}
} else null,
after = if (truncate && shortcuts.size > 5) {
{
ShowAllButton(onShowAll = onShowAll)
}
} else null
)
}

View File

@ -6,14 +6,12 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.ArrowForward
import androidx.compose.material.icons.rounded.Bolt
import androidx.compose.material.icons.rounded.FitnessCenter
import androidx.compose.material.icons.rounded.Schedule
@ -24,7 +22,6 @@ import androidx.compose.material.icons.rounded.Straighten
import androidx.compose.material.icons.rounded.Thermostat
import androidx.compose.material.icons.rounded.Toll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@ -45,7 +42,7 @@ import androidx.compose.ui.unit.dp
import de.mm20.launcher2.search.data.CurrencyUnitConverter
import de.mm20.launcher2.search.data.UnitConverter
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.ktx.TextButtonWithTrailingIconContentPadding
import de.mm20.launcher2.ui.launcher.search.common.ShowAllButton
import de.mm20.launcher2.ui.launcher.search.common.list.ListItemSurface
import de.mm20.launcher2.unitconverter.Dimension
import java.util.Date
@ -211,22 +208,7 @@ fun LazyListScope.UnitConverterResults(
isLast = true,
reverse = reverse,
) {
TextButton(
modifier = Modifier
.align(Alignment.End)
.padding(4.dp),
onClick = onShowAll,
contentPadding = ButtonDefaults.TextButtonWithTrailingIconContentPadding,
) {
Text(stringResource(R.string.unit_converter_show_all))
Icon(
Icons.AutoMirrored.Rounded.ArrowForward,
null,
modifier = Modifier
.padding(start = ButtonDefaults.IconSpacing)
.size(ButtonDefaults.IconSize)
)
}
ShowAllButton(onShowAll = onShowAll)
}
}
}