Add IME_FLAG_NO_PERSONALIZED_LEARNING flag to text input when incognito is enabled

Tested with Gboard only.
This commit is contained in:
Ivan Iskandar 2021-08-27 20:57:28 +07:00
parent 4b2a9bc621
commit 068399dbb3
No known key found for this signature in database
GPG Key ID: 2C57784F9E46D60D
9 changed files with 92 additions and 5 deletions

View File

@ -9,6 +9,9 @@ import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
/**
* A controller that displays a dialog window, floating on top of its activity's window.
@ -23,6 +26,22 @@ abstract class DialogController : Controller {
private var dismissed = false
lateinit var lifecycleScope: CoroutineScope
init {
addLifecycleListener(
object : LifecycleListener() {
override fun preCreateView(controller: Controller) {
lifecycleScope = MainScope()
}
override fun preDestroyView(controller: Controller, view: View) {
lifecycleScope.cancel()
}
}
)
}
/**
* Convenience constructor for use when no arguments are needed.
*/

View File

@ -9,6 +9,7 @@ import androidx.annotation.StringRes
import androidx.appcompat.widget.SearchView
import androidx.viewbinding.ViewBinding
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.view.setIncognitoFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.appcompat.QueryTextEvent
@ -49,9 +50,17 @@ abstract class SearchableNucleusController<VB : ViewBinding, P : BasePresenter<*
// Initialize search option.
val searchItem = menu.findItem(searchItemId)
val searchView = searchItem.actionView as SearchView
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
searchItem.fixExpand(
onExpand = {
val result = invalidateMenuOnExpand()
// For BrowseSourceController :)
searchView.setIncognitoFlow(viewScope)
result
}
)
searchView.maxWidth = Int.MAX_VALUE
searchView.setIncognitoFlow(viewScope)
searchView.queryTextEvents()
.onEach {
val newText = it.queryText.toString()

View File

@ -19,6 +19,7 @@ import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.browse.BrowseController
import eu.kanade.tachiyomi.ui.browse.extension.details.ExtensionDetailsController
import eu.kanade.tachiyomi.util.view.setIncognitoFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@ -127,7 +128,13 @@ open class ExtensionController :
searchView.maxWidth = Int.MAX_VALUE
// Fixes problem with the overflow icon showing up in lieu of search
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
searchItem.fixExpand(
onExpand = {
val result = invalidateMenuOnExpand()
searchView.setIncognitoFlow(viewScope)
result
}
)
if (query.isNotEmpty()) {
searchItem.expandActionView()

View File

@ -32,7 +32,7 @@ class CategoryCreateDialog<T>(bundle: Bundle? = null) : DialogController(bundle)
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(activity!!)
.setTitle(R.string.action_add_category)
.setTextInput(prefill = currentName) {
.setTextInput(lifecycleScope = lifecycleScope, prefill = currentName) {
currentName = it
}
.setPositiveButton(android.R.string.ok) { _, _ ->

View File

@ -37,7 +37,7 @@ class CategoryRenameDialog<T>(bundle: Bundle? = null) : DialogController(bundle)
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(activity!!)
.setTitle(R.string.action_rename_category)
.setTextInput(prefill = currentName) {
.setTextInput(lifecycleScope = lifecycleScope, prefill = currentName) {
currentName = it
}
.setPositiveButton(android.R.string.ok) { _, _ -> onPositive() }

View File

@ -20,6 +20,7 @@ import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.databinding.TrackSearchDialogBinding
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.util.view.setIncognitoFlow
import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
@ -92,6 +93,7 @@ class TrackSearchDialog : DialogController {
search(currentlySearched)
// Input listener
binding?.titleInput?.editText?.setIncognitoFlow(trackController.viewScope)
binding?.titleInput?.editText
?.editorActionEvents {
when (it.actionId) {

View File

@ -28,6 +28,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.onAnimationsFinished
import eu.kanade.tachiyomi.util.view.setIncognitoFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@ -208,7 +209,11 @@ class HistoryController :
// Fixes problem with the overflow icon showing up in lieu of search
searchItem.fixExpand(
onExpand = { invalidateMenuOnExpand() }
onExpand = {
val result = invalidateMenuOnExpand()
searchView.setIncognitoFlow(viewScope)
result
}
)
}

View File

@ -10,16 +10,19 @@ import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.TextView
import androidx.annotation.MenuRes
import androidx.annotation.StringRes
import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.TooltipCompat
import androidx.core.view.children
import androidx.core.view.descendants
import androidx.core.view.forEach
import androidx.core.view.inputmethod.EditorInfoCompat
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.ViewPager
import com.google.android.material.card.MaterialCardView
@ -29,8 +32,14 @@ import com.google.android.material.elevation.ElevationOverlayProvider
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.snackbar.Snackbar
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.isNightMode
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
/**
* Returns coordinates of view.
@ -255,3 +264,35 @@ fun ViewPager.getActivePageView(): View? {
false
}
}
/**
* Sets Flow to this [SearchView] that sets [EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING] to imeOptions
* if [PreferencesHelper.incognitoMode] is true.
*
* Some IMEs may not respect this flag.
*/
fun SearchView.setIncognitoFlow(viewScope: CoroutineScope) {
Injekt.get<PreferencesHelper>().incognitoMode().asImmediateFlow {
imeOptions = if (it) {
imeOptions or EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING
} else {
imeOptions and EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING.inv()
}
}.launchIn(viewScope)
}
/**
* Sets Flow to this [EditText] that sets [EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING] to imeOptions
* if [PreferencesHelper.incognitoMode] is true.
*
* Some IMEs may not respect this flag.
*/
fun EditText.setIncognitoFlow(viewScope: CoroutineScope) {
Injekt.get<PreferencesHelper>().incognitoMode().asImmediateFlow {
imeOptions = if (it) {
imeOptions or EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING
} else {
imeOptions and EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING.inv()
}
}.launchIn(viewScope)
}

View File

@ -11,8 +11,11 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.tachiyomi.databinding.DialogStubQuadstatemultichoiceBinding
import eu.kanade.tachiyomi.databinding.DialogStubTextinputBinding
import eu.kanade.tachiyomi.util.view.setIncognitoFlow
import kotlinx.coroutines.CoroutineScope
fun MaterialAlertDialogBuilder.setTextInput(
lifecycleScope: CoroutineScope,
hint: String? = null,
prefill: String? = null,
onTextChanged: (String) -> Unit
@ -20,6 +23,7 @@ fun MaterialAlertDialogBuilder.setTextInput(
val binding = DialogStubTextinputBinding.inflate(LayoutInflater.from(context))
binding.textField.hint = hint
binding.textField.editText?.apply {
setIncognitoFlow(lifecycleScope)
setText(prefill, TextView.BufferType.EDITABLE)
doAfterTextChanged {
onTextChanged(it?.toString() ?: "")