Skip to content

Commit 4a94c7b

Browse files
committed
feat: enable search functionality for ControlSettings (Reviews & Previews)
1 parent ecfe4b1 commit 4a94c7b

File tree

4 files changed

+66
-2
lines changed

4 files changed

+66
-2
lines changed

AnkiDroid/src/main/java/com/ichi2/anki/preferences/ControlsSettingsFragment.kt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,37 @@ class ControlsSettingsFragment :
6161
setupNewStudyScreenSettings()
6262
}
6363

64+
/**
65+
* Selects the appropriate tab based on a preference key from search results.
66+
* This allows search navigation to automatically switch to the correct tab.
67+
*/
68+
fun selectTabForPreference(key: String) {
69+
val targetTabIndex =
70+
if (isPreviewerPreference(key)) {
71+
ControlPreferenceScreen.PREVIEWER.ordinal
72+
} else {
73+
ControlPreferenceScreen.REVIEWER.ordinal
74+
}
75+
76+
view?.post {
77+
val tabLayout =
78+
requirePreference<ControlsTabPreference>(
79+
R.string.pref_controls_tab_layout_key,
80+
).getTabLayout() ?: return@post
81+
82+
tabLayout
83+
.getTabAt(targetTabIndex)
84+
?.takeIf { it.position != tabLayout.selectedTabPosition }
85+
?.select()
86+
}
87+
}
88+
89+
/**
90+
* Determines if a preference key belongs to the previewer tab.
91+
* Previewer preferences typically have "previewer_" prefix in their keys.
92+
*/
93+
private fun isPreviewerPreference(preferenceKey: String): Boolean = preferenceKey.contains("previewer_", ignoreCase = true)
94+
6495
private fun setControlPreferencesDefaultValues(screen: ControlPreferenceScreen) {
6596
val commands = screen.getActions().associateBy { it.preferenceKey }
6697
val prefs = sharedPrefs()

AnkiDroid/src/main/java/com/ichi2/anki/preferences/ControlsTabPreference.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ class ControlsTabPreference
4545
tabLayout?.addOnTabSelectedListener(listener)
4646
}
4747

48+
/**
49+
* Gets the underlying TabLayout for programmatic access.
50+
* @return The TabLayout instance, or null if not yet bound.
51+
*/
52+
fun getTabLayout(): TabLayout? = tabLayout
53+
4854
override fun onBindViewHolder(holder: PreferenceViewHolder) {
4955
super.onBindViewHolder(holder)
5056
tabLayout = holder.itemView as? TabLayout

AnkiDroid/src/main/java/com/ichi2/anki/preferences/HeaderFragment.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ class HeaderFragment : SettingsFragment() {
130130
.addBreadcrumb(R.string.pref_cat_appearance)
131131
}
132132
index(R.xml.preferences_controls)
133+
index(R.xml.preferences_reviewer_controls)
134+
.addBreadcrumb(activity.getString(R.string.pref_cat_controls))
135+
.addBreadcrumb(activity.getString(R.string.pref_controls_reviews_tab))
136+
index(R.xml.preferences_previewer_controls)
137+
.addBreadcrumb(activity.getString(R.string.pref_cat_controls))
138+
.addBreadcrumb(activity.getString(R.string.pref_controls_previews_tab))
133139
index(R.xml.preferences_accessibility)
134140
index(R.xml.preferences_backup_limits)
135141
ignorePreference(activity.getString(R.string.pref_backups_help_key))

AnkiDroid/src/main/java/com/ichi2/anki/preferences/Preferences.kt

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import androidx.fragment.app.FragmentFactory
3232
import androidx.fragment.app.FragmentManager
3333
import androidx.fragment.app.FragmentTransaction
3434
import androidx.fragment.app.commit
35+
import androidx.lifecycle.lifecycleScope
3536
import androidx.preference.Preference
3637
import androidx.preference.PreferenceFragmentCompat
3738
import com.bytehamster.lib.preferencesearch.SearchConfiguration
@@ -49,6 +50,8 @@ import com.ichi2.anki.utils.ext.sharedPrefs
4950
import com.ichi2.anki.utils.isWindowCompact
5051
import com.ichi2.themes.Themes
5152
import com.ichi2.utils.FragmentFactoryUtils
53+
import kotlinx.coroutines.delay
54+
import kotlinx.coroutines.launch
5255
import timber.log.Timber
5356
import kotlin.reflect.KClass
5457
import kotlin.reflect.jvm.jvmName
@@ -136,10 +139,26 @@ class PreferencesFragment :
136139
addToBackStack(fragment.javaClass.name)
137140
}
138141

139-
Timber.i("Highlighting key '%s' on %s", result.key, fragment)
140-
result.highlight(fragment as PreferenceFragmentCompat)
142+
if (isTabSpecificPreference(result.resourceFile)) {
143+
(fragment as? ControlsSettingsFragment)?.lifecycleScope?.launch {
144+
delay(100)
145+
fragment.selectTabForPreference(result.key)
146+
delay(150)
147+
(fragment as PreferenceFragmentCompat).let { result.highlight(it) }
148+
}
149+
} else {
150+
result.highlight(fragment as PreferenceFragmentCompat)
151+
}
141152
}
142153

154+
/**
155+
* Checks if the given resource file represents a tab-specific preference
156+
* that requires special tab navigation handling.
157+
*/
158+
private fun isTabSpecificPreference(
159+
@XmlRes file: Int,
160+
) = file in setOf(R.xml.preferences_reviewer_controls, R.xml.preferences_previewer_controls)
161+
143162
private fun setupBackCallbacks() {
144163
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, childFragmentOnBackPressedCallback)
145164
childFragmentManager.addOnBackStackChangedListener(childBackStackListener)
@@ -280,6 +299,8 @@ fun getFragmentFromXmlRes(
280299
R.xml.preferences_notifications -> NotificationsSettingsFragment()
281300
R.xml.preferences_appearance -> AppearanceSettingsFragment()
282301
R.xml.preferences_controls -> ControlsSettingsFragment()
302+
R.xml.preferences_reviewer_controls -> ControlsSettingsFragment()
303+
R.xml.preferences_previewer_controls -> ControlsSettingsFragment()
283304
R.xml.preferences_advanced -> AdvancedSettingsFragment()
284305
R.xml.preferences_accessibility -> AccessibilitySettingsFragment()
285306
R.xml.preferences_dev_options -> DevOptionsFragment()

0 commit comments

Comments
 (0)