mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-27 15:26:58 +00:00
feat(search): Implement empty state and search settings UI
This commit is contained in:
36
lawnchair/res/layout/search_result_empty_state.xml
Normal file
36
lawnchair/res/layout/search_result_empty_state.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<app.lawnchair.allapps.views.SearchResultEmptyState xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/search_result_empty_state"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal"
|
||||
android:padding="32dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/empty_state_icon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_qsb_search"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:tint="?android:textColorSecondary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_state_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:layout_marginBottom="4dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_state_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary" />
|
||||
|
||||
</app.lawnchair.allapps.views.SearchResultEmptyState>
|
||||
21
lawnchair/res/layout/search_result_search_settings.xml
Normal file
21
lawnchair/res/layout/search_result_search_settings.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<app.lawnchair.allapps.views.SearchResultSearchSettings xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/search_result_search_settings"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/search_result_text_height"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="end">
|
||||
|
||||
<ImageButton
|
||||
android:background="@drawable/pill_ripple"
|
||||
android:id="@+id/search_settings"
|
||||
android:layout_gravity="bottom|center|end"
|
||||
android:layout_width="@dimen/search_box_height"
|
||||
android:textAllCaps="false"
|
||||
android:clickable="true"
|
||||
android:layout_height="@dimen/search_box_height"
|
||||
android:src="@drawable/ic_setting"
|
||||
android:textStyle="normal"
|
||||
android:contentDescription="@string/settings" />
|
||||
|
||||
</app.lawnchair.allapps.views.SearchResultSearchSettings>
|
||||
@@ -725,7 +725,7 @@
|
||||
|
||||
-->
|
||||
<!-- Launcher strings used -->
|
||||
<string name="all_apps_device_search_hint">Search</string>
|
||||
<string name="all_apps_device_search_hint">Search apps, web, and more</string>
|
||||
<string name="all_apps_search_bar_hint">Search apps</string>
|
||||
<string name="all_apps_no_search_results">No apps found matching \"<xliff:g example="Android" id="query">%1$s</xliff:g>\"</string>
|
||||
|
||||
@@ -808,4 +808,8 @@
|
||||
<string name="warn_files_permission_content">To search your files, grant storage permissions to Lawnchair</string>
|
||||
<string name="grant_requested_permissions">Grant permissions</string>
|
||||
<string name="custom_search_label">Custom search engine name</string>
|
||||
|
||||
<string name="search_empty_state_title">Start searching</string>
|
||||
<string name="search_empty_state_no_history_subtitle">Find apps, contacts, and more. Your recent searches will appear here.</string>
|
||||
<string name="search_empty_state_history_disabled_subtitle">Find apps, contacts, and more.</string>
|
||||
</resources>
|
||||
|
||||
@@ -138,6 +138,10 @@ class AllAppsSearchInput(context: Context, attrs: AttributeSet?) :
|
||||
|
||||
with(input) {
|
||||
addTextChangedListener {
|
||||
if (input.text.toString().isEmpty()) {
|
||||
searchAlgorithm?.doZeroStateSearch(this@AllAppsSearchInput)
|
||||
}
|
||||
|
||||
actionButton.isVisible = !it.isNullOrEmpty()
|
||||
micIcon.isVisible = shouldShowIcons && voiceIntent != null && it.isNullOrEmpty()
|
||||
lensIcon.isVisible = shouldShowIcons && supportsLens && lensIntent != null && it.isNullOrEmpty()
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package app.lawnchair.allapps.views
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.ViewCompat
|
||||
import app.lawnchair.search.adapter.SearchTargetCompat
|
||||
import app.lawnchair.search.model.SearchResultActionCallBack
|
||||
import app.lawnchair.theme.color.tokens.ColorTokens
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.util.Themes
|
||||
|
||||
class SearchResultEmptyState(context: Context, attrs: AttributeSet?) :
|
||||
LinearLayout(context, attrs),
|
||||
SearchResultView {
|
||||
|
||||
private lateinit var icon: ImageView
|
||||
private lateinit var title: TextView
|
||||
private lateinit var subtitle: TextView
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
title = ViewCompat.requireViewById(this, R.id.empty_state_title)
|
||||
subtitle = ViewCompat.requireViewById(this, R.id.empty_state_subtitle)
|
||||
icon = ViewCompat.requireViewById(this, R.id.empty_state_icon)
|
||||
|
||||
subtitle.setTextColor(Themes.getAttrColor(context, android.R.attr.textColorTertiary))
|
||||
icon.setColorFilter(ColorTokens.ColorAccent.resolveColor(context))
|
||||
}
|
||||
|
||||
override val isQuickLaunch: Boolean = false
|
||||
override fun launch(): Boolean = false
|
||||
|
||||
override fun bind(
|
||||
target: SearchTargetCompat,
|
||||
shortcuts: List<SearchTargetCompat>,
|
||||
callBack: SearchResultActionCallBack?,
|
||||
) {
|
||||
val extras = target.extras
|
||||
val titleRes = extras.getInt("titleRes")
|
||||
val subtitleRes = extras.getInt("subtitleRes")
|
||||
|
||||
if (titleRes != 0) title.setText(titleRes)
|
||||
if (subtitleRes != 0) subtitle.setText(subtitleRes)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package app.lawnchair.allapps.views
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.ImageButton
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.view.ViewCompat
|
||||
import app.lawnchair.search.adapter.SearchTargetCompat
|
||||
import app.lawnchair.search.model.SearchResultActionCallBack
|
||||
import app.lawnchair.ui.preferences.PreferenceActivity
|
||||
import app.lawnchair.ui.preferences.destinations.SearchRoute
|
||||
import app.lawnchair.ui.preferences.navigation.Search
|
||||
import com.android.launcher3.R
|
||||
|
||||
class SearchResultSearchSettings(context: Context, attrs: AttributeSet?) :
|
||||
LinearLayout(context, attrs),
|
||||
SearchResultView {
|
||||
|
||||
private lateinit var iconButton: ImageButton
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
iconButton = ViewCompat.requireViewById(this, R.id.search_settings)
|
||||
iconButton.setOnClickListener {
|
||||
context.startActivity(PreferenceActivity.createIntent(context, Search(SearchRoute.DRAWER_SEARCH)))
|
||||
}
|
||||
}
|
||||
|
||||
override val isQuickLaunch: Boolean = false
|
||||
override fun launch(): Boolean = false
|
||||
|
||||
override fun bind(
|
||||
target: SearchTargetCompat,
|
||||
shortcuts: List<SearchTargetCompat>,
|
||||
callBack: SearchResultActionCallBack?,
|
||||
) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,8 @@ class LawnchairSearchAdapterProvider(
|
||||
append(SEARCH_RESULT_SETTINGS_TILE, R.layout.search_result_small_icon_row)
|
||||
append(SEARCH_RESULT_RECENT_TILE, R.layout.search_result_small_icon_row)
|
||||
append(SEARCH_RESULT_CALCULATOR, R.layout.search_result_tall_icon_row_calculator)
|
||||
append(SEARCH_RESULT_EMPTY_STATE, R.layout.search_result_empty_state)
|
||||
append(SEARCH_RESULT_SEARCH_SETTINGS, R.layout.search_result_search_settings)
|
||||
}
|
||||
private var quickLaunchItem: SearchResultView? = null
|
||||
set(value) {
|
||||
@@ -108,6 +110,8 @@ class LawnchairSearchAdapterProvider(
|
||||
private const val SEARCH_RESULT_SETTINGS_TILE = 1 shl 18
|
||||
private const val SEARCH_RESULT_RECENT_TILE = 1 shl 19
|
||||
private const val SEARCH_RESULT_CALCULATOR = 1 shl 20
|
||||
private const val SEARCH_RESULT_EMPTY_STATE = 1 shl 21
|
||||
private const val SEARCH_RESULT_SEARCH_SETTINGS = 1 shl 22
|
||||
|
||||
val viewTypeMap = mapOf(
|
||||
LayoutType.ICON_SINGLE_VERTICAL_TEXT to SEARCH_RESULT_ICON,
|
||||
@@ -121,6 +125,8 @@ class LawnchairSearchAdapterProvider(
|
||||
LayoutType.ICON_SLICE to SEARCH_RESULT_SETTINGS_TILE,
|
||||
LayoutType.WIDGET_LIVE to SEARCH_RESULT_RECENT_TILE,
|
||||
LayoutType.CALCULATOR to SEARCH_RESULT_CALCULATOR,
|
||||
LayoutType.EMPTY_STATE to SEARCH_RESULT_EMPTY_STATE,
|
||||
LayoutType.SEARCH_SETTINGS to SEARCH_RESULT_SEARCH_SETTINGS,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,6 +275,8 @@ data class SearchTargetCompat(
|
||||
RESULT_TYPE_FILE_TILE,
|
||||
RESULT_TYPE_SETTING_TILE,
|
||||
RESULT_TYPE_CALCULATOR,
|
||||
RESULT_TYPE_EMPTY_RESULT,
|
||||
RESULT_TYPE_SEARCH_SETTINGS,
|
||||
],
|
||||
)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
@@ -292,6 +294,8 @@ data class SearchTargetCompat(
|
||||
const val RESULT_TYPE_FILE_TILE = 1 shl 8
|
||||
const val RESULT_TYPE_SETTING_TILE = 1 shl 9
|
||||
const val RESULT_TYPE_CALCULATOR = 1 shl 10
|
||||
const val RESULT_TYPE_EMPTY_RESULT = 1 shl 11
|
||||
const val RESULT_TYPE_SEARCH_SETTINGS = 1 shl 12
|
||||
|
||||
fun wrap(target: SearchTarget): SearchTargetCompat = SearchTargetCompat(target)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import android.provider.ContactsContract
|
||||
import android.provider.MediaStore
|
||||
import android.util.Log
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.os.bundleOf
|
||||
import app.lawnchair.allapps.views.SearchResultView
|
||||
@@ -313,6 +314,53 @@ class SearchTargetFactory(
|
||||
)
|
||||
}
|
||||
|
||||
fun createEmptyStateTarget(
|
||||
@StringRes titleRes: Int,
|
||||
@StringRes subtitleRes: Int,
|
||||
): SearchTargetCompat {
|
||||
val id = "empty_state:$titleRes"
|
||||
// The action doesn't do anything, it's just for display.
|
||||
val action = SearchActionCompat.Builder(id, "")
|
||||
.setIntent(Intent())
|
||||
.build()
|
||||
|
||||
return SearchTargetCompat.Builder(
|
||||
SearchTargetCompat.RESULT_TYPE_EMPTY_RESULT,
|
||||
LayoutType.EMPTY_STATE,
|
||||
id,
|
||||
).apply {
|
||||
setPackageName(EMPTY_STATE)
|
||||
setUserHandle(Process.myUserHandle())
|
||||
setSearchAction(action)
|
||||
setExtras(
|
||||
bundleOf(
|
||||
"titleRes" to titleRes,
|
||||
"subtitleRes" to subtitleRes,
|
||||
),
|
||||
)
|
||||
}.build()
|
||||
}
|
||||
|
||||
fun createSearchSettingsTarget(): SearchTargetCompat {
|
||||
val id = "action:search_settings"
|
||||
|
||||
// The action doesn't do anything, it's just for display.
|
||||
val action = SearchActionCompat.Builder(id, "")
|
||||
.setIntent(Intent())
|
||||
.build()
|
||||
|
||||
return SearchTargetCompat.Builder(
|
||||
SearchTargetCompat.RESULT_TYPE_SEARCH_SETTINGS,
|
||||
LayoutType.SEARCH_SETTINGS,
|
||||
id,
|
||||
).apply {
|
||||
setPackageName(SEARCH_SETTINGS)
|
||||
setUserHandle(Process.myUserHandle())
|
||||
setSearchAction(action)
|
||||
setExtras(Bundle())
|
||||
}.build()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val HASH_ALGORITHM = "SHA-256"
|
||||
|
||||
@@ -423,3 +471,5 @@ const val SHORTCUT = "shortcut"
|
||||
const val HISTORY = "recent_keyword"
|
||||
const val HEADER_JUSTIFY = "header_justify"
|
||||
const val CALCULATOR = "calculator"
|
||||
const val EMPTY_STATE = "empty_state"
|
||||
const val SEARCH_SETTINGS = "search_settings"
|
||||
|
||||
@@ -10,10 +10,12 @@ import app.lawnchair.search.algorithms.engine.ActionsSectionBuilder
|
||||
import app.lawnchair.search.algorithms.engine.AppsAndShortcutsSectionBuilder
|
||||
import app.lawnchair.search.algorithms.engine.CalculationSectionBuilder
|
||||
import app.lawnchair.search.algorithms.engine.ContactsSectionBuilder
|
||||
import app.lawnchair.search.algorithms.engine.EmptyStateSectionBuilder
|
||||
import app.lawnchair.search.algorithms.engine.FilesSectionBuilder
|
||||
import app.lawnchair.search.algorithms.engine.HistorySectionBuilder
|
||||
import app.lawnchair.search.algorithms.engine.SearchProvider
|
||||
import app.lawnchair.search.algorithms.engine.SearchResult
|
||||
import app.lawnchair.search.algorithms.engine.SearchSettingsSectionBuilder
|
||||
import app.lawnchair.search.algorithms.engine.SectionBuilder
|
||||
import app.lawnchair.search.algorithms.engine.SettingsSectionBuilder
|
||||
import app.lawnchair.search.algorithms.engine.WebSuggestionsSectionBuilder
|
||||
@@ -26,7 +28,9 @@ import app.lawnchair.search.algorithms.engine.provider.SettingsSearchProvider
|
||||
import app.lawnchair.search.algorithms.engine.provider.ShortcutSearchProvider
|
||||
import app.lawnchair.search.algorithms.engine.provider.web.CustomWebSearchProvider
|
||||
import app.lawnchair.search.algorithms.engine.provider.web.WebSuggestionProvider
|
||||
import com.android.internal.R.id.actions
|
||||
import com.android.launcher3.LauncherAppState
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.allapps.BaseAllAppsAdapter
|
||||
import com.android.launcher3.search.SearchCallback
|
||||
import com.patrykmichalik.opto.core.firstBlocking
|
||||
@@ -89,12 +93,40 @@ class LawnchairNewLocalSearchAlgorithm(context: Context) : LawnchairSearchAlgori
|
||||
override fun doZeroStateSearch(callback: SearchCallback<BaseAllAppsAdapter.AdapterItem>) {
|
||||
currentJob?.cancel()
|
||||
currentJob = coroutineScope.launch {
|
||||
val prefs = PreferenceManager.getInstance(context)
|
||||
val prefs2 = PreferenceManager2.getInstance(context)
|
||||
|
||||
val historyEnabled = prefs.searchResulRecentSuggestion.get()
|
||||
val maxHistory = prefs2.maxRecentResultCount.firstBlocking()
|
||||
|
||||
val historyResults = historySearchProvider.getRecentKeywords(context, maxHistory)
|
||||
val historyResults = if (historyEnabled) {
|
||||
historySearchProvider.getRecentKeywords(context, maxHistory)
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
val searchTargets = translateToSearchTargets(historyResults)
|
||||
val resultsToTranslate = if (historyResults.isNotEmpty()) {
|
||||
historyResults + listOf(SearchResult.Action.SearchSettings)
|
||||
} else {
|
||||
listOf(
|
||||
if (historyEnabled) {
|
||||
// State A: No History
|
||||
SearchResult.Action.EmptyState(
|
||||
titleRes = R.string.search_empty_state_title,
|
||||
subtitleRes = R.string.search_empty_state_no_history_subtitle,
|
||||
)
|
||||
} else {
|
||||
// State B: History Disabled
|
||||
SearchResult.Action.EmptyState(
|
||||
titleRes = R.string.search_empty_state_title,
|
||||
subtitleRes = R.string.search_empty_state_history_disabled_subtitle,
|
||||
)
|
||||
},
|
||||
SearchResult.Action.SearchSettings,
|
||||
)
|
||||
}
|
||||
|
||||
val searchTargets = translateToSearchTargets(resultsToTranslate)
|
||||
val adapterItems = transformSearchResults(searchTargets)
|
||||
withContext(Dispatchers.Main) {
|
||||
callback.onSearchResult("", ArrayList(adapterItems))
|
||||
@@ -111,8 +143,6 @@ class LawnchairNewLocalSearchAlgorithm(context: Context) : LawnchairSearchAlgori
|
||||
val prefs = PreferenceManager.getInstance(context)
|
||||
val prefs2 = PreferenceManager2.getInstance(context)
|
||||
|
||||
actions.add(SearchResult.Action.Divider())
|
||||
|
||||
if (prefs.searchResultStartPageSuggestion.get()) {
|
||||
val provider = prefs2.webSuggestionProvider.firstBlocking()
|
||||
val webProvider = provider.configure(context)
|
||||
@@ -137,6 +167,9 @@ class LawnchairNewLocalSearchAlgorithm(context: Context) : LawnchairSearchAlgori
|
||||
actions.add(SearchResult.Action.MarketSearch(query = query))
|
||||
}
|
||||
|
||||
actions.add(SearchResult.Action.SearchSettings)
|
||||
actions.add(SearchResult.Action.SearchSettings)
|
||||
|
||||
return actions
|
||||
}
|
||||
|
||||
@@ -149,6 +182,8 @@ class LawnchairNewLocalSearchAlgorithm(context: Context) : LawnchairSearchAlgori
|
||||
SettingsSectionBuilder,
|
||||
HistorySectionBuilder,
|
||||
ActionsSectionBuilder,
|
||||
EmptyStateSectionBuilder,
|
||||
SearchSettingsSectionBuilder,
|
||||
)
|
||||
|
||||
private fun translateToSearchTargets(
|
||||
|
||||
@@ -12,11 +12,13 @@ import app.lawnchair.search.adapter.SearchTargetCompat.Companion.RESULT_TYPE_APP
|
||||
import app.lawnchair.search.adapter.SearchTargetCompat.Companion.RESULT_TYPE_SHORTCUT
|
||||
import com.android.app.search.LayoutType.CALCULATOR
|
||||
import com.android.app.search.LayoutType.EMPTY_DIVIDER
|
||||
import com.android.app.search.LayoutType.EMPTY_STATE
|
||||
import com.android.app.search.LayoutType.HORIZONTAL_MEDIUM_TEXT
|
||||
import com.android.app.search.LayoutType.ICON_HORIZONTAL_TEXT
|
||||
import com.android.app.search.LayoutType.ICON_SINGLE_VERTICAL_TEXT
|
||||
import com.android.app.search.LayoutType.ICON_SLICE
|
||||
import com.android.app.search.LayoutType.PEOPLE_TILE
|
||||
import com.android.app.search.LayoutType.SEARCH_SETTINGS
|
||||
import com.android.app.search.LayoutType.SMALL_ICON_HORIZONTAL_TEXT
|
||||
import com.android.app.search.LayoutType.TEXT_HEADER
|
||||
import com.android.app.search.LayoutType.THUMBNAIL
|
||||
@@ -32,6 +34,12 @@ sealed class LawnchairSearchAlgorithm(
|
||||
protected val context: Context,
|
||||
) : SearchAlgorithm<BaseAllAppsAdapter.AdapterItem> {
|
||||
|
||||
private val transparentBackground = SearchItemBackground(
|
||||
context,
|
||||
showBackground = false,
|
||||
roundBottom = false,
|
||||
roundTop = false,
|
||||
)
|
||||
private val iconBackground = SearchItemBackground(
|
||||
context,
|
||||
showBackground = false,
|
||||
@@ -169,6 +177,8 @@ sealed class LawnchairSearchAlgorithm(
|
||||
layoutType == ICON_SLICE -> getGroupedBackground(index, settingIndices)
|
||||
layoutType == WIDGET_LIVE -> getGroupedBackground(index, recentIndices)
|
||||
layoutType == CALCULATOR && calculator.isNotEmpty() -> normalBackground
|
||||
layoutType == EMPTY_STATE -> transparentBackground
|
||||
layoutType == SEARCH_SETTINGS -> transparentBackground
|
||||
isFirst && isLast -> normalBackground
|
||||
isFirst -> topBackground
|
||||
isLast -> bottomBackground
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package app.lawnchair.search.algorithms.engine
|
||||
|
||||
import android.annotation.DrawableRes
|
||||
import android.content.pm.ShortcutInfo
|
||||
import app.lawnchair.search.adapter.HEADER
|
||||
import app.lawnchair.search.adapter.SPACE
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import app.lawnchair.search.algorithms.data.ContactInfo
|
||||
import app.lawnchair.search.algorithms.data.IFileInfo
|
||||
import app.lawnchair.search.algorithms.data.RecentKeyword
|
||||
@@ -32,7 +31,10 @@ sealed class SearchResult {
|
||||
val searchUrl: String,
|
||||
@DrawableRes val providerIconRes: Int,
|
||||
) : Action()
|
||||
data class Header(val title: String, val pkg: String = HEADER) : Action()
|
||||
data class Divider(val pkg: String = SPACE) : Action()
|
||||
data class EmptyState(
|
||||
@StringRes val titleRes: Int,
|
||||
@StringRes val subtitleRes: Int,
|
||||
) : Action()
|
||||
data object SearchSettings : Action()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,3 +209,42 @@ object AppsAndShortcutsSectionBuilder : SectionBuilder {
|
||||
return targets
|
||||
}
|
||||
}
|
||||
|
||||
object EmptyStateSectionBuilder : SectionBuilder {
|
||||
override fun build(
|
||||
context: Context,
|
||||
factory: SearchTargetFactory,
|
||||
results: List<SearchResult>,
|
||||
): List<SearchTargetCompat> {
|
||||
val result = results.filterIsInstance<SearchResult.Action.EmptyState>()
|
||||
val targets = mutableListOf<SearchTargetCompat>()
|
||||
|
||||
result.firstOrNull()?.let {
|
||||
targets.add(
|
||||
factory.createEmptyStateTarget(
|
||||
it.titleRes,
|
||||
it.subtitleRes,
|
||||
),
|
||||
)
|
||||
}
|
||||
return targets
|
||||
}
|
||||
}
|
||||
|
||||
object SearchSettingsSectionBuilder : SectionBuilder {
|
||||
override fun build(
|
||||
context: Context,
|
||||
factory: SearchTargetFactory,
|
||||
results: List<SearchResult>,
|
||||
): List<SearchTargetCompat> {
|
||||
val result = results.filterIsInstance<SearchResult.Action.SearchSettings>()
|
||||
val targets = mutableListOf<SearchTargetCompat>()
|
||||
|
||||
result.firstOrNull()?.let {
|
||||
targets.add(
|
||||
factory.createSearchSettingsTarget(),
|
||||
)
|
||||
}
|
||||
return targets
|
||||
}
|
||||
}
|
||||
|
||||
Submodule platform_frameworks_libs_systemui updated: cc37c52766...87a0e7b617
Reference in New Issue
Block a user