From ff50dae8e94b75fed61147048dc72f6409ffbd57 Mon Sep 17 00:00:00 2001 From: Mihai Branescu Date: Thu, 25 Jun 2020 10:49:35 +0300 Subject: [PATCH] For #11498 - removed SignIn ViewHolder and unified with the Error one --- .../mozilla/fenix/sync/SyncedTabsAdapter.kt | 17 ++++--- .../mozilla/fenix/sync/SyncedTabsLayout.kt | 40 +++++++++++----- .../fenix/sync/SyncedTabsViewHolder.kt | 48 ++++++++----------- .../main/res/layout/sync_tabs_error_row.xml | 31 ++++++++++++ app/src/main/res/values/strings.xml | 2 + 5 files changed, 89 insertions(+), 49 deletions(-) create mode 100644 app/src/main/res/layout/sync_tabs_error_row.xml diff --git a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsAdapter.kt b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsAdapter.kt index 2d3e8b885..e51419df4 100644 --- a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsAdapter.kt @@ -12,7 +12,6 @@ import androidx.recyclerview.widget.ListAdapter import mozilla.components.browser.storage.sync.SyncedDeviceTabs import org.mozilla.fenix.sync.SyncedTabsViewHolder.DeviceViewHolder import org.mozilla.fenix.sync.SyncedTabsViewHolder.ErrorViewHolder -import org.mozilla.fenix.sync.SyncedTabsViewHolder.SignInViewHolder import org.mozilla.fenix.sync.SyncedTabsViewHolder.TabViewHolder import mozilla.components.browser.storage.sync.Tab as SyncTab import mozilla.components.concept.sync.Device as SyncDevice @@ -28,7 +27,6 @@ class SyncedTabsAdapter( DeviceViewHolder.LAYOUT_ID -> DeviceViewHolder(itemView) TabViewHolder.LAYOUT_ID -> TabViewHolder(itemView) ErrorViewHolder.LAYOUT_ID -> ErrorViewHolder(itemView) - SignInViewHolder.LAYOUT_ID -> SignInViewHolder(itemView) else -> throw IllegalStateException() } } @@ -38,10 +36,9 @@ class SyncedTabsAdapter( } override fun getItemViewType(position: Int) = when (getItem(position)) { - is AdapterItem.Device -> DeviceViewHolder.LAYOUT_ID - is AdapterItem.Tab -> TabViewHolder.LAYOUT_ID - is AdapterItem.Error -> ErrorViewHolder.LAYOUT_ID - is AdapterItem.SignIn -> SignInViewHolder.LAYOUT_ID + is AdapterItem.Device -> DeviceViewHolder.LAYOUT_ID + is AdapterItem.Tab -> TabViewHolder.LAYOUT_ID + is AdapterItem.Error -> ErrorViewHolder.LAYOUT_ID } fun updateData(syncedTabs: List) { @@ -62,7 +59,7 @@ class SyncedTabsAdapter( when (oldItem) { is AdapterItem.Device -> newItem is AdapterItem.Device && oldItem.device.id == newItem.device.id - is AdapterItem.Tab, AdapterItem.Error, AdapterItem.SignIn -> + is AdapterItem.Tab, is AdapterItem.Error -> oldItem == newItem } @@ -74,7 +71,9 @@ class SyncedTabsAdapter( sealed class AdapterItem { data class Device(val device: SyncDevice) : AdapterItem() data class Tab(val tab: SyncTab) : AdapterItem() - data class SignIn(val navController: NavController) : AdapterItem() - data class Error(val errorResId: Int) : AdapterItem() + data class Error( + val descriptionResId: Int, + val navController: NavController? = null + ) : AdapterItem() } } diff --git a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt index 16288aa15..564efb63f 100644 --- a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt +++ b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt @@ -9,6 +9,7 @@ import android.util.AttributeSet import android.widget.FrameLayout import androidx.annotation.StringRes import androidx.fragment.app.findFragment +import androidx.navigation.NavController import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import kotlinx.android.synthetic.main.component_sync_tabs.view.* @@ -19,6 +20,7 @@ import kotlinx.coroutines.launch import mozilla.components.browser.storage.sync.SyncedDeviceTabs import mozilla.components.feature.syncedtabs.view.SyncedTabsView import org.mozilla.fenix.R +import java.lang.IllegalStateException class SyncedTabsLayout @JvmOverloads constructor( context: Context, @@ -45,10 +47,17 @@ class SyncedTabsLayout @JvmOverloads constructor( // We may still be displaying a "loading" spinner, hide it. stopLoading() - sync_tabs_status.text = context.getText(stringResourceForError(error)) + val navController: NavController? = try { + findFragment().findNavController() + } catch (exception: IllegalStateException) { + null + } - synced_tabs_list.visibility = View.GONE - sync_tabs_status.visibility = View.VISIBLE + val descriptionResId = stringResourceForError(error) + val errorItem = getErrorItem(navController, error, descriptionResId) + + val errorList: List = listOf(errorItem) + adapter.submitList(errorList) synced_tabs_pull_to_refresh.isEnabled = pullToRefreshEnableState(error) } @@ -56,17 +65,11 @@ class SyncedTabsLayout @JvmOverloads constructor( override fun displaySyncedTabs(syncedTabs: List) { coroutineScope.launch { - synced_tabs_list.visibility = View.VISIBLE - sync_tabs_status.visibility = View.GONE - adapter.updateData(syncedTabs) } } override fun startLoading() { - synced_tabs_list.visibility = View.VISIBLE - sync_tabs_status.visibility = View.GONE - synced_tabs_pull_to_refresh.isRefreshing = true } @@ -80,7 +83,8 @@ class SyncedTabsLayout @JvmOverloads constructor( } companion object { - internal fun pullToRefreshEnableState(error: SyncedTabsView.ErrorType) = when (error) { + + private fun pullToRefreshEnableState(error: SyncedTabsView.ErrorType) = when (error) { // Disable "pull-to-refresh" when we clearly can't sync tabs, and user needs to take an // action within the app. SyncedTabsView.ErrorType.SYNC_UNAVAILABLE, @@ -93,12 +97,26 @@ class SyncedTabsLayout @JvmOverloads constructor( SyncedTabsView.ErrorType.NO_TABS_AVAILABLE -> true } - internal fun stringResourceForError(error: SyncedTabsView.ErrorType) = when (error) { + private fun stringResourceForError(error: SyncedTabsView.ErrorType) = when (error) { SyncedTabsView.ErrorType.MULTIPLE_DEVICES_UNAVAILABLE -> R.string.synced_tabs_connect_another_device SyncedTabsView.ErrorType.SYNC_ENGINE_UNAVAILABLE -> R.string.synced_tabs_enable_tab_syncing SyncedTabsView.ErrorType.SYNC_UNAVAILABLE -> R.string.synced_tabs_sign_in_message SyncedTabsView.ErrorType.SYNC_NEEDS_REAUTHENTICATION -> R.string.synced_tabs_reauth SyncedTabsView.ErrorType.NO_TABS_AVAILABLE -> R.string.synced_tabs_no_tabs } + + private fun getErrorItem( + navController: NavController?, + error: SyncedTabsView.ErrorType, + @StringRes stringResId: Int + ): SyncedTabsAdapter.AdapterItem = when (error) { + SyncedTabsView.ErrorType.MULTIPLE_DEVICES_UNAVAILABLE, + SyncedTabsView.ErrorType.SYNC_ENGINE_UNAVAILABLE, + SyncedTabsView.ErrorType.SYNC_NEEDS_REAUTHENTICATION, + SyncedTabsView.ErrorType.NO_TABS_AVAILABLE -> SyncedTabsAdapter.AdapterItem + .Error(descriptionResId = stringResId) + SyncedTabsView.ErrorType.SYNC_UNAVAILABLE -> SyncedTabsAdapter.AdapterItem + .Error(descriptionResId = stringResId, navController = navController) + } } } diff --git a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsViewHolder.kt b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsViewHolder.kt index 8be6c56d1..95abada88 100644 --- a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsViewHolder.kt @@ -6,10 +6,10 @@ package org.mozilla.fenix.sync import android.view.View import android.view.View.GONE +import android.view.View.VISIBLE import android.widget.LinearLayout -import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.synthetic.main.no_content_message_with_action.view.* +import kotlinx.android.synthetic.main.sync_tabs_error_row.view.* import kotlinx.android.synthetic.main.sync_tabs_list_item.view.* import kotlinx.android.synthetic.main.view_synced_tabs_group.view.* import mozilla.components.browser.storage.sync.Tab @@ -44,41 +44,26 @@ sealed class SyncedTabsViewHolder(itemView: View) : RecyclerView.ViewHolder(item } } - class SignInViewHolder(itemView: View) : SyncedTabsViewHolder(itemView) { - - override fun bind(item: T, interactor: (Tab) -> Unit) { - val signInItem = item as AdapterItem.SignIn - setErrorMargins() - - itemView.no_content_header.visibility = GONE - itemView.no_content_description.text = - itemView.context.getString(R.string.synced_tabs_sign_in_message) - itemView.no_content_button.text = - itemView.context.getString(R.string.synced_tabs_sign_in_button) - itemView.no_content_button.icon = - ContextCompat.getDrawable(itemView.context, R.drawable.ic_sign_in) - itemView.no_content_button.setOnClickListener { - signInItem.navController.navigate(NavGraphDirections.actionGlobalTurnOnSync()) - } - } - - companion object { - const val LAYOUT_ID = R.layout.no_content_message_with_action - } - } - class ErrorViewHolder(itemView: View) : SyncedTabsViewHolder(itemView) { override fun bind(item: T, interactor: (Tab) -> Unit) { val errorItem = item as AdapterItem.Error setErrorMargins() - itemView.no_content_header.visibility = GONE - itemView.no_content_description.text = itemView.context.getString(errorItem.errorResId) + itemView.sync_tabs_error_description.text = + itemView.context.getString(errorItem.descriptionResId) + itemView.sync_tabs_error_cta_button.visibility = GONE + + errorItem.navController?.let { navController -> + itemView.sync_tabs_error_cta_button.visibility = VISIBLE + itemView.sync_tabs_error_cta_button.setOnClickListener { + navController.navigate(NavGraphDirections.actionGlobalTurnOnSync()) + } + } } companion object { - const val LAYOUT_ID = R.layout.no_content_message + const val LAYOUT_ID = R.layout.sync_tabs_error_row } } @@ -95,7 +80,12 @@ sealed class SyncedTabsViewHolder(itemView: View) : RecyclerView.ViewHolder(item } itemView.synced_tabs_group_name.text = device.device.displayName - itemView.synced_tabs_group_name.setCompoundDrawablesWithIntrinsicBounds(deviceLogoDrawable, 0, 0, 0) + itemView.synced_tabs_group_name.setCompoundDrawablesWithIntrinsicBounds( + deviceLogoDrawable, + 0, + 0, + 0 + ) } companion object { diff --git a/app/src/main/res/layout/sync_tabs_error_row.xml b/app/src/main/res/layout/sync_tabs_error_row.xml new file mode 100644 index 000000000..f9005af30 --- /dev/null +++ b/app/src/main/res/layout/sync_tabs_error_row.xml @@ -0,0 +1,31 @@ + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2e71813b0..1760b7a58 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1464,4 +1464,6 @@ Show search shortcuts Search Engine + + Connect with a Firefox Account.