Skip to content

Commit

Permalink
For mozilla-mobile#17917: Use View binding in add-ons
Browse files Browse the repository at this point in the history
  • Loading branch information
codrut.topliceanu authored and mergify[bot] committed Aug 23, 2021
1 parent 05f74eb commit 7070bb5
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 136 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import mozilla.components.feature.addons.update.DefaultAddonUpdater.UpdateAttemp
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.FragmentAddOnDetailsBinding
import org.mozilla.fenix.ext.showToolbar

/**
Expand All @@ -38,7 +39,8 @@ class AddonDetailsFragment : Fragment(R.layout.fragment_add_on_details), AddonDe
showToolbar(title = args.addon.translateName(it))
}

AddonDetailsView(view, interactor = this).bind(args.addon)
val binding = FragmentAddOnDetailsBinding.bind(view)
AddonDetailsView(binding, interactor = this).bind(args.addon)
}

override fun openWebsite(addonSiteUrl: Uri) {
Expand Down
33 changes: 16 additions & 17 deletions app/src/main/java/org/mozilla/fenix/addons/AddonDetailsView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ import android.view.View
import androidx.core.net.toUri
import androidx.core.text.HtmlCompat
import androidx.core.text.getSpans
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.fragment_add_on_details.*
import mozilla.components.feature.addons.Addon
import mozilla.components.feature.addons.ui.translateDescription
import mozilla.components.feature.addons.ui.updatedAtDate
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.FragmentAddOnDetailsBinding
import java.text.DateFormat
import java.text.NumberFormat
import java.util.Locale
Expand All @@ -40,9 +39,9 @@ interface AddonDetailsInteractor {
* Shows the details of an add-on.
*/
class AddonDetailsView(
override val containerView: View,
private val binding: FragmentAddOnDetailsBinding,
private val interactor: AddonDetailsInteractor
) : LayoutContainer {
) {

private val dateFormatter = DateFormat.getDateInstance()
private val numberFormatter = NumberFormat.getNumberInstance(Locale.getDefault())
Expand All @@ -58,49 +57,49 @@ class AddonDetailsView(

private fun bindRating(addon: Addon) {
addon.rating?.let { rating ->
val resources = containerView.resources
val resources = binding.root.resources
val ratingContentDescription =
resources.getString(R.string.mozac_feature_addons_rating_content_description)
rating_view.contentDescription = String.format(ratingContentDescription, rating.average)
rating_view.rating = rating.average
binding.ratingView.contentDescription = String.format(ratingContentDescription, rating.average)
binding.ratingView.rating = rating.average

users_count.text = numberFormatter.format(rating.reviews)
binding.usersCount.text = numberFormatter.format(rating.reviews)
}
}

private fun bindWebsite(addon: Addon) {
home_page_label.setOnClickListener {
binding.homePageLabel.setOnClickListener {
interactor.openWebsite(addon.siteUrl.toUri())
}
}

private fun bindLastUpdated(addon: Addon) {
last_updated_text.text = dateFormatter.format(addon.updatedAtDate)
binding.lastUpdatedText.text = dateFormatter.format(addon.updatedAtDate)
}

private fun bindVersion(addon: Addon) {
var version = addon.installedState?.version
if (version.isNullOrEmpty()) {
version = addon.version
}
version_text.text = version
binding.versionText.text = version

if (addon.isInstalled()) {
version_text.setOnLongClickListener {
binding.versionText.setOnLongClickListener {
interactor.showUpdaterDialog(addon)
true
}
} else {
version_text.setOnLongClickListener(null)
binding.versionText.setOnLongClickListener(null)
}
}

private fun bindAuthors(addon: Addon) {
author_text.text = addon.authors.joinToString { author -> author.name }.trim()
binding.authorText.text = addon.authors.joinToString { author -> author.name }.trim()
}

private fun bindDetails(addon: Addon) {
val detailsText = addon.translateDescription(containerView.context)
val detailsText = addon.translateDescription(binding.root.context)

val parsedText = detailsText.replace("\n", "<br/>")
val text = HtmlCompat.fromHtml(parsedText, HtmlCompat.FROM_HTML_MODE_COMPACT)
Expand All @@ -110,8 +109,8 @@ class AddonDetailsView(
for (link in links) {
addActionToLinks(spannableStringBuilder, link)
}
details.text = spannableStringBuilder
details.movementMethod = LinkMovementMethod.getInstance()
binding.details.text = spannableStringBuilder
binding.details.movementMethod = LinkMovementMethod.getInstance()
}

private fun addActionToLinks(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import kotlinx.android.synthetic.main.fragment_add_on_internal_settings.*
import mozilla.components.feature.addons.ui.translateName
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.FragmentAddOnInternalSettingsBinding
import org.mozilla.fenix.ext.showToolbar

/**
Expand Down Expand Up @@ -40,10 +40,10 @@ class AddonInternalSettingsFragment : AddonPopupBaseFragment() {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val binding = FragmentAddOnInternalSettingsBinding.bind(view)
args.addon.installedState?.optionsPageUrl?.let {
engineSession?.let { engineSession ->
addonSettingsEngineView.render(engineSession)
binding.addonSettingsEngineView.render(engineSession)
engineSession.loadUrl(it)
}
} ?: findNavController().navigateUp()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@
package org.mozilla.fenix.addons

import android.net.Uri
import android.view.View
import androidx.core.net.toUri
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.fragment_add_on_permissions.*
import mozilla.components.feature.addons.Addon
import mozilla.components.feature.addons.ui.AddonPermissionsAdapter
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.FragmentAddOnPermissionsBinding
import org.mozilla.fenix.theme.ThemeManager

interface AddonPermissionsDetailsInteractor {
Expand All @@ -26,18 +24,18 @@ interface AddonPermissionsDetailsInteractor {
/**
* Shows the permission details of an add-on.
*/
class AddonPermissionsDetailsView(
override val containerView: View,
class AddonPermissionDetailsBindingDelegate(
val binding: FragmentAddOnPermissionsBinding,
private val interactor: AddonPermissionsDetailsInteractor
) : LayoutContainer {
) {

fun bind(addon: Addon) {
bindPermissions(addon)
bindLearnMore()
}

private fun bindPermissions(addon: Addon) {
add_ons_permissions.apply {
binding.addOnsPermissions.apply {
layoutManager = LinearLayoutManager(context)
val sortedPermissions = addon.translatePermissions(context).sorted()
adapter = AddonPermissionsAdapter(
Expand All @@ -50,7 +48,7 @@ class AddonPermissionsDetailsView(
}

private fun bindLearnMore() {
learn_more_label.setOnClickListener {
binding.learnMoreLabel.setOnClickListener {
interactor.openWebsite(LEARN_MORE_URL.toUri())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import mozilla.components.feature.addons.ui.translateName
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.FragmentAddOnPermissionsBinding
import org.mozilla.fenix.ext.showToolbar

/**
Expand All @@ -29,7 +30,8 @@ class AddonPermissionsDetailsFragment :
context?.let {
showToolbar(args.addon.translateName(it))
}
AddonPermissionsDetailsView(view, interactor = this).bind(args.addon)
val binding = FragmentAddOnPermissionsBinding.bind(view)
AddonPermissionDetailsBindingDelegate(binding, interactor = this).bind(args.addon)
}

override fun openWebsite(addonSiteUrl: Uri) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_add_ons_management.*
import kotlinx.android.synthetic.main.fragment_add_ons_management.view.*
import kotlinx.android.synthetic.main.overlay_add_on_progress.view.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
Expand All @@ -34,6 +31,7 @@ import org.mozilla.fenix.Config
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.databinding.FragmentAddOnsManagementBinding
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getRootView
import org.mozilla.fenix.ext.requireComponents
Expand All @@ -52,6 +50,9 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)

private val args by navArgs<AddonsManagementFragmentArgs>()

private var _binding: FragmentAddOnsManagementBinding? = null
private val binding get() = _binding!!

/**
* Whether or not an add-on installation is in progress.
*/
Expand All @@ -69,7 +70,8 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
bindRecyclerView(view)
_binding = FragmentAddOnsManagementBinding.bind(view)
bindRecyclerView()
}

override fun onResume() {
Expand All @@ -88,15 +90,16 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
super.onDestroyView()
// letting go of the resources to avoid memory leak.
adapter = null
_binding = null
}

private fun bindRecyclerView(view: View) {
private fun bindRecyclerView() {
val managementView = AddonsManagementView(
navController = findNavController(),
showPermissionDialog = ::showPermissionDialog
)

val recyclerView = view.add_ons_list
val recyclerView = binding.addOnsList
recyclerView.layoutManager = LinearLayoutManager(requireContext())
val shouldRefresh = adapter != null

Expand Down Expand Up @@ -126,8 +129,8 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
)
}
isInstallationInProgress = false
view.add_ons_progress_bar.isVisible = false
view.add_ons_empty_message.isVisible = false
binding.addOnsProgressBar.isVisible = false
binding.addOnsEmptyMessage.isVisible = false

recyclerView.adapter = adapter
if (shouldRefresh) {
Expand All @@ -145,12 +148,12 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
lifecycleScope.launch(Dispatchers.Main) {
runIfFragmentIsAttached {
showSnackBar(
view,
binding.root,
getString(R.string.mozac_feature_addons_failed_to_query_add_ons)
)
isInstallationInProgress = false
view.add_ons_progress_bar.isVisible = false
view.add_ons_empty_message.isVisible = true
binding.addOnsProgressBar.isVisible = false
binding.addOnsEmptyMessage.isVisible = true
}
}
}
Expand Down Expand Up @@ -277,10 +280,10 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
}

private val onPositiveButtonClicked: ((Addon) -> Unit) = { addon ->
addonProgressOverlay?.visibility = View.VISIBLE
binding.addonProgressOverlay.overlayCardView.visibility = View.VISIBLE

if (requireContext().settings().accessibilityServicesEnabled) {
announceForAccessibility(addonProgressOverlay.add_ons_overlay_text.text)
announceForAccessibility(binding.addonProgressOverlay.addOnsOverlayText.text)
}

isInstallationInProgress = true
Expand All @@ -291,7 +294,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
runIfFragmentIsAttached {
isInstallationInProgress = false
adapter?.updateAddon(it)
addonProgressOverlay?.visibility = View.GONE
binding.addonProgressOverlay.overlayCardView.visibility = View.GONE
showInstallationDialog(it)
}
},
Expand All @@ -310,17 +313,17 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
)
}
}
addonProgressOverlay?.visibility = View.GONE
binding.addonProgressOverlay.overlayCardView.visibility = View.GONE
isInstallationInProgress = false
}
}
)

addonProgressOverlay.cancel_button.setOnClickListener {
binding.addonProgressOverlay.cancelButton.setOnClickListener {
lifecycleScope.launch(Dispatchers.Main) {
// Hide the installation progress overlay once cancellation is successful.
if (installOperation.cancel().await()) {
addonProgressOverlay.visibility = View.GONE
binding.addonProgressOverlay.overlayCardView.visibility = View.GONE
}
}
}
Expand All @@ -330,10 +333,14 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
val event = AccessibilityEvent.obtain(
AccessibilityEvent.TYPE_ANNOUNCEMENT
)
addonProgressOverlay.onInitializeAccessibilityEvent(event)

binding.addonProgressOverlay.overlayCardView.onInitializeAccessibilityEvent(event)
event.text.add(announcementText)
event.contentDescription = null
addonProgressOverlay.parent.requestSendAccessibilityEvent(addonProgressOverlay, event)
binding.addonProgressOverlay.overlayCardView.parent.requestSendAccessibilityEvent(
binding.addonProgressOverlay.overlayCardView,
event
)
}

companion object {
Expand Down

0 comments on commit 7070bb5

Please sign in to comment.