* For #4529, #4427: Resuming after restoring instance state breaks UI * Clear up warningsmaster
parent
c21c91eac5
commit
ef97173cd9
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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>()
|
||||
|
|
Loading…
Reference in New Issue