Switch refactored entities to ViewBinding (#695)
* build: Enable ViewBinding * autofill: oreo: Switch to ViewBinding * PasswordFragment: switch to ViewBinding * AutofillPublisherChangedActivity: use with(binding) { } syntax Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
parent
575ef84726
commit
f21b6426af
4 changed files with 66 additions and 49 deletions
|
@ -31,6 +31,8 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewBinding.enabled = true
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId versions.packageName
|
applicationId versions.packageName
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import com.zeapo.pwdstore.databinding.PasswordRecyclerViewBinding
|
||||||
import com.zeapo.pwdstore.git.GitActivity
|
import com.zeapo.pwdstore.git.GitActivity
|
||||||
import com.zeapo.pwdstore.ui.OnOffItemAnimator
|
import com.zeapo.pwdstore.ui.OnOffItemAnimator
|
||||||
import com.zeapo.pwdstore.ui.adapters.PasswordItemRecyclerAdapter
|
import com.zeapo.pwdstore.ui.adapters.PasswordItemRecyclerAdapter
|
||||||
|
@ -39,8 +40,10 @@ class PasswordFragment : Fragment() {
|
||||||
|
|
||||||
private var recyclerViewStateToRestore: Parcelable? = null
|
private var recyclerViewStateToRestore: Parcelable? = null
|
||||||
private var actionMode: ActionMode? = null
|
private var actionMode: ActionMode? = null
|
||||||
|
private var _binding: PasswordRecyclerViewBinding? = null
|
||||||
|
|
||||||
private val model: SearchableRepositoryViewModel by activityViewModels()
|
private val model: SearchableRepositoryViewModel by activityViewModels()
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
private fun requireStore() = requireActivity() as PasswordStore
|
private fun requireStore() = requireActivity() as PasswordStore
|
||||||
|
|
||||||
|
@ -49,28 +52,28 @@ class PasswordFragment : Fragment() {
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
val view = inflater.inflate(R.layout.password_recycler_view, container, false)
|
_binding = PasswordRecyclerViewBinding.inflate(inflater, container, false)
|
||||||
initializePasswordList(view)
|
initializePasswordList()
|
||||||
val fab = view.findViewById<FloatingActionButton>(R.id.fab)
|
val fab = binding.fab
|
||||||
fab.setOnClickListener {
|
fab.setOnClickListener {
|
||||||
toggleFabExpand(fab)
|
toggleFabExpand(fab)
|
||||||
}
|
}
|
||||||
view.findViewById<FloatingActionButton>(R.id.create_folder).setOnClickListener {
|
binding.createFolder.setOnClickListener {
|
||||||
requireStore().createFolder()
|
requireStore().createFolder()
|
||||||
toggleFabExpand(fab)
|
toggleFabExpand(fab)
|
||||||
}
|
}
|
||||||
view.findViewById<FloatingActionButton>(R.id.create_password).setOnClickListener {
|
binding.createPassword.setOnClickListener {
|
||||||
requireStore().createPassword()
|
requireStore().createPassword()
|
||||||
toggleFabExpand(fab)
|
toggleFabExpand(fab)
|
||||||
}
|
}
|
||||||
return view
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializePasswordList(rootView: View) {
|
private fun initializePasswordList() {
|
||||||
swipeRefresher = rootView.findViewById(R.id.swipe_refresher)
|
swipeRefresher = binding.swipeRefresher
|
||||||
swipeRefresher.setOnRefreshListener {
|
swipeRefresher.setOnRefreshListener {
|
||||||
if (!PasswordRepository.isGitRepo()) {
|
if (!PasswordRepository.isGitRepo()) {
|
||||||
Snackbar.make(rootView, getString(R.string.clone_git_repo), Snackbar.LENGTH_SHORT)
|
Snackbar.make(binding.root, getString(R.string.clone_git_repo), Snackbar.LENGTH_SHORT)
|
||||||
.show()
|
.show()
|
||||||
swipeRefresher.isRefreshing = false
|
swipeRefresher.isRefreshing = false
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,7 +103,7 @@ class PasswordFragment : Fragment() {
|
||||||
actionMode!!.finish()
|
actionMode!!.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
recyclerView = rootView.findViewById(R.id.pass_recycler)
|
recyclerView = binding.passRecycler
|
||||||
recyclerView.apply {
|
recyclerView.apply {
|
||||||
layoutManager = LinearLayoutManager(requireContext())
|
layoutManager = LinearLayoutManager(requireContext())
|
||||||
itemAnimator = OnOffItemAnimator()
|
itemAnimator = OnOffItemAnimator()
|
||||||
|
@ -129,6 +132,11 @@ class PasswordFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
_binding = null
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
|
||||||
private fun toggleFabExpand(fab: FloatingActionButton) = with(fab) {
|
private fun toggleFabExpand(fab: FloatingActionButton) = with(fab) {
|
||||||
isExpanded = !isExpanded
|
isExpanded = !isExpanded
|
||||||
isActivated = isExpanded
|
isActivated = isExpanded
|
||||||
|
@ -142,7 +150,7 @@ class PasswordFragment : Fragment() {
|
||||||
// Inflate a menu resource providing context menu items
|
// Inflate a menu resource providing context menu items
|
||||||
mode.menuInflater.inflate(R.menu.context_pass, menu)
|
mode.menuInflater.inflate(R.menu.context_pass, menu)
|
||||||
// hide the fab
|
// hide the fab
|
||||||
requireActivity().findViewById<View>(R.id.fab).visibility = View.GONE
|
binding.fab.visibility = View.GONE
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +196,7 @@ class PasswordFragment : Fragment() {
|
||||||
recyclerAdapter.requireSelectionTracker().clearSelection()
|
recyclerAdapter.requireSelectionTracker().clearSelection()
|
||||||
actionMode = null
|
actionMode = null
|
||||||
// show the fab
|
// show the fab
|
||||||
requireActivity().findViewById<View>(R.id.fab).visibility = View.VISIBLE
|
binding.fab.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,8 @@ import com.zeapo.pwdstore.autofill.oreo.AutofillMatcher
|
||||||
import com.zeapo.pwdstore.autofill.oreo.AutofillPreferences
|
import com.zeapo.pwdstore.autofill.oreo.AutofillPreferences
|
||||||
import com.zeapo.pwdstore.autofill.oreo.DirectoryStructure
|
import com.zeapo.pwdstore.autofill.oreo.DirectoryStructure
|
||||||
import com.zeapo.pwdstore.autofill.oreo.FormOrigin
|
import com.zeapo.pwdstore.autofill.oreo.FormOrigin
|
||||||
|
import com.zeapo.pwdstore.databinding.ActivityOreoAutofillFilterBinding
|
||||||
import com.zeapo.pwdstore.utils.PasswordItem
|
import com.zeapo.pwdstore.utils.PasswordItem
|
||||||
import kotlinx.android.synthetic.main.activity_oreo_autofill_filter.*
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.O)
|
@TargetApi(Build.VERSION_CODES.O)
|
||||||
class AutofillFilterView : AppCompatActivity() {
|
class AutofillFilterView : AppCompatActivity() {
|
||||||
|
@ -71,6 +71,7 @@ class AutofillFilterView : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var formOrigin: FormOrigin
|
private lateinit var formOrigin: FormOrigin
|
||||||
private lateinit var directoryStructure: DirectoryStructure
|
private lateinit var directoryStructure: DirectoryStructure
|
||||||
|
private lateinit var binding: ActivityOreoAutofillFilterBinding
|
||||||
|
|
||||||
private val model: SearchableRepositoryViewModel by viewModels {
|
private val model: SearchableRepositoryViewModel by viewModels {
|
||||||
ViewModelProvider.AndroidViewModelFactory(application)
|
ViewModelProvider.AndroidViewModelFactory(application)
|
||||||
|
@ -78,7 +79,8 @@ class AutofillFilterView : AppCompatActivity() {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_oreo_autofill_filter)
|
binding = ActivityOreoAutofillFilterBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
setFinishOnTouchOutside(true)
|
setFinishOnTouchOutside(true)
|
||||||
|
|
||||||
val params = window.attributes
|
val params = window.attributes
|
||||||
|
@ -127,13 +129,13 @@ class AutofillFilterView : AppCompatActivity() {
|
||||||
}.onItemClicked { _, item ->
|
}.onItemClicked { _, item ->
|
||||||
decryptAndFill(item)
|
decryptAndFill(item)
|
||||||
}
|
}
|
||||||
rvPassword.apply {
|
binding.rvPassword.apply {
|
||||||
adapter = recyclerAdapter
|
adapter = recyclerAdapter
|
||||||
layoutManager = LinearLayoutManager(context)
|
layoutManager = LinearLayoutManager(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
val initialFilter = formOrigin.getPrettyIdentifier(applicationContext, untrusted = false)
|
val initialFilter = formOrigin.getPrettyIdentifier(applicationContext, untrusted = false)
|
||||||
search.setText(initialFilter, TextView.BufferType.EDITABLE)
|
binding.search.setText(initialFilter, TextView.BufferType.EDITABLE)
|
||||||
val filterMode =
|
val filterMode =
|
||||||
if (formOrigin is FormOrigin.Web) FilterMode.StrictDomain else FilterMode.Fuzzy
|
if (formOrigin is FormOrigin.Web) FilterMode.StrictDomain else FilterMode.Fuzzy
|
||||||
model.search(
|
model.search(
|
||||||
|
@ -142,7 +144,7 @@ class AutofillFilterView : AppCompatActivity() {
|
||||||
searchMode = SearchMode.RecursivelyInSubdirectories,
|
searchMode = SearchMode.RecursivelyInSubdirectories,
|
||||||
listMode = ListMode.FilesOnly
|
listMode = ListMode.FilesOnly
|
||||||
)
|
)
|
||||||
search.addTextChangedListener {
|
binding.search.addTextChangedListener {
|
||||||
model.search(
|
model.search(
|
||||||
it.toString().trim(),
|
it.toString().trim(),
|
||||||
filterMode = FilterMode.Fuzzy,
|
filterMode = FilterMode.Fuzzy,
|
||||||
|
@ -155,21 +157,21 @@ class AutofillFilterView : AppCompatActivity() {
|
||||||
recyclerAdapter.submitList(list)
|
recyclerAdapter.submitList(list)
|
||||||
// Switch RecyclerView out for a "no results" message if the new list is empty and
|
// Switch RecyclerView out for a "no results" message if the new list is empty and
|
||||||
// the message is not yet shown (and vice versa).
|
// the message is not yet shown (and vice versa).
|
||||||
if ((list.isEmpty() && rvPasswordSwitcher.nextView.id == rvPasswordEmpty.id) ||
|
if ((list.isEmpty() && binding.rvPasswordSwitcher.nextView.id == binding.rvPasswordEmpty.id) ||
|
||||||
(list.isNotEmpty() && rvPasswordSwitcher.nextView.id == rvPassword.id)
|
(list.isNotEmpty() && binding.rvPasswordSwitcher.nextView.id == binding.rvPassword.id)
|
||||||
)
|
)
|
||||||
rvPasswordSwitcher.showNext()
|
binding.rvPasswordSwitcher.showNext()
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldMatch.text = getString(
|
binding.shouldMatch.text = getString(
|
||||||
R.string.oreo_autofill_match_with,
|
R.string.oreo_autofill_match_with,
|
||||||
formOrigin.getPrettyIdentifier(applicationContext)
|
formOrigin.getPrettyIdentifier(applicationContext)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun decryptAndFill(item: PasswordItem) {
|
private fun decryptAndFill(item: PasswordItem) {
|
||||||
if (shouldClear.isChecked) AutofillMatcher.clearMatchesFor(applicationContext, formOrigin)
|
if (binding.shouldClear.isChecked) AutofillMatcher.clearMatchesFor(applicationContext, formOrigin)
|
||||||
if (shouldMatch.isChecked) AutofillMatcher.addMatchFor(
|
if (binding.shouldMatch.isChecked) AutofillMatcher.addMatchFor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
formOrigin,
|
formOrigin,
|
||||||
item.file
|
item.file
|
||||||
|
|
|
@ -21,7 +21,7 @@ import com.zeapo.pwdstore.autofill.oreo.AutofillMatcher
|
||||||
import com.zeapo.pwdstore.autofill.oreo.AutofillPublisherChangedException
|
import com.zeapo.pwdstore.autofill.oreo.AutofillPublisherChangedException
|
||||||
import com.zeapo.pwdstore.autofill.oreo.FormOrigin
|
import com.zeapo.pwdstore.autofill.oreo.FormOrigin
|
||||||
import com.zeapo.pwdstore.autofill.oreo.computeCertificatesHash
|
import com.zeapo.pwdstore.autofill.oreo.computeCertificatesHash
|
||||||
import kotlinx.android.synthetic.main.activity_oreo_autofill_publisher_changed.*
|
import com.zeapo.pwdstore.databinding.ActivityOreoAutofillPublisherChangedBinding
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.O)
|
@TargetApi(Build.VERSION_CODES.O)
|
||||||
class AutofillPublisherChangedActivity : AppCompatActivity() {
|
class AutofillPublisherChangedActivity : AppCompatActivity() {
|
||||||
|
@ -45,10 +45,12 @@ class AutofillPublisherChangedActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var appPackage: String
|
private lateinit var appPackage: String
|
||||||
|
private lateinit var binding: ActivityOreoAutofillPublisherChangedBinding
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_oreo_autofill_publisher_changed)
|
binding = ActivityOreoAutofillPublisherChangedBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
setFinishOnTouchOutside(true)
|
setFinishOnTouchOutside(true)
|
||||||
|
|
||||||
appPackage = intent.getStringExtra(EXTRA_APP_PACKAGE) ?: run {
|
appPackage = intent.getStringExtra(EXTRA_APP_PACKAGE) ?: run {
|
||||||
|
@ -58,36 +60,39 @@ class AutofillPublisherChangedActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
supportActionBar?.hide()
|
supportActionBar?.hide()
|
||||||
showPackageInfo()
|
showPackageInfo()
|
||||||
|
with(binding) {
|
||||||
okButton.setOnClickListener { finish() }
|
okButton.setOnClickListener { finish() }
|
||||||
advancedButton.setOnClickListener {
|
advancedButton.setOnClickListener {
|
||||||
advancedButton.visibility = View.INVISIBLE
|
advancedButton.visibility = View.INVISIBLE
|
||||||
warningAppAdvancedInfo.visibility = View.VISIBLE
|
warningAppAdvancedInfo.visibility = View.VISIBLE
|
||||||
resetButton.visibility = View.VISIBLE
|
resetButton.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
resetButton.setOnClickListener {
|
resetButton.setOnClickListener {
|
||||||
AutofillMatcher.clearMatchesFor(this, FormOrigin.App(appPackage))
|
AutofillMatcher.clearMatchesFor(this@AutofillPublisherChangedActivity, FormOrigin.App(appPackage))
|
||||||
finish()
|
finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showPackageInfo() {
|
private fun showPackageInfo() {
|
||||||
try {
|
try {
|
||||||
val packageInfo =
|
with(binding) {
|
||||||
packageManager.getPackageInfo(appPackage, PackageManager.GET_META_DATA)
|
val packageInfo =
|
||||||
val installTime = DateUtils.getRelativeTimeSpanString(packageInfo.firstInstallTime)
|
packageManager.getPackageInfo(appPackage, PackageManager.GET_META_DATA)
|
||||||
warningAppInstallDate.text =
|
val installTime = DateUtils.getRelativeTimeSpanString(packageInfo.firstInstallTime)
|
||||||
getString(R.string.oreo_autofill_warning_publisher_install_time, installTime)
|
warningAppInstallDate.text =
|
||||||
val appInfo =
|
getString(R.string.oreo_autofill_warning_publisher_install_time, installTime)
|
||||||
packageManager.getApplicationInfo(appPackage, PackageManager.GET_META_DATA)
|
val appInfo =
|
||||||
warningAppName.text = "“${packageManager.getApplicationLabel(appInfo)}”"
|
packageManager.getApplicationInfo(appPackage, PackageManager.GET_META_DATA)
|
||||||
|
warningAppName.text = "“${packageManager.getApplicationLabel(appInfo)}”"
|
||||||
|
|
||||||
val currentHash = computeCertificatesHash(this, appPackage)
|
val currentHash = computeCertificatesHash(this@AutofillPublisherChangedActivity, appPackage)
|
||||||
warningAppAdvancedInfo.text = getString(
|
warningAppAdvancedInfo.text = getString(
|
||||||
R.string.oreo_autofill_warning_publisher_advanced_info_template,
|
R.string.oreo_autofill_warning_publisher_advanced_info_template,
|
||||||
appPackage,
|
appPackage,
|
||||||
currentHash
|
currentHash
|
||||||
)
|
)
|
||||||
|
}
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
e(exception) { "Failed to retrieve package info for $appPackage" }
|
e(exception) { "Failed to retrieve package info for $appPackage" }
|
||||||
finish()
|
finish()
|
||||||
|
|
Loading…
Reference in a new issue