diff options
author | Harsh Shandilya <me@msfjarvis.dev> | 2021-05-15 12:53:31 +0530 |
---|---|---|
committer | Harsh Shandilya <me@msfjarvis.dev> | 2021-05-15 15:48:05 +0530 |
commit | 285bf9d92944c49c36d1828bc388b12a97525b1a (patch) | |
tree | 1c51ef43afb30a38cd4334a13ac1126ae32e673d /app/src/main/java | |
parent | cdf8e76ac66aca46f2fbfcbc239731c19eb6bec9 (diff) |
Move file reads in RV adapters to a background dispatcher
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
Diffstat (limited to 'app/src/main/java')
5 files changed, 24 insertions, 10 deletions
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/adapters/PasswordItemRecyclerAdapter.kt b/app/src/main/java/dev/msfjarvis/aps/ui/adapters/PasswordItemRecyclerAdapter.kt index a551a8b1..be0267c4 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/adapters/PasswordItemRecyclerAdapter.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/adapters/PasswordItemRecyclerAdapter.kt @@ -17,12 +17,16 @@ import dev.msfjarvis.aps.R import dev.msfjarvis.aps.data.password.PasswordItem import dev.msfjarvis.aps.util.viewmodel.SearchableRepositoryAdapter import dev.msfjarvis.aps.util.viewmodel.stableId +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext -open class PasswordItemRecyclerAdapter : +open class PasswordItemRecyclerAdapter(coroutineScope: CoroutineScope) : SearchableRepositoryAdapter<PasswordItemRecyclerAdapter.PasswordItemViewHolder>( R.layout.password_row_layout, ::PasswordItemViewHolder, - PasswordItemViewHolder::bind + coroutineScope, + PasswordItemViewHolder::bind, ) { fun makeSelectable(recyclerView: RecyclerView) { @@ -48,7 +52,7 @@ open class PasswordItemRecyclerAdapter : private val folderIndicator: AppCompatImageView = itemView.findViewById(R.id.folder_indicator) lateinit var itemDetails: ItemDetailsLookup.ItemDetails<String> - fun bind(item: PasswordItem) { + suspend fun bind(item: PasswordItem) { val parentPath = item.fullPathToParent.replace("(^/)|(/$)".toRegex(), "") val source = if (parentPath.isNotEmpty()) { @@ -62,7 +66,9 @@ open class PasswordItemRecyclerAdapter : if (item.type == PasswordItem.TYPE_CATEGORY) { folderIndicator.visibility = View.VISIBLE val count = - item.file.listFiles { path -> path.isDirectory || path.extension == "gpg" }?.size ?: 0 + withContext(Dispatchers.IO) { + item.file.listFiles { path -> path.isDirectory || path.extension == "gpg" }?.size ?: 0 + } childCount.visibility = if (count > 0) View.VISIBLE else View.GONE childCount.text = "$count" } else { diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillFilterActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillFilterActivity.kt index aac7008d..afa2a6a0 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillFilterActivity.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillFilterActivity.kt @@ -22,6 +22,7 @@ import androidx.core.text.buildSpannedString import androidx.core.text.underline import androidx.core.widget.addTextChangedListener import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import com.github.ajalt.timberkt.e import com.github.androidpasswordstore.autofillparser.FormOrigin @@ -132,8 +133,11 @@ class AutofillFilterView : AppCompatActivity() { with(binding) { rvPassword.apply { adapter = - SearchableRepositoryAdapter(R.layout.oreo_autofill_filter_row, ::PasswordViewHolder) { - item -> + SearchableRepositoryAdapter( + R.layout.oreo_autofill_filter_row, + ::PasswordViewHolder, + lifecycleScope, + ) { item -> val file = item.file.relativeTo(item.rootDir) val pathToIdentifier = directoryStructure.getPathToIdentifierFor(file) val identifier = directoryStructure.getIdentifierFor(file) diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/folderselect/SelectFolderFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/folderselect/SelectFolderFragment.kt index 8c9d5801..ae430485 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/folderselect/SelectFolderFragment.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/folderselect/SelectFolderFragment.kt @@ -10,6 +10,7 @@ import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import com.github.michaelbull.result.onFailure import com.github.michaelbull.result.runCatching @@ -36,7 +37,7 @@ class SelectFolderFragment : Fragment(R.layout.password_recycler_view) { super.onViewCreated(view, savedInstanceState) binding.fab.hide() recyclerAdapter = - PasswordItemRecyclerAdapter().onItemClicked { _, item -> + PasswordItemRecyclerAdapter(lifecycleScope).onItemClicked { _, item -> listener.onFragmentInteraction(item) } binding.passRecycler.apply { diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt index 541a3f9e..c0f2616d 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt @@ -133,7 +133,7 @@ class PasswordFragment : Fragment(R.layout.password_recycler_view) { } recyclerAdapter = - PasswordItemRecyclerAdapter() + PasswordItemRecyclerAdapter(lifecycleScope) .onItemClicked { _, item -> listener.onFragmentInteraction(item) } .onSelectionChanged { selection -> // In order to not interfere with drag selection, we disable the diff --git a/app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt b/app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt index 7106dbe3..f2d0dc64 100644 --- a/app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt +++ b/app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt @@ -36,6 +36,7 @@ import java.io.File import java.text.Collator import java.util.Locale import java.util.Stack +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview @@ -48,6 +49,7 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.launch import kotlinx.coroutines.yield import me.zhanghai.android.fastscroll.PopupTextProvider @@ -376,7 +378,8 @@ private object PasswordItemDiffCallback : DiffUtil.ItemCallback<PasswordItem>() open class SearchableRepositoryAdapter<T : RecyclerView.ViewHolder>( private val layoutRes: Int, private val viewHolderCreator: (view: View) -> T, - private val viewHolderBinder: T.(item: PasswordItem) -> Unit + private val coroutineScope: CoroutineScope, + private val viewHolderBinder: suspend T.(item: PasswordItem) -> Unit, ) : ListAdapter<PasswordItem, T>(PasswordItemDiffCallback), PopupTextProvider { fun <T : ItemDetailsLookup<String>> makeSelectable( @@ -454,7 +457,7 @@ open class SearchableRepositoryAdapter<T : RecyclerView.ViewHolder>( final override fun onBindViewHolder(holder: T, position: Int) { val item = getItem(position) holder.apply { - viewHolderBinder.invoke(this, item) + coroutineScope.launch(Dispatchers.Main.immediate) { viewHolderBinder.invoke(holder, item) } selectionTracker?.let { itemView.isSelected = it.isSelected(item.stableId) } itemView.setOnClickListener { // Do not emit custom click events while the user is selecting items. |