mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-19 09:25:34 +00:00
[fenix] For https://github.com/mozilla-mobile/fenix/issues/10925: Fix breaking APIs in tabs tray
This commit is contained in:
parent
2c08b342e8
commit
312addd8be
@ -28,7 +28,6 @@ import androidx.navigation.NavDirections
|
|||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import androidx.navigation.ui.AppBarConfiguration
|
import androidx.navigation.ui.AppBarConfiguration
|
||||||
import androidx.navigation.ui.NavigationUI
|
import androidx.navigation.ui.NavigationUI
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import kotlinx.android.synthetic.main.activity_home.*
|
import kotlinx.android.synthetic.main.activity_home.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -41,10 +40,7 @@ import mozilla.components.browser.session.SessionManager
|
|||||||
import mozilla.components.browser.state.state.SessionState
|
import mozilla.components.browser.state.state.SessionState
|
||||||
import mozilla.components.browser.state.state.WebExtensionState
|
import mozilla.components.browser.state.state.WebExtensionState
|
||||||
import mozilla.components.browser.state.store.BrowserStore
|
import mozilla.components.browser.state.store.BrowserStore
|
||||||
import mozilla.components.browser.tabstray.BrowserTabsTray
|
|
||||||
import mozilla.components.browser.thumbnails.loader.ThumbnailLoader
|
|
||||||
import mozilla.components.concept.engine.EngineView
|
import mozilla.components.concept.engine.EngineView
|
||||||
import mozilla.components.concept.tabstray.TabsTray
|
|
||||||
import mozilla.components.feature.contextmenu.DefaultSelectionActionDelegate
|
import mozilla.components.feature.contextmenu.DefaultSelectionActionDelegate
|
||||||
import mozilla.components.feature.search.BrowserStoreSearchAdapter
|
import mozilla.components.feature.search.BrowserStoreSearchAdapter
|
||||||
import mozilla.components.feature.search.SearchAdapter
|
import mozilla.components.feature.search.SearchAdapter
|
||||||
@ -97,7 +93,6 @@ import org.mozilla.fenix.settings.search.AddSearchEngineFragmentDirections
|
|||||||
import org.mozilla.fenix.settings.search.EditCustomSearchEngineFragmentDirections
|
import org.mozilla.fenix.settings.search.EditCustomSearchEngineFragmentDirections
|
||||||
import org.mozilla.fenix.share.AddNewDeviceFragmentDirections
|
import org.mozilla.fenix.share.AddNewDeviceFragmentDirections
|
||||||
import org.mozilla.fenix.sync.SyncedTabsFragmentDirections
|
import org.mozilla.fenix.sync.SyncedTabsFragmentDirections
|
||||||
import org.mozilla.fenix.tabtray.FenixTabsAdapter
|
|
||||||
import org.mozilla.fenix.tabtray.TabTrayDialogFragment
|
import org.mozilla.fenix.tabtray.TabTrayDialogFragment
|
||||||
import org.mozilla.fenix.theme.DefaultThemeManager
|
import org.mozilla.fenix.theme.DefaultThemeManager
|
||||||
import org.mozilla.fenix.theme.ThemeManager
|
import org.mozilla.fenix.theme.ThemeManager
|
||||||
@ -315,17 +310,6 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
|||||||
actionSorter = ::actionSorter
|
actionSorter = ::actionSorter
|
||||||
)
|
)
|
||||||
}.asView()
|
}.asView()
|
||||||
TabsTray::class.java.name -> {
|
|
||||||
val layout = LinearLayoutManager(context).apply {
|
|
||||||
reverseLayout = true
|
|
||||||
stackFromEnd = true
|
|
||||||
}
|
|
||||||
|
|
||||||
val thumbnailLoader = ThumbnailLoader(components.core.thumbnailStorage)
|
|
||||||
val adapter = FenixTabsAdapter(context, thumbnailLoader)
|
|
||||||
|
|
||||||
BrowserTabsTray(context, attrs, 0, adapter, layout)
|
|
||||||
}
|
|
||||||
else -> super.onCreateView(parent, name, context, attrs)
|
else -> super.onCreateView(parent, name, context, attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class FenixTabsAdapter(
|
|||||||
context: Context,
|
context: Context,
|
||||||
imageLoader: ImageLoader
|
imageLoader: ImageLoader
|
||||||
) : TabsAdapter(
|
) : TabsAdapter(
|
||||||
viewHolderProvider = { parentView, _ ->
|
viewHolderProvider = { parentView ->
|
||||||
TabTrayViewHolder(
|
TabTrayViewHolder(
|
||||||
LayoutInflater.from(context).inflate(
|
LayoutInflater.from(context).inflate(
|
||||||
R.layout.tab_tray_item,
|
R.layout.tab_tray_item,
|
||||||
|
@ -23,6 +23,7 @@ import kotlinx.android.synthetic.main.fragment_tab_tray_dialog.view.*
|
|||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import mozilla.components.browser.session.Session
|
import mozilla.components.browser.session.Session
|
||||||
import mozilla.components.browser.state.state.TabSessionState
|
import mozilla.components.browser.state.state.TabSessionState
|
||||||
|
import mozilla.components.browser.thumbnails.loader.ThumbnailLoader
|
||||||
import mozilla.components.feature.tab.collections.TabCollection
|
import mozilla.components.feature.tab.collections.TabCollection
|
||||||
import mozilla.components.feature.tabs.TabsUseCases
|
import mozilla.components.feature.tabs.TabsUseCases
|
||||||
import mozilla.components.feature.tabs.tabstray.TabsFeature
|
import mozilla.components.feature.tabs.tabstray.TabsFeature
|
||||||
@ -127,8 +128,12 @@ class TabTrayDialogFragment : AppCompatDialogFragment() {
|
|||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
val isPrivate = (activity as HomeActivity).browsingModeManager.mode.isPrivate
|
val isPrivate = (activity as HomeActivity).browsingModeManager.mode.isPrivate
|
||||||
|
|
||||||
|
val thumbnailLoader = ThumbnailLoader(requireContext().components.core.thumbnailStorage)
|
||||||
|
val adapter = FenixTabsAdapter(requireContext(), thumbnailLoader)
|
||||||
|
|
||||||
_tabTrayView = TabTrayView(
|
_tabTrayView = TabTrayView(
|
||||||
view.tabLayout,
|
view.tabLayout,
|
||||||
|
adapter,
|
||||||
interactor = TabTrayFragmentInteractor(
|
interactor = TabTrayFragmentInteractor(
|
||||||
DefaultTabTrayController(
|
DefaultTabTrayController(
|
||||||
activity = (activity as HomeActivity),
|
activity = (activity as HomeActivity),
|
||||||
@ -152,7 +157,7 @@ class TabTrayDialogFragment : AppCompatDialogFragment() {
|
|||||||
|
|
||||||
tabsFeature.set(
|
tabsFeature.set(
|
||||||
TabsFeature(
|
TabsFeature(
|
||||||
tabTrayView.view.tabsTray,
|
adapter,
|
||||||
view.context.components.core.store,
|
view.context.components.core.store,
|
||||||
selectTabUseCase,
|
selectTabUseCase,
|
||||||
removeTabUseCase,
|
removeTabUseCase,
|
||||||
|
@ -13,6 +13,7 @@ import androidx.cardview.widget.CardView
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.LifecycleCoroutineScope
|
import androidx.lifecycle.LifecycleCoroutineScope
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
import com.google.android.material.tabs.TabLayout
|
import com.google.android.material.tabs.TabLayout
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
@ -29,7 +30,6 @@ import mozilla.components.browser.menu.item.SimpleBrowserMenuItem
|
|||||||
import mozilla.components.browser.state.selector.normalTabs
|
import mozilla.components.browser.state.selector.normalTabs
|
||||||
import mozilla.components.browser.state.selector.privateTabs
|
import mozilla.components.browser.state.selector.privateTabs
|
||||||
import mozilla.components.browser.state.state.BrowserState
|
import mozilla.components.browser.state.state.BrowserState
|
||||||
import mozilla.components.browser.tabstray.BrowserTabsTray
|
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
@ -41,6 +41,7 @@ import org.mozilla.fenix.ext.settings
|
|||||||
@Suppress("LongParameterList", "TooManyFunctions", "LargeClass")
|
@Suppress("LongParameterList", "TooManyFunctions", "LargeClass")
|
||||||
class TabTrayView(
|
class TabTrayView(
|
||||||
private val container: ViewGroup,
|
private val container: ViewGroup,
|
||||||
|
private val tabsAdapter: FenixTabsAdapter,
|
||||||
private val interactor: TabTrayInteractor,
|
private val interactor: TabTrayInteractor,
|
||||||
isPrivate: Boolean,
|
isPrivate: Boolean,
|
||||||
startingInLandscape: Boolean,
|
startingInLandscape: Boolean,
|
||||||
@ -118,12 +119,18 @@ class TabTrayView(
|
|||||||
|
|
||||||
setTopOffset(startingInLandscape)
|
setTopOffset(startingInLandscape)
|
||||||
|
|
||||||
(view.tabsTray as? BrowserTabsTray)?.also { tray ->
|
view.tabsTray.apply {
|
||||||
TabsTouchHelper(tray.tabsAdapter).attachToRecyclerView(tray)
|
layoutManager = LinearLayoutManager(container.context).apply {
|
||||||
(tray.tabsAdapter as? FenixTabsAdapter)?.also { adapter ->
|
reverseLayout = true
|
||||||
adapter.onTabsUpdated = {
|
stackFromEnd = true
|
||||||
|
}
|
||||||
|
adapter = tabsAdapter
|
||||||
|
|
||||||
|
TabsTouchHelper(tabsAdapter).attachToRecyclerView(this)
|
||||||
|
|
||||||
|
tabsAdapter.onTabsUpdated = {
|
||||||
if (hasAccessibilityEnabled) {
|
if (hasAccessibilityEnabled) {
|
||||||
adapter.notifyDataSetChanged()
|
tabsAdapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
if (!hasLoaded) {
|
if (!hasLoaded) {
|
||||||
hasLoaded = true
|
hasLoaded = true
|
||||||
@ -132,9 +139,9 @@ class TabTrayView(
|
|||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
delay(SELECTION_DELAY.toLong())
|
delay(SELECTION_DELAY.toLong())
|
||||||
lifecycleScope.launch(Main) {
|
lifecycleScope.launch(Main) {
|
||||||
tray.layoutManager?.findViewByPosition(selectedBrowserTabIndex)
|
layoutManager?.findViewByPosition(selectedBrowserTabIndex)
|
||||||
?.requestFocus()
|
?.requestFocus()
|
||||||
tray.layoutManager?.findViewByPosition(selectedBrowserTabIndex)
|
layoutManager?.findViewByPosition(selectedBrowserTabIndex)
|
||||||
?.sendAccessibilityEvent(
|
?.sendAccessibilityEvent(
|
||||||
AccessibilityEvent.TYPE_VIEW_FOCUSED
|
AccessibilityEvent.TYPE_VIEW_FOCUSED
|
||||||
)
|
)
|
||||||
@ -144,7 +151,6 @@ class TabTrayView(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
tabTrayItemMenu =
|
tabTrayItemMenu =
|
||||||
TabTrayItemMenu(view.context, { view.tab_layout.selectedTabPosition == 0 }) {
|
TabTrayItemMenu(view.context, { view.tab_layout.selectedTabPosition == 0 }) {
|
||||||
@ -241,7 +247,7 @@ class TabTrayView(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
view.tabsTray.asView().visibility = if (hasNoTabs) {
|
view.tabsTray.visibility = if (hasNoTabs) {
|
||||||
View.INVISIBLE
|
View.INVISIBLE
|
||||||
} else {
|
} else {
|
||||||
View.VISIBLE
|
View.VISIBLE
|
||||||
@ -288,7 +294,7 @@ class TabTrayView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun scrollToTab(sessionId: String?) {
|
fun scrollToTab(sessionId: String?) {
|
||||||
(view.tabsTray as? BrowserTabsTray)?.also { tray ->
|
view.tabsTray.apply {
|
||||||
val tabs = if (isPrivateModeSelected) {
|
val tabs = if (isPrivateModeSelected) {
|
||||||
view.context.components.core.store.state.privateTabs
|
view.context.components.core.store.state.privateTabs
|
||||||
} else {
|
} else {
|
||||||
@ -298,7 +304,7 @@ class TabTrayView(
|
|||||||
val selectedBrowserTabIndex = tabs
|
val selectedBrowserTabIndex = tabs
|
||||||
.indexOfFirst { it.id == sessionId }
|
.indexOfFirst { it.id == sessionId }
|
||||||
|
|
||||||
tray.layoutManager?.scrollToPosition(selectedBrowserTabIndex)
|
layoutManager?.scrollToPosition(selectedBrowserTabIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import androidx.core.content.ContextCompat
|
|||||||
import mozilla.components.browser.state.state.MediaState
|
import mozilla.components.browser.state.state.MediaState
|
||||||
import mozilla.components.browser.state.store.BrowserStore
|
import mozilla.components.browser.state.store.BrowserStore
|
||||||
import mozilla.components.browser.tabstray.TabViewHolder
|
import mozilla.components.browser.tabstray.TabViewHolder
|
||||||
|
import mozilla.components.browser.tabstray.TabsTrayStyling
|
||||||
import mozilla.components.browser.tabstray.thumbnail.TabThumbnailView
|
import mozilla.components.browser.tabstray.thumbnail.TabThumbnailView
|
||||||
import mozilla.components.browser.toolbar.MAX_URI_LENGTH
|
import mozilla.components.browser.toolbar.MAX_URI_LENGTH
|
||||||
import mozilla.components.concept.tabstray.Tab
|
import mozilla.components.concept.tabstray.Tab
|
||||||
@ -64,7 +65,12 @@ class TabTrayViewHolder(
|
|||||||
/**
|
/**
|
||||||
* Displays the data of the given session and notifies the given observable about events.
|
* Displays the data of the given session and notifies the given observable about events.
|
||||||
*/
|
*/
|
||||||
override fun bind(tab: Tab, isSelected: Boolean, observable: Observable<TabsTray.Observer>) {
|
override fun bind(
|
||||||
|
tab: Tab,
|
||||||
|
isSelected: Boolean,
|
||||||
|
styling: TabsTrayStyling,
|
||||||
|
observable: Observable<TabsTray.Observer>
|
||||||
|
) {
|
||||||
// This is a hack to workaround a bug in a-c.
|
// This is a hack to workaround a bug in a-c.
|
||||||
// https://github.com/mozilla-mobile/android-components/issues/7186
|
// https://github.com/mozilla-mobile/android-components/issues/7186
|
||||||
val isSelected2 = tab.id == getSelectedTabId()
|
val isSelected2 = tab.id == getSelectedTabId()
|
||||||
|
@ -105,7 +105,7 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/tab_layout" />
|
app:layout_constraintTop_toBottomOf="@+id/tab_layout" />
|
||||||
|
|
||||||
<mozilla.components.concept.tabstray.TabsTray
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/tabsTray"
|
android:id="@+id/tabsTray"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
@ -115,12 +115,6 @@
|
|||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/divider"
|
app:layout_constraintTop_toBottomOf="@+id/divider" />
|
||||||
mozac:tabsTrayItemBackgroundColor="@color/foundation_normal_theme"
|
|
||||||
mozac:tabsTrayItemTextColor="@color/tab_tray_item_text_normal_theme"
|
|
||||||
mozac:tabsTraySelectedItemBackgroundColor="@color/tab_tray_item_selected_background_normal_theme"
|
|
||||||
mozac:tabsTraySelectedItemTextColor="@color/tab_tray_item_selected_background_normal_theme"
|
|
||||||
mozac:tabsTrayItemUrlTextColor="@color/tab_tray_item_selected_background_normal_theme"
|
|
||||||
mozac:tabsTraySelectedItemUrlTextColor="@color/tab_tray_item_url_normal_theme" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
@ -59,7 +59,7 @@ class TabTrayViewHolderTest {
|
|||||||
id = "123",
|
id = "123",
|
||||||
url = extremelyLongUrl
|
url = extremelyLongUrl
|
||||||
)
|
)
|
||||||
tabViewHolder.bind(tab, false, mockk())
|
tabViewHolder.bind(tab, false, mockk(), mockk())
|
||||||
|
|
||||||
assertEquals("m".repeat(MAX_URI_LENGTH), tabViewHolder.urlView?.text)
|
assertEquals("m".repeat(MAX_URI_LENGTH), tabViewHolder.urlView?.text)
|
||||||
verify { imageLoader.loadIntoView(any(), ImageLoadRequest("123", 92)) }
|
verify { imageLoader.loadIntoView(any(), ImageLoadRequest("123", 92)) }
|
||||||
@ -82,7 +82,7 @@ class TabTrayViewHolderTest {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
tabViewHolder.bind(tab, false, mockk())
|
tabViewHolder.bind(tab, false, mockk(), mockk())
|
||||||
|
|
||||||
assertEquals("Play", playPauseButtonView.contentDescription)
|
assertEquals("Play", playPauseButtonView.contentDescription)
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ class TabTrayViewHolderTest {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
tabViewHolder.bind(tab, false, mockk())
|
tabViewHolder.bind(tab, false, mockk(), mockk())
|
||||||
|
|
||||||
assertEquals("Pause", playPauseButtonView.contentDescription)
|
assertEquals("Pause", playPauseButtonView.contentDescription)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user