1
0
Fork 0

For #6313 - Removes unused browser animations, improve delayed paint interactions

master
ekager 2020-08-05 18:33:43 -04:00 committed by Emily Kager
parent d45af2a717
commit 5d664b979d
7 changed files with 58 additions and 88 deletions

View File

@ -554,7 +554,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
BrowserDirection.FromGlobal -> BrowserDirection.FromGlobal ->
NavGraphDirections.actionGlobalBrowser(customTabSessionId) NavGraphDirections.actionGlobalBrowser(customTabSessionId)
BrowserDirection.FromHome -> BrowserDirection.FromHome ->
HomeFragmentDirections.actionHomeFragmentToBrowserFragment(customTabSessionId, true) HomeFragmentDirections.actionGlobalBrowser(customTabSessionId)
BrowserDirection.FromSearch -> BrowserDirection.FromSearch ->
SearchFragmentDirections.actionGlobalBrowser(customTabSessionId) SearchFragmentDirections.actionGlobalBrowser(customTabSessionId)
BrowserDirection.FromSearchDialog -> BrowserDirection.FromSearchDialog ->

View File

@ -198,8 +198,7 @@ class InstalledAddonDetailsFragment : Fragment() {
components.useCases.tabsUseCases.addTab(settingUrl) components.useCases.tabsUseCases.addTab(settingUrl)
} }
InstalledAddonDetailsFragmentDirections InstalledAddonDetailsFragmentDirections.actionGlobalBrowser(null)
.actionGlobalBrowser(null, false)
} else { } else {
InstalledAddonDetailsFragmentDirections InstalledAddonDetailsFragmentDirections
.actionInstalledAddonFragmentToAddonInternalSettingsFragment(addon) .actionInstalledAddonFragmentToAddonInternalSettingsFragment(addon)

View File

@ -204,7 +204,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
engineView = WeakReference(engineView), engineView = WeakReference(engineView),
swipeRefresh = WeakReference(swipeRefresh), swipeRefresh = WeakReference(swipeRefresh),
viewLifecycleScope = WeakReference(viewLifecycleOwner.lifecycleScope), viewLifecycleScope = WeakReference(viewLifecycleOwner.lifecycleScope),
arguments = requireArguments(),
firstContentfulHappened = ::didFirstContentfulHappen firstContentfulHappened = ::didFirstContentfulHappen
).apply { ).apply {
beginAnimateInIfNecessary() beginAnimateInIfNecessary()
@ -586,8 +585,15 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
} }
.ifChanged { it.content.firstContentfulPaint } .ifChanged { it.content.firstContentfulPaint }
.collect { .collect {
engineView?.asView()?.isVisible = val showEngineView =
it.content.firstContentfulPaint || it.content.progress == 100 it.content.firstContentfulPaint || it.content.progress == 100
if (showEngineView) {
engineView?.asView()?.isVisible = true
swipeRefresh.alpha = 1f
} else {
engineView?.asView()?.isVisible = false
}
} }
} }
} }

View File

@ -4,19 +4,14 @@
package org.mozilla.fenix.browser package org.mozilla.fenix.browser
import android.animation.ValueAnimator
import android.content.Context import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.View import android.view.View
import android.view.animation.DecelerateInterpolator
import androidx.core.animation.doOnEnd
import androidx.core.graphics.drawable.toDrawable import androidx.core.graphics.drawable.toDrawable
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.LifecycleCoroutineScope
import androidx.navigation.NavOptions import androidx.navigation.NavOptions
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mozilla.components.concept.engine.EngineView import mozilla.components.concept.engine.EngineView
@ -34,7 +29,6 @@ class BrowserAnimator(
private val engineView: WeakReference<EngineView>, private val engineView: WeakReference<EngineView>,
private val swipeRefresh: WeakReference<View>, private val swipeRefresh: WeakReference<View>,
private val viewLifecycleScope: WeakReference<LifecycleCoroutineScope>, private val viewLifecycleScope: WeakReference<LifecycleCoroutineScope>,
private val arguments: Bundle,
private val firstContentfulHappened: () -> Boolean private val firstContentfulHappened: () -> Boolean
) { ) {
@ -44,46 +38,19 @@ class BrowserAnimator(
private val unwrappedSwipeRefresh: View? private val unwrappedSwipeRefresh: View?
get() = swipeRefresh.get() get() = swipeRefresh.get()
private val browserZoomInValueAnimator = ValueAnimator.ofFloat(0f, END_ANIMATOR_VALUE).apply {
addUpdateListener {
unwrappedSwipeRefresh?.scaleX =
STARTING_XY_SCALE + XY_SCALE_MULTIPLIER * it.animatedFraction
unwrappedSwipeRefresh?.scaleY =
STARTING_XY_SCALE + XY_SCALE_MULTIPLIER * it.animatedFraction
unwrappedSwipeRefresh?.alpha = it.animatedFraction
}
doOnEnd {
if (firstContentfulHappened()) {
unwrappedEngineView?.asView()?.visibility = View.VISIBLE
}
unwrappedSwipeRefresh?.background = null
arguments.putBoolean(SHOULD_ANIMATE_FLAG, false)
}
interpolator = DecelerateInterpolator()
duration = ANIMATION_DURATION
}
/**
* Triggers the *zoom in* browser animation to run if necessary (based on the SHOULD_ANIMATE_FLAG).
* Also removes the flag from the bundle so it is not played on future entries into the fragment.
*/
fun beginAnimateInIfNecessary() { fun beginAnimateInIfNecessary() {
val shouldAnimate = arguments.getBoolean(SHOULD_ANIMATE_FLAG, false) if (unwrappedSwipeRefresh?.context?.settings()?.waitToShowPageUntilFirstPaint == true) {
if (shouldAnimate) { if (firstContentfulHappened()) {
viewLifecycleScope.get()?.launch(Dispatchers.Main) { viewLifecycleScope.get()?.launch {
delay(ANIMATION_DELAY) delay(100)
captureEngineViewAndDrawStatically { unwrappedEngineView?.asView()?.visibility = View.VISIBLE
unwrappedSwipeRefresh?.alpha = 0f unwrappedSwipeRefresh?.background = null
browserZoomInValueAnimator.start() unwrappedSwipeRefresh?.alpha = 1f
} }
} }
} else { } else {
unwrappedSwipeRefresh?.alpha = 1f unwrappedSwipeRefresh?.alpha = 1f
if (firstContentfulHappened()) { unwrappedEngineView?.asView()?.visibility = View.VISIBLE
unwrappedEngineView?.asView()?.visibility = View.VISIBLE
}
unwrappedSwipeRefresh?.background = null unwrappedSwipeRefresh?.background = null
} }
} }
@ -124,13 +91,6 @@ class BrowserAnimator(
} }
companion object { companion object {
private const val SHOULD_ANIMATE_FLAG = "shouldAnimate"
private const val ANIMATION_DELAY = 50L
private const val ANIMATION_DURATION = 115L
private const val END_ANIMATOR_VALUE = 500f
private const val XY_SCALE_MULTIPLIER = .05f
private const val STARTING_XY_SCALE = .95f
fun getToolbarNavOptions(context: Context): NavOptions { fun getToolbarNavOptions(context: Context): NavOptions {
val navOptions = NavOptions.Builder() val navOptions = NavOptions.Builder()

View File

@ -94,18 +94,25 @@ class DefaultBrowserToolbarController(
internal var ioScope: CoroutineScope = CoroutineScope(Dispatchers.IO) internal var ioScope: CoroutineScope = CoroutineScope(Dispatchers.IO)
override fun handleToolbarPaste(text: String) { override fun handleToolbarPaste(text: String) {
val directions = if (useNewSearchExperience) { if (useNewSearchExperience) {
BrowserFragmentDirections.actionGlobalSearchDialog( navController.nav(
sessionId = currentSession?.id, R.id.browserFragment, BrowserFragmentDirections.actionGlobalSearchDialog(
pastedText = text sessionId = currentSession?.id,
pastedText = text
), getToolbarNavOptions(activity)
) )
} else { } else {
BrowserFragmentDirections.actionBrowserFragmentToSearchFragment( browserAnimator.captureEngineViewAndDrawStatically {
sessionId = currentSession?.id, navController.nav(
pastedText = text R.id.browserFragment,
) BrowserFragmentDirections.actionBrowserFragmentToSearchFragment(
sessionId = currentSession?.id,
pastedText = text
),
getToolbarNavOptions(activity)
)
}
} }
navController.nav(R.id.browserFragment, directions, getToolbarNavOptions(activity))
} }
override fun handleToolbarPasteAndGo(text: String) { override fun handleToolbarPasteAndGo(text: String) {
@ -127,17 +134,23 @@ class DefaultBrowserToolbarController(
Event.SearchBarTapped(Event.SearchBarTapped.Source.BROWSER) Event.SearchBarTapped(Event.SearchBarTapped.Source.BROWSER)
) )
val directions = if (useNewSearchExperience) { if (useNewSearchExperience) {
BrowserFragmentDirections.actionGlobalSearchDialog( navController.nav(
currentSession?.id R.id.browserFragment, BrowserFragmentDirections.actionGlobalSearchDialog(
)
} else {
BrowserFragmentDirections.actionBrowserFragmentToSearchFragment(
currentSession?.id currentSession?.id
), getToolbarNavOptions(activity)
)
} else {
browserAnimator.captureEngineViewAndDrawStatically {
navController.nav(
R.id.browserFragment,
BrowserFragmentDirections.actionBrowserFragmentToSearchFragment(
currentSession?.id
),
getToolbarNavOptions(activity)
) )
} }
}
navController.nav(R.id.browserFragment, directions, getToolbarNavOptions(activity))
} }
override fun handleTabCounterClick() { override fun handleTabCounterClick() {
@ -162,7 +175,11 @@ class DefaultBrowserToolbarController(
if (sessionManager.sessionsOfType(it.private).count() == 1) { if (sessionManager.sessionsOfType(it.private).count() == 1) {
// The tab tray always returns to normal mode so do that here too // The tab tray always returns to normal mode so do that here too
activity.browsingModeManager.mode = BrowsingMode.Normal activity.browsingModeManager.mode = BrowsingMode.Normal
navController.navigate(BrowserFragmentDirections.actionGlobalHome(sessionToDelete = it.id)) navController.navigate(
BrowserFragmentDirections.actionGlobalHome(
sessionToDelete = it.id
)
)
} else { } else {
onCloseTab.invoke(it) onCloseTab.invoke(it)
activity.components.useCases.tabsUseCases.removeTab.invoke(it) activity.components.useCases.tabsUseCases.removeTab.invoke(it)
@ -211,7 +228,7 @@ class DefaultBrowserToolbarController(
val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment() val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment()
navController.nav(R.id.browserFragment, directions) navController.nav(R.id.browserFragment, directions)
} }
ToolbarMenu.Item.SyncedTabs -> { ToolbarMenu.Item.SyncedTabs -> browserAnimator.captureEngineViewAndDrawStatically {
navController.nav( navController.nav(
R.id.browserFragment, R.id.browserFragment,
BrowserFragmentDirections.actionBrowserFragmentToSyncedTabsFragment() BrowserFragmentDirections.actionBrowserFragmentToSyncedTabsFragment()
@ -272,7 +289,7 @@ class DefaultBrowserToolbarController(
activity.components.analytics.metrics.track(Event.FindInPageOpened) activity.components.analytics.metrics.track(Event.FindInPageOpened)
} }
ToolbarMenu.Item.AddonsManager -> { ToolbarMenu.Item.AddonsManager -> browserAnimator.captureEngineViewAndDrawStatically {
navController.nav( navController.nav(
R.id.browserFragment, R.id.browserFragment,
BrowserFragmentDirections.actionGlobalAddonsManagementFragment() BrowserFragmentDirections.actionGlobalAddonsManagementFragment()
@ -348,13 +365,13 @@ class DefaultBrowserToolbarController(
bookmarkTapped(it) bookmarkTapped(it)
} }
} }
ToolbarMenu.Item.Bookmarks -> { ToolbarMenu.Item.Bookmarks -> browserAnimator.captureEngineViewAndDrawStatically {
navController.nav( navController.nav(
R.id.browserFragment, R.id.browserFragment,
BrowserFragmentDirections.actionGlobalBookmarkFragment(BookmarkRoot.Mobile.id) BrowserFragmentDirections.actionGlobalBookmarkFragment(BookmarkRoot.Mobile.id)
) )
} }
ToolbarMenu.Item.History -> { ToolbarMenu.Item.History -> browserAnimator.captureEngineViewAndDrawStatically {
navController.nav( navController.nav(
R.id.browserFragment, R.id.browserFragment,
BrowserFragmentDirections.actionGlobalHistoryFragment() BrowserFragmentDirections.actionGlobalHistoryFragment()

View File

@ -478,9 +478,7 @@ class HomeFragment : Fragment() {
engineSessionState = state engineSessionState = state
) )
findNavController().navigate( findNavController().navigate(
HomeFragmentDirections.actionHomeFragmentToBrowserFragment( HomeFragmentDirections.actionGlobalBrowser(null)
null
)
) )
}, },
operation = { }, operation = { },

View File

@ -124,12 +124,6 @@
android:id="@+id/homeFragment" android:id="@+id/homeFragment"
android:name="org.mozilla.fenix.home.HomeFragment" android:name="org.mozilla.fenix.home.HomeFragment"
tools:layout="@layout/fragment_home"> tools:layout="@layout/fragment_home">
<action
android:id="@+id/action_homeFragment_to_browserFragment"
app:destination="@id/browserFragment"
app:exitAnim="@anim/zoom_in_fade"
app:popEnterAnim="@anim/zoom_out_fade" />
<argument <argument
android:name="focusOnAddressBar" android:name="focusOnAddressBar"
android:defaultValue="false" android:defaultValue="false"
@ -202,10 +196,6 @@
android:name="activeSessionId" android:name="activeSessionId"
app:argType="string" app:argType="string"
app:nullable="true" /> app:nullable="true" />
<argument
android:name="shouldAnimate"
android:defaultValue="false"
app:argType="boolean" />
<action <action
android:id="@+id/action_browserFragment_to_syncedTabsFragment" android:id="@+id/action_browserFragment_to_syncedTabsFragment"
app:destination="@id/syncedTabsFragment" /> app:destination="@id/syncedTabsFragment" />