diff --git a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsTitleDecoration.kt b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsTitleDecoration.kt new file mode 100644 index 000000000..13722a915 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsTitleDecoration.kt @@ -0,0 +1,77 @@ +/* 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/. */ + +package org.mozilla.fenix.sync + +import android.content.Context +import android.graphics.Canvas +import android.graphics.Rect +import android.graphics.drawable.Drawable +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.RecyclerView.ItemDecoration +import mozilla.components.support.ktx.android.util.dpToPx +import org.mozilla.fenix.R +import org.mozilla.fenix.sync.SyncedTabsViewHolder.DeviceViewHolder + +/** + * Adds an [ItemDecoration] to the device name of each Synced Tab group. + */ +class SyncedTabsTitleDecoration( + context: Context, + private val style: Style = Style( + height = 1.dpToPx(context.resources.displayMetrics), + color = run { + val a = context.obtainStyledAttributes(intArrayOf(R.attr.toolbarDivider)) + val color = a.getDrawable(0)!! + a.recycle() + color + } + ) +) : ItemDecoration() { + + /** + * A class for holding various customizations. + */ + data class Style(val height: Int, val color: Drawable) + + override fun getItemOffsets( + outRect: Rect, + view: View, + parent: RecyclerView, + state: RecyclerView.State + ) { + val viewHolder = parent.getChildViewHolder(view) + val position = viewHolder.bindingAdapterPosition + val viewType = viewHolder.itemViewType + + // Only add offsets on the device title that is not the first. + if (viewType == DeviceViewHolder.LAYOUT_ID && position != 0) { + outRect.set(0, style.height, 0, 0) + return + } + + outRect.setEmpty() + } + + override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { + for (i in 0 until parent.childCount) { + val view = parent.getChildAt(i) + val viewHolder = parent.getChildViewHolder(view) + val position = viewHolder.bindingAdapterPosition + val viewType = viewHolder.itemViewType + + // Only draw on the device title that is not the first. + if (viewType == DeviceViewHolder.LAYOUT_ID && position != 0) { + style.color.setBounds( + view.left, + view.top - style.height, + view.right, + view.top + ) + style.color.draw(c) + } + } + } +} 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 3b45a1e66..7bee7accd 100644 --- a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsViewHolder.kt @@ -9,17 +9,18 @@ import android.view.View.GONE import android.view.View.VISIBLE import android.view.animation.Animation import android.view.animation.AnimationUtils -import android.widget.LinearLayout import androidx.recyclerview.widget.RecyclerView 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 kotlinx.android.synthetic.main.view_synced_tabs_title.view.* -import mozilla.components.concept.sync.DeviceType +import mozilla.components.browser.toolbar.MAX_URI_LENGTH import mozilla.components.feature.syncedtabs.view.SyncedTabsView import org.mozilla.fenix.NavGraphDirections import org.mozilla.fenix.R +import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph +import org.mozilla.fenix.ext.toShortUrl import org.mozilla.fenix.sync.SyncedTabsAdapter.AdapterItem /** @@ -44,6 +45,8 @@ sealed class SyncedTabsViewHolder(itemView: View) : RecyclerView.ViewHolder(item val active = tab.tab.active() itemView.synced_tab_item_title.text = active.title itemView.synced_tab_item_url.text = active.url + .toShortUrl(itemView.context.components.publicSuffixList) + .take(MAX_URI_LENGTH) } companion object { @@ -55,7 +58,6 @@ sealed class SyncedTabsViewHolder(itemView: View) : RecyclerView.ViewHolder(item override fun bind(item: T, interactor: SyncedTabsView.Listener) { val errorItem = item as AdapterItem.Error - setErrorMargins() itemView.sync_tabs_error_description.text = itemView.context.getString(errorItem.descriptionResId) @@ -81,18 +83,7 @@ sealed class SyncedTabsViewHolder(itemView: View) : RecyclerView.ViewHolder(item } private fun bindHeader(device: AdapterItem.Device) { - val deviceLogoDrawable = when (device.device.deviceType) { - DeviceType.DESKTOP -> R.drawable.mozac_ic_device_desktop - else -> R.drawable.mozac_ic_device_mobile - } - itemView.synced_tabs_group_name.text = device.device.displayName - itemView.synced_tabs_group_name.setCompoundDrawablesRelativeWithIntrinsicBounds( - deviceLogoDrawable, - 0, - 0, - 0 - ) } companion object { @@ -129,14 +120,4 @@ sealed class SyncedTabsViewHolder(itemView: View) : RecyclerView.ViewHolder(item const val LAYOUT_ID = R.layout.view_synced_tabs_title } } - - internal fun setErrorMargins() { - val lp = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT - ) - val margin = itemView.resources.getDimensionPixelSize(R.dimen.synced_tabs_error_margin) - lp.setMargins(margin, margin, margin, 0) - itemView.layoutParams = lp - } } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsTrayLayout.kt b/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsTrayLayout.kt index 5314fd7aa..f5e4002b1 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsTrayLayout.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsTrayLayout.kt @@ -22,6 +22,7 @@ import mozilla.components.support.base.observer.Observable import mozilla.components.support.base.observer.ObserverRegistry import org.mozilla.fenix.ext.components import org.mozilla.fenix.sync.SyncedTabsAdapter +import org.mozilla.fenix.sync.SyncedTabsTitleDecoration import org.mozilla.fenix.sync.ext.toAdapterItem import org.mozilla.fenix.sync.ext.toStringRes import org.mozilla.fenix.tabstray.TabsTrayAction @@ -64,6 +65,12 @@ class SyncedTabsTrayLayout @JvmOverloads constructor( override var listener: SyncedTabsView.Listener? = null + override fun onFinishInflate() { + synced_tabs_list.addItemDecoration(SyncedTabsTitleDecoration(context)) + + super.onFinishInflate() + } + override fun displaySyncedTabs(syncedTabs: List) { coroutineScope.launch { (synced_tabs_list.adapter as SyncedTabsAdapter).updateData(syncedTabs) diff --git a/app/src/main/res/layout/component_sync_tabs_tray_layout.xml b/app/src/main/res/layout/component_sync_tabs_tray_layout.xml index 451b9a780..f325e8548 100644 --- a/app/src/main/res/layout/component_sync_tabs_tray_layout.xml +++ b/app/src/main/res/layout/component_sync_tabs_tray_layout.xml @@ -4,21 +4,10 @@ - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - @@ -16,8 +16,8 @@ android:id="@+id/synced_tab_item_title" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="72dp" - android:layout_marginEnd="48dp" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" android:singleLine="true" android:textAlignment="viewStart" android:textColor="@color/primary_text_normal_theme" @@ -31,8 +31,8 @@ android:id="@+id/synced_tab_item_url" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="72dp" - android:layout_marginEnd="48dp" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" android:layout_marginTop="2dp" android:singleLine="true" android:textAlignment="viewStart" diff --git a/app/src/main/res/layout/view_synced_tabs_group.xml b/app/src/main/res/layout/view_synced_tabs_group.xml index 91abefcc5..987ce8df7 100644 --- a/app/src/main/res/layout/view_synced_tabs_group.xml +++ b/app/src/main/res/layout/view_synced_tabs_group.xml @@ -8,36 +8,24 @@ android:id="@+id/synced_tabs_group" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="8dp"> + android:paddingStart="16dp" + android:paddingEnd="8dp" + android:paddingTop="16dp" + android:paddingBottom="7dp"> - - diff --git a/app/src/main/res/layout/view_synced_tabs_no_item.xml b/app/src/main/res/layout/view_synced_tabs_no_item.xml index 362e45190..521c832ab 100644 --- a/app/src/main/res/layout/view_synced_tabs_no_item.xml +++ b/app/src/main/res/layout/view_synced_tabs_no_item.xml @@ -5,13 +5,13 @@ + android:paddingBottom="7dp">