For #11498 - removed SignIn ViewHolder and unified with the Error one
This commit is contained in:
parent
5d1aeb5ea7
commit
ff50dae8e9
|
@ -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<SyncedDeviceTabs>) {
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<SyncedTabsFragment>().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<SyncedTabsAdapter.AdapterItem> = 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<SyncedDeviceTabs>) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <T : AdapterItem> 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 <T : AdapterItem> 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 {
|
||||
|
|
31
app/src/main/res/layout/sync_tabs_error_row.xml
Normal file
31
app/src/main/res/layout/sync_tabs_error_row.xml
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:background="@drawable/empty_session_control_background"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:padding="16dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sync_tabs_error_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textSize="14sp"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="@string/synced_tabs_no_tabs"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/sync_tabs_error_cta_button"
|
||||
style="@style/PositiveButton"
|
||||
app:icon="@drawable/ic_sign_in"
|
||||
android:visibility="gone"
|
||||
android:text="@string/synced_tabs_sign_in_button"
|
||||
android:layout_marginTop="8dp"/>
|
||||
</LinearLayout>
|
|
@ -1464,4 +1464,6 @@
|
|||
<string name="preferences_show_search_shortcuts">Show search shortcuts</string>
|
||||
<!-- DEPRECATED: Button in the search view that lets a user search by using a shortcut -->
|
||||
<string name="search_engines_shortcut_button">Search Engine</string>
|
||||
<!-- DEPRECATED: Text displayed when user is not logged into a Firefox Account -->
|
||||
<string name="synced_tabs_connect_to_sync_account">Connect with a Firefox Account.</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue
Block a user