1
0
Fork 0

For #4529, #4427: Resuming after restoring instance state breaks UI (#4571)

* For #4529, #4427: Resuming after restoring instance state breaks UI

* Clear up warnings
master
Colin Lee 2019-08-08 11:05:01 -05:00 committed by GitHub
parent c21c91eac5
commit ef97173cd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 277 additions and 248 deletions

View File

@ -8,7 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- #4137 - Adds pagination to the history view
- #3695 - Made search suggestions for other tabs clickable
### Changed
- Remove forced focus of toolbar on homescreen
- #4529 - Fixed an issue where the app would sometimes return to a blank toolbar
- #4427 - Fixed an issue where the app would sometimes return to the home fragment
### Removed
## [1.1.0 and earlier] - 2019-07-23
### Added

View File

@ -7,10 +7,10 @@ package org.mozilla.fenix
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import org.mozilla.fenix.mvi.ViewState
import org.mozilla.fenix.mvi.Change
import org.mozilla.fenix.mvi.UIComponentViewModelBase
import org.mozilla.fenix.mvi.UIComponentViewModelProvider
import org.mozilla.fenix.mvi.ViewState
object FenixViewModelProvider {
fun <S : ViewState, C : Change, T : UIComponentViewModelBase<S, C>> create(

View File

@ -15,7 +15,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.net.toUri
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.google.android.material.bottomsheet.BottomSheetBehavior
@ -25,9 +25,12 @@ import kotlinx.android.synthetic.main.fragment_browser.*
import kotlinx.android.synthetic.main.fragment_browser.view.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import mozilla.components.browser.session.Session
import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.session.intent.EXTRA_SESSION_ID
import mozilla.components.feature.app.links.AppLinksFeature
import mozilla.components.feature.contextmenu.ContextMenuFeature
@ -76,8 +79,8 @@ import org.mozilla.fenix.utils.Settings
* This class only contains shared code focused on the main browsing content.
* UI code specific to the app or to custom tabs can be found in the subclasses.
*/
@Suppress("TooManyFunctions")
abstract class BaseBrowserFragment : Fragment(), BackHandler {
@Suppress("TooManyFunctions", "LargeClass")
abstract class BaseBrowserFragment : Fragment(), BackHandler, SessionManager.Observer {
protected lateinit var browserStore: BrowserStore
protected lateinit var browserInteractor: BrowserInteractor
protected lateinit var browserToolbarView: BrowserToolbarView
@ -95,6 +98,9 @@ abstract class BaseBrowserFragment : Fragment(), BackHandler {
var customTabSessionId: String? = null
private var browserInitialized: Boolean = false
private var initUIJob: Job? = null
@CallSuper
override fun onCreateView(
inflater: LayoutInflater,
@ -127,17 +133,19 @@ abstract class BaseBrowserFragment : Fragment(), BackHandler {
return view
}
@Suppress("ComplexMethod")
@CallSuper
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
browserInitialized = initializeUI(view) != null
}
@Suppress("ComplexMethod")
@CallSuper
protected open fun initializeUI(view: View): Session? {
val sessionManager = requireComponents.core.sessionManager
getSessionById()?.let { session ->
val viewModel = activity!!.run {
ViewModelProvider(this).get(CreateCollectionViewModel::class.java)
}
return getSessionById()?.also { session ->
val viewModel: CreateCollectionViewModel by activityViewModels()
val browserToolbarController = DefaultBrowserToolbarController(
context!!,
@ -185,157 +193,179 @@ abstract class BaseBrowserFragment : Fragment(), BackHandler {
browserToolbarView.view.setOnSiteSecurityClickedListener {
showQuickSettingsDialog()
}
}
contextMenuFeature.set(
feature = ContextMenuFeature(
requireFragmentManager(),
sessionManager,
FenixContextMenuCandidate.defaultCandidates(
requireContext(),
requireComponents.useCases.tabsUseCases,
view,
FenixSnackbarDelegate(
contextMenuFeature.set(
feature = ContextMenuFeature(
requireFragmentManager(),
sessionManager,
FenixContextMenuCandidate.defaultCandidates(
requireContext(),
requireComponents.useCases.tabsUseCases,
view,
if (getSessionById()?.isCustomTabSession() == true) null else nestedScrollQuickAction
)
),
view.engineView
),
owner = this,
view = view
)
downloadsFeature.set(
feature = DownloadsFeature(
requireContext().applicationContext,
sessionManager = sessionManager,
fragmentManager = childFragmentManager,
sessionId = customTabSessionId,
downloadManager = FetchDownloadManager(requireContext().applicationContext, DownloadService::class),
onNeedToRequestPermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_DOWNLOAD_PERMISSIONS)
}),
owner = this,
view = view
)
appLinksFeature.set(
feature = AppLinksFeature(
requireContext(),
sessionManager = sessionManager,
sessionId = customTabSessionId,
interceptLinkClicks = true,
fragmentManager = requireFragmentManager()
),
owner = this,
view = view
)
promptsFeature.set(
feature = PromptFeature(
fragment = this,
sessionManager = sessionManager,
sessionId = customTabSessionId,
fragmentManager = requireFragmentManager(),
onNeedToRequestPermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_PROMPT_PERMISSIONS)
}),
owner = this,
view = view
)
sessionFeature.set(
feature = SessionFeature(
sessionManager,
SessionUseCases(sessionManager),
view.engineView,
customTabSessionId
),
owner = this,
view = view
)
val accentHighContrastColor = ThemeManager.resolveAttribute(R.attr.accentHighContrast, requireContext())
sitePermissionsFeature.set(
feature = SitePermissionsFeature(
context = requireContext(),
sessionManager = sessionManager,
fragmentManager = requireFragmentManager(),
promptsStyling = SitePermissionsFeature.PromptsStyling(
gravity = getAppropriateLayoutGravity(),
shouldWidthMatchParent = true,
positiveButtonBackgroundColor = accentHighContrastColor,
positiveButtonTextColor = R.color.photonWhite
),
sessionId = customTabSessionId
) { permissions ->
requestPermissions(permissions, REQUEST_CODE_APP_PERMISSIONS)
},
owner = this,
view = view
)
fullScreenFeature.set(
feature = FullScreenFeature(
sessionManager,
SessionUseCases(sessionManager),
customTabSessionId
) { inFullScreen ->
if (inFullScreen) {
FenixSnackbar.make(view.rootView, Snackbar.LENGTH_SHORT)
.setText(getString(R.string.full_screen_notification))
.show()
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
activity?.enterToImmersiveMode()
toolbar.visibility = View.GONE
nestedScrollQuickAction.visibility = View.GONE
} else {
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER
activity?.exitImmersiveModeIfNeeded()
(activity as HomeActivity).let { activity: HomeActivity ->
ThemeManager.applyStatusBarTheme(
activity.window,
activity.themeManager,
activity
FenixSnackbarDelegate(
view,
if (getSessionById()?.isCustomTabSession() == true) null else nestedScrollQuickAction
)
}
toolbar.visibility = View.VISIBLE
nestedScrollQuickAction.visibility = View.VISIBLE
}
view.swipeRefresh.apply {
val (topMargin, bottomMargin) = if (inFullScreen) 0 to 0 else getEngineMargins()
(layoutParams as CoordinatorLayout.LayoutParams).setMargins(0, topMargin, 0, bottomMargin)
}
},
owner = this,
view = view
)
),
view.engineView
),
owner = this,
view = view
)
if (FeatureFlags.pullToRefreshEnabled) {
val primaryTextColor = ThemeManager.resolveAttribute(R.attr.primaryText, requireContext())
view.swipeRefresh.setColorSchemeColors(primaryTextColor)
swipeRefreshFeature.set(
feature = SwipeRefreshFeature(
requireComponents.core.sessionManager,
requireComponents.useCases.sessionUseCases.reload,
view.swipeRefresh,
downloadsFeature.set(
feature = DownloadsFeature(
requireContext().applicationContext,
sessionManager = sessionManager,
fragmentManager = childFragmentManager,
sessionId = customTabSessionId,
downloadManager = FetchDownloadManager(requireContext().applicationContext, DownloadService::class),
onNeedToRequestPermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_DOWNLOAD_PERMISSIONS)
}),
owner = this,
view = view
)
appLinksFeature.set(
feature = AppLinksFeature(
requireContext(),
sessionManager = sessionManager,
sessionId = customTabSessionId,
interceptLinkClicks = true,
fragmentManager = requireFragmentManager()
),
owner = this,
view = view
)
promptsFeature.set(
feature = PromptFeature(
fragment = this,
sessionManager = sessionManager,
sessionId = customTabSessionId,
fragmentManager = requireFragmentManager(),
onNeedToRequestPermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_PROMPT_PERMISSIONS)
}),
owner = this,
view = view
)
sessionFeature.set(
feature = SessionFeature(
sessionManager,
SessionUseCases(sessionManager),
view.engineView,
customTabSessionId
),
owner = this,
view = view
)
} else {
// Disable pull to refresh
view.swipeRefresh.setOnChildScrollUpCallback { _, _ -> true }
val accentHighContrastColor = ThemeManager.resolveAttribute(R.attr.accentHighContrast, requireContext())
sitePermissionsFeature.set(
feature = SitePermissionsFeature(
context = requireContext(),
sessionManager = sessionManager,
fragmentManager = requireFragmentManager(),
promptsStyling = SitePermissionsFeature.PromptsStyling(
gravity = getAppropriateLayoutGravity(),
shouldWidthMatchParent = true,
positiveButtonBackgroundColor = accentHighContrastColor,
positiveButtonTextColor = R.color.photonWhite
),
sessionId = customTabSessionId
) { permissions ->
requestPermissions(permissions, REQUEST_CODE_APP_PERMISSIONS)
},
owner = this,
view = view
)
fullScreenFeature.set(
feature = FullScreenFeature(
sessionManager,
SessionUseCases(sessionManager),
customTabSessionId
) { inFullScreen ->
if (inFullScreen) {
FenixSnackbar.make(view.rootView, Snackbar.LENGTH_SHORT)
.setText(getString(R.string.full_screen_notification))
.show()
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
activity?.enterToImmersiveMode()
toolbar.visibility = View.GONE
nestedScrollQuickAction.visibility = View.GONE
} else {
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER
activity?.exitImmersiveModeIfNeeded()
(activity as HomeActivity).let { activity: HomeActivity ->
ThemeManager.applyStatusBarTheme(
activity.window,
activity.themeManager,
activity
)
}
toolbar.visibility = View.VISIBLE
nestedScrollQuickAction.visibility = View.VISIBLE
}
view.swipeRefresh.apply {
val (topMargin, bottomMargin) = if (inFullScreen) 0 to 0 else getEngineMargins()
(layoutParams as CoordinatorLayout.LayoutParams).setMargins(0, topMargin, 0, bottomMargin)
}
},
owner = this,
view = view
)
@Suppress("ConstantConditionIf")
if (FeatureFlags.pullToRefreshEnabled) {
val primaryTextColor = ThemeManager.resolveAttribute(R.attr.primaryText, requireContext())
view.swipeRefresh.setColorSchemeColors(primaryTextColor)
swipeRefreshFeature.set(
feature = SwipeRefreshFeature(
requireComponents.core.sessionManager,
requireComponents.useCases.sessionUseCases.reload,
view.swipeRefresh,
customTabSessionId
),
owner = this,
view = view
)
} else {
// Disable pull to refresh
view.swipeRefresh.setOnChildScrollUpCallback { _, _ -> true }
}
(activity as HomeActivity).updateThemeForSession(session)
}
}
@CallSuper
override fun onSessionSelected(session: Session) {
super.onSessionSelected(session)
if (!browserInitialized) {
// Initializing a new coroutineScope to avoid ConcurrentModificationException in ObserverRegistry
// This will be removed when ObserverRegistry is deprecated by browser-state.
initUIJob = MainScope().launch {
view?.let {
browserInitialized = initializeUI(it) != null
}
}
}
}
@CallSuper
override fun onStart() {
super.onStart()
requireComponents.core.sessionManager.register(this, this, autoPause = true)
}
@CallSuper
override fun onResume() {
super.onResume()
val session = getSessionById() ?: return
val components = requireComponents
val preferredColorScheme = components.core.getPreferredColorScheme()
@ -343,20 +373,23 @@ abstract class BaseBrowserFragment : Fragment(), BackHandler {
components.core.engine.settings.preferredColorScheme = preferredColorScheme
components.useCases.sessionUseCases.reload()
}
(activity as HomeActivity).updateThemeForSession(session)
(activity as AppCompatActivity).supportActionBar?.hide()
assignSitePermissionsRules()
}
/**
* Exits full screen mode.
*/
@CallSuper
final override fun onPause() {
super.onPause()
fullScreenFeature.onBackPressed()
}
@CallSuper
override fun onStop() {
super.onStop()
initUIJob?.cancel()
}
@CallSuper
override fun onBackPressed(): Boolean {
return findInPageIntegration.onBackPressed() ||
@ -480,8 +513,9 @@ abstract class BaseBrowserFragment : Fragment(), BackHandler {
*/
protected fun getSessionById(): Session? {
val sessionManager = context?.components?.core?.sessionManager ?: return null
return if (customTabSessionId != null) {
sessionManager.findSessionById(customTabSessionId!!)
val localCustomTabId = customTabSessionId
return if (localCustomTabId != null) {
sessionManager.findSessionById(localCustomTabId)
} else {
sessionManager.selectedSession
}

View File

@ -14,7 +14,6 @@ import android.widget.RadioButton
import androidx.core.content.ContextCompat
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.NavHostFragment.findNavController
import androidx.navigation.fragment.findNavController
import androidx.transition.TransitionInflater
import com.google.android.material.snackbar.Snackbar
@ -30,7 +29,6 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import mozilla.appservices.places.BookmarkRoot
import mozilla.components.browser.session.Session
import mozilla.components.browser.session.SessionManager
import mozilla.components.feature.readerview.ReaderViewFeature
import mozilla.components.feature.session.ThumbnailsFeature
import mozilla.components.lib.state.ext.consumeFrom
@ -59,6 +57,8 @@ import java.net.URL
/**
* Fragment used for browsing the web within the main app and external apps.
*/
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
@Suppress("TooManyFunctions")
class BrowserFragment : BaseBrowserFragment(), BackHandler {
private lateinit var quickActionSheetView: QuickActionSheetView
@ -91,17 +91,12 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
return view
}
@Suppress("LongMethod", "ComplexMethod")
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
override fun initializeUI(view: View): Session? {
val sessionManager = requireComponents.core.sessionManager
getSessionById()?.let {
quickActionSheetView =
QuickActionSheetView(view.nestedScrollQuickAction, browserInteractor)
return super.initializeUI(view)?.also { session ->
quickActionSheetView = QuickActionSheetView(view.nestedScrollQuickAction, browserInteractor)
customTabSessionId?.let { customTabSessionId ->
customTabsIntegration.set(
@ -119,57 +114,58 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
view = view)
}
thumbnailsFeature.set(
feature = ThumbnailsFeature(
requireContext(),
view.engineView,
requireComponents.core.sessionManager
),
owner = this,
view = view
)
readerViewFeature.set(
feature = ReaderViewFeature(
requireContext(),
requireComponents.core.engine,
requireComponents.core.sessionManager,
view.readerViewControlsBar
) { available ->
if (available) {
requireComponents.analytics.metrics.track(Event.ReaderModeAvailable)
}
browserStore.apply {
dispatch(QuickActionSheetAction.ReadableStateChange(available))
dispatch(
QuickActionSheetAction.ReaderActiveStateChange(
sessionManager.selectedSession?.readerMode ?: false
)
)
}
},
owner = this,
view = view
)
if ((activity as HomeActivity).browsingModeManager.isPrivate) {
// We need to update styles for private mode programmatically for now:
// https://github.com/mozilla-mobile/android-components/issues/3400
themeReaderViewControlsForPrivateMode(view.readerViewControlsBar)
}
updateBookmarkState(session)
consumeFrom(browserStore) {
quickActionSheetView.update(it)
browserToolbarView.update(it)
}
}
thumbnailsFeature.set(
feature = ThumbnailsFeature(
requireContext(),
view.engineView,
requireComponents.core.sessionManager
),
owner = this,
view = view
)
readerViewFeature.set(
feature = ReaderViewFeature(
requireContext(),
requireComponents.core.engine,
requireComponents.core.sessionManager,
view.readerViewControlsBar
) { available ->
if (available) {
requireComponents.analytics.metrics.track(Event.ReaderModeAvailable)
}
browserStore.apply {
dispatch(QuickActionSheetAction.ReadableStateChange(available))
dispatch(
QuickActionSheetAction.ReaderActiveStateChange(
sessionManager.selectedSession?.readerMode ?: false
)
)
}
},
owner = this,
view = view
)
if ((activity as HomeActivity).browsingModeManager.isPrivate) {
// We need to update styles for private mode programmatically for now:
// https://github.com/mozilla-mobile/android-components/issues/3400
themeReaderViewControlsForPrivateMode(view.readerViewControlsBar)
}
}
override fun onStart() {
super.onStart()
subscribeToSession()
subscribeToSessions()
subscribeToTabCollections()
}
@ -177,11 +173,6 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
super.onResume()
requireComponents.core.tabCollectionStorage.register(collectionStorageObserver, this)
getSessionById()?.let { updateBookmarkState(it) }
// See #4387 for why we're popping here
if (getSessionById() == null) findNavController(this).popBackStack(R.id.homeFragment, false)
}
override fun onBackPressed(): Boolean {
@ -332,14 +323,9 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
getSessionById()?.register(observer, this, autoPause = true)
}
private fun subscribeToSessions() {
val observer = object : SessionManager.Observer {
override fun onSessionSelected(session: Session) {
(activity as HomeActivity).updateThemeForSession(session)
updateBookmarkState(session)
}
}
requireComponents.core.sessionManager.register(observer, this, autoPause = true)
override fun onSessionSelected(session: Session) {
super.onSessionSelected(session)
updateBookmarkState(session)
}
private suspend fun findBookmarkedURL(session: Session?): Boolean {

View File

@ -10,7 +10,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.ViewModelProvider
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import kotlinx.android.synthetic.main.fragment_create_collection.view.*
import kotlinx.coroutines.Dispatchers
@ -28,7 +28,7 @@ import org.mozilla.fenix.mvi.getManagedEmitter
class CreateCollectionFragment : DialogFragment() {
private lateinit var collectionCreationComponent: CollectionCreationComponent
private lateinit var viewModel: CreateCollectionViewModel
private val viewModel: CreateCollectionViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -43,10 +43,6 @@ class CreateCollectionFragment : DialogFragment() {
): View? {
val view = inflater.inflate(R.layout.fragment_create_collection, container, false)
viewModel = activity!!.run {
ViewModelProvider(this).get(CreateCollectionViewModel::class.java)
}
collectionCreationComponent = CollectionCreationComponent(
view.createCollectionWrapper,
ActionBusFactory.get(this),

View File

@ -10,6 +10,8 @@ import android.content.Intent
import androidx.core.widget.NestedScrollView
import androidx.navigation.NavController
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import mozilla.components.browser.session.Session
import mozilla.components.concept.engine.EngineView
import org.mozilla.fenix.BrowsingModeManager
@ -59,6 +61,8 @@ class DefaultBrowserToolbarController(
)
}
@ExperimentalCoroutinesApi
@ObsoleteCoroutinesApi
@SuppressWarnings("ComplexMethod")
override fun handleToolbarItemInteraction(item: ToolbarMenu.Item) {
val sessionUseCases = context.components.useCases.sessionUseCases

View File

@ -19,11 +19,11 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.PARENT_ID
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.Observer
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.FragmentNavigator
import androidx.navigation.fragment.NavHostFragment.findNavController
@ -204,15 +204,12 @@ class HomeFragment : Fragment(), AccountObserver {
}
private fun restoreLayoutState() {
val homeViewModel = activity?.run {
ViewModelProvider(this).get(HomeScreenViewModel::class.java)
}
homeViewModel?.layoutManagerState?.also { parcelable ->
val homeViewModel: HomeScreenViewModel by activityViewModels()
homeViewModel.layoutManagerState?.also { parcelable ->
sessionControlComponent.view.layoutManager?.onRestoreInstanceState(parcelable)
}
homeLayout?.progress = homeViewModel?.motionLayoutProgress ?: 0F
homeViewModel?.layoutManagerState = null
homeLayout?.progress = homeViewModel.motionLayoutProgress
homeViewModel.layoutManagerState = null
}
@SuppressWarnings("LongMethod")
@ -555,12 +552,10 @@ class HomeFragment : Fragment(), AccountObserver {
override fun onPause() {
invokePendingDeleteJobs()
super.onPause()
val homeViewModel = activity?.run {
ViewModelProvider(this).get(HomeScreenViewModel::class.java)
}
homeViewModel?.layoutManagerState =
val homeViewModel: HomeScreenViewModel by activityViewModels()
homeViewModel.layoutManagerState =
sessionControlComponent.view.layoutManager?.onSaveInstanceState()
homeViewModel?.motionLayoutProgress = homeLayout?.progress ?: 0F
homeViewModel.motionLayoutProgress = homeLayout?.progress ?: 0F
}
private fun setupHomeMenu() {
@ -691,21 +686,18 @@ class HomeFragment : Fragment(), AccountObserver {
val tabs = getListOfSessions().toTabs()
val viewModel = activity?.run {
ViewModelProvider(this).get(CreateCollectionViewModel::class.java)
}
viewModel?.tabs = tabs
val viewModel: CreateCollectionViewModel by activityViewModels()
viewModel.tabs = tabs
val selectedTabs =
tabs.find { tab -> tab.sessionId == selectedTabId }
?: if (tabs.size == 1) tabs[0] else null
val selectedSet = if (selectedTabs == null) mutableSetOf() else mutableSetOf(selectedTabs)
viewModel?.selectedTabs = selectedSet
viewModel?.tabCollections =
requireComponents.core.tabCollectionStorage.cachedTabCollections.reversed()
viewModel?.selectedTabCollection = selectedTabCollection
viewModel?.saveCollectionStep =
step ?: viewModel?.getStepForTabsAndCollectionSize() ?: SaveCollectionStep.SelectTabs
viewModel?.previousFragmentId = R.id.homeFragment
viewModel.selectedTabs = selectedSet
viewModel.tabCollections = requireComponents.core.tabCollectionStorage.cachedTabCollections.reversed()
viewModel.selectedTabCollection = selectedTabCollection
viewModel.saveCollectionStep =
step ?: viewModel.getStepForTabsAndCollectionSize()
viewModel.previousFragmentId = R.id.homeFragment
// Only register the observer right before moving to collection creation
requireComponents.core.tabCollectionStorage.register(collectionStorageObserver, this)

View File

@ -14,6 +14,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import kotlinx.android.synthetic.main.fragment_delete_browsing_data.*
import kotlinx.android.synthetic.main.fragment_delete_browsing_data.view.*
import kotlinx.coroutines.Dispatchers
@ -114,14 +115,15 @@ class DeleteBrowsingDataFragment : Fragment() {
}
}
fun startDeletion() {
private fun startDeletion() {
progress_bar.visibility = View.VISIBLE
delete_browsing_data_wrapper.isEnabled = false
delete_browsing_data_wrapper.isClickable = false
delete_browsing_data_wrapper.alpha = DISABLED_ALPHA
}
fun finishDeletion() {
private fun finishDeletion() {
val popAfter = open_tabs_item.isChecked
progress_bar.visibility = View.GONE
delete_browsing_data_wrapper.isEnabled = true
delete_browsing_data_wrapper.isClickable = true
@ -138,6 +140,10 @@ class DeleteBrowsingDataFragment : Fragment() {
FenixSnackbar.make(view!!, FenixSnackbar.LENGTH_SHORT)
.setText(resources.getString(R.string.preferences_delete_browsing_data_snackbar))
.show()
if (popAfter) viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
findNavController().popBackStack(R.id.homeFragment, false)
}
}
private fun updateDeleteButton() {

View File

@ -26,6 +26,8 @@ import androidx.navigation.fragment.NavHostFragment.findNavController
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.launch
import mozilla.components.browser.session.Session
import mozilla.components.feature.sitepermissions.SitePermissions
@ -48,6 +50,7 @@ import com.google.android.material.R as MaterialR
private const val REQUEST_CODE_QUICK_SETTINGS_PERMISSIONS = 4
@ObsoleteCoroutinesApi
@SuppressWarnings("TooManyFunctions")
class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() {
private val safeArguments get() = requireNotNull(arguments)
@ -167,6 +170,8 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() {
}
}
@ExperimentalCoroutinesApi
@ObsoleteCoroutinesApi
override fun onResume() {
super.onResume()
getAutoDisposeObservable<QuickSettingsAction>()