Closes #4602 - Add back transitions
parent
4566bd6fba
commit
0b98d43c23
|
@ -16,6 +16,7 @@ import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.NavHostFragment.findNavController
|
import androidx.navigation.fragment.NavHostFragment.findNavController
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import androidx.transition.TransitionInflater
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import kotlinx.android.synthetic.main.component_search.*
|
import kotlinx.android.synthetic.main.component_search.*
|
||||||
import kotlinx.android.synthetic.main.fragment_browser.view.*
|
import kotlinx.android.synthetic.main.fragment_browser.view.*
|
||||||
|
@ -66,19 +67,21 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
|
||||||
private val customTabsIntegration = ViewBoundFeatureWrapper<CustomTabsIntegration>()
|
private val customTabsIntegration = ViewBoundFeatureWrapper<CustomTabsIntegration>()
|
||||||
private var findBookmarkJob: Job? = null
|
private var findBookmarkJob: Job? = null
|
||||||
|
|
||||||
/*
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
// Disabled while awaiting a better solution to #3209
|
|
||||||
postponeEnterTransition()
|
postponeEnterTransition()
|
||||||
sharedElementEnterTransition =
|
sharedElementEnterTransition =
|
||||||
TransitionInflater.from(context).inflateTransition(android.R.transition.move).setDuration(
|
TransitionInflater.from(context).inflateTransition(android.R.transition.move)
|
||||||
SHARED_TRANSITION_MS
|
.setDuration(
|
||||||
)
|
SHARED_TRANSITION_MS
|
||||||
|
)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
val view = super.onCreateView(inflater, container, savedInstanceState)
|
val view = super.onCreateView(inflater, container, savedInstanceState)
|
||||||
view.browserLayout.transitionName = "$TAB_ITEM_TRANSITION_NAME${getSessionById()?.id}"
|
view.browserLayout.transitionName = "$TAB_ITEM_TRANSITION_NAME${getSessionById()?.id}"
|
||||||
|
|
||||||
|
@ -96,7 +99,8 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
|
||||||
val sessionManager = requireComponents.core.sessionManager
|
val sessionManager = requireComponents.core.sessionManager
|
||||||
|
|
||||||
getSessionById()?.let {
|
getSessionById()?.let {
|
||||||
quickActionSheetView = QuickActionSheetView(view.nestedScrollQuickAction, browserInteractor)
|
quickActionSheetView =
|
||||||
|
QuickActionSheetView(view.nestedScrollQuickAction, browserInteractor)
|
||||||
|
|
||||||
customTabSessionId?.let { customTabSessionId ->
|
customTabSessionId?.let { customTabSessionId ->
|
||||||
customTabsIntegration.set(
|
customTabsIntegration.set(
|
||||||
|
@ -137,13 +141,17 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
|
||||||
requireComponents.core.sessionManager,
|
requireComponents.core.sessionManager,
|
||||||
view.readerViewControlsBar
|
view.readerViewControlsBar
|
||||||
) { available ->
|
) { available ->
|
||||||
if (available) { requireComponents.analytics.metrics.track(Event.ReaderModeAvailable) }
|
if (available) {
|
||||||
|
requireComponents.analytics.metrics.track(Event.ReaderModeAvailable)
|
||||||
|
}
|
||||||
|
|
||||||
browserStore.apply {
|
browserStore.apply {
|
||||||
dispatch(QuickActionSheetAction.ReadableStateChange(available))
|
dispatch(QuickActionSheetAction.ReadableStateChange(available))
|
||||||
dispatch(QuickActionSheetAction.ReaderActiveStateChange(
|
dispatch(
|
||||||
sessionManager.selectedSession?.readerMode ?: false
|
QuickActionSheetAction.ReaderActiveStateChange(
|
||||||
))
|
sessionManager.selectedSession?.readerMode ?: false
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
owner = this,
|
owner = this,
|
||||||
|
@ -183,7 +191,9 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
|
||||||
if (customTabsIntegration.onBackPressed()) return true
|
if (customTabsIntegration.onBackPressed()) return true
|
||||||
|
|
||||||
getSessionById()?.let { session ->
|
getSessionById()?.let { session ->
|
||||||
if (session.source == Session.Source.ACTION_VIEW) requireComponents.core.sessionManager.remove(session)
|
if (session.source == Session.Source.ACTION_VIEW) requireComponents.core.sessionManager.remove(
|
||||||
|
session
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -198,7 +208,8 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
|
||||||
quickActionSheetController = DefaultQuickActionSheetController(
|
quickActionSheetController = DefaultQuickActionSheetController(
|
||||||
context = context!!,
|
context = context!!,
|
||||||
navController = findNavController(),
|
navController = findNavController(),
|
||||||
currentSession = getSessionById() ?: requireComponents.core.sessionManager.selectedSessionOrThrow,
|
currentSession = getSessionById()
|
||||||
|
?: requireComponents.core.sessionManager.selectedSessionOrThrow,
|
||||||
appLinksUseCases = requireComponents.useCases.appLinksUseCases,
|
appLinksUseCases = requireComponents.useCases.appLinksUseCases,
|
||||||
bookmarkTapped = {
|
bookmarkTapped = {
|
||||||
lifecycleScope.launch { bookmarkTapped(it) }
|
lifecycleScope.launch { bookmarkTapped(it) }
|
||||||
|
@ -214,7 +225,8 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
|
||||||
return if (customTabSessionId != null) Pair(toolbarSize, 0) else Pair(0, toolbarAndQASSize)
|
return if (customTabSessionId != null) Pair(toolbarSize, 0) else Pair(0, toolbarAndQASSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAppropriateLayoutGravity() = if (customTabSessionId != null) Gravity.TOP else Gravity.BOTTOM
|
override fun getAppropriateLayoutGravity() =
|
||||||
|
if (customTabSessionId != null) Gravity.TOP else Gravity.BOTTOM
|
||||||
|
|
||||||
private fun themeReaderViewControlsForPrivateMode(view: View) = with(view) {
|
private fun themeReaderViewControlsForPrivateMode(view: View) = with(view) {
|
||||||
listOf(
|
listOf(
|
||||||
|
@ -223,7 +235,12 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
|
||||||
).map {
|
).map {
|
||||||
findViewById<Button>(it)
|
findViewById<Button>(it)
|
||||||
}.forEach {
|
}.forEach {
|
||||||
it.setTextColor(ContextCompat.getColorStateList(context, R.color.readerview_private_button_color))
|
it.setTextColor(
|
||||||
|
ContextCompat.getColorStateList(
|
||||||
|
context,
|
||||||
|
R.color.readerview_private_button_color
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
listOf(
|
listOf(
|
||||||
|
@ -232,13 +249,19 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
|
||||||
).map {
|
).map {
|
||||||
findViewById<RadioButton>(it)
|
findViewById<RadioButton>(it)
|
||||||
}.forEach {
|
}.forEach {
|
||||||
it.setTextColor(ContextCompat.getColorStateList(context, R.color.readerview_private_radio_color))
|
it.setTextColor(
|
||||||
|
ContextCompat.getColorStateList(
|
||||||
|
context,
|
||||||
|
R.color.readerview_private_radio_color
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun bookmarkTapped(session: Session) = withContext(IO) {
|
private suspend fun bookmarkTapped(session: Session) = withContext(IO) {
|
||||||
val bookmarksStorage = requireComponents.core.bookmarksStorage
|
val bookmarksStorage = requireComponents.core.bookmarksStorage
|
||||||
val existing = bookmarksStorage.getBookmarksWithUrl(session.url).firstOrNull { it.url == session.url }
|
val existing =
|
||||||
|
bookmarksStorage.getBookmarksWithUrl(session.url).firstOrNull { it.url == session.url }
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
// Bookmark exists, go to edit fragment
|
// Bookmark exists, go to edit fragment
|
||||||
withContext(Main) {
|
withContext(Main) {
|
||||||
|
@ -268,7 +291,9 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
|
||||||
.setAction(getString(R.string.edit_bookmark_snackbar_action)) {
|
.setAction(getString(R.string.edit_bookmark_snackbar_action)) {
|
||||||
nav(
|
nav(
|
||||||
R.id.browserFragment,
|
R.id.browserFragment,
|
||||||
BrowserFragmentDirections.actionBrowserFragmentToBookmarkEditFragment(guid)
|
BrowserFragmentDirections.actionBrowserFragmentToBookmarkEditFragment(
|
||||||
|
guid
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.setText(getString(R.string.bookmark_saved_snackbar))
|
.setText(getString(R.string.bookmark_saved_snackbar))
|
||||||
|
@ -281,7 +306,11 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
|
||||||
private fun subscribeToTabCollections() {
|
private fun subscribeToTabCollections() {
|
||||||
requireComponents.core.tabCollectionStorage.getCollections().observe(this, Observer {
|
requireComponents.core.tabCollectionStorage.getCollections().observe(this, Observer {
|
||||||
requireComponents.core.tabCollectionStorage.cachedTabCollections = it
|
requireComponents.core.tabCollectionStorage.cachedTabCollections = it
|
||||||
getManagedEmitter<SessionControlChange>().onNext(SessionControlChange.CollectionsChange(it))
|
getManagedEmitter<SessionControlChange>().onNext(
|
||||||
|
SessionControlChange.CollectionsChange(
|
||||||
|
it
|
||||||
|
)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,7 @@ class BrowserToolbarView(
|
||||||
toolbarIntegration = ToolbarIntegration(
|
toolbarIntegration = ToolbarIntegration(
|
||||||
this,
|
this,
|
||||||
view,
|
view,
|
||||||
|
container,
|
||||||
menuToolbar,
|
menuToolbar,
|
||||||
ShippedDomainsProvider().also { it.initialize(this) },
|
ShippedDomainsProvider().also { it.initialize(this) },
|
||||||
components.core.historyStorage,
|
components.core.historyStorage,
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
package org.mozilla.fenix.components.toolbar
|
package org.mozilla.fenix.components.toolbar
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.view.ViewGroup
|
||||||
import androidx.navigation.NavOptions
|
import androidx.navigation.NavOptions
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
|
import androidx.navigation.fragment.FragmentNavigator
|
||||||
import mozilla.components.browser.domains.autocomplete.DomainAutocompleteProvider
|
import mozilla.components.browser.domains.autocomplete.DomainAutocompleteProvider
|
||||||
import mozilla.components.browser.session.SessionManager
|
import mozilla.components.browser.session.SessionManager
|
||||||
import mozilla.components.browser.session.runWithSession
|
import mozilla.components.browser.session.runWithSession
|
||||||
|
@ -27,6 +29,7 @@ import org.mozilla.fenix.utils.Settings
|
||||||
class ToolbarIntegration(
|
class ToolbarIntegration(
|
||||||
context: Context,
|
context: Context,
|
||||||
toolbar: BrowserToolbar,
|
toolbar: BrowserToolbar,
|
||||||
|
browserLayout: ViewGroup,
|
||||||
toolbarMenu: ToolbarMenu,
|
toolbarMenu: ToolbarMenu,
|
||||||
domainAutocompleteProvider: DomainAutocompleteProvider,
|
domainAutocompleteProvider: DomainAutocompleteProvider,
|
||||||
historyStorage: HistoryStorage,
|
historyStorage: HistoryStorage,
|
||||||
|
@ -57,15 +60,13 @@ class ToolbarIntegration(
|
||||||
// We need to dynamically add the options here because if you do it in XML it overwrites
|
// We need to dynamically add the options here because if you do it in XML it overwrites
|
||||||
val options = NavOptions.Builder().setPopUpTo(R.id.nav_graph, false)
|
val options = NavOptions.Builder().setPopUpTo(R.id.nav_graph, false)
|
||||||
.setEnterAnim(R.anim.fade_in).build()
|
.setEnterAnim(R.anim.fade_in).build()
|
||||||
val extras = null
|
val extras =
|
||||||
// Disabled while awaiting a better solution to #3209
|
FragmentNavigator.Extras.Builder()
|
||||||
// val extras =
|
.addSharedElement(
|
||||||
// FragmentNavigator.Extras.Builder()
|
browserLayout,
|
||||||
// .addSharedElement(
|
"$TAB_ITEM_TRANSITION_NAME${sessionManager.selectedSession?.id}"
|
||||||
// browserLayout,
|
)
|
||||||
// "$TAB_ITEM_TRANSITION_NAME${sessionManager.selectedSession?.id}"
|
.build()
|
||||||
// )
|
|
||||||
// .build()
|
|
||||||
val navController = Navigation.findNavController(toolbar)
|
val navController = Navigation.findNavController(toolbar)
|
||||||
if (!navController.popBackStack(
|
if (!navController.popBackStack(
|
||||||
R.id.homeFragment,
|
R.id.homeFragment,
|
||||||
|
@ -104,7 +105,8 @@ class ToolbarIntegration(
|
||||||
ThemeManager.resolveAttribute(R.attr.primaryText, context), renderStyle = renderStyle
|
ThemeManager.resolveAttribute(R.attr.primaryText, context), renderStyle = renderStyle
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
private var menuPresenter = MenuPresenter(toolbar, context.components.core.sessionManager, sessionId)
|
private var menuPresenter =
|
||||||
|
MenuPresenter(toolbar, context.components.core.sessionManager, sessionId)
|
||||||
|
|
||||||
override fun start() {
|
override fun start() {
|
||||||
menuPresenter.start()
|
menuPresenter.start()
|
||||||
|
|
|
@ -25,10 +25,12 @@ import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.OnLifecycleEvent
|
import androidx.lifecycle.OnLifecycleEvent
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.fragment.FragmentNavigator
|
||||||
import androidx.navigation.fragment.NavHostFragment.findNavController
|
import androidx.navigation.fragment.NavHostFragment.findNavController
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
|
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
|
||||||
|
import androidx.transition.TransitionInflater
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import kotlinx.android.synthetic.main.fragment_home.*
|
import kotlinx.android.synthetic.main.fragment_home.*
|
||||||
import kotlinx.android.synthetic.main.fragment_home.view.*
|
import kotlinx.android.synthetic.main.fragment_home.view.*
|
||||||
|
@ -114,8 +116,10 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
delay(ANIM_SCROLL_DELAY)
|
delay(ANIM_SCROLL_DELAY)
|
||||||
restoreLayoutState()
|
restoreLayoutState()
|
||||||
// startPostponedEnterTransition()
|
startPostponedEnterTransition()
|
||||||
}.invokeOnCompletion { sessionControlComponent.view.viewTreeObserver.removeOnPreDrawListener(this) }
|
}.invokeOnCompletion {
|
||||||
|
sessionControlComponent.view.viewTreeObserver.removeOnPreDrawListener(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -136,10 +140,10 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
// Disabled while awaiting a better solution to #3209
|
postponeEnterTransition()
|
||||||
// postponeEnterTransition()
|
sharedElementEnterTransition =
|
||||||
// sharedElementEnterTransition = TransitionInflater.from(context).inflateTransition(android.R.transition.move)
|
TransitionInflater.from(context).inflateTransition(android.R.transition.move)
|
||||||
// .setDuration(SHARED_TRANSITION_MS)
|
.setDuration(SHARED_TRANSITION_MS)
|
||||||
|
|
||||||
val sessionObserver = BrowserSessionsObserver(sessionManager, singleSessionObserver) {
|
val sessionObserver = BrowserSessionsObserver(sessionManager, singleSessionObserver) {
|
||||||
emitSessionChanges()
|
emitSessionChanges()
|
||||||
|
@ -189,12 +193,11 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// postponeEnterTransition()
|
|
||||||
|
|
||||||
ActionBusFactory.get(this).logMergedObservables()
|
ActionBusFactory.get(this).logMergedObservables()
|
||||||
val activity = activity as HomeActivity
|
val activity = activity as HomeActivity
|
||||||
ThemeManager.applyStatusBarTheme(activity.window, activity.themeManager, activity)
|
ThemeManager.applyStatusBarTheme(activity.window, activity.themeManager, activity)
|
||||||
|
|
||||||
|
postponeEnterTransition()
|
||||||
sessionControlComponent.view.viewTreeObserver.addOnPreDrawListener(preDrawListener)
|
sessionControlComponent.view.viewTreeObserver.addOnPreDrawListener(preDrawListener)
|
||||||
|
|
||||||
return view
|
return view
|
||||||
|
@ -208,9 +211,7 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
homeViewModel?.layoutManagerState?.also { parcelable ->
|
homeViewModel?.layoutManagerState?.also { parcelable ->
|
||||||
sessionControlComponent.view.layoutManager?.onRestoreInstanceState(parcelable)
|
sessionControlComponent.view.layoutManager?.onRestoreInstanceState(parcelable)
|
||||||
}
|
}
|
||||||
val progress = homeViewModel?.motionLayoutProgress
|
homeLayout?.progress = homeViewModel?.motionLayoutProgress ?: 0F
|
||||||
homeLayout?.progress =
|
|
||||||
if (progress ?: 0F > MOTION_LAYOUT_PROGRESS_ROUND_POINT) 1.0f else 0f
|
|
||||||
homeViewModel?.layoutManagerState = null
|
homeViewModel?.layoutManagerState = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +224,8 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
val iconSize = resources.getDimension(R.dimen.preference_icon_drawable_size).toInt()
|
val iconSize = resources.getDimension(R.dimen.preference_icon_drawable_size).toInt()
|
||||||
|
|
||||||
val searchEngine = requireComponents.search.searchEngineManager.getDefaultSearchEngine(requireContext())
|
val searchEngine =
|
||||||
|
requireComponents.search.searchEngineManager.getDefaultSearchEngine(requireContext())
|
||||||
val searchIcon = BitmapDrawable(resources, searchEngine.icon)
|
val searchIcon = BitmapDrawable(resources, searchEngine.icon)
|
||||||
searchIcon.setBounds(0, 0, iconSize, iconSize)
|
searchIcon.setBounds(0, 0, iconSize, iconSize)
|
||||||
|
|
||||||
|
@ -244,13 +246,11 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
invokePendingDeleteJobs()
|
invokePendingDeleteJobs()
|
||||||
onboarding.finish()
|
onboarding.finish()
|
||||||
val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null)
|
val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null)
|
||||||
// Disabled while awaiting a better solution to #3209
|
val extras =
|
||||||
// val extras =
|
FragmentNavigator.Extras.Builder()
|
||||||
// FragmentNavigator.Extras.Builder()
|
.addSharedElement(toolbar_wrapper, "toolbar_wrapper_transition")
|
||||||
// .addSharedElement(toolbar_wrapper, "toolbar_wrapper_transition")
|
.build()
|
||||||
// .build()
|
nav(R.id.homeFragment, directions, extras)
|
||||||
// nav(R.id.homeFragment, directions, extras)
|
|
||||||
nav(R.id.homeFragment, directions)
|
|
||||||
requireComponents.analytics.metrics.track(Event.SearchBarTapped(Event.SearchBarTapped.Source.HOME))
|
requireComponents.analytics.metrics.track(Event.SearchBarTapped(Event.SearchBarTapped.Source.HOME))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,8 +268,13 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onboarding.userHasBeenOnboarded()) {
|
if (onboarding.userHasBeenOnboarded()) {
|
||||||
val mode = if (newMode == BrowsingModeManager.Mode.Private) Mode.Private else Mode.Normal
|
val mode =
|
||||||
getManagedEmitter<SessionControlChange>().onNext(SessionControlChange.ModeChange(mode))
|
if (newMode == BrowsingModeManager.Mode.Private) Mode.Private else Mode.Normal
|
||||||
|
getManagedEmitter<SessionControlChange>().onNext(
|
||||||
|
SessionControlChange.ModeChange(
|
||||||
|
mode
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
browsingModeManager.mode = newMode
|
browsingModeManager.mode = newMode
|
||||||
|
@ -324,7 +329,11 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
onboarding.finish()
|
onboarding.finish()
|
||||||
|
|
||||||
val mode = currentMode(context!!)
|
val mode = currentMode(context!!)
|
||||||
getManagedEmitter<SessionControlChange>().onNext(SessionControlChange.ModeChange(mode))
|
getManagedEmitter<SessionControlChange>().onNext(
|
||||||
|
SessionControlChange.ModeChange(
|
||||||
|
mode
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,13 +353,14 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
val session = sessionManager.findSessionById(action.sessionId)
|
val session = sessionManager.findSessionById(action.sessionId)
|
||||||
sessionManager.select(session!!)
|
sessionManager.select(session!!)
|
||||||
val directions = HomeFragmentDirections.actionHomeFragmentToBrowserFragment(null)
|
val directions = HomeFragmentDirections.actionHomeFragmentToBrowserFragment(null)
|
||||||
// Disabled while awaiting a better solution to #3209
|
val extras =
|
||||||
// val extras =
|
FragmentNavigator.Extras.Builder()
|
||||||
// FragmentNavigator.Extras.Builder()
|
.addSharedElement(
|
||||||
// .addSharedElement(action.tabView, "$TAB_ITEM_TRANSITION_NAME${action.sessionId}")
|
action.tabView,
|
||||||
// .build()
|
"$TAB_ITEM_TRANSITION_NAME${action.sessionId}"
|
||||||
// nav(R.id.homeFragment, directions, extras)
|
)
|
||||||
nav(R.id.homeFragment, directions)
|
.build()
|
||||||
|
nav(R.id.homeFragment, directions, extras)
|
||||||
}
|
}
|
||||||
is TabAction.Close -> {
|
is TabAction.Close -> {
|
||||||
if (pendingSessionDeletion?.deletionJob == null) {
|
if (pendingSessionDeletion?.deletionJob == null) {
|
||||||
|
@ -430,7 +440,8 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
private fun createDeleteCollectionPrompt(tabCollection: TabCollection) {
|
private fun createDeleteCollectionPrompt(tabCollection: TabCollection) {
|
||||||
context?.let {
|
context?.let {
|
||||||
AlertDialog.Builder(it).apply {
|
AlertDialog.Builder(it).apply {
|
||||||
val message = context.getString(R.string.tab_collection_dialog_message, tabCollection.title)
|
val message =
|
||||||
|
context.getString(R.string.tab_collection_dialog_message, tabCollection.title)
|
||||||
setMessage(message)
|
setMessage(message)
|
||||||
setNegativeButton(R.string.tab_collection_dialog_negative) { dialog: DialogInterface, _ ->
|
setNegativeButton(R.string.tab_collection_dialog_negative) { dialog: DialogInterface, _ ->
|
||||||
dialog.cancel()
|
dialog.cancel()
|
||||||
|
@ -531,7 +542,10 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
}
|
}
|
||||||
is CollectionAction.RemoveTab -> {
|
is CollectionAction.RemoveTab -> {
|
||||||
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
requireComponents.core.tabCollectionStorage.removeTabFromCollection(action.collection, action.tab)
|
requireComponents.core.tabCollectionStorage.removeTabFromCollection(
|
||||||
|
action.collection,
|
||||||
|
action.tab
|
||||||
|
)
|
||||||
}
|
}
|
||||||
requireComponents.analytics.metrics.track(Event.CollectionTabRemoved)
|
requireComponents.analytics.metrics.track(Event.CollectionTabRemoved)
|
||||||
}
|
}
|
||||||
|
@ -594,7 +608,11 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
private fun subscribeToTabCollections(): Observer<List<TabCollection>> {
|
private fun subscribeToTabCollections(): Observer<List<TabCollection>> {
|
||||||
return Observer<List<TabCollection>> {
|
return Observer<List<TabCollection>> {
|
||||||
requireComponents.core.tabCollectionStorage.cachedTabCollections = it
|
requireComponents.core.tabCollectionStorage.cachedTabCollections = it
|
||||||
getManagedEmitter<SessionControlChange>().onNext(SessionControlChange.CollectionsChange(it))
|
getManagedEmitter<SessionControlChange>().onNext(
|
||||||
|
SessionControlChange.CollectionsChange(
|
||||||
|
it
|
||||||
|
)
|
||||||
|
)
|
||||||
}.also { observer ->
|
}.also { observer ->
|
||||||
requireComponents.core.tabCollectionStorage.getCollections().observe(this, observer)
|
requireComponents.core.tabCollectionStorage.getCollections().observe(this, observer)
|
||||||
}
|
}
|
||||||
|
@ -659,7 +677,8 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
|
|
||||||
private fun getListOfSessions(): List<Session> {
|
private fun getListOfSessions(): List<Session> {
|
||||||
val isPrivate = (activity as HomeActivity).browsingModeManager.isPrivate
|
val isPrivate = (activity as HomeActivity).browsingModeManager.isPrivate
|
||||||
val notPendingDeletion: (Session) -> Boolean = { it.id != pendingSessionDeletion?.sessionId }
|
val notPendingDeletion: (Session) -> Boolean =
|
||||||
|
{ it.id != pendingSessionDeletion?.sessionId }
|
||||||
return sessionManager.filteredSessions(isPrivate, notPendingDeletion)
|
return sessionManager.filteredSessions(isPrivate, notPendingDeletion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,10 +696,12 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
}
|
}
|
||||||
viewModel?.tabs = tabs
|
viewModel?.tabs = tabs
|
||||||
val selectedTabs =
|
val selectedTabs =
|
||||||
tabs.find { tab -> tab.sessionId == selectedTabId } ?: if (tabs.size == 1) tabs[0] else null
|
tabs.find { tab -> tab.sessionId == selectedTabId }
|
||||||
|
?: if (tabs.size == 1) tabs[0] else null
|
||||||
val selectedSet = if (selectedTabs == null) mutableSetOf() else mutableSetOf(selectedTabs)
|
val selectedSet = if (selectedTabs == null) mutableSetOf() else mutableSetOf(selectedTabs)
|
||||||
viewModel?.selectedTabs = selectedSet
|
viewModel?.selectedTabs = selectedSet
|
||||||
viewModel?.tabCollections = requireComponents.core.tabCollectionStorage.cachedTabCollections.reversed()
|
viewModel?.tabCollections =
|
||||||
|
requireComponents.core.tabCollectionStorage.cachedTabCollections.reversed()
|
||||||
viewModel?.selectedTabCollection = selectedTabCollection
|
viewModel?.selectedTabCollection = selectedTabCollection
|
||||||
viewModel?.saveCollectionStep =
|
viewModel?.saveCollectionStep =
|
||||||
step ?: viewModel?.getStepForTabsAndCollectionSize() ?: SaveCollectionStep.SelectTabs
|
step ?: viewModel?.getStepForTabsAndCollectionSize() ?: SaveCollectionStep.SelectTabs
|
||||||
|
@ -743,7 +764,10 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
override fun onLoggedOut() = emitAccountChanges()
|
override fun onLoggedOut() = emitAccountChanges()
|
||||||
override fun onProfileUpdated(profile: Profile) = emitAccountChanges()
|
override fun onProfileUpdated(profile: Profile) = emitAccountChanges()
|
||||||
|
|
||||||
private fun scrollAndAnimateCollection(tabsAddedToCollectionSize: Int, changedCollection: TabCollection? = null) {
|
private fun scrollAndAnimateCollection(
|
||||||
|
tabsAddedToCollectionSize: Int,
|
||||||
|
changedCollection: TabCollection? = null
|
||||||
|
) {
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
val recyclerView = sessionControlComponent.view
|
val recyclerView = sessionControlComponent.view
|
||||||
|
@ -762,10 +786,14 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val lastVisiblePosition =
|
val lastVisiblePosition =
|
||||||
(recyclerView.layoutManager as? LinearLayoutManager)?.findLastCompletelyVisibleItemPosition() ?: 0
|
(recyclerView.layoutManager as? LinearLayoutManager)?.findLastCompletelyVisibleItemPosition()
|
||||||
|
?: 0
|
||||||
if (lastVisiblePosition < indexOfCollection) {
|
if (lastVisiblePosition < indexOfCollection) {
|
||||||
val onScrollListener = object : RecyclerView.OnScrollListener() {
|
val onScrollListener = object : RecyclerView.OnScrollListener() {
|
||||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
override fun onScrollStateChanged(
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
newState: Int
|
||||||
|
) {
|
||||||
super.onScrollStateChanged(recyclerView, newState)
|
super.onScrollStateChanged(recyclerView, newState)
|
||||||
if (newState == SCROLL_STATE_IDLE) {
|
if (newState == SCROLL_STATE_IDLE) {
|
||||||
animateCollection(tabsAddedToCollectionSize, indexOfCollection)
|
animateCollection(tabsAddedToCollectionSize, indexOfCollection)
|
||||||
|
@ -784,8 +812,10 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
|
|
||||||
private fun animateCollection(addedTabsSize: Int, indexOfCollection: Int) {
|
private fun animateCollection(addedTabsSize: Int, indexOfCollection: Int) {
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
val viewHolder = sessionControlComponent.view.findViewHolderForAdapterPosition(indexOfCollection)
|
val viewHolder =
|
||||||
val border = (viewHolder as? CollectionViewHolder)?.view?.findViewById<View>(R.id.selected_border)
|
sessionControlComponent.view.findViewHolderForAdapterPosition(indexOfCollection)
|
||||||
|
val border =
|
||||||
|
(viewHolder as? CollectionViewHolder)?.view?.findViewById<View>(R.id.selected_border)
|
||||||
val listener = object : Animator.AnimatorListener {
|
val listener = object : Animator.AnimatorListener {
|
||||||
override fun onAnimationCancel(animation: Animator?) {
|
override fun onAnimationCancel(animation: Animator?) {
|
||||||
border?.visibility = View.GONE
|
border?.visibility = View.GONE
|
||||||
|
@ -799,7 +829,8 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
?.start()
|
?.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
border?.animate()?.alpha(1.0F)?.setStartDelay(ANIM_ON_SCREEN_DELAY)?.setDuration(FADE_ANIM_DURATION)
|
border?.animate()?.alpha(1.0F)?.setStartDelay(ANIM_ON_SCREEN_DELAY)
|
||||||
|
?.setDuration(FADE_ANIM_DURATION)
|
||||||
?.setListener(listener)?.start()
|
?.setListener(listener)?.start()
|
||||||
}.invokeOnCompletion {
|
}.invokeOnCompletion {
|
||||||
showSavedSnackbar(addedTabsSize)
|
showSavedSnackbar(addedTabsSize)
|
||||||
|
@ -816,7 +847,8 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
} else {
|
} else {
|
||||||
R.string.create_collection_tab_saved
|
R.string.create_collection_tab_saved
|
||||||
}
|
}
|
||||||
FenixSnackbar.make(view, Snackbar.LENGTH_LONG).setText(view.context.getString(stringRes)).show()
|
FenixSnackbar.make(view, Snackbar.LENGTH_LONG)
|
||||||
|
.setText(view.context.getString(stringRes)).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -853,7 +885,6 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
private const val SHARED_TRANSITION_MS = 200L
|
private const val SHARED_TRANSITION_MS = 200L
|
||||||
private const val TAB_ITEM_TRANSITION_NAME = "tab_item"
|
private const val TAB_ITEM_TRANSITION_NAME = "tab_item"
|
||||||
private const val toolbarPaddingDp = 12f
|
private const val toolbarPaddingDp = 12f
|
||||||
private const val MOTION_LAYOUT_PROGRESS_ROUND_POINT = 0.25f
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import androidx.transition.TransitionInflater
|
||||||
import kotlinx.android.synthetic.main.fragment_search.*
|
import kotlinx.android.synthetic.main.fragment_search.*
|
||||||
import kotlinx.android.synthetic.main.fragment_search.view.*
|
import kotlinx.android.synthetic.main.fragment_search.view.*
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
@ -54,6 +55,12 @@ class SearchFragment : Fragment(), BackHandler {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
postponeEnterTransition()
|
||||||
|
sharedElementEnterTransition =
|
||||||
|
TransitionInflater.from(context).inflateTransition(android.R.transition.move)
|
||||||
|
.setDuration(
|
||||||
|
SHARED_TRANSITION_MS
|
||||||
|
)
|
||||||
requireComponents.analytics.metrics.track(Event.InteractWithSearchURLArea)
|
requireComponents.analytics.metrics.track(Event.InteractWithSearchURLArea)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +108,7 @@ class SearchFragment : Fragment(), BackHandler {
|
||||||
(activity as HomeActivity).browsingModeManager.isPrivate
|
(activity as HomeActivity).browsingModeManager.isPrivate
|
||||||
)
|
)
|
||||||
|
|
||||||
|
startPostponedEnterTransition()
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +199,8 @@ class SearchFragment : Fragment(), BackHandler {
|
||||||
|
|
||||||
// The user has the option to go to 'Shortcuts' -> 'Search engine settings' to modify the default search engine.
|
// The user has the option to go to 'Shortcuts' -> 'Search engine settings' to modify the default search engine.
|
||||||
// When returning from that settings screen we need to update it to account for any changes.
|
// When returning from that settings screen we need to update it to account for any changes.
|
||||||
val currentDefaultEngine = requireComponents.search.searchEngineManager.getDefaultSearchEngine(requireContext())
|
val currentDefaultEngine =
|
||||||
|
requireComponents.search.searchEngineManager.getDefaultSearchEngine(requireContext())
|
||||||
if (searchStore.state.defaultEngineSource.searchEngine != currentDefaultEngine) {
|
if (searchStore.state.defaultEngineSource.searchEngine != currentDefaultEngine) {
|
||||||
searchStore.dispatch(
|
searchStore.dispatch(
|
||||||
SearchAction.SelectNewDefaultSearchEngine
|
SearchAction.SelectNewDefaultSearchEngine
|
||||||
|
@ -232,7 +241,8 @@ class SearchFragment : Fragment(), BackHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSearchWithLabel(searchState: SearchState) {
|
private fun updateSearchWithLabel(searchState: SearchState) {
|
||||||
searchWithShortcuts.visibility = if (searchState.showShortcutEnginePicker) View.VISIBLE else View.GONE
|
searchWithShortcuts.visibility =
|
||||||
|
if (searchState.showShortcutEnginePicker) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSearchShortuctsIcon(searchState: SearchState) {
|
private fun updateSearchShortuctsIcon(searchState: SearchState) {
|
||||||
|
@ -246,7 +256,11 @@ class SearchFragment : Fragment(), BackHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
override fun onRequestPermissionsResult(
|
||||||
|
requestCode: Int,
|
||||||
|
permissions: Array<String>,
|
||||||
|
grantResults: IntArray
|
||||||
|
) {
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
REQUEST_CODE_CAMERA_PERMISSIONS -> qrFeature.withFeature {
|
REQUEST_CODE_CAMERA_PERMISSIONS -> qrFeature.withFeature {
|
||||||
it.onPermissionsResult(permissions, grantResults)
|
it.onPermissionsResult(permissions, grantResults)
|
||||||
|
@ -270,6 +284,7 @@ class SearchFragment : Fragment(), BackHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val SHARED_TRANSITION_MS = 200L
|
||||||
private const val REQUEST_CODE_CAMERA_PERMISSIONS = 1
|
private const val REQUEST_CODE_CAMERA_PERMISSIONS = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue