Skip to content

Commit 0ce9b33

Browse files
committed
Add search bar preference in assistant selector
1 parent 748a81f commit 0ce9b33

9 files changed

Lines changed: 117 additions & 5 deletions

File tree

app/src/main/java/com/wstxda/switchai/ui/component/AssistantSelectorBottomSheet.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,24 @@ import android.widget.TextView
99
import android.widget.Toast
1010
import androidx.core.view.isInvisible
1111
import androidx.core.view.isVisible
12+
import androidx.core.widget.doOnTextChanged
1213
import androidx.fragment.app.viewModels
1314
import androidx.recyclerview.widget.LinearLayoutManager
1415
import androidx.recyclerview.widget.RecyclerView
1516
import com.wstxda.switchai.R
1617
import com.wstxda.switchai.databinding.FragmentAssistantDialogBinding
18+
import com.wstxda.switchai.logic.PreferenceHelper
1719
import com.wstxda.switchai.ui.adapter.AssistantSelectorAdapter
1820
import com.wstxda.switchai.utils.AssistantsMap
21+
import com.wstxda.switchai.utils.Constants
1922
import com.wstxda.switchai.viewmodel.AssistantSelectorViewModel
2023

2124
class AssistantSelectorBottomSheet : BaseBottomSheet<FragmentAssistantDialogBinding>() {
2225

2326
private val viewModel: AssistantSelectorViewModel by viewModels()
27+
private val preferenceHelper by lazy {
28+
PreferenceHelper(requireContext())
29+
}
2430
private lateinit var assistantSelectorAdapter: AssistantSelectorAdapter
2531

2632
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?) =
@@ -35,6 +41,20 @@ class AssistantSelectorBottomSheet : BaseBottomSheet<FragmentAssistantDialogBind
3541
super.onViewCreated(view, savedInstanceState)
3642
setupRecyclerView()
3743
setupObservers()
44+
setupSearch()
45+
}
46+
47+
private fun setupSearch() {
48+
val isSearchBarEnabled =
49+
preferenceHelper.getBoolean(Constants.ASSISTANT_SEARCH_BAR_PREF_KEY, true)
50+
51+
binding.searchTextInputLayout.isVisible = isSearchBarEnabled
52+
53+
if (isSearchBarEnabled) {
54+
binding.searchEditText.doOnTextChanged { text, _, _, _ ->
55+
viewModel.searchAssistants(text?.toString())
56+
}
57+
}
3858
}
3959

4060
private fun setupRecyclerView() {
@@ -61,6 +81,14 @@ class AssistantSelectorBottomSheet : BaseBottomSheet<FragmentAssistantDialogBind
6181
binding.assistantLoading.isVisible = isLoading
6282
binding.assistantsRecyclerView.isInvisible = isLoading
6383
}
84+
85+
viewModel.searchResultEmpty.observe(viewLifecycleOwner) { isResultEmpty ->
86+
if (isResultEmpty) {
87+
binding.searchTextInputLayout.error = getString(R.string.assistant_search_empty)
88+
} else {
89+
binding.searchTextInputLayout.error = null
90+
}
91+
}
6492
}
6593

6694
override fun setupScrollListener() {

app/src/main/java/com/wstxda/switchai/utils/Constants.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ object Constants {
77
const val DIGITAL_ASSISTANT_SETUP_PREF_KEY = "digital_assistant_setup"
88
const val DIGITAL_ASSISTANT_SELECT_PREF_KEY = "digital_assistant_select"
99
const val ASSISTANT_SELECTOR_DIALOG_PREF_KEY = "assistant_selector_dialog"
10+
const val ASSISTANT_SEARCH_BAR_PREF_KEY = "assistant_search_bar"
1011
const val ASSISTANT_MANAGER_DIALOG_PREF_KEY = "assistant_selector_manager"
1112
const val OPEN_ASSISTANT_TILE_PREF_KEY = "open_assistant_tile"
1213
const val OPEN_ASSISTANT_WIDGET_PREF_KEY = "open_assistant_widget"

app/src/main/java/com/wstxda/switchai/viewmodel/AssistantSelectorViewModel.kt

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ class AssistantSelectorViewModel(application: Application) : AndroidViewModel(ap
2828
private val _assistantItems = MutableLiveData<List<AssistantSelectorRecyclerView>>()
2929
val assistantItems: LiveData<List<AssistantSelectorRecyclerView>> = _assistantItems
3030

31+
private var allAssistantItems: List<AssistantSelectorRecyclerView> = emptyList()
32+
33+
private val _searchResultEmpty = MutableLiveData<Boolean>()
34+
val searchResultEmpty: LiveData<Boolean> = _searchResultEmpty
35+
3136
private val _isLoading = MutableLiveData<Boolean>()
3237
val isLoading: LiveData<Boolean> = _isLoading
3338

@@ -65,13 +70,30 @@ class AssistantSelectorViewModel(application: Application) : AndroidViewModel(ap
6570
val allVisibleAssistantDetails = getVisibleAssistantDetails(installedKeys)
6671
val categorizedItems = buildCategorizedList(allVisibleAssistantDetails)
6772
withContext(Dispatchers.Main) {
73+
allAssistantItems = categorizedItems
6874
_assistantItems.value = categorizedItems
6975
}
7076
}
7177
_isLoading.value = false
7278
}
7379
}
7480

81+
fun searchAssistants(query: String?) {
82+
if (query.isNullOrBlank()) {
83+
_assistantItems.value = allAssistantItems
84+
_searchResultEmpty.value = false
85+
return
86+
}
87+
88+
val filteredList = allAssistantItems.filterIsInstance<AssistantSelectorRecyclerView.AssistantSelector>()
89+
.filter { assistant ->
90+
assistant.assistantItem.name.contains(query, ignoreCase = true)
91+
}
92+
93+
_assistantItems.value = filteredList
94+
_searchResultEmpty.value = filteredList.isEmpty()
95+
}
96+
7597
fun togglePinAssistant(assistantKey: String) {
7698
viewModelScope.launch {
7799
val currentAssistantItems =
@@ -155,8 +177,7 @@ class AssistantSelectorViewModel(application: Application) : AndroidViewModel(ap
155177
iconRes = assistantResourcesManager.getAssistantIcon(key),
156178
isInstalled = key in installedKeys,
157179
isPinned = key in pinnedAssistantKeys,
158-
lastUsedTime = recentlyUsedAssistants.find { it.first == key }?.second
159-
?: 0L
180+
lastUsedTime = recentlyUsedAssistants.find { it.first == key }?.second ?: 0L
160181
)
161182
}
162183
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:tint="?attr/colorControlNormal"
5+
android:viewportWidth="960"
6+
android:viewportHeight="960">
7+
<path
8+
android:fillColor="@android:color/white"
9+
android:pathData="M784,840L532,588Q502,612 463,626Q424,640 380,640Q271,640 195.5,564.5Q120,489 120,380Q120,271 195.5,195.5Q271,120 380,120Q489,120 564.5,195.5Q640,271 640,380Q640,424 626,463Q612,502 588,532L840,784L784,840ZM380,560Q455,560 507.5,507.5Q560,455 560,380Q560,305 507.5,252.5Q455,200 380,200Q305,200 252.5,252.5Q200,305 200,380Q200,455 252.5,507.5Q305,560 380,560Z" />
10+
</vector>

app/src/main/res/layout/fragment_assistant_dialog.xml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,31 @@
2525
android:textAlignment="center"
2626
tools:text="@string/assistant_select" />
2727

28+
<com.google.android.material.textfield.TextInputLayout
29+
android:id="@+id/search_text_input_layout"
30+
style="?attr/textInputOutlinedDenseStyle"
31+
android:layout_width="match_parent"
32+
android:layout_height="wrap_content"
33+
android:paddingHorizontal="24dp"
34+
android:paddingBottom="24dp"
35+
app:boxBackgroundColor="?attr/colorSurfaceContainerLowest"
36+
app:boxStrokeColor="?attr/colorSurfaceContainerLowest"
37+
app:boxStrokeErrorColor="?attr/colorSurfaceContainerLowest"
38+
app:boxStrokeWidth="0dp"
39+
app:endIconMode="clear_text"
40+
app:placeholderText="@string/assistant_search_hint"
41+
app:shapeAppearance="?attr/shapeAppearanceCornerExtraExtraLarge"
42+
app:startIconDrawable="@drawable/ic_search"
43+
app:startIconTint="?attr/colorOnSurface">
44+
45+
<com.google.android.material.textfield.TextInputEditText
46+
android:id="@+id/search_edit_text"
47+
android:layout_width="match_parent"
48+
android:layout_height="wrap_content"
49+
android:forceHasOverlappingRendering="false"
50+
android:maxLines="1" />
51+
</com.google.android.material.textfield.TextInputLayout>
52+
2853
<com.google.android.material.divider.MaterialDivider
2954
android:id="@+id/divider_top"
3055
style="?attr/materialDividerStyle"

app/src/main/res/values-ar/strings.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@
5656
<string name="pref_assistant_selector">استخدام مُحدِّد المساعد</string>
5757
<string name="pref_assistant_selector_summary">اذا تم تفعيله اذن اختر مساعدًا في كل مرة يتم البدء. وإلا خيار <b>المساعد الرقمي</b> سيتم استخدامه</string>
5858

59+
<string name="pref_assistant_search_bar">شريط البحث</string>
60+
<string name="pref_assistant_search_bar_summary">تمكين شريط البحث للعثور بسرعة على المساعدين في المحدد</string>
61+
5962
<string name="pref_assistant_manage">إدارة المساعد</string>
6063
<string name="pref_assistant_manage_summary">اختر المساعدات التي ستظهر في القائمة</string>
6164

@@ -95,6 +98,9 @@
9598
<!--digital/selector/open assistant-->
9699

97100
<string name="assistant_select">اختيار المساعد</string>
101+
<!--selector assistant search-->
102+
<string name="assistant_search_hint">البحث في المساعدين</string>
103+
<string name="assistant_search_empty">لم يتم العثور على مساعدين</string>
98104
<!--selector assistant categories-->
99105
<string name="assistant_category_pin">مثبت</string>
100106
<string name="assistant_category_recent">المستخدمة مؤخرًا</string>

app/src/main/res/values-pt-rBR/strings.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
<string name="pref_setup_digital_assistant">Configurar assistente digital</string>
5454
<string name="pref_setup_digital_assistant_summary">Definir o SwitchAI como o aplicativo de assistente digital padrão</string>
5555

56+
<string name="pref_assistant_search_bar">Barra de pesquisa</string>
57+
<string name="pref_assistant_search_bar_summary">Habilitar a barra de pesquisa para encontrar assistentes rapidamente no seletor</string>
58+
5659
<string name="pref_assistant_selector">Usar seletor de assistente</string>
5760
<string name="pref_assistant_selector_summary">Se ativado, selecione um assistente toda vez que iniciar. Caso contrário, será usado a opção <b>Assistente digital</b></string>
5861

@@ -95,6 +98,9 @@
9598
<!--digital/selector/open assistant-->
9699

97100
<string name="assistant_select">Selecionar assistente</string>
101+
<!--selector assistant search-->
102+
<string name="assistant_search_hint">Pesquisar assistentes</string>
103+
<string name="assistant_search_empty">Nenhum assistente encontrado</string>
98104
<!--selector assistant categories-->
99105
<string name="assistant_category_pin">Fixados</string>
100106
<string name="assistant_category_recent">Usados recentemente</string>

app/src/main/res/values/strings.xml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,17 @@
6060
<string name="pref_assistant_selector">Use assistant selector</string>
6161
<string name="pref_assistant_selector_summary">If enabled, select an assistant each time it starts. Otherwise, the <b>Digital assistant</b> option will be used</string>
6262

63+
<string name="pref_assistant_search_bar">Search bar</string>
64+
<string name="pref_assistant_search_bar_summary">Enable the search bar to quickly find assistants in the selector</string>
65+
6366
<string name="pref_assistant_manage">Manage assistants</string>
6467
<string name="pref_assistant_manage_summary">Choose which assistants are displayed in the selector</string>
6568

6669
<string name="pref_assistant_tile">Add assistant tile</string>
6770
<string name="pref_assistant_tile_summary">Add a quick settings tile to access the assistant on your device</string>
6871

6972
<string name="pref_assistant_widget">Add assistant widget</string>
70-
<string name="pref_assistant_widget_summary">Add widget to access the assistant on your device\'s home screen</string>
73+
<string name="pref_assistant_widget_summary">Add widget to access the assistant on your device\s home screen</string>
7174

7275
<string name="pref_assistant_vibration">Vibrate when opening</string>
7376
<string name="pref_assistant_vibration_summary">Provides haptic feedback when opening the assistant. This may be affected by system settings</string>
@@ -99,6 +102,9 @@
99102
<!--digital/selector/open assistant-->
100103

101104
<string name="assistant_select">Select assistant</string>
105+
<!--selector assistant search-->
106+
<string name="assistant_search_hint">Search assistants</string>
107+
<string name="assistant_search_empty">No assistants found</string>
102108
<!--selector assistant categories-->
103109
<string name="assistant_category_pin">Pinned</string>
104110
<string name="assistant_category_recent">Recently used</string>
@@ -119,9 +125,9 @@
119125
<!--tutorial digital assistant-->
120126

121127
<string name="tutorial_edge_gestures">Using screen edge gestures</string>
122-
<string name="tutorial_edge_gestures_summary">On devices using gesture navigation (Android 10+), swipe up and in from either of the bottom corners of the screen. A glowing arc will appear from the corner to confirm that the digital assistant is opening. For this to work, <b>Gesture navigation</b> must be selected as the system navigation mode in your device\'s settings</string>
128+
<string name="tutorial_edge_gestures_summary">On devices using gesture navigation (Android 10+), swipe up and in from either of the bottom corners of the screen. A glowing arc will appear from the corner to confirm that the digital assistant is opening. For this to work, <b>Gesture navigation</b> must be selected as the system navigation mode in your device\s settings</string>
123129
<string name="tutorial_home_button">Using the home navigation button</string>
124-
<string name="tutorial_home_button_summary">If your device uses the classic 3-button navigation, press and hold the center home button for a moment. This action is typically reserved to open the digital assistant. If this action performs a different function, it may have been customized by your device\'s manufacturer</string>
130+
<string name="tutorial_home_button_summary">If your device uses the classic 3-button navigation, press and hold the center home button for a moment. This action is typically reserved to open the digital assistant. If this action performs a different function, it may have been customized by your device\s manufacturer</string>
125131
<string name="tutorial_power_button">Using the power button</string>
126132
<string name="tutorial_power_button_summary">Many devices allow you to open the digital assistant by long-pressing the power button. If the power off/restart menu appears when you do this, the feature is likely disabled. You can often enable it in your system settings, typically under a path like <b>Settings &gt; System &gt; Gestures &gt; Press and hold power button</b></string>
127133
<string name="tutorial_headset_button">Using wired and bluetooth headsets</string>

app/src/main/res/xml/main_preferences.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@
3535
app:iconSpaceReserved="false"
3636
app:layout="@layout/preference_material_top" />
3737

38+
<SwitchPreferenceCompat
39+
android:defaultValue="true"
40+
android:dependency="assistant_selector_dialog"
41+
android:key="assistant_search_bar"
42+
android:summary="@string/pref_assistant_search_bar_summary"
43+
android:title="@string/pref_assistant_search_bar"
44+
app:iconSpaceReserved="false"
45+
app:layout="@layout/preference_material_middle" />
46+
3847
<com.wstxda.switchai.fragment.preferences.MultiSelectListPreference
3948
android:dependency="assistant_selector_dialog"
4049
android:entries="@array/assistant_entries"

0 commit comments

Comments
 (0)