Use lifecycleScope for collections fragments
parent
6bf8d6be34
commit
d01bb8c442
|
@ -353,7 +353,8 @@ dependencies {
|
||||||
implementation Deps.androidx_navigation_fragment
|
implementation Deps.androidx_navigation_fragment
|
||||||
implementation Deps.androidx_navigation_ui
|
implementation Deps.androidx_navigation_ui
|
||||||
implementation Deps.androidx_recyclerview
|
implementation Deps.androidx_recyclerview
|
||||||
implementation Deps.androidx_lifecycle_viewmodel_ktx
|
implementation Deps.androidx_lifecycle_runtime
|
||||||
|
implementation Deps.androidx_lifecycle_viewmodel
|
||||||
implementation Deps.androidx_lifecycle_viewmodel_ss
|
implementation Deps.androidx_lifecycle_viewmodel_ss
|
||||||
implementation Deps.androidx_core
|
implementation Deps.androidx_core
|
||||||
implementation Deps.androidx_core_ktx
|
implementation Deps.androidx_core_ktx
|
||||||
|
|
|
@ -23,14 +23,13 @@ import androidx.core.net.toUri
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.NavHostFragment.findNavController
|
import androidx.navigation.fragment.NavHostFragment.findNavController
|
||||||
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.*
|
import kotlinx.android.synthetic.main.fragment_browser.*
|
||||||
import kotlinx.android.synthetic.main.fragment_browser.view.*
|
import kotlinx.android.synthetic.main.fragment_browser.view.*
|
||||||
import kotlinx.android.synthetic.main.fragment_search.*
|
import kotlinx.android.synthetic.main.fragment_search.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.Dispatchers.Main
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
@ -100,10 +99,9 @@ import org.mozilla.fenix.utils.ItsNotBrokenSnack
|
||||||
import org.mozilla.fenix.utils.Settings
|
import org.mozilla.fenix.utils.Settings
|
||||||
import java.net.MalformedURLException
|
import java.net.MalformedURLException
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
||||||
class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
|
class BrowserFragment : Fragment(), BackHandler {
|
||||||
|
|
||||||
private lateinit var toolbarComponent: ToolbarComponent
|
private lateinit var toolbarComponent: ToolbarComponent
|
||||||
|
|
||||||
|
@ -125,12 +123,9 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
|
||||||
private val swipeRefreshFeature = ViewBoundFeatureWrapper<SwipeRefreshFeature>()
|
private val swipeRefreshFeature = ViewBoundFeatureWrapper<SwipeRefreshFeature>()
|
||||||
private val customTabsIntegration = ViewBoundFeatureWrapper<CustomTabsIntegration>()
|
private val customTabsIntegration = ViewBoundFeatureWrapper<CustomTabsIntegration>()
|
||||||
private var findBookmarkJob: Job? = null
|
private var findBookmarkJob: Job? = null
|
||||||
private lateinit var job: Job
|
|
||||||
|
|
||||||
var customTabSessionId: String? = null
|
var customTabSessionId: String? = null
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext get() = Dispatchers.IO + job
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
// Disabled while awaiting a better solution to #3209
|
// Disabled while awaiting a better solution to #3209
|
||||||
|
@ -139,7 +134,6 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
|
||||||
// TransitionInflater.from(context).inflateTransition(android.R.transition.move).setDuration(
|
// TransitionInflater.from(context).inflateTransition(android.R.transition.move).setDuration(
|
||||||
// SHARED_TRANSITION_MS
|
// SHARED_TRANSITION_MS
|
||||||
// )
|
// )
|
||||||
job = Job()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("ComplexMethod")
|
@SuppressWarnings("ComplexMethod")
|
||||||
|
@ -564,9 +558,9 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
|
||||||
|
|
||||||
private fun bookmarkTapped() {
|
private fun bookmarkTapped() {
|
||||||
getSessionById()?.let { session ->
|
getSessionById()?.let { session ->
|
||||||
CoroutineScope(IO).launch {
|
lifecycleScope.launch(IO) {
|
||||||
val components = requireComponents
|
val bookmarksStorage = requireComponents.core.bookmarksStorage
|
||||||
val existing = components.core.bookmarksStorage.getBookmarksWithUrl(session.url)
|
val existing = bookmarksStorage.getBookmarksWithUrl(session.url)
|
||||||
val found = existing.isNotEmpty() && existing[0].url == session.url
|
val found = existing.isNotEmpty() && existing[0].url == session.url
|
||||||
if (found) {
|
if (found) {
|
||||||
launch(Main) {
|
launch(Main) {
|
||||||
|
@ -577,13 +571,12 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val guid = components.core.bookmarksStorage
|
val guid = bookmarksStorage.addItem(
|
||||||
.addItem(
|
BookmarkRoot.Mobile.id,
|
||||||
BookmarkRoot.Mobile.id,
|
session.url,
|
||||||
session.url,
|
session.title,
|
||||||
session.title,
|
null
|
||||||
null
|
)
|
||||||
)
|
|
||||||
launch(Main) {
|
launch(Main) {
|
||||||
getManagedEmitter<QuickActionChange>()
|
getManagedEmitter<QuickActionChange>()
|
||||||
.onNext(QuickActionChange.BookmarkedStateChange(true))
|
.onNext(QuickActionChange.BookmarkedStateChange(true))
|
||||||
|
@ -685,11 +678,6 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
|
||||||
promptsFeature.withFeature { it.onActivityResult(requestCode, resultCode, data) }
|
promptsFeature.withFeature { it.onActivityResult(requestCode, resultCode, data) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
job.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method triggers the complexity warning. However it's actually not that hard to understand.
|
// This method triggers the complexity warning. However it's actually not that hard to understand.
|
||||||
@SuppressWarnings("ComplexMethod")
|
@SuppressWarnings("ComplexMethod")
|
||||||
private fun trackToolbarItemInteraction(action: SearchAction.ToolbarMenuItemTapped) {
|
private fun trackToolbarItemInteraction(action: SearchAction.ToolbarMenuItemTapped) {
|
||||||
|
@ -824,8 +812,8 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
|
||||||
|
|
||||||
private fun showQuickSettingsDialog() {
|
private fun showQuickSettingsDialog() {
|
||||||
val session = getSessionById() ?: return
|
val session = getSessionById() ?: return
|
||||||
launch {
|
lifecycleScope.launch(IO) {
|
||||||
val host = session.url.toUri()?.host
|
val host = session.url.toUri().host
|
||||||
val sitePermissions: SitePermissions? = host?.let {
|
val sitePermissions: SitePermissions? = host?.let {
|
||||||
val storage = requireContext().components.core.permissionStorage
|
val storage = requireContext().components.core.permissionStorage
|
||||||
storage.findSitePermissionsBy(it)
|
storage.findSitePermissionsBy(it)
|
||||||
|
@ -923,7 +911,7 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
|
||||||
|
|
||||||
private fun updateBookmarkState(session: Session) {
|
private fun updateBookmarkState(session: Session) {
|
||||||
if (findBookmarkJob?.isActive == true) findBookmarkJob?.cancel()
|
if (findBookmarkJob?.isActive == true) findBookmarkJob?.cancel()
|
||||||
findBookmarkJob = launch {
|
findBookmarkJob = lifecycleScope.launch(IO) {
|
||||||
val found = findBookmarkedURL(session)
|
val found = findBookmarkedURL(session)
|
||||||
launch(Main) {
|
launch(Main) {
|
||||||
getManagedEmitter<QuickActionChange>()
|
getManagedEmitter<QuickActionChange>()
|
||||||
|
|
|
@ -11,28 +11,23 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import kotlinx.android.synthetic.main.fragment_create_collection.view.*
|
import kotlinx.android.synthetic.main.fragment_create_collection.view.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.mozilla.fenix.FenixViewModelProvider
|
import org.mozilla.fenix.FenixViewModelProvider
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.home.sessioncontrol.toSessionBundle
|
import org.mozilla.fenix.home.sessioncontrol.toSessionBundle
|
||||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||||
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
||||||
import org.mozilla.fenix.mvi.getManagedEmitter
|
import org.mozilla.fenix.mvi.getManagedEmitter
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class CreateCollectionFragment : DialogFragment(), CoroutineScope {
|
class CreateCollectionFragment : DialogFragment() {
|
||||||
private lateinit var collectionCreationComponent: CollectionCreationComponent
|
private lateinit var collectionCreationComponent: CollectionCreationComponent
|
||||||
private lateinit var job: Job
|
|
||||||
private lateinit var viewModel: CreateCollectionViewModel
|
private lateinit var viewModel: CreateCollectionViewModel
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = Dispatchers.Main + job
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
isCancelable = false
|
isCancelable = false
|
||||||
|
@ -44,7 +39,6 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope {
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
job = Job()
|
|
||||||
val view = inflater.inflate(R.layout.fragment_create_collection, container, false)
|
val view = inflater.inflate(R.layout.fragment_create_collection, container, false)
|
||||||
|
|
||||||
viewModel = activity!!.run {
|
viewModel = activity!!.run {
|
||||||
|
@ -86,11 +80,6 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope {
|
||||||
subscribeToActions()
|
subscribeToActions()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
job.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("ComplexMethod")
|
@Suppress("ComplexMethod")
|
||||||
private fun subscribeToActions() {
|
private fun subscribeToActions() {
|
||||||
getAutoDisposeObservable<CollectionCreationAction>().subscribe {
|
getAutoDisposeObservable<CollectionCreationAction>().subscribe {
|
||||||
|
@ -129,8 +118,8 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope {
|
||||||
|
|
||||||
context?.let { context ->
|
context?.let { context ->
|
||||||
val sessionBundle = it.tabs.toList().toSessionBundle(context)
|
val sessionBundle = it.tabs.toList().toSessionBundle(context)
|
||||||
launch(Dispatchers.IO) {
|
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
requireComponents.core.tabCollectionStorage.createCollection(it.name, sessionBundle)
|
context.components.core.tabCollectionStorage.createCollection(it.name, sessionBundle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,15 +127,15 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope {
|
||||||
dismiss()
|
dismiss()
|
||||||
context?.let { context ->
|
context?.let { context ->
|
||||||
val sessionBundle = it.tabs.toList().toSessionBundle(context)
|
val sessionBundle = it.tabs.toList().toSessionBundle(context)
|
||||||
launch(Dispatchers.IO) {
|
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
requireComponents.core.tabCollectionStorage
|
context.components.core.tabCollectionStorage
|
||||||
.addTabsToCollection(it.collection, sessionBundle)
|
.addTabsToCollection(it.collection, sessionBundle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is CollectionCreationAction.RenameCollection -> {
|
is CollectionCreationAction.RenameCollection -> {
|
||||||
dismiss()
|
dismiss()
|
||||||
launch(Dispatchers.IO) {
|
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
requireComponents.core.tabCollectionStorage.renameCollection(it.collection, it.name)
|
requireComponents.core.tabCollectionStorage.renameCollection(it.collection, it.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,11 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
import kotlinx.android.synthetic.main.fragment_exceptions.view.*
|
import kotlinx.android.synthetic.main.fragment_exceptions.view.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.mozilla.fenix.FenixViewModelProvider
|
import org.mozilla.fenix.FenixViewModelProvider
|
||||||
|
@ -22,19 +22,10 @@ import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||||
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
||||||
import org.mozilla.fenix.mvi.getManagedEmitter
|
import org.mozilla.fenix.mvi.getManagedEmitter
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class ExceptionsFragment : Fragment(), CoroutineScope {
|
class ExceptionsFragment : Fragment() {
|
||||||
private var job = Job()
|
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = job + Dispatchers.Main
|
|
||||||
private lateinit var exceptionsComponent: ExceptionsComponent
|
private lateinit var exceptionsComponent: ExceptionsComponent
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
job = Job()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
activity?.title = getString(R.string.preference_exceptions)
|
activity?.title = getString(R.string.preference_exceptions)
|
||||||
|
@ -65,14 +56,14 @@ class ExceptionsFragment : Fragment(), CoroutineScope {
|
||||||
getAutoDisposeObservable<ExceptionsAction>()
|
getAutoDisposeObservable<ExceptionsAction>()
|
||||||
.subscribe {
|
.subscribe {
|
||||||
when (it) {
|
when (it) {
|
||||||
is ExceptionsAction.Delete.All -> launch(Dispatchers.IO) {
|
is ExceptionsAction.Delete.All -> viewLifecycleOwner.lifecycleScope.launch(IO) {
|
||||||
val domains = ExceptionDomains.load(context!!)
|
val domains = ExceptionDomains.load(context!!)
|
||||||
ExceptionDomains.remove(context!!, domains)
|
ExceptionDomains.remove(context!!, domains)
|
||||||
launch(Dispatchers.Main) {
|
launch(Main) {
|
||||||
view?.let { view: View -> Navigation.findNavController(view).navigateUp() }
|
view?.let { view -> Navigation.findNavController(view).navigateUp() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is ExceptionsAction.Delete.One -> launch(Dispatchers.IO) {
|
is ExceptionsAction.Delete.One -> viewLifecycleOwner.lifecycleScope.launch(IO) {
|
||||||
ExceptionDomains.remove(context!!, listOf(it.item.url))
|
ExceptionDomains.remove(context!!, listOf(it.item.url))
|
||||||
reloadData()
|
reloadData()
|
||||||
}
|
}
|
||||||
|
@ -93,7 +84,7 @@ class ExceptionsFragment : Fragment(), CoroutineScope {
|
||||||
val items = loadAndMapExceptions()
|
val items = loadAndMapExceptions()
|
||||||
|
|
||||||
coroutineScope {
|
coroutineScope {
|
||||||
launch(Dispatchers.Main) {
|
launch(Main) {
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
view?.let { view: View -> Navigation.findNavController(view).navigateUp() }
|
view?.let { view: View -> Navigation.findNavController(view).navigateUp() }
|
||||||
return@launch
|
return@launch
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
package org.mozilla.fenix.home
|
package org.mozilla.fenix.home
|
||||||
|
|
||||||
import android.animation.Animator
|
import android.animation.Animator
|
||||||
import android.content.Context
|
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
@ -14,12 +13,14 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewTreeObserver
|
import android.view.ViewTreeObserver
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.PARENT_ID
|
import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.PARENT_ID
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
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
|
||||||
|
@ -27,9 +28,7 @@ import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
|
||||||
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.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
@ -79,11 +78,10 @@ import org.mozilla.fenix.onboarding.FenixOnboarding
|
||||||
import org.mozilla.fenix.settings.SupportUtils
|
import org.mozilla.fenix.settings.SupportUtils
|
||||||
import org.mozilla.fenix.share.ShareTab
|
import org.mozilla.fenix.share.ShareTab
|
||||||
import org.mozilla.fenix.utils.allowUndo
|
import org.mozilla.fenix.utils.allowUndo
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
||||||
class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
class HomeFragment : Fragment(), AccountObserver {
|
||||||
private val bus = ActionBusFactory.get(this)
|
private val bus = ActionBusFactory.get(this)
|
||||||
private var tabCollectionObserver: Observer<List<TabCollection>>? = null
|
private var tabCollectionObserver: Observer<List<TabCollection>>? = null
|
||||||
|
|
||||||
|
@ -110,10 +108,6 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
private val onboarding by lazy { FenixOnboarding(requireContext()) }
|
private val onboarding by lazy { FenixOnboarding(requireContext()) }
|
||||||
private lateinit var sessionControlComponent: SessionControlComponent
|
private lateinit var sessionControlComponent: SessionControlComponent
|
||||||
|
|
||||||
private lateinit var job: Job
|
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = Dispatchers.Main + job
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
// Disabled while awaiting a better solution to #3209
|
// Disabled while awaiting a better solution to #3209
|
||||||
|
@ -135,7 +129,6 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
job = Job()
|
|
||||||
val view = inflater.inflate(R.layout.fragment_home, container, false)
|
val view = inflater.inflate(R.layout.fragment_home, container, false)
|
||||||
|
|
||||||
val mode = currentMode()
|
val mode = currentMode()
|
||||||
|
@ -177,7 +170,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
|
|
||||||
val listener = object : ViewTreeObserver.OnPreDrawListener {
|
val listener = object : ViewTreeObserver.OnPreDrawListener {
|
||||||
override fun onPreDraw(): Boolean {
|
override fun onPreDraw(): Boolean {
|
||||||
launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
delay(ANIM_SCROLL_DELAY)
|
delay(ANIM_SCROLL_DELAY)
|
||||||
restoreLayoutState()
|
restoreLayoutState()
|
||||||
startPostponedEnterTransition()
|
startPostponedEnterTransition()
|
||||||
|
@ -209,7 +202,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
|
|
||||||
setupHomeMenu()
|
setupHomeMenu()
|
||||||
|
|
||||||
launch(Dispatchers.Default) {
|
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Default) {
|
||||||
val iconSize = resources.getDimension(R.dimen.preference_icon_drawable_size).toInt()
|
val iconSize = resources.getDimension(R.dimen.preference_icon_drawable_size).toInt()
|
||||||
|
|
||||||
val searchIcon = requireComponents.search.searchEngineManager.getDefaultSearchEngine(
|
val searchIcon = requireComponents.search.searchEngineManager.getDefaultSearchEngine(
|
||||||
|
@ -274,7 +267,6 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
homeMenu = null
|
homeMenu = null
|
||||||
job.cancel()
|
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +351,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
removeTabWithUndo(action.sessionId)
|
removeTabWithUndo(action.sessionId)
|
||||||
} else {
|
} else {
|
||||||
pendingSessionDeletion?.deletionJob?.let {
|
pendingSessionDeletion?.deletionJob?.let {
|
||||||
launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
it.invoke()
|
it.invoke()
|
||||||
}.invokeOnCompletion {
|
}.invokeOnCompletion {
|
||||||
pendingSessionDeletion = null
|
pendingSessionDeletion = null
|
||||||
|
@ -379,7 +371,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
sessionManager.filteredSessions(action.private)
|
sessionManager.filteredSessions(action.private)
|
||||||
) else {
|
) else {
|
||||||
pendingSessionDeletion?.deletionJob?.let {
|
pendingSessionDeletion?.deletionJob?.let {
|
||||||
launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
it.invoke()
|
it.invoke()
|
||||||
}.invokeOnCompletion {
|
}.invokeOnCompletion {
|
||||||
pendingSessionDeletion = null
|
pendingSessionDeletion = null
|
||||||
|
@ -413,7 +405,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
|
|
||||||
private fun invokePendingDeleteJobs() {
|
private fun invokePendingDeleteJobs() {
|
||||||
pendingSessionDeletion?.deletionJob?.let {
|
pendingSessionDeletion?.deletionJob?.let {
|
||||||
launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
it.invoke()
|
it.invoke()
|
||||||
}.invokeOnCompletion {
|
}.invokeOnCompletion {
|
||||||
pendingSessionDeletion = null
|
pendingSessionDeletion = null
|
||||||
|
@ -421,7 +413,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAllSessionsJob?.let {
|
deleteAllSessionsJob?.let {
|
||||||
launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
it.invoke()
|
it.invoke()
|
||||||
}.invokeOnCompletion {
|
}.invokeOnCompletion {
|
||||||
deleteAllSessionsJob = null
|
deleteAllSessionsJob = null
|
||||||
|
@ -438,7 +430,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
dialog.cancel()
|
dialog.cancel()
|
||||||
}
|
}
|
||||||
setPositiveButton(R.string.tab_collection_dialog_positive) { dialog: DialogInterface, _ ->
|
setPositiveButton(R.string.tab_collection_dialog_positive) { dialog: DialogInterface, _ ->
|
||||||
launch(Dispatchers.IO) {
|
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
requireComponents.core.tabCollectionStorage.removeCollection(tabCollection)
|
requireComponents.core.tabCollectionStorage.removeCollection(tabCollection)
|
||||||
}.invokeOnCompletion {
|
}.invokeOnCompletion {
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
|
@ -517,7 +509,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
delay(ANIM_SCROLL_DELAY)
|
delay(ANIM_SCROLL_DELAY)
|
||||||
sessionControlComponent.view.smoothScrollToPosition(0)
|
sessionControlComponent.view.smoothScrollToPosition(0)
|
||||||
}
|
}
|
||||||
|
@ -527,7 +519,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
share(tabs = shareTabs)
|
share(tabs = shareTabs)
|
||||||
}
|
}
|
||||||
is CollectionAction.RemoveTab -> {
|
is CollectionAction.RemoveTab -> {
|
||||||
launch(Dispatchers.IO) {
|
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
requireComponents.core.tabCollectionStorage.removeTabFromCollection(action.collection, action.tab)
|
requireComponents.core.tabCollectionStorage.removeTabFromCollection(action.collection, action.tab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -608,7 +600,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
}
|
}
|
||||||
deleteAllSessionsJob = deleteOperation
|
deleteAllSessionsJob = deleteOperation
|
||||||
|
|
||||||
allowUndo(
|
viewLifecycleOwner.lifecycleScope.allowUndo(
|
||||||
view!!,
|
view!!,
|
||||||
getString(R.string.snackbar_tabs_deleted),
|
getString(R.string.snackbar_tabs_deleted),
|
||||||
getString(R.string.snackbar_deleted_undo), {
|
getString(R.string.snackbar_deleted_undo), {
|
||||||
|
@ -631,7 +623,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
|
|
||||||
pendingSessionDeletion = PendingSessionDeletion(deleteOperation, sessionId)
|
pendingSessionDeletion = PendingSessionDeletion(deleteOperation, sessionId)
|
||||||
|
|
||||||
allowUndo(
|
viewLifecycleOwner.lifecycleScope.allowUndo(
|
||||||
view!!,
|
view!!,
|
||||||
getString(R.string.snackbar_tab_deleted),
|
getString(R.string.snackbar_tab_deleted),
|
||||||
getString(R.string.snackbar_deleted_undo), {
|
getString(R.string.snackbar_deleted_undo), {
|
||||||
|
@ -732,7 +724,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scrollAndAnimateCollection(tabsAddedToCollectionSize: Int, changedCollection: TabCollection? = null) {
|
private fun scrollAndAnimateCollection(tabsAddedToCollectionSize: Int, changedCollection: TabCollection? = null) {
|
||||||
launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
val recyclerView = sessionControlComponent.view
|
val recyclerView = sessionControlComponent.view
|
||||||
delay(ANIM_SCROLL_DELAY)
|
delay(ANIM_SCROLL_DELAY)
|
||||||
val tabsSize = getListOfSessions().size
|
val tabsSize = getListOfSessions().size
|
||||||
|
@ -768,7 +760,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun animateCollection(addedTabsSize: Int, indexOfCollection: Int) {
|
private fun animateCollection(addedTabsSize: Int, indexOfCollection: Int) {
|
||||||
launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
val viewHolder = sessionControlComponent.view.findViewHolderForAdapterPosition(indexOfCollection)
|
val viewHolder = sessionControlComponent.view.findViewHolderForAdapterPosition(indexOfCollection)
|
||||||
val border = (viewHolder as? CollectionViewHolder)?.view?.findViewById<View>(R.id.selected_border)
|
val border = (viewHolder as? CollectionViewHolder)?.view?.findViewById<View>(R.id.selected_border)
|
||||||
val listener = object : Animator.AnimatorListener {
|
val listener = object : Animator.AnimatorListener {
|
||||||
|
@ -815,27 +807,24 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showSavedSnackbar(tabSize: Int) {
|
private fun showSavedSnackbar(tabSize: Int) {
|
||||||
launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
delay(ANIM_SNACKBAR_DELAY)
|
delay(ANIM_SNACKBAR_DELAY)
|
||||||
context?.let { context: Context ->
|
view?.let { view ->
|
||||||
view?.let { view: View ->
|
@StringRes
|
||||||
val string =
|
val stringRes = if (tabSize > 1) {
|
||||||
if (tabSize > 1) context.getString(R.string.create_collection_tabs_saved) else
|
R.string.create_collection_tabs_saved
|
||||||
context.getString(R.string.create_collection_tab_saved)
|
} else {
|
||||||
val snackbar = FenixSnackbar.make(view, Snackbar.LENGTH_LONG).setText(string)
|
R.string.create_collection_tab_saved
|
||||||
snackbar.show()
|
|
||||||
}
|
}
|
||||||
|
FenixSnackbar.make(view, Snackbar.LENGTH_LONG).setText(view.context.getString(stringRes)).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showRenamedSnackbar() {
|
private fun showRenamedSnackbar() {
|
||||||
context?.let { context: Context ->
|
view?.let { view ->
|
||||||
view?.let { view: View ->
|
val string = view.context.getString(R.string.snackbar_collection_renamed)
|
||||||
val string = context.getString(R.string.snackbar_collection_renamed)
|
FenixSnackbar.make(view, Snackbar.LENGTH_LONG).setText(string).show()
|
||||||
FenixSnackbar.make(view, Snackbar.LENGTH_LONG).setText(string)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,10 @@ import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
import kotlinx.android.synthetic.main.fragment_bookmark.view.*
|
import kotlinx.android.synthetic.main.fragment_bookmark.view.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.Dispatchers.Main
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
@ -55,12 +55,10 @@ import org.mozilla.fenix.mvi.ActionBusFactory
|
||||||
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
||||||
import org.mozilla.fenix.mvi.getManagedEmitter
|
import org.mozilla.fenix.mvi.getManagedEmitter
|
||||||
import org.mozilla.fenix.utils.allowUndo
|
import org.mozilla.fenix.utils.allowUndo
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
||||||
class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserver {
|
class BookmarkFragment : Fragment(), BackHandler, AccountObserver {
|
||||||
|
|
||||||
private lateinit var job: Job
|
|
||||||
private lateinit var bookmarkComponent: BookmarkComponent
|
private lateinit var bookmarkComponent: BookmarkComponent
|
||||||
private lateinit var signInComponent: SignInComponent
|
private lateinit var signInComponent: SignInComponent
|
||||||
var currentRoot: BookmarkNode? = null
|
var currentRoot: BookmarkNode? = null
|
||||||
|
@ -74,9 +72,6 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
||||||
}
|
}
|
||||||
lateinit var initialJob: Job
|
lateinit var initialJob: Job
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = Main + job
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
val view = inflater.inflate(R.layout.fragment_bookmark, container, false)
|
val view = inflater.inflate(R.layout.fragment_bookmark, container, false)
|
||||||
bookmarkComponent = BookmarkComponent(
|
bookmarkComponent = BookmarkComponent(
|
||||||
|
@ -109,7 +104,6 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
job = Job()
|
|
||||||
activity?.title = getString(R.string.library_bookmarks)
|
activity?.title = getString(R.string.library_bookmarks)
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
}
|
}
|
||||||
|
@ -126,11 +120,11 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadInitialBookmarkFolder(currentGuid: String): Job {
|
private fun loadInitialBookmarkFolder(currentGuid: String): Job {
|
||||||
return launch(IO) {
|
return lifecycleScope.launch(IO) {
|
||||||
currentRoot =
|
currentRoot =
|
||||||
context?.bookmarkStorage()?.getTree(currentGuid).withOptionalDesktopFolders(context) as BookmarkNode
|
context?.bookmarkStorage()?.getTree(currentGuid).withOptionalDesktopFolders(context) as BookmarkNode
|
||||||
|
|
||||||
launch(Main) {
|
lifecycleScope.launch(Main) {
|
||||||
getManagedEmitter<BookmarkChange>().onNext(BookmarkChange.Change(currentRoot!!))
|
getManagedEmitter<BookmarkChange>().onNext(BookmarkChange.Change(currentRoot!!))
|
||||||
|
|
||||||
activity?.run {
|
activity?.run {
|
||||||
|
@ -151,7 +145,6 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
navigation.removeOnDestinationChangedListener(onDestinationChangedListener)
|
navigation.removeOnDestinationChangedListener(onDestinationChangedListener)
|
||||||
job.cancel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
|
@ -260,7 +253,7 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
||||||
getManagedEmitter<BookmarkChange>()
|
getManagedEmitter<BookmarkChange>()
|
||||||
.onNext(BookmarkChange.Change(currentRoot - it.item.guid))
|
.onNext(BookmarkChange.Change(currentRoot - it.item.guid))
|
||||||
|
|
||||||
allowUndo(
|
lifecycleScope.allowUndo(
|
||||||
view!!,
|
view!!,
|
||||||
getString(
|
getString(
|
||||||
R.string.bookmark_deletion_snackbar_message,
|
R.string.bookmark_deletion_snackbar_message,
|
||||||
|
@ -340,7 +333,7 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
||||||
val selectedBookmarks = getSelectedBookmarks()
|
val selectedBookmarks = getSelectedBookmarks()
|
||||||
getManagedEmitter<BookmarkChange>().onNext(BookmarkChange.Change(currentRoot - selectedBookmarks))
|
getManagedEmitter<BookmarkChange>().onNext(BookmarkChange.Change(currentRoot - selectedBookmarks))
|
||||||
|
|
||||||
allowUndo(
|
lifecycleScope.allowUndo(
|
||||||
view!!, getString(R.string.bookmark_deletion_multiple_snackbar_message),
|
view!!, getString(R.string.bookmark_deletion_multiple_snackbar_message),
|
||||||
getString(R.string.bookmark_undo_deletion), { refreshBookmarks() }
|
getString(R.string.bookmark_undo_deletion), { refreshBookmarks() }
|
||||||
) {
|
) {
|
||||||
|
@ -359,7 +352,7 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
||||||
|
|
||||||
override fun onAuthenticated(account: OAuthAccount) {
|
override fun onAuthenticated(account: OAuthAccount) {
|
||||||
getManagedEmitter<SignInChange>().onNext(SignInChange.SignedIn)
|
getManagedEmitter<SignInChange>().onNext(SignInChange.SignedIn)
|
||||||
launch {
|
lifecycleScope.launch {
|
||||||
refreshBookmarks()
|
refreshBookmarks()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,12 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
import kotlinx.android.synthetic.main.fragment_add_bookmark_folder.*
|
import kotlinx.android.synthetic.main.fragment_add_bookmark_folder.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.Dispatchers.Main
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import mozilla.appservices.places.BookmarkRoot
|
import mozilla.appservices.places.BookmarkRoot
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
|
@ -31,23 +29,14 @@ import org.mozilla.fenix.ext.getColorFromAttr
|
||||||
import org.mozilla.fenix.ext.nav
|
import org.mozilla.fenix.ext.nav
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.library.bookmarks.BookmarksSharedViewModel
|
import org.mozilla.fenix.library.bookmarks.BookmarksSharedViewModel
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class AddBookmarkFolderFragment : Fragment(), CoroutineScope {
|
class AddBookmarkFolderFragment : Fragment() {
|
||||||
|
|
||||||
private lateinit var sharedViewModel: BookmarksSharedViewModel
|
private val sharedViewModel: BookmarksSharedViewModel by activityViewModels()
|
||||||
private lateinit var job: Job
|
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = Dispatchers.Main + job
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
job = Job()
|
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
sharedViewModel = activity?.run {
|
|
||||||
ViewModelProviders.of(this).get(BookmarksSharedViewModel::class.java)
|
|
||||||
}!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
@ -60,7 +49,7 @@ class AddBookmarkFolderFragment : Fragment(), CoroutineScope {
|
||||||
getString(R.string.bookmark_add_folder_fragment_label)
|
getString(R.string.bookmark_add_folder_fragment_label)
|
||||||
(activity as AppCompatActivity).supportActionBar?.show()
|
(activity as AppCompatActivity).supportActionBar?.show()
|
||||||
|
|
||||||
launch(IO) {
|
lifecycleScope.launch(IO) {
|
||||||
sharedViewModel.selectedFolder = sharedViewModel.selectedFolder
|
sharedViewModel.selectedFolder = sharedViewModel.selectedFolder
|
||||||
?: requireComponents.core.bookmarksStorage.getTree(BookmarkRoot.Mobile.id)
|
?: requireComponents.core.bookmarksStorage.getTree(BookmarkRoot.Mobile.id)
|
||||||
launch(Main) {
|
launch(Main) {
|
||||||
|
@ -79,11 +68,6 @@ class AddBookmarkFolderFragment : Fragment(), CoroutineScope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
job.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
inflater.inflate(R.menu.bookmarks_add_folder, menu)
|
inflater.inflate(R.menu.bookmarks_add_folder, menu)
|
||||||
menu.findItem(R.id.confirm_add_folder_button).icon.colorFilter =
|
menu.findItem(R.id.confirm_add_folder_button).icon.colorFilter =
|
||||||
|
@ -97,7 +81,7 @@ class AddBookmarkFolderFragment : Fragment(), CoroutineScope {
|
||||||
bookmark_add_folder_title_edit.error = getString(R.string.bookmark_empty_title_error)
|
bookmark_add_folder_title_edit.error = getString(R.string.bookmark_empty_title_error)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
launch(IO) {
|
lifecycleScope.launch(IO) {
|
||||||
val newGuid = requireComponents.core.bookmarksStorage.addFolder(
|
val newGuid = requireComponents.core.bookmarksStorage.addFolder(
|
||||||
sharedViewModel.selectedFolder!!.guid, bookmark_add_folder_title_edit.text.toString(), null
|
sharedViewModel.selectedFolder!!.guid, bookmark_add_folder_title_edit.text.toString(), null
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,7 +18,8 @@ import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AlertDialog
|
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.lifecycle.ViewModelProviders
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
import com.jakewharton.rxbinding3.widget.textChanges
|
import com.jakewharton.rxbinding3.widget.textChanges
|
||||||
import com.uber.autodispose.AutoDispose
|
import com.uber.autodispose.AutoDispose
|
||||||
|
@ -28,10 +29,8 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.functions.BiFunction
|
import io.reactivex.functions.BiFunction
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import kotlinx.android.synthetic.main.fragment_edit_bookmark.*
|
import kotlinx.android.synthetic.main.fragment_edit_bookmark.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.Dispatchers.Main
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import mozilla.appservices.places.UrlParseFailed
|
import mozilla.appservices.places.UrlParseFailed
|
||||||
import mozilla.components.concept.storage.BookmarkInfo
|
import mozilla.components.concept.storage.BookmarkInfo
|
||||||
|
@ -46,26 +45,17 @@ import org.mozilla.fenix.ext.setRootTitles
|
||||||
import org.mozilla.fenix.ext.withRootTitle
|
import org.mozilla.fenix.ext.withRootTitle
|
||||||
import org.mozilla.fenix.library.bookmarks.BookmarksSharedViewModel
|
import org.mozilla.fenix.library.bookmarks.BookmarksSharedViewModel
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class EditBookmarkFragment : Fragment(), CoroutineScope {
|
class EditBookmarkFragment : Fragment() {
|
||||||
|
|
||||||
private lateinit var sharedViewModel: BookmarksSharedViewModel
|
|
||||||
private lateinit var job: Job
|
|
||||||
private lateinit var guidToEdit: String
|
private lateinit var guidToEdit: String
|
||||||
|
private val sharedViewModel: BookmarksSharedViewModel by activityViewModels()
|
||||||
private var bookmarkNode: BookmarkNode? = null
|
private var bookmarkNode: BookmarkNode? = null
|
||||||
private var bookmarkParent: BookmarkNode? = null
|
private var bookmarkParent: BookmarkNode? = null
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = Main + job
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
job = Job()
|
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
sharedViewModel = activity?.run {
|
|
||||||
ViewModelProviders.of(this).get(BookmarksSharedViewModel::class.java)
|
|
||||||
}!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
@ -83,7 +73,7 @@ class EditBookmarkFragment : Fragment(), CoroutineScope {
|
||||||
activity?.supportActionBar?.show()
|
activity?.supportActionBar?.show()
|
||||||
|
|
||||||
guidToEdit = EditBookmarkFragmentArgs.fromBundle(arguments!!).guidToEdit
|
guidToEdit = EditBookmarkFragmentArgs.fromBundle(arguments!!).guidToEdit
|
||||||
launch(IO) {
|
lifecycleScope.launch(IO) {
|
||||||
bookmarkNode = requireComponents.core.bookmarksStorage.getTree(guidToEdit)
|
bookmarkNode = requireComponents.core.bookmarksStorage.getTree(guidToEdit)
|
||||||
bookmarkParent = sharedViewModel.selectedFolder
|
bookmarkParent = sharedViewModel.selectedFolder
|
||||||
?: bookmarkNode?.parentGuid?.let {
|
?: bookmarkNode?.parentGuid?.let {
|
||||||
|
@ -149,11 +139,6 @@ class EditBookmarkFragment : Fragment(), CoroutineScope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
job.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
inflater.inflate(R.menu.bookmarks_edit, menu)
|
inflater.inflate(R.menu.bookmarks_edit, menu)
|
||||||
menu.findItem(R.id.delete_bookmark_button).icon.colorFilter =
|
menu.findItem(R.id.delete_bookmark_button).icon.colorFilter =
|
||||||
|
@ -178,7 +163,7 @@ class EditBookmarkFragment : Fragment(), CoroutineScope {
|
||||||
dialog.cancel()
|
dialog.cancel()
|
||||||
}
|
}
|
||||||
setPositiveButton(R.string.tab_collection_dialog_positive) { dialog: DialogInterface, _ ->
|
setPositiveButton(R.string.tab_collection_dialog_positive) { dialog: DialogInterface, _ ->
|
||||||
launch(IO) {
|
lifecycleScope.launch(IO) {
|
||||||
requireComponents.core.bookmarksStorage.deleteNode(guidToEdit)
|
requireComponents.core.bookmarksStorage.deleteNode(guidToEdit)
|
||||||
requireComponents.analytics.metrics.track(Event.RemoveBookmark)
|
requireComponents.analytics.metrics.track(Event.RemoveBookmark)
|
||||||
launch(Main) {
|
launch(Main) {
|
||||||
|
@ -193,7 +178,7 @@ class EditBookmarkFragment : Fragment(), CoroutineScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateBookmarkNode(pair: Pair<String?, String?>) {
|
private fun updateBookmarkNode(pair: Pair<String?, String?>) {
|
||||||
launch(IO) {
|
lifecycleScope.launch(IO) {
|
||||||
try {
|
try {
|
||||||
requireComponents.let {
|
requireComponents.let {
|
||||||
if (pair != Pair(bookmarkNode?.title, bookmarkNode?.url)) {
|
if (pair != Pair(bookmarkNode?.title, bookmarkNode?.url)) {
|
||||||
|
|
|
@ -16,13 +16,12 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import kotlinx.android.synthetic.main.fragment_select_bookmark_folder.*
|
import kotlinx.android.synthetic.main.fragment_select_bookmark_folder.*
|
||||||
import kotlinx.android.synthetic.main.fragment_select_bookmark_folder.view.*
|
import kotlinx.android.synthetic.main.fragment_select_bookmark_folder.view.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.Dispatchers.Main
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import mozilla.appservices.places.BookmarkRoot
|
import mozilla.appservices.places.BookmarkRoot
|
||||||
import mozilla.components.concept.storage.BookmarkNode
|
import mozilla.components.concept.storage.BookmarkNode
|
||||||
|
@ -47,21 +46,16 @@ import org.mozilla.fenix.library.bookmarks.SignInViewModel
|
||||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||||
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
||||||
import org.mozilla.fenix.mvi.getManagedEmitter
|
import org.mozilla.fenix.mvi.getManagedEmitter
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
@SuppressWarnings("TooManyFunctions")
|
@SuppressWarnings("TooManyFunctions")
|
||||||
class SelectBookmarkFolderFragment : Fragment(), CoroutineScope, AccountObserver {
|
class SelectBookmarkFolderFragment : Fragment(), AccountObserver {
|
||||||
|
|
||||||
private lateinit var sharedViewModel: BookmarksSharedViewModel
|
private val sharedViewModel: BookmarksSharedViewModel by activityViewModels()
|
||||||
private lateinit var job: Job
|
|
||||||
private var folderGuid: String? = null
|
private var folderGuid: String? = null
|
||||||
private var bookmarkNode: BookmarkNode? = null
|
private var bookmarkNode: BookmarkNode? = null
|
||||||
|
|
||||||
private lateinit var signInComponent: SignInComponent
|
private lateinit var signInComponent: SignInComponent
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = Main + job
|
|
||||||
|
|
||||||
// Fill out our title map once we have context.
|
// Fill out our title map once we have context.
|
||||||
override fun onAttach(context: Context) {
|
override fun onAttach(context: Context) {
|
||||||
super.onAttach(context)
|
super.onAttach(context)
|
||||||
|
@ -70,11 +64,7 @@ class SelectBookmarkFolderFragment : Fragment(), CoroutineScope, AccountObserver
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
job = Job()
|
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
sharedViewModel = activity?.run {
|
|
||||||
ViewModelProviders.of(this).get(BookmarksSharedViewModel::class.java)
|
|
||||||
}!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
@ -116,7 +106,7 @@ class SelectBookmarkFolderFragment : Fragment(), CoroutineScope, AccountObserver
|
||||||
folderGuid = SelectBookmarkFolderFragmentArgs.fromBundle(arguments!!).folderGuid ?: BookmarkRoot.Root.id
|
folderGuid = SelectBookmarkFolderFragmentArgs.fromBundle(arguments!!).folderGuid ?: BookmarkRoot.Root.id
|
||||||
checkIfSignedIn()
|
checkIfSignedIn()
|
||||||
|
|
||||||
launch(IO) {
|
lifecycleScope.launch(IO) {
|
||||||
bookmarkNode =
|
bookmarkNode =
|
||||||
requireComponents.core.bookmarksStorage.getTree(BookmarkRoot.Root.id, true)
|
requireComponents.core.bookmarksStorage.getTree(BookmarkRoot.Root.id, true)
|
||||||
.withOptionalDesktopFolders(context, showMobileRoot = true)
|
.withOptionalDesktopFolders(context, showMobileRoot = true)
|
||||||
|
@ -136,11 +126,6 @@ class SelectBookmarkFolderFragment : Fragment(), CoroutineScope, AccountObserver
|
||||||
?: getManagedEmitter<SignInChange>().onNext(SignInChange.SignedOut)
|
?: getManagedEmitter<SignInChange>().onNext(SignInChange.SignedOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
job.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
val visitedAddBookmark = SelectBookmarkFolderFragmentArgs.fromBundle(arguments!!).visitedAddBookmark
|
val visitedAddBookmark = SelectBookmarkFolderFragmentArgs.fromBundle(arguments!!).visitedAddBookmark
|
||||||
if (!visitedAddBookmark) {
|
if (!visitedAddBookmark) {
|
||||||
|
@ -153,7 +138,7 @@ class SelectBookmarkFolderFragment : Fragment(), CoroutineScope, AccountObserver
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
return when (item.itemId) {
|
return when (item.itemId) {
|
||||||
R.id.add_folder_button -> {
|
R.id.add_folder_button -> {
|
||||||
launch(Main) {
|
lifecycleScope.launch(Main) {
|
||||||
nav(
|
nav(
|
||||||
R.id.bookmarkSelectFolderFragment,
|
R.id.bookmarkSelectFolderFragment,
|
||||||
SelectBookmarkFolderFragmentDirections
|
SelectBookmarkFolderFragmentDirections
|
||||||
|
|
|
@ -18,14 +18,11 @@ import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
import kotlinx.android.synthetic.main.fragment_history.view.*
|
import kotlinx.android.synthetic.main.fragment_history.view.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Dispatchers.Main
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.MainScope
|
|
||||||
import kotlinx.coroutines.cancel
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import mozilla.components.concept.storage.VisitType
|
import mozilla.components.concept.storage.VisitType
|
||||||
|
@ -47,7 +44,7 @@ import org.mozilla.fenix.share.ShareTab
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@SuppressWarnings("TooManyFunctions")
|
@SuppressWarnings("TooManyFunctions")
|
||||||
class HistoryFragment : Fragment(), CoroutineScope by MainScope(), BackHandler {
|
class HistoryFragment : Fragment(), BackHandler {
|
||||||
|
|
||||||
private lateinit var historyComponent: HistoryComponent
|
private lateinit var historyComponent: HistoryComponent
|
||||||
private val navigation by lazy { Navigation.findNavController(requireView()) }
|
private val navigation by lazy { Navigation.findNavController(requireView()) }
|
||||||
|
@ -78,7 +75,7 @@ class HistoryFragment : Fragment(), CoroutineScope by MainScope(), BackHandler {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
launch { reloadData() }
|
lifecycleScope.launch { reloadData() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
|
@ -95,11 +92,6 @@ class HistoryFragment : Fragment(), CoroutineScope by MainScope(), BackHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
coroutineContext.cancel()
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
val mode = (historyComponent.uiView as HistoryUIView).mode
|
val mode = (historyComponent.uiView as HistoryUIView).mode
|
||||||
when (mode) {
|
when (mode) {
|
||||||
|
@ -144,7 +136,7 @@ class HistoryFragment : Fragment(), CoroutineScope by MainScope(), BackHandler {
|
||||||
val components = context?.applicationContext?.components!!
|
val components = context?.applicationContext?.components!!
|
||||||
val selectedHistory = (historyComponent.uiView as HistoryUIView).getSelected()
|
val selectedHistory = (historyComponent.uiView as HistoryUIView).getSelected()
|
||||||
|
|
||||||
GlobalScope.launch(Main) {
|
lifecycleScope.launch(Main) {
|
||||||
deleteSelectedHistory(selectedHistory, components)
|
deleteSelectedHistory(selectedHistory, components)
|
||||||
reloadData()
|
reloadData()
|
||||||
}
|
}
|
||||||
|
@ -200,13 +192,13 @@ class HistoryFragment : Fragment(), CoroutineScope by MainScope(), BackHandler {
|
||||||
emitChange { HistoryChange.ExitEditMode }
|
emitChange { HistoryChange.ExitEditMode }
|
||||||
is HistoryAction.Delete.All ->
|
is HistoryAction.Delete.All ->
|
||||||
displayDeleteAllDialog()
|
displayDeleteAllDialog()
|
||||||
is HistoryAction.Delete.One -> launch {
|
is HistoryAction.Delete.One -> lifecycleScope.launch {
|
||||||
requireComponents.core
|
requireComponents.core
|
||||||
.historyStorage
|
.historyStorage
|
||||||
.deleteVisit(action.item.url, action.item.visitedAt)
|
.deleteVisit(action.item.url, action.item.visitedAt)
|
||||||
reloadData()
|
reloadData()
|
||||||
}
|
}
|
||||||
is HistoryAction.Delete.Some -> launch {
|
is HistoryAction.Delete.Some -> lifecycleScope.launch {
|
||||||
val storage = requireComponents.core.historyStorage
|
val storage = requireComponents.core.historyStorage
|
||||||
for (item in action.items) {
|
for (item in action.items) {
|
||||||
storage.deleteVisit(item.url, item.visitedAt)
|
storage.deleteVisit(item.url, item.visitedAt)
|
||||||
|
@ -235,7 +227,7 @@ class HistoryFragment : Fragment(), CoroutineScope by MainScope(), BackHandler {
|
||||||
}
|
}
|
||||||
setPositiveButton(R.string.history_clear_dialog) { dialog: DialogInterface, _ ->
|
setPositiveButton(R.string.history_clear_dialog) { dialog: DialogInterface, _ ->
|
||||||
emitChange { HistoryChange.EnterDeletionMode }
|
emitChange { HistoryChange.EnterDeletionMode }
|
||||||
launch {
|
lifecycleScope.launch {
|
||||||
requireComponents.core.historyStorage.deleteEverything()
|
requireComponents.core.historyStorage.deleteEverything()
|
||||||
reloadData()
|
reloadData()
|
||||||
launch(Dispatchers.Main) {
|
launch(Dispatchers.Main) {
|
||||||
|
|
|
@ -26,15 +26,13 @@ internal const val UNDO_DELAY = 3000L
|
||||||
* @param onCancel A suspend block to execute in case of cancellation.
|
* @param onCancel A suspend block to execute in case of cancellation.
|
||||||
* @param operation A suspend block to execute if user doesn't cancel via the displayed [FenixSnackbar].
|
* @param operation A suspend block to execute if user doesn't cancel via the displayed [FenixSnackbar].
|
||||||
*/
|
*/
|
||||||
fun allowUndo(
|
fun CoroutineScope.allowUndo(
|
||||||
view: View,
|
view: View,
|
||||||
message: String,
|
message: String,
|
||||||
undoActionTitle: String,
|
undoActionTitle: String,
|
||||||
onCancel: suspend () -> Unit = {},
|
onCancel: suspend () -> Unit = {},
|
||||||
operation: suspend () -> Unit
|
operation: suspend () -> Unit
|
||||||
) {
|
) {
|
||||||
val mainScope = CoroutineScope(Dispatchers.Main)
|
|
||||||
|
|
||||||
// By using an AtomicBoolean, we achieve memory effects of reading and
|
// By using an AtomicBoolean, we achieve memory effects of reading and
|
||||||
// writing a volatile variable.
|
// writing a volatile variable.
|
||||||
val requestedUndo = AtomicBoolean(false)
|
val requestedUndo = AtomicBoolean(false)
|
||||||
|
@ -45,7 +43,7 @@ fun allowUndo(
|
||||||
.setText(message)
|
.setText(message)
|
||||||
.setAction(undoActionTitle) {
|
.setAction(undoActionTitle) {
|
||||||
requestedUndo.set(true)
|
requestedUndo.set(true)
|
||||||
mainScope.launch {
|
launch {
|
||||||
onCancel.invoke()
|
onCancel.invoke()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +53,7 @@ fun allowUndo(
|
||||||
|
|
||||||
// Wait a bit, and if user didn't request cancellation, proceed with
|
// Wait a bit, and if user didn't request cancellation, proceed with
|
||||||
// requested operation and hide the snackbar.
|
// requested operation and hide the snackbar.
|
||||||
mainScope.launch {
|
launch {
|
||||||
delay(UNDO_DELAY)
|
delay(UNDO_DELAY)
|
||||||
|
|
||||||
if (!requestedUndo.get()) {
|
if (!requestedUndo.get()) {
|
||||||
|
|
|
@ -141,14 +141,14 @@ object Deps {
|
||||||
const val leanplum = "com.leanplum:leanplum-core:${Versions.leanplum}"
|
const val leanplum = "com.leanplum:leanplum-core:${Versions.leanplum}"
|
||||||
|
|
||||||
const val androidx_annotation = "androidx.annotation:annotation:${Versions.androidx_annotation}"
|
const val androidx_annotation = "androidx.annotation:annotation:${Versions.androidx_annotation}"
|
||||||
const val androidx_fragment = "androidx.fragment:fragment:${Versions.androidx_fragment}"
|
const val androidx_fragment = "androidx.fragment:fragment-ktx:${Versions.androidx_fragment}"
|
||||||
const val androidx_appcompat = "androidx.appcompat:appcompat:${Versions.androidx_appcompat}"
|
const val androidx_appcompat = "androidx.appcompat:appcompat:${Versions.androidx_appcompat}"
|
||||||
const val androidx_coordinatorlayout = "androidx.coordinatorlayout:coordinatorlayout:${Versions.androidx_coordinator_layout}"
|
const val androidx_coordinatorlayout = "androidx.coordinatorlayout:coordinatorlayout:${Versions.androidx_coordinator_layout}"
|
||||||
const val androidx_constraintlayout = "androidx.constraintlayout:constraintlayout:${Versions.androidx_constraint_layout}"
|
const val androidx_constraintlayout = "androidx.constraintlayout:constraintlayout:${Versions.androidx_constraint_layout}"
|
||||||
const val androidx_legacy = "androidx.legacy:legacy-support-v4:${Versions.androidx_legacy}"
|
const val androidx_legacy = "androidx.legacy:legacy-support-v4:${Versions.androidx_legacy}"
|
||||||
const val androidx_lifecycle_extensions = "androidx.lifecycle:lifecycle-extensions:${Versions.androidx_lifecycle}"
|
const val androidx_lifecycle_extensions = "androidx.lifecycle:lifecycle-extensions:${Versions.androidx_lifecycle}"
|
||||||
const val androidx_lifecycle_viewmodel_ktx = "androidx.lifecycle:lifecycle-viewmodel-ktx:${Versions.androidx_lifecycle}"
|
const val androidx_lifecycle_viewmodel = "androidx.lifecycle:lifecycle-viewmodel-ktx:${Versions.androidx_lifecycle}"
|
||||||
const val androidx_lifecycle_runtime = "androidx.lifecycle:lifecycle-runtime:${Versions.androidx_lifecycle}"
|
const val androidx_lifecycle_runtime = "androidx.lifecycle:lifecycle-runtime-ktx:${Versions.androidx_lifecycle}"
|
||||||
const val androidx_lifecycle_viewmodel_ss = "androidx.lifecycle:lifecycle-viewmodel-savedstate:${Versions.androidx_lifecycle_savedstate}"
|
const val androidx_lifecycle_viewmodel_ss = "androidx.lifecycle:lifecycle-viewmodel-savedstate:${Versions.androidx_lifecycle_savedstate}"
|
||||||
const val androidx_preference = "androidx.preference:preference-ktx:${Versions.androidx_preference}"
|
const val androidx_preference = "androidx.preference:preference-ktx:${Versions.androidx_preference}"
|
||||||
const val androidx_safeargs = "androidx.navigation:navigation-safe-args-gradle-plugin:${Versions.androidx_navigation}"
|
const val androidx_safeargs = "androidx.navigation:navigation-safe-args-gradle-plugin:${Versions.androidx_navigation}"
|
||||||
|
|
Loading…
Reference in New Issue