2019-02-13 00:04:01 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
2019-07-12 18:38:15 +00:00
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2019-01-09 22:22:58 +00:00
|
|
|
|
|
|
|
package org.mozilla.fenix.home
|
|
|
|
|
2021-08-17 07:43:57 +00:00
|
|
|
import android.annotation.SuppressLint
|
2021-01-29 20:16:21 +00:00
|
|
|
import android.content.res.Configuration
|
2019-01-28 23:26:37 +00:00
|
|
|
import android.graphics.drawable.BitmapDrawable
|
2020-03-18 14:41:18 +00:00
|
|
|
import android.graphics.drawable.ColorDrawable
|
2022-08-30 13:53:13 +00:00
|
|
|
import android.net.Uri
|
2019-01-09 22:22:58 +00:00
|
|
|
import android.os.Bundle
|
2020-06-08 17:45:33 +00:00
|
|
|
import android.os.StrictMode
|
2019-09-11 17:52:33 +00:00
|
|
|
import android.view.Gravity
|
2019-01-09 22:22:58 +00:00
|
|
|
import android.view.LayoutInflater
|
|
|
|
import android.view.View
|
|
|
|
import android.view.ViewGroup
|
2019-09-11 17:52:33 +00:00
|
|
|
import android.widget.Button
|
|
|
|
import android.widget.LinearLayout
|
|
|
|
import android.widget.PopupWindow
|
2021-01-27 21:54:48 +00:00
|
|
|
import androidx.annotation.VisibleForTesting
|
2020-09-18 23:13:57 +00:00
|
|
|
import androidx.appcompat.content.res.AppCompatResources
|
2020-02-04 04:40:51 +00:00
|
|
|
import androidx.constraintlayout.widget.ConstraintLayout
|
2020-02-10 18:32:26 +00:00
|
|
|
import androidx.constraintlayout.widget.ConstraintSet
|
|
|
|
import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
|
2020-03-11 21:08:58 +00:00
|
|
|
import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
|
2020-02-10 18:32:26 +00:00
|
|
|
import androidx.constraintlayout.widget.ConstraintSet.TOP
|
2020-02-04 04:40:51 +00:00
|
|
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
2020-01-21 21:02:14 +00:00
|
|
|
import androidx.core.content.ContextCompat
|
2022-08-17 08:37:59 +00:00
|
|
|
import androidx.core.view.isVisible
|
2020-02-04 04:40:51 +00:00
|
|
|
import androidx.core.view.updateLayoutParams
|
2019-01-15 01:42:58 +00:00
|
|
|
import androidx.fragment.app.Fragment
|
2019-08-08 16:05:01 +00:00
|
|
|
import androidx.fragment.app.activityViewModels
|
2019-05-16 21:02:24 +00:00
|
|
|
import androidx.lifecycle.Observer
|
2019-06-13 00:14:46 +00:00
|
|
|
import androidx.lifecycle.lifecycleScope
|
2019-08-20 17:45:41 +00:00
|
|
|
import androidx.navigation.fragment.findNavController
|
2020-06-10 22:34:26 +00:00
|
|
|
import androidx.navigation.fragment.navArgs
|
2022-06-14 00:18:46 +00:00
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
|
|
|
import androidx.recyclerview.widget.LinearSmoothScroller
|
|
|
|
import androidx.recyclerview.widget.RecyclerView.SmoothScroller
|
2020-12-03 20:30:00 +00:00
|
|
|
import com.google.android.material.appbar.AppBarLayout
|
2022-06-03 21:04:50 +00:00
|
|
|
import com.google.android.material.button.MaterialButton
|
2019-06-07 14:45:38 +00:00
|
|
|
import com.google.android.material.snackbar.Snackbar
|
2020-01-02 22:31:52 +00:00
|
|
|
import kotlinx.coroutines.Dispatchers.IO
|
|
|
|
import kotlinx.coroutines.Dispatchers.Main
|
2022-06-14 00:18:46 +00:00
|
|
|
import kotlinx.coroutines.MainScope
|
|
|
|
import kotlinx.coroutines.delay
|
2020-11-09 11:16:48 +00:00
|
|
|
import kotlinx.coroutines.flow.map
|
2019-05-01 00:45:56 +00:00
|
|
|
import kotlinx.coroutines.launch
|
2020-03-30 16:48:40 +00:00
|
|
|
import mozilla.components.browser.menu.view.MenuButton
|
2020-09-07 14:06:04 +00:00
|
|
|
import mozilla.components.browser.state.selector.findTab
|
2020-06-05 17:59:08 +00:00
|
|
|
import mozilla.components.browser.state.selector.normalTabs
|
|
|
|
import mozilla.components.browser.state.selector.privateTabs
|
2020-07-06 11:25:19 +00:00
|
|
|
import mozilla.components.browser.state.state.BrowserState
|
2020-11-09 11:16:48 +00:00
|
|
|
import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine
|
2020-07-23 19:27:39 +00:00
|
|
|
import mozilla.components.browser.state.store.BrowserStore
|
2020-10-14 15:19:35 +00:00
|
|
|
import mozilla.components.concept.storage.FrecencyThresholdOption
|
2019-05-23 04:40:10 +00:00
|
|
|
import mozilla.components.concept.sync.AccountObserver
|
2019-09-04 20:56:22 +00:00
|
|
|
import mozilla.components.concept.sync.AuthType
|
2019-05-23 04:40:10 +00:00
|
|
|
import mozilla.components.concept.sync.OAuthAccount
|
2019-07-23 21:15:46 +00:00
|
|
|
import mozilla.components.feature.tab.collections.TabCollection
|
2020-08-18 21:55:52 +00:00
|
|
|
import mozilla.components.feature.top.sites.TopSitesConfig
|
|
|
|
import mozilla.components.feature.top.sites.TopSitesFeature
|
2022-06-27 09:54:13 +00:00
|
|
|
import mozilla.components.feature.top.sites.TopSitesFrecencyConfig
|
2022-02-07 22:11:37 +00:00
|
|
|
import mozilla.components.feature.top.sites.TopSitesProviderConfig
|
2020-11-09 11:16:48 +00:00
|
|
|
import mozilla.components.lib.state.ext.consumeFlow
|
2020-04-30 20:53:10 +00:00
|
|
|
import mozilla.components.lib.state.ext.consumeFrom
|
2022-03-30 14:47:31 +00:00
|
|
|
import mozilla.components.service.glean.private.NoExtras
|
2020-08-18 21:55:52 +00:00
|
|
|
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
|
2020-09-18 23:13:57 +00:00
|
|
|
import mozilla.components.support.ktx.android.content.res.resolveAttribute
|
2020-11-09 11:16:48 +00:00
|
|
|
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
|
2021-02-04 23:42:05 +00:00
|
|
|
import org.mozilla.fenix.Config
|
2022-03-29 12:28:40 +00:00
|
|
|
import org.mozilla.fenix.GleanMetrics.Events
|
2022-04-15 07:28:16 +00:00
|
|
|
import org.mozilla.fenix.GleanMetrics.HomeScreen
|
2019-02-08 17:43:17 +00:00
|
|
|
import org.mozilla.fenix.HomeActivity
|
2019-01-09 22:22:58 +00:00
|
|
|
import org.mozilla.fenix.R
|
2020-03-30 19:07:00 +00:00
|
|
|
import org.mozilla.fenix.browser.BrowserAnimator.Companion.getToolbarNavOptions
|
2019-09-11 17:52:33 +00:00
|
|
|
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
2019-06-07 14:45:38 +00:00
|
|
|
import org.mozilla.fenix.components.FenixSnackbar
|
2019-09-11 17:52:33 +00:00
|
|
|
import org.mozilla.fenix.components.PrivateShortcutCreateManager
|
2019-06-07 14:45:38 +00:00
|
|
|
import org.mozilla.fenix.components.TabCollectionStorage
|
2022-03-07 01:13:19 +00:00
|
|
|
import org.mozilla.fenix.components.appstate.AppAction
|
2020-07-23 02:23:38 +00:00
|
|
|
import org.mozilla.fenix.components.toolbar.ToolbarPosition
|
2021-08-17 07:43:57 +00:00
|
|
|
import org.mozilla.fenix.databinding.FragmentHomeBinding
|
2019-08-30 17:42:46 +00:00
|
|
|
import org.mozilla.fenix.ext.components
|
2022-06-27 09:54:13 +00:00
|
|
|
import org.mozilla.fenix.ext.containsQueryParameters
|
2019-11-25 20:36:47 +00:00
|
|
|
import org.mozilla.fenix.ext.hideToolbar
|
2019-06-06 19:40:10 +00:00
|
|
|
import org.mozilla.fenix.ext.nav
|
2019-01-30 02:59:19 +00:00
|
|
|
import org.mozilla.fenix.ext.requireComponents
|
2021-01-05 21:15:22 +00:00
|
|
|
import org.mozilla.fenix.ext.runIfFragmentIsAttached
|
2021-02-04 23:42:05 +00:00
|
|
|
import org.mozilla.fenix.ext.settings
|
2022-03-22 22:02:42 +00:00
|
|
|
import org.mozilla.fenix.gleanplumb.DefaultMessageController
|
|
|
|
import org.mozilla.fenix.gleanplumb.MessagingFeature
|
2021-02-04 23:42:05 +00:00
|
|
|
import org.mozilla.fenix.home.mozonline.showPrivacyPopWindow
|
2021-10-06 20:25:17 +00:00
|
|
|
import org.mozilla.fenix.home.pocket.DefaultPocketStoriesController
|
|
|
|
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesCategory
|
2021-07-09 19:36:20 +00:00
|
|
|
import org.mozilla.fenix.home.recentbookmarks.RecentBookmarksFeature
|
|
|
|
import org.mozilla.fenix.home.recentbookmarks.controller.DefaultRecentBookmarksController
|
2022-03-28 20:13:07 +00:00
|
|
|
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTabFeature
|
|
|
|
import org.mozilla.fenix.home.recentsyncedtabs.controller.DefaultRecentSyncedTabController
|
2021-07-29 23:03:06 +00:00
|
|
|
import org.mozilla.fenix.home.recenttabs.RecentTabsListFeature
|
2021-06-09 19:33:11 +00:00
|
|
|
import org.mozilla.fenix.home.recenttabs.controller.DefaultRecentTabsController
|
2021-11-29 20:12:52 +00:00
|
|
|
import org.mozilla.fenix.home.recentvisits.RecentVisitsFeature
|
|
|
|
import org.mozilla.fenix.home.recentvisits.controller.DefaultRecentVisitsController
|
2019-12-05 03:06:05 +00:00
|
|
|
import org.mozilla.fenix.home.sessioncontrol.DefaultSessionControlController
|
|
|
|
import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
|
|
|
|
import org.mozilla.fenix.home.sessioncontrol.SessionControlView
|
2022-06-14 00:18:46 +00:00
|
|
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionHeaderViewHolder
|
2021-10-06 20:38:18 +00:00
|
|
|
import org.mozilla.fenix.home.topsites.DefaultTopSitesView
|
2022-01-28 12:48:05 +00:00
|
|
|
import org.mozilla.fenix.nimbus.FxNimbus
|
2019-05-16 03:46:52 +00:00
|
|
|
import org.mozilla.fenix.onboarding.FenixOnboarding
|
2021-10-13 23:13:16 +00:00
|
|
|
import org.mozilla.fenix.perf.MarkersFragmentLifecycleCallbacks
|
2022-08-17 20:56:38 +00:00
|
|
|
import org.mozilla.fenix.perf.runBlockingIncrement
|
2022-04-05 17:16:09 +00:00
|
|
|
import org.mozilla.fenix.tabstray.TabsTrayAccessPoint
|
2022-02-07 22:11:37 +00:00
|
|
|
import org.mozilla.fenix.utils.Settings.Companion.TOP_SITES_PROVIDER_MAX_THRESHOLD
|
2020-07-25 00:55:32 +00:00
|
|
|
import org.mozilla.fenix.utils.ToolbarPopupWindow
|
2020-06-10 22:34:26 +00:00
|
|
|
import org.mozilla.fenix.utils.allowUndo
|
2020-03-30 16:48:40 +00:00
|
|
|
import java.lang.ref.WeakReference
|
2019-11-26 18:07:31 +00:00
|
|
|
import kotlin.math.min
|
2019-01-28 23:26:37 +00:00
|
|
|
|
2020-06-23 00:38:58 +00:00
|
|
|
@Suppress("TooManyFunctions", "LargeClass")
|
2019-09-23 16:33:55 +00:00
|
|
|
class HomeFragment : Fragment() {
|
2020-06-12 22:55:07 +00:00
|
|
|
private val args by navArgs<HomeFragmentArgs>()
|
2022-08-31 14:46:22 +00:00
|
|
|
@VisibleForTesting
|
|
|
|
internal lateinit var bundleArgs: Bundle
|
2020-06-12 22:55:07 +00:00
|
|
|
|
2021-08-17 07:43:57 +00:00
|
|
|
private var _binding: FragmentHomeBinding? = null
|
|
|
|
private val binding get() = _binding!!
|
|
|
|
|
2020-10-30 23:13:52 +00:00
|
|
|
private val homeViewModel: HomeScreenViewModel by activityViewModels()
|
2020-03-10 13:07:31 +00:00
|
|
|
|
2020-01-31 15:55:02 +00:00
|
|
|
private val snackbarAnchorView: View?
|
2020-07-23 02:23:38 +00:00
|
|
|
get() = when (requireContext().settings().toolbarPosition) {
|
2021-08-17 07:43:57 +00:00
|
|
|
ToolbarPosition.BOTTOM -> binding.toolbarLayout
|
2020-07-23 02:23:38 +00:00
|
|
|
ToolbarPosition.TOP -> null
|
2020-01-31 15:55:02 +00:00
|
|
|
}
|
|
|
|
|
2020-02-23 05:46:50 +00:00
|
|
|
private val browsingModeManager get() = (activity as HomeActivity).browsingModeManager
|
2019-06-12 17:49:20 +00:00
|
|
|
|
2019-06-27 18:29:00 +00:00
|
|
|
private val collectionStorageObserver = object : TabCollectionStorage.Observer {
|
2021-08-17 07:43:57 +00:00
|
|
|
@SuppressLint("NotifyDataSetChanged")
|
2019-07-23 21:15:46 +00:00
|
|
|
override fun onCollectionRenamed(tabCollection: TabCollection, title: String) {
|
2020-09-20 22:45:00 +00:00
|
|
|
lifecycleScope.launch(Main) {
|
2021-08-17 07:43:57 +00:00
|
|
|
binding.sessionControlRecyclerView.adapter?.notifyDataSetChanged()
|
2020-09-20 22:45:00 +00:00
|
|
|
}
|
2019-06-27 18:29:00 +00:00
|
|
|
showRenamedSnackbar()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-23 19:27:39 +00:00
|
|
|
private val store: BrowserStore
|
|
|
|
get() = requireComponents.core.store
|
2019-06-14 15:59:57 +00:00
|
|
|
|
2020-08-22 01:44:51 +00:00
|
|
|
private val onboarding by lazy {
|
2020-09-24 23:35:36 +00:00
|
|
|
requireComponents.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
|
2020-08-22 01:44:51 +00:00
|
|
|
FenixOnboarding(requireContext())
|
|
|
|
}
|
|
|
|
}
|
2020-08-17 05:46:41 +00:00
|
|
|
|
2020-04-18 02:13:43 +00:00
|
|
|
private var _sessionControlInteractor: SessionControlInteractor? = null
|
2021-10-07 17:33:37 +00:00
|
|
|
private val sessionControlInteractor: SessionControlInteractor
|
2020-04-18 02:13:43 +00:00
|
|
|
get() = _sessionControlInteractor!!
|
|
|
|
|
2020-02-04 04:40:51 +00:00
|
|
|
private var sessionControlView: SessionControlView? = null
|
2020-12-03 20:30:00 +00:00
|
|
|
private var appBarLayout: AppBarLayout? = null
|
2019-09-23 16:33:55 +00:00
|
|
|
private lateinit var currentMode: CurrentMode
|
2022-08-25 16:20:23 +00:00
|
|
|
@VisibleForTesting
|
2022-08-31 14:46:22 +00:00
|
|
|
internal var wallpapersObserver: WallpapersObserver? = null
|
2019-02-08 18:35:48 +00:00
|
|
|
|
2020-08-18 21:55:52 +00:00
|
|
|
private val topSitesFeature = ViewBoundFeatureWrapper<TopSitesFeature>()
|
2022-03-22 22:02:42 +00:00
|
|
|
private val messagingFeature = ViewBoundFeatureWrapper<MessagingFeature>()
|
2021-06-09 19:33:11 +00:00
|
|
|
private val recentTabsListFeature = ViewBoundFeatureWrapper<RecentTabsListFeature>()
|
2022-03-28 20:13:07 +00:00
|
|
|
private val recentSyncedTabFeature = ViewBoundFeatureWrapper<RecentSyncedTabFeature>()
|
2021-07-09 19:36:20 +00:00
|
|
|
private val recentBookmarksFeature = ViewBoundFeatureWrapper<RecentBookmarksFeature>()
|
2021-11-29 20:12:52 +00:00
|
|
|
private val historyMetadataFeature = ViewBoundFeatureWrapper<RecentVisitsFeature>()
|
2020-08-18 21:55:52 +00:00
|
|
|
|
2021-01-29 20:16:21 +00:00
|
|
|
@VisibleForTesting
|
2021-08-17 07:43:57 +00:00
|
|
|
internal var getMenuButton: () -> MenuButton? = { binding.menuButton }
|
2021-01-29 20:16:21 +00:00
|
|
|
|
2019-05-22 18:46:31 +00:00
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
2021-10-13 23:13:16 +00:00
|
|
|
// DO NOT ADD ANYTHING ABOVE THIS getProfilerTime CALL!
|
|
|
|
val profilerStartTime = requireComponents.core.engine.profiler?.getProfilerTime()
|
|
|
|
|
2019-05-22 18:46:31 +00:00
|
|
|
super.onCreate(savedInstanceState)
|
2020-11-09 11:16:48 +00:00
|
|
|
|
2020-07-20 17:48:16 +00:00
|
|
|
bundleArgs = args.toBundle()
|
2020-10-30 07:04:37 +00:00
|
|
|
|
|
|
|
if (!onboarding.userHasBeenOnboarded() &&
|
|
|
|
requireContext().settings().shouldShowPrivacyPopWindow &&
|
2021-07-29 15:39:44 +00:00
|
|
|
Config.channel.isMozillaOnline
|
|
|
|
) {
|
2020-10-30 07:04:37 +00:00
|
|
|
showPrivacyPopWindow(requireContext(), requireActivity())
|
|
|
|
}
|
2021-10-13 23:13:16 +00:00
|
|
|
|
|
|
|
// DO NOT MOVE ANYTHING BELOW THIS addMarker CALL!
|
|
|
|
requireComponents.core.engine.profiler?.addMarker(
|
|
|
|
MarkersFragmentLifecycleCallbacks.MARKER_NAME, profilerStartTime, "HomeFragment.onCreate",
|
|
|
|
)
|
2019-05-22 18:46:31 +00:00
|
|
|
}
|
|
|
|
|
2020-08-29 20:39:38 +00:00
|
|
|
@Suppress("LongMethod")
|
2019-01-09 22:22:58 +00:00
|
|
|
override fun onCreateView(
|
2019-01-30 16:36:14 +00:00
|
|
|
inflater: LayoutInflater,
|
|
|
|
container: ViewGroup?,
|
2019-01-09 22:22:58 +00:00
|
|
|
savedInstanceState: Bundle?
|
2021-08-17 07:43:57 +00:00
|
|
|
): View {
|
2021-10-13 23:13:16 +00:00
|
|
|
// DO NOT ADD ANYTHING ABOVE THIS getProfilerTime CALL!
|
|
|
|
val profilerStartTime = requireComponents.core.engine.profiler?.getProfilerTime()
|
|
|
|
|
2021-08-17 07:43:57 +00:00
|
|
|
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
2019-12-05 03:06:05 +00:00
|
|
|
val activity = activity as HomeActivity
|
2020-07-17 20:07:01 +00:00
|
|
|
val components = requireComponents
|
2019-05-16 03:46:52 +00:00
|
|
|
|
2022-08-25 16:20:23 +00:00
|
|
|
if (shouldEnableWallpaper()) {
|
|
|
|
wallpapersObserver = WallpapersObserver(
|
|
|
|
appStore = components.appStore,
|
|
|
|
wallpapersUseCases = components.useCases.wallpaperUseCases,
|
|
|
|
wallpaperImageView = binding.wallpaperImageView,
|
|
|
|
).also {
|
|
|
|
viewLifecycleOwner.lifecycle.addObserver(it)
|
|
|
|
}
|
|
|
|
}
|
2022-08-17 20:56:38 +00:00
|
|
|
|
2019-09-23 16:33:55 +00:00
|
|
|
currentMode = CurrentMode(
|
2021-08-17 07:43:57 +00:00
|
|
|
requireContext(),
|
2019-09-23 16:33:55 +00:00
|
|
|
onboarding,
|
|
|
|
browsingModeManager,
|
2019-12-05 03:06:05 +00:00
|
|
|
::dispatchModeChanges
|
2019-09-23 16:33:55 +00:00
|
|
|
)
|
2019-05-06 18:20:19 +00:00
|
|
|
|
2022-03-16 17:56:17 +00:00
|
|
|
components.appStore.dispatch(AppAction.ModeChange(currentMode.getCurrentMode()))
|
|
|
|
|
2021-09-29 08:56:52 +00:00
|
|
|
lifecycleScope.launch(IO) {
|
2021-09-21 16:02:35 +00:00
|
|
|
if (requireContext().settings().showPocketRecommendationsFeature) {
|
2021-09-01 12:53:24 +00:00
|
|
|
val categories = components.core.pocketStoriesService.getStories()
|
|
|
|
.groupBy { story -> story.category }
|
2021-10-04 06:22:25 +00:00
|
|
|
.map { (category, stories) -> PocketRecommendedStoriesCategory(category, stories) }
|
2021-09-01 12:53:24 +00:00
|
|
|
|
2022-03-07 01:13:19 +00:00
|
|
|
components.appStore.dispatch(AppAction.PocketStoriesCategoriesChange(categories))
|
2022-04-29 15:59:28 +00:00
|
|
|
|
2022-05-25 15:32:25 +00:00
|
|
|
if (requireContext().settings().showPocketSponsoredStories) {
|
2022-04-29 15:59:28 +00:00
|
|
|
components.appStore.dispatch(
|
|
|
|
AppAction.PocketSponsoredStoriesChange(
|
|
|
|
components.core.pocketStoriesService.getSponsoredStories()
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
2021-09-29 08:56:52 +00:00
|
|
|
} else {
|
2022-05-02 14:15:27 +00:00
|
|
|
components.appStore.dispatch(AppAction.PocketStoriesClean)
|
2021-08-18 11:50:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-22 22:02:42 +00:00
|
|
|
if (requireContext().settings().isExperimentationEnabled) {
|
|
|
|
messagingFeature.set(
|
|
|
|
feature = MessagingFeature(
|
|
|
|
store = requireComponents.appStore,
|
|
|
|
),
|
|
|
|
owner = viewLifecycleOwner,
|
|
|
|
view = binding.root
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-03-11 17:54:23 +00:00
|
|
|
if (requireContext().settings().showTopSitesFeature) {
|
|
|
|
topSitesFeature.set(
|
|
|
|
feature = TopSitesFeature(
|
|
|
|
view = DefaultTopSitesView(
|
2022-03-07 01:13:19 +00:00
|
|
|
store = components.appStore,
|
2022-03-11 17:54:23 +00:00
|
|
|
settings = components.settings
|
|
|
|
),
|
|
|
|
storage = components.core.topSitesStorage,
|
|
|
|
config = ::getTopSitesConfig
|
2022-02-07 22:11:37 +00:00
|
|
|
),
|
2022-03-11 17:54:23 +00:00
|
|
|
owner = viewLifecycleOwner,
|
|
|
|
view = binding.root
|
|
|
|
)
|
|
|
|
}
|
2020-08-18 21:55:52 +00:00
|
|
|
|
2021-08-30 23:33:59 +00:00
|
|
|
if (requireContext().settings().showRecentTabsFeature) {
|
2021-06-09 19:33:11 +00:00
|
|
|
recentTabsListFeature.set(
|
|
|
|
feature = RecentTabsListFeature(
|
|
|
|
browserStore = components.core.store,
|
2022-03-07 01:13:19 +00:00
|
|
|
appStore = components.appStore
|
2021-06-09 19:33:11 +00:00
|
|
|
),
|
|
|
|
owner = viewLifecycleOwner,
|
2021-08-17 07:43:57 +00:00
|
|
|
view = binding.root
|
2021-06-09 19:33:11 +00:00
|
|
|
)
|
2022-03-28 20:13:07 +00:00
|
|
|
|
2022-05-26 23:54:29 +00:00
|
|
|
if (requireContext().settings().enableTaskContinuityEnhancements) {
|
2022-03-28 20:13:07 +00:00
|
|
|
recentSyncedTabFeature.set(
|
2022-07-08 22:25:04 +00:00
|
|
|
feature = RecentSyncedTabFeature(
|
2022-08-15 23:05:09 +00:00
|
|
|
context = requireContext(),
|
2022-07-08 22:25:04 +00:00
|
|
|
appStore = requireComponents.appStore,
|
|
|
|
syncStore = requireComponents.backgroundServices.syncStore,
|
|
|
|
storage = requireComponents.backgroundServices.syncedTabsStorage,
|
|
|
|
accountManager = requireComponents.backgroundServices.accountManager,
|
2022-07-26 23:06:00 +00:00
|
|
|
historyStorage = requireComponents.core.historyStorage,
|
2022-07-08 20:28:17 +00:00
|
|
|
coroutineScope = viewLifecycleOwner.lifecycleScope,
|
2022-07-08 22:25:04 +00:00
|
|
|
),
|
2022-03-28 20:13:07 +00:00
|
|
|
owner = viewLifecycleOwner,
|
|
|
|
view = binding.root
|
|
|
|
)
|
|
|
|
}
|
2021-06-09 19:33:11 +00:00
|
|
|
}
|
|
|
|
|
2021-08-30 23:33:59 +00:00
|
|
|
if (requireContext().settings().showRecentBookmarksFeature) {
|
2021-07-09 19:36:20 +00:00
|
|
|
recentBookmarksFeature.set(
|
|
|
|
feature = RecentBookmarksFeature(
|
2022-03-07 01:13:19 +00:00
|
|
|
appStore = components.appStore,
|
2021-07-09 19:36:20 +00:00
|
|
|
bookmarksUseCase = run {
|
|
|
|
requireContext().components.useCases.bookmarksUseCases
|
|
|
|
},
|
|
|
|
scope = viewLifecycleOwner.lifecycleScope
|
|
|
|
),
|
|
|
|
owner = viewLifecycleOwner,
|
2021-08-17 07:43:57 +00:00
|
|
|
view = binding.root
|
2021-07-09 19:36:20 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-08-19 20:54:49 +00:00
|
|
|
if (requireContext().settings().historyMetadataUIFeature) {
|
2021-06-23 22:00:56 +00:00
|
|
|
historyMetadataFeature.set(
|
2021-11-29 20:12:52 +00:00
|
|
|
feature = RecentVisitsFeature(
|
2022-03-07 01:13:19 +00:00
|
|
|
appStore = components.appStore,
|
2021-06-23 22:00:56 +00:00
|
|
|
historyMetadataStorage = components.core.historyStorage,
|
2021-11-29 20:12:52 +00:00
|
|
|
historyHighlightsStorage = components.core.lazyHistoryStorage,
|
2021-06-23 22:00:56 +00:00
|
|
|
scope = viewLifecycleOwner.lifecycleScope
|
|
|
|
),
|
|
|
|
owner = viewLifecycleOwner,
|
2021-08-17 07:43:57 +00:00
|
|
|
view = binding.root
|
2021-06-23 22:00:56 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2020-04-18 02:13:43 +00:00
|
|
|
_sessionControlInteractor = SessionControlInteractor(
|
2021-06-09 19:33:11 +00:00
|
|
|
controller = DefaultSessionControlController(
|
2019-12-05 03:06:05 +00:00
|
|
|
activity = activity,
|
2020-08-22 01:44:51 +00:00
|
|
|
settings = components.settings,
|
2020-07-17 20:07:01 +00:00
|
|
|
engine = components.core.engine,
|
2022-03-22 22:02:42 +00:00
|
|
|
messageController = DefaultMessageController(
|
|
|
|
appStore = components.appStore,
|
|
|
|
messagingStorage = components.analytics.messagingStorage,
|
2022-03-26 22:59:58 +00:00
|
|
|
homeActivity = activity,
|
2022-03-22 22:02:42 +00:00
|
|
|
),
|
2020-11-09 11:16:48 +00:00
|
|
|
store = store,
|
2020-07-17 20:07:01 +00:00
|
|
|
tabCollectionStorage = components.core.tabCollectionStorage,
|
|
|
|
addTabUseCase = components.useCases.tabsUseCases.addTab,
|
2020-12-14 13:45:10 +00:00
|
|
|
restoreUseCase = components.useCases.tabsUseCases.restore,
|
2020-12-07 17:32:27 +00:00
|
|
|
reloadUrlUseCase = components.useCases.sessionUseCases.reload,
|
2021-01-12 13:02:07 +00:00
|
|
|
selectTabUseCase = components.useCases.tabsUseCases.selectTab,
|
2022-03-07 01:13:19 +00:00
|
|
|
appStore = components.appStore,
|
2019-12-05 03:06:05 +00:00
|
|
|
navController = findNavController(),
|
2020-04-22 03:41:20 +00:00
|
|
|
viewLifecycleScope = viewLifecycleOwner.lifecycleScope,
|
2020-01-21 13:23:14 +00:00
|
|
|
hideOnboarding = ::hideOnboardingAndOpenSearch,
|
2019-12-05 03:06:05 +00:00
|
|
|
registerCollectionStorageObserver = ::registerCollectionStorageObserver,
|
2021-07-27 20:44:25 +00:00
|
|
|
removeCollectionWithUndo = ::removeCollectionWithUndo,
|
2021-10-07 17:56:37 +00:00
|
|
|
showTabTray = ::openTabsTray
|
2021-06-09 19:33:11 +00:00
|
|
|
),
|
|
|
|
recentTabController = DefaultRecentTabsController(
|
|
|
|
selectTabUseCase = components.useCases.tabsUseCases.selectTab,
|
2021-06-23 15:13:48 +00:00
|
|
|
navController = findNavController(),
|
2022-02-17 19:27:42 +00:00
|
|
|
store = components.core.store,
|
2022-03-07 01:13:19 +00:00
|
|
|
appStore = components.appStore,
|
2021-07-09 19:36:20 +00:00
|
|
|
),
|
2022-03-28 20:13:07 +00:00
|
|
|
recentSyncedTabController = DefaultRecentSyncedTabController(
|
2022-08-09 00:04:51 +00:00
|
|
|
tabsUseCase = requireComponents.useCases.tabsUseCases,
|
2022-03-28 20:13:07 +00:00
|
|
|
navController = findNavController(),
|
2022-04-05 17:16:09 +00:00
|
|
|
accessPoint = TabsTrayAccessPoint.HomeRecentSyncedTab,
|
2022-08-17 08:37:59 +00:00
|
|
|
appStore = components.appStore,
|
2022-03-28 20:13:07 +00:00
|
|
|
),
|
2021-07-09 19:36:20 +00:00
|
|
|
recentBookmarksController = DefaultRecentBookmarksController(
|
|
|
|
activity = activity,
|
2022-02-17 19:27:42 +00:00
|
|
|
navController = findNavController(),
|
2022-03-07 01:13:19 +00:00
|
|
|
appStore = components.appStore,
|
2021-06-23 22:00:56 +00:00
|
|
|
),
|
2021-11-29 20:12:52 +00:00
|
|
|
recentVisitsController = DefaultRecentVisitsController(
|
2021-09-14 23:35:44 +00:00
|
|
|
navController = findNavController(),
|
2022-03-07 01:13:19 +00:00
|
|
|
appStore = components.appStore,
|
2021-11-29 20:12:52 +00:00
|
|
|
selectOrAddTabUseCase = components.useCases.tabsUseCases.selectOrAddTab,
|
2021-09-14 23:35:44 +00:00
|
|
|
storage = components.core.historyStorage,
|
2021-10-13 08:54:30 +00:00
|
|
|
scope = viewLifecycleOwner.lifecycleScope,
|
2021-10-26 21:50:11 +00:00
|
|
|
store = components.core.store,
|
2021-09-01 12:53:24 +00:00
|
|
|
),
|
|
|
|
pocketStoriesController = DefaultPocketStoriesController(
|
2021-09-28 20:30:18 +00:00
|
|
|
homeActivity = activity,
|
2022-03-07 01:13:19 +00:00
|
|
|
appStore = components.appStore,
|
2021-10-06 06:06:05 +00:00
|
|
|
navController = findNavController(),
|
2019-12-05 03:06:05 +00:00
|
|
|
)
|
2019-02-17 02:55:49 +00:00
|
|
|
)
|
2020-08-29 20:39:38 +00:00
|
|
|
|
2021-08-17 07:43:57 +00:00
|
|
|
updateLayout(binding.root)
|
2020-02-04 06:15:18 +00:00
|
|
|
sessionControlView = SessionControlView(
|
2022-08-30 17:26:47 +00:00
|
|
|
containerView = binding.sessionControlRecyclerView,
|
|
|
|
viewLifecycleOwner = viewLifecycleOwner,
|
|
|
|
interactor = sessionControlInteractor,
|
2020-02-04 06:15:18 +00:00
|
|
|
)
|
2020-02-05 23:46:56 +00:00
|
|
|
|
2021-08-17 07:43:57 +00:00
|
|
|
updateSessionControlView()
|
2020-06-18 23:43:20 +00:00
|
|
|
|
2021-08-17 07:43:57 +00:00
|
|
|
appBarLayout = binding.homeAppBar
|
2020-12-03 20:30:00 +00:00
|
|
|
|
2020-06-18 23:43:20 +00:00
|
|
|
activity.themeManager.applyStatusBarTheme(activity)
|
2021-09-21 16:02:35 +00:00
|
|
|
|
2022-01-28 12:48:05 +00:00
|
|
|
FxNimbus.features.homescreen.recordExposure()
|
2021-10-13 23:13:16 +00:00
|
|
|
|
|
|
|
// DO NOT MOVE ANYTHING BELOW THIS addMarker CALL!
|
|
|
|
requireComponents.core.engine.profiler?.addMarker(
|
|
|
|
MarkersFragmentLifecycleCallbacks.MARKER_NAME, profilerStartTime, "HomeFragment.onCreateView",
|
|
|
|
)
|
2021-08-17 07:43:57 +00:00
|
|
|
return binding.root
|
2020-01-22 17:06:26 +00:00
|
|
|
}
|
|
|
|
|
2021-01-29 20:16:21 +00:00
|
|
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
|
|
|
super.onConfigurationChanged(newConfig)
|
|
|
|
|
|
|
|
getMenuButton()?.dismissMenu()
|
2022-08-25 16:20:23 +00:00
|
|
|
|
|
|
|
if (shouldEnableWallpaper()) {
|
|
|
|
// Setting the wallpaper is a potentially expensive operation - can take 100ms.
|
|
|
|
// Running this on the Main thread helps to ensure that the just updated configuration
|
|
|
|
// will be used when the wallpaper is scaled to match.
|
|
|
|
// Otherwise the portrait wallpaper may remain shown on landscape,
|
|
|
|
// see https://github.com/mozilla-mobile/fenix/issues/26638
|
|
|
|
runBlockingIncrement {
|
2022-08-31 14:46:22 +00:00
|
|
|
wallpapersObserver?.applyCurrentWallpaper()
|
2022-08-25 16:20:23 +00:00
|
|
|
}
|
|
|
|
}
|
2021-01-29 20:16:21 +00:00
|
|
|
}
|
|
|
|
|
2020-08-18 21:55:52 +00:00
|
|
|
/**
|
|
|
|
* Returns a [TopSitesConfig] which specifies how many top sites to display and whether or
|
|
|
|
* not frequently visited sites should be displayed.
|
|
|
|
*/
|
2021-01-27 21:54:48 +00:00
|
|
|
@VisibleForTesting
|
|
|
|
internal fun getTopSitesConfig(): TopSitesConfig {
|
2020-08-18 21:55:52 +00:00
|
|
|
val settings = requireContext().settings()
|
2020-10-14 15:19:35 +00:00
|
|
|
return TopSitesConfig(
|
2022-01-25 20:48:26 +00:00
|
|
|
totalSites = settings.topSitesMaxLimit,
|
2022-06-27 09:54:13 +00:00
|
|
|
frecencyConfig = TopSitesFrecencyConfig(
|
|
|
|
FrecencyThresholdOption.SKIP_ONE_TIME_PAGES
|
2022-08-30 13:53:13 +00:00
|
|
|
) { !Uri.parse(it.url).containsQueryParameters(settings.frecencyFilterQuery) },
|
2022-02-07 22:11:37 +00:00
|
|
|
providerConfig = TopSitesProviderConfig(
|
|
|
|
showProviderTopSites = settings.showContileFeature,
|
2022-04-28 11:46:15 +00:00
|
|
|
maxThreshold = TOP_SITES_PROVIDER_MAX_THRESHOLD,
|
|
|
|
providerFilter = { topSite ->
|
|
|
|
when (store.state.search.selectedOrDefaultSearchEngine?.name) {
|
|
|
|
AMAZON_SEARCH_ENGINE_NAME -> topSite.title != AMAZON_SPONSORED_TITLE
|
|
|
|
EBAY_SPONSORED_TITLE -> topSite.title != EBAY_SPONSORED_TITLE
|
|
|
|
else -> true
|
|
|
|
}
|
|
|
|
}
|
2022-02-07 22:11:37 +00:00
|
|
|
)
|
2020-10-14 15:19:35 +00:00
|
|
|
)
|
2020-08-18 21:55:52 +00:00
|
|
|
}
|
|
|
|
|
2020-06-18 23:43:20 +00:00
|
|
|
/**
|
|
|
|
* The [SessionControlView] is forced to update with our current state when we call
|
|
|
|
* [HomeFragment.onCreateView] in order to be able to draw everything at once with the current
|
|
|
|
* data in our store. The [View.consumeFrom] coroutine dispatch
|
|
|
|
* doesn't get run right away which means that we won't draw on the first layout pass.
|
|
|
|
*/
|
2021-08-17 07:43:57 +00:00
|
|
|
private fun updateSessionControlView() {
|
2020-06-26 18:54:20 +00:00
|
|
|
if (browsingModeManager.mode == BrowsingMode.Private) {
|
2022-03-07 01:13:19 +00:00
|
|
|
binding.root.consumeFrom(requireContext().components.appStore, viewLifecycleOwner) {
|
2020-06-26 18:54:20 +00:00
|
|
|
sessionControlView?.update(it)
|
|
|
|
}
|
|
|
|
} else {
|
2022-03-07 01:13:19 +00:00
|
|
|
sessionControlView?.update(requireContext().components.appStore.state)
|
2020-06-18 23:43:20 +00:00
|
|
|
|
2022-03-07 01:13:19 +00:00
|
|
|
binding.root.consumeFrom(requireContext().components.appStore, viewLifecycleOwner) {
|
2021-11-02 23:08:30 +00:00
|
|
|
sessionControlView?.update(it, shouldReportMetrics = true)
|
2020-06-26 18:54:20 +00:00
|
|
|
}
|
2020-06-18 23:43:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-22 17:06:26 +00:00
|
|
|
private fun updateLayout(view: View) {
|
2021-08-17 07:43:57 +00:00
|
|
|
when (requireContext().settings().toolbarPosition) {
|
2020-07-23 02:23:38 +00:00
|
|
|
ToolbarPosition.TOP -> {
|
2021-08-17 07:43:57 +00:00
|
|
|
binding.toolbarLayout.layoutParams = CoordinatorLayout.LayoutParams(
|
2020-07-23 02:23:38 +00:00
|
|
|
ConstraintLayout.LayoutParams.MATCH_PARENT,
|
|
|
|
ConstraintLayout.LayoutParams.WRAP_CONTENT
|
|
|
|
).apply {
|
2020-02-04 04:40:51 +00:00
|
|
|
gravity = Gravity.TOP
|
|
|
|
}
|
2019-02-26 22:21:29 +00:00
|
|
|
|
2020-07-23 02:23:38 +00:00
|
|
|
ConstraintSet().apply {
|
2021-08-17 07:43:57 +00:00
|
|
|
clone(binding.toolbarLayout)
|
|
|
|
clear(binding.bottomBar.id, BOTTOM)
|
|
|
|
clear(binding.bottomBarShadow.id, BOTTOM)
|
|
|
|
connect(binding.bottomBar.id, TOP, PARENT_ID, TOP)
|
|
|
|
connect(binding.bottomBarShadow.id, TOP, binding.bottomBar.id, BOTTOM)
|
|
|
|
connect(binding.bottomBarShadow.id, BOTTOM, PARENT_ID, BOTTOM)
|
|
|
|
applyTo(binding.toolbarLayout)
|
2020-07-23 02:23:38 +00:00
|
|
|
}
|
2020-02-10 18:32:26 +00:00
|
|
|
|
2021-08-17 07:43:57 +00:00
|
|
|
binding.bottomBar.background = AppCompatResources.getDrawable(
|
2020-09-18 23:13:57 +00:00
|
|
|
view.context,
|
|
|
|
view.context.theme.resolveAttribute(R.attr.bottomBarBackgroundTop)
|
2020-07-23 02:23:38 +00:00
|
|
|
)
|
2020-02-10 18:32:26 +00:00
|
|
|
|
2021-08-17 07:43:57 +00:00
|
|
|
binding.homeAppBar.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
2020-09-22 01:16:02 +00:00
|
|
|
topMargin =
|
|
|
|
resources.getDimensionPixelSize(R.dimen.home_fragment_top_toolbar_header_margin)
|
2020-07-23 02:23:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ToolbarPosition.BOTTOM -> {
|
|
|
|
}
|
2020-01-22 17:06:26 +00:00
|
|
|
}
|
2019-01-09 22:22:58 +00:00
|
|
|
}
|
2020-02-04 06:15:18 +00:00
|
|
|
|
2020-08-28 20:28:15 +00:00
|
|
|
@Suppress("LongMethod", "ComplexMethod")
|
2021-08-07 12:45:13 +00:00
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
2021-10-13 23:13:16 +00:00
|
|
|
// DO NOT ADD ANYTHING ABOVE THIS getProfilerTime CALL!
|
|
|
|
val profilerStartTime = requireComponents.core.engine.profiler?.getProfilerTime()
|
|
|
|
|
2021-08-07 12:45:13 +00:00
|
|
|
super.onViewCreated(view, savedInstanceState)
|
2022-04-15 07:28:16 +00:00
|
|
|
HomeScreen.homeScreenDisplayed.record(NoExtras())
|
|
|
|
HomeScreen.homeScreenViewCount.add()
|
2021-08-07 12:45:13 +00:00
|
|
|
|
|
|
|
observeSearchEngineChanges()
|
2022-04-28 11:46:15 +00:00
|
|
|
observeSearchEngineNameChanges()
|
2021-08-07 12:45:13 +00:00
|
|
|
|
2022-04-28 05:29:55 +00:00
|
|
|
HomeMenuBuilder(
|
|
|
|
view = view,
|
|
|
|
context = view.context,
|
|
|
|
lifecycleOwner = viewLifecycleOwner,
|
|
|
|
homeActivity = activity as HomeActivity,
|
|
|
|
navController = findNavController(),
|
|
|
|
menuButton = WeakReference(binding.menuButton),
|
|
|
|
hideOnboardingIfNeeded = ::hideOnboardingIfNeeded,
|
|
|
|
).build()
|
|
|
|
|
2022-04-30 01:43:21 +00:00
|
|
|
TabCounterBuilder(
|
|
|
|
context = requireContext(),
|
|
|
|
browsingModeManager = browsingModeManager,
|
|
|
|
navController = findNavController(),
|
|
|
|
tabCounter = binding.tabButton,
|
|
|
|
).build()
|
2019-02-02 00:04:49 +00:00
|
|
|
|
2021-08-17 07:43:57 +00:00
|
|
|
binding.toolbar.compoundDrawablePadding =
|
2021-08-07 12:45:13 +00:00
|
|
|
view.resources.getDimensionPixelSize(R.dimen.search_bar_search_engine_icon_padding)
|
2021-08-17 07:43:57 +00:00
|
|
|
binding.toolbarWrapper.setOnClickListener {
|
2021-08-07 12:45:13 +00:00
|
|
|
navigateToSearch()
|
|
|
|
}
|
2020-07-25 00:55:32 +00:00
|
|
|
|
2021-08-17 07:43:57 +00:00
|
|
|
binding.toolbarWrapper.setOnLongClickListener {
|
2021-08-07 12:45:13 +00:00
|
|
|
ToolbarPopupWindow.show(
|
|
|
|
WeakReference(it),
|
|
|
|
handlePasteAndGo = sessionControlInteractor::onPasteAndGo,
|
|
|
|
handlePaste = sessionControlInteractor::onPaste,
|
|
|
|
copyVisible = false
|
|
|
|
)
|
|
|
|
true
|
|
|
|
}
|
2020-04-30 20:53:10 +00:00
|
|
|
|
2021-09-01 23:54:24 +00:00
|
|
|
PrivateBrowsingButtonView(binding.privateBrowsingButton, browsingModeManager) { newMode ->
|
|
|
|
sessionControlInteractor.onPrivateModeButtonClicked(
|
|
|
|
newMode,
|
|
|
|
onboarding.userHasBeenOnboarded()
|
|
|
|
)
|
2021-08-07 12:45:13 +00:00
|
|
|
}
|
2020-07-20 17:48:16 +00:00
|
|
|
|
2021-08-07 12:45:13 +00:00
|
|
|
consumeFrom(requireComponents.core.store) {
|
|
|
|
updateTabCounter(it)
|
|
|
|
}
|
|
|
|
|
|
|
|
homeViewModel.sessionToDelete?.also {
|
|
|
|
if (it == ALL_NORMAL_TABS || it == ALL_PRIVATE_TABS) {
|
|
|
|
removeAllTabsAndShowSnackbar(it)
|
|
|
|
} else {
|
|
|
|
removeTabAndShowSnackbar(it)
|
2020-07-22 17:57:41 +00:00
|
|
|
}
|
2021-08-07 12:45:13 +00:00
|
|
|
}
|
2020-07-20 17:48:16 +00:00
|
|
|
|
2021-08-07 12:45:13 +00:00
|
|
|
homeViewModel.sessionToDelete = null
|
2020-09-24 22:39:24 +00:00
|
|
|
|
2021-08-07 12:45:13 +00:00
|
|
|
updateTabCounter(requireComponents.core.store.state)
|
2020-08-06 23:51:58 +00:00
|
|
|
|
2021-08-07 12:45:13 +00:00
|
|
|
if (bundleArgs.getBoolean(FOCUS_ON_ADDRESS_BAR)) {
|
|
|
|
navigateToSearch()
|
2022-06-14 00:18:46 +00:00
|
|
|
} else if (bundleArgs.getBoolean(SCROLL_TO_COLLECTION)) {
|
|
|
|
MainScope().launch {
|
|
|
|
delay(ANIM_SCROLL_DELAY)
|
|
|
|
val smoothScroller: SmoothScroller =
|
|
|
|
object : LinearSmoothScroller(sessionControlView!!.view.context) {
|
|
|
|
override fun getVerticalSnapPreference(): Int {
|
|
|
|
return SNAP_TO_START
|
|
|
|
}
|
|
|
|
}
|
|
|
|
val recyclerView = sessionControlView!!.view
|
|
|
|
val adapter = recyclerView.adapter!!
|
|
|
|
val collectionPosition = IntRange(0, adapter.itemCount - 1).firstOrNull {
|
|
|
|
adapter.getItemViewType(it) == CollectionHeaderViewHolder.LAYOUT_ID
|
|
|
|
}
|
|
|
|
collectionPosition?.run {
|
|
|
|
appBarLayout?.setExpanded(false)
|
|
|
|
val linearLayoutManager = recyclerView.layoutManager as LinearLayoutManager
|
|
|
|
smoothScroller.targetPosition = this
|
|
|
|
linearLayoutManager.startSmoothScroll(smoothScroller)
|
|
|
|
}
|
|
|
|
}
|
2020-08-06 23:51:58 +00:00
|
|
|
}
|
2021-10-13 23:13:16 +00:00
|
|
|
|
|
|
|
// DO NOT MOVE ANYTHING BELOW THIS addMarker CALL!
|
|
|
|
requireComponents.core.engine.profiler?.addMarker(
|
|
|
|
MarkersFragmentLifecycleCallbacks.MARKER_NAME, profilerStartTime, "HomeFragment.onViewCreated",
|
|
|
|
)
|
2021-08-07 12:45:13 +00:00
|
|
|
}
|
2020-07-22 17:57:41 +00:00
|
|
|
|
2020-11-09 11:16:48 +00:00
|
|
|
private fun observeSearchEngineChanges() {
|
|
|
|
consumeFlow(store) { flow ->
|
|
|
|
flow.map { state -> state.search.selectedOrDefaultSearchEngine }
|
|
|
|
.ifChanged()
|
|
|
|
.collect { searchEngine ->
|
|
|
|
if (searchEngine != null) {
|
|
|
|
val iconSize =
|
|
|
|
requireContext().resources.getDimensionPixelSize(R.dimen.preference_icon_drawable_size)
|
2021-01-27 21:54:48 +00:00
|
|
|
val searchIcon =
|
|
|
|
BitmapDrawable(requireContext().resources, searchEngine.icon)
|
2020-11-09 11:16:48 +00:00
|
|
|
searchIcon.setBounds(0, 0, iconSize, iconSize)
|
2021-08-17 07:43:57 +00:00
|
|
|
binding.searchEngineIcon.setImageDrawable(searchIcon)
|
2020-11-09 11:16:48 +00:00
|
|
|
} else {
|
2021-08-17 07:43:57 +00:00
|
|
|
binding.searchEngineIcon.setImageDrawable(null)
|
2020-11-09 11:16:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-28 11:46:15 +00:00
|
|
|
/**
|
|
|
|
* Method used to listen to search engine name changes and trigger a top sites update accordingly
|
|
|
|
*/
|
|
|
|
private fun observeSearchEngineNameChanges() {
|
|
|
|
consumeFlow(store) { flow ->
|
|
|
|
flow.map { state ->
|
|
|
|
when (state.search.selectedOrDefaultSearchEngine?.name) {
|
|
|
|
AMAZON_SEARCH_ENGINE_NAME -> AMAZON_SPONSORED_TITLE
|
|
|
|
EBAY_SPONSORED_TITLE -> EBAY_SPONSORED_TITLE
|
|
|
|
else -> null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.ifChanged()
|
|
|
|
.collect {
|
|
|
|
topSitesFeature.withFeature {
|
|
|
|
it.storage.notifyObservers { onStorageUpdated() }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-22 17:57:41 +00:00
|
|
|
private fun removeAllTabsAndShowSnackbar(sessionCode: String) {
|
2020-09-21 14:24:56 +00:00
|
|
|
if (sessionCode == ALL_PRIVATE_TABS) {
|
2021-01-26 00:14:52 +00:00
|
|
|
requireComponents.useCases.tabsUseCases.removePrivateTabs()
|
2020-09-21 14:24:56 +00:00
|
|
|
} else {
|
2021-01-26 00:14:52 +00:00
|
|
|
requireComponents.useCases.tabsUseCases.removeNormalTabs()
|
2020-07-20 17:48:16 +00:00
|
|
|
}
|
|
|
|
|
2020-07-22 17:57:41 +00:00
|
|
|
val snackbarMessage = if (sessionCode == ALL_PRIVATE_TABS) {
|
|
|
|
getString(R.string.snackbar_private_tabs_closed)
|
|
|
|
} else {
|
|
|
|
getString(R.string.snackbar_tabs_closed)
|
|
|
|
}
|
|
|
|
|
|
|
|
viewLifecycleOwner.lifecycleScope.allowUndo(
|
|
|
|
requireView(),
|
|
|
|
snackbarMessage,
|
|
|
|
requireContext().getString(R.string.snackbar_deleted_undo),
|
|
|
|
{
|
2020-09-21 14:24:56 +00:00
|
|
|
requireComponents.useCases.tabsUseCases.undo.invoke()
|
2020-07-22 17:57:41 +00:00
|
|
|
},
|
|
|
|
operation = { },
|
|
|
|
anchorView = snackbarAnchorView
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun removeTabAndShowSnackbar(sessionId: String) {
|
2020-09-21 14:24:56 +00:00
|
|
|
val tab = store.state.findTab(sessionId) ?: return
|
2020-07-22 17:57:41 +00:00
|
|
|
|
2020-09-21 14:24:56 +00:00
|
|
|
requireComponents.useCases.tabsUseCases.removeTab(sessionId)
|
2020-07-22 17:57:41 +00:00
|
|
|
|
2020-09-21 14:24:56 +00:00
|
|
|
val snackbarMessage = if (tab.content.private) {
|
|
|
|
requireContext().getString(R.string.snackbar_private_tab_closed)
|
|
|
|
} else {
|
|
|
|
requireContext().getString(R.string.snackbar_tab_closed)
|
2020-07-22 17:57:41 +00:00
|
|
|
}
|
2020-09-21 14:24:56 +00:00
|
|
|
|
|
|
|
viewLifecycleOwner.lifecycleScope.allowUndo(
|
|
|
|
requireView(),
|
|
|
|
snackbarMessage,
|
|
|
|
requireContext().getString(R.string.snackbar_deleted_undo),
|
|
|
|
{
|
|
|
|
requireComponents.useCases.tabsUseCases.undo.invoke()
|
2021-06-17 19:08:26 +00:00
|
|
|
findNavController().navigate(
|
2020-09-21 14:24:56 +00:00
|
|
|
HomeFragmentDirections.actionGlobalBrowser(null)
|
|
|
|
)
|
|
|
|
},
|
|
|
|
operation = { },
|
|
|
|
anchorView = snackbarAnchorView
|
|
|
|
)
|
2019-02-02 00:04:49 +00:00
|
|
|
}
|
|
|
|
|
2020-02-04 04:40:51 +00:00
|
|
|
override fun onDestroyView() {
|
2020-02-05 23:46:56 +00:00
|
|
|
super.onDestroyView()
|
2020-11-09 11:16:48 +00:00
|
|
|
|
2020-04-18 02:13:43 +00:00
|
|
|
_sessionControlInteractor = null
|
2020-02-04 04:40:51 +00:00
|
|
|
sessionControlView = null
|
2020-12-16 09:33:51 +00:00
|
|
|
appBarLayout = null
|
2022-08-31 14:46:22 +00:00
|
|
|
wallpapersObserver = null
|
2021-08-17 07:43:57 +00:00
|
|
|
_binding = null
|
2020-07-20 17:48:16 +00:00
|
|
|
bundleArgs.clear()
|
2020-02-04 04:40:51 +00:00
|
|
|
}
|
|
|
|
|
2019-11-26 22:53:03 +00:00
|
|
|
override fun onStart() {
|
|
|
|
super.onStart()
|
2020-11-09 11:16:48 +00:00
|
|
|
|
2019-11-26 22:53:03 +00:00
|
|
|
subscribeToTabCollections()
|
2019-05-23 04:40:10 +00:00
|
|
|
|
2019-08-30 17:42:46 +00:00
|
|
|
val context = requireContext()
|
2019-05-14 20:49:02 +00:00
|
|
|
|
2020-03-30 16:48:12 +00:00
|
|
|
requireComponents.backgroundServices.accountManagerAvailableQueue.runIfReadyOrQueue {
|
2020-04-17 01:06:57 +00:00
|
|
|
// By the time this code runs, we may not be attached to a context or have a view lifecycle owner.
|
|
|
|
if ((this@HomeFragment).view?.context == null) {
|
2020-03-30 16:48:12 +00:00
|
|
|
return@runIfReadyOrQueue
|
|
|
|
}
|
2020-04-17 01:06:57 +00:00
|
|
|
|
|
|
|
requireComponents.backgroundServices.accountManager.register(
|
|
|
|
currentMode,
|
|
|
|
owner = this@HomeFragment.viewLifecycleOwner
|
|
|
|
)
|
2021-07-29 15:39:44 +00:00
|
|
|
requireComponents.backgroundServices.accountManager.register(
|
|
|
|
object : AccountObserver {
|
|
|
|
override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
|
|
|
|
if (authType != AuthType.Existing) {
|
|
|
|
view?.let {
|
|
|
|
FenixSnackbar.make(
|
|
|
|
view = it,
|
|
|
|
duration = Snackbar.LENGTH_SHORT,
|
|
|
|
isDisplayedWithBrowserToolbar = false
|
|
|
|
)
|
|
|
|
.setText(it.context.getString(R.string.onboarding_firefox_account_sync_is_on))
|
2021-08-17 07:43:57 +00:00
|
|
|
.setAnchorView(binding.toolbarLayout)
|
2021-07-29 15:39:44 +00:00
|
|
|
.show()
|
|
|
|
}
|
2020-03-30 16:48:12 +00:00
|
|
|
}
|
2019-09-23 16:33:55 +00:00
|
|
|
}
|
2021-07-29 15:39:44 +00:00
|
|
|
},
|
|
|
|
owner = this@HomeFragment.viewLifecycleOwner
|
|
|
|
)
|
2020-03-30 16:48:12 +00:00
|
|
|
}
|
2019-10-03 19:04:27 +00:00
|
|
|
|
2020-09-22 01:16:02 +00:00
|
|
|
if (browsingModeManager.mode.isPrivate &&
|
2020-12-21 22:52:48 +00:00
|
|
|
// We will be showing the search dialog and don't want to show the CFR while the dialog shows
|
|
|
|
!bundleArgs.getBoolean(FOCUS_ON_ADDRESS_BAR) &&
|
|
|
|
context.settings().shouldShowPrivateModeCfr
|
2020-02-22 05:04:43 +00:00
|
|
|
) {
|
2019-09-11 17:52:33 +00:00
|
|
|
recommendPrivateBrowsingShortcut()
|
|
|
|
}
|
2019-06-27 18:29:00 +00:00
|
|
|
|
|
|
|
// We only want this observer live just before we navigate away to the collection creation screen
|
|
|
|
requireComponents.core.tabCollectionStorage.unregister(collectionStorageObserver)
|
2020-08-26 20:31:31 +00:00
|
|
|
|
|
|
|
lifecycleScope.launch(IO) {
|
|
|
|
requireComponents.reviewPromptController.promptReview(requireActivity())
|
|
|
|
}
|
2019-02-08 18:35:48 +00:00
|
|
|
}
|
|
|
|
|
2019-12-05 03:06:05 +00:00
|
|
|
private fun dispatchModeChanges(mode: Mode) {
|
2019-12-05 08:51:14 +00:00
|
|
|
if (mode != Mode.fromBrowsingMode(browsingModeManager.mode)) {
|
2022-03-07 01:13:19 +00:00
|
|
|
requireContext().components.appStore.dispatch(AppAction.ModeChange(mode))
|
2019-12-05 08:51:14 +00:00
|
|
|
}
|
2019-12-05 03:06:05 +00:00
|
|
|
}
|
|
|
|
|
2021-07-27 20:44:25 +00:00
|
|
|
@VisibleForTesting
|
|
|
|
internal fun removeCollectionWithUndo(tabCollection: TabCollection) {
|
|
|
|
val snackbarMessage = getString(R.string.snackbar_collection_deleted)
|
|
|
|
|
|
|
|
lifecycleScope.allowUndo(
|
|
|
|
requireView(),
|
|
|
|
snackbarMessage,
|
|
|
|
getString(R.string.snackbar_deleted_undo),
|
|
|
|
{
|
|
|
|
requireComponents.core.tabCollectionStorage.createCollection(tabCollection)
|
|
|
|
},
|
|
|
|
operation = { },
|
|
|
|
elevation = TOAST_ELEVATION,
|
|
|
|
anchorView = null
|
|
|
|
)
|
|
|
|
|
|
|
|
lifecycleScope.launch(IO) {
|
|
|
|
requireComponents.core.tabCollectionStorage.removeCollection(tabCollection)
|
|
|
|
}
|
2019-05-08 17:27:38 +00:00
|
|
|
}
|
|
|
|
|
2019-12-05 17:36:39 +00:00
|
|
|
override fun onResume() {
|
|
|
|
super.onResume()
|
2020-03-18 14:41:18 +00:00
|
|
|
if (browsingModeManager.mode == BrowsingMode.Private) {
|
|
|
|
activity?.window?.setBackgroundDrawableResource(R.drawable.private_home_background_gradient)
|
|
|
|
}
|
2020-06-10 22:34:26 +00:00
|
|
|
|
2019-12-05 17:36:39 +00:00
|
|
|
hideToolbar()
|
2021-11-16 22:05:29 +00:00
|
|
|
|
|
|
|
// Whenever a tab is selected its last access timestamp is automatically updated by A-C.
|
|
|
|
// However, in the case of resuming the app to the home fragment, we already have an
|
|
|
|
// existing selected tab, but its last access timestamp is outdated. No action is
|
|
|
|
// triggered to cause an automatic update on warm start (no tab selection occurs). So we
|
|
|
|
// update it manually here.
|
|
|
|
requireComponents.useCases.sessionUseCases.updateLastAccess()
|
2019-12-05 17:36:39 +00:00
|
|
|
}
|
|
|
|
|
2020-02-04 04:40:51 +00:00
|
|
|
override fun onPause() {
|
|
|
|
super.onPause()
|
2020-03-18 14:41:18 +00:00
|
|
|
if (browsingModeManager.mode == BrowsingMode.Private) {
|
|
|
|
activity?.window?.setBackgroundDrawable(
|
|
|
|
ColorDrawable(
|
|
|
|
ContextCompat.getColor(
|
|
|
|
requireContext(),
|
2022-02-21 16:40:34 +00:00
|
|
|
R.color.fx_mobile_private_layer_color_1
|
2020-03-18 14:41:18 +00:00
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
2021-11-16 22:05:29 +00:00
|
|
|
|
|
|
|
// Counterpart to the update in onResume to keep the last access timestamp of the selected
|
|
|
|
// tab up-to-date.
|
|
|
|
requireComponents.useCases.sessionUseCases.updateLastAccess()
|
2020-02-04 04:40:51 +00:00
|
|
|
}
|
|
|
|
|
2022-02-10 19:00:59 +00:00
|
|
|
@SuppressLint("InflateParams")
|
2019-09-11 17:52:33 +00:00
|
|
|
private fun recommendPrivateBrowsingShortcut() {
|
2020-09-22 01:16:02 +00:00
|
|
|
context?.let { context ->
|
|
|
|
val layout = LayoutInflater.from(context)
|
2019-09-11 17:52:33 +00:00
|
|
|
.inflate(R.layout.pbm_shortcut_popup, null)
|
2019-11-26 18:07:31 +00:00
|
|
|
val privateBrowsingRecommend =
|
2019-09-11 17:52:33 +00:00
|
|
|
PopupWindow(
|
|
|
|
layout,
|
2019-11-26 18:07:31 +00:00
|
|
|
min(
|
|
|
|
(resources.displayMetrics.widthPixels / CFR_WIDTH_DIVIDER).toInt(),
|
|
|
|
(resources.displayMetrics.heightPixels / CFR_WIDTH_DIVIDER).toInt()
|
|
|
|
),
|
2019-09-11 17:52:33 +00:00
|
|
|
LinearLayout.LayoutParams.WRAP_CONTENT,
|
|
|
|
true
|
|
|
|
)
|
|
|
|
layout.findViewById<Button>(R.id.cfr_pos_button).apply {
|
|
|
|
setOnClickListener {
|
|
|
|
PrivateShortcutCreateManager.createPrivateShortcut(context)
|
2019-11-26 18:07:31 +00:00
|
|
|
privateBrowsingRecommend.dismiss()
|
2019-09-11 17:52:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
layout.findViewById<Button>(R.id.cfr_neg_button).apply {
|
2019-09-10 16:42:46 +00:00
|
|
|
setOnClickListener {
|
2019-11-26 18:07:31 +00:00
|
|
|
privateBrowsingRecommend.dismiss()
|
2019-09-10 16:42:46 +00:00
|
|
|
}
|
2019-09-11 17:52:33 +00:00
|
|
|
}
|
|
|
|
// We want to show the popup only after privateBrowsingButton is available.
|
|
|
|
// Otherwise, we will encounter an activity token error.
|
2021-08-17 07:43:57 +00:00
|
|
|
binding.privateBrowsingButton.post {
|
2020-12-21 22:52:48 +00:00
|
|
|
runIfFragmentIsAttached {
|
|
|
|
context.settings().showedPrivateModeContextualFeatureRecommender = true
|
|
|
|
context.settings().lastCfrShownTimeInMillis = System.currentTimeMillis()
|
|
|
|
privateBrowsingRecommend.showAsDropDown(
|
2021-08-17 07:43:57 +00:00
|
|
|
binding.privateBrowsingButton, 0, CFR_Y_OFFSET, Gravity.TOP or Gravity.END
|
2020-12-21 22:52:48 +00:00
|
|
|
)
|
|
|
|
}
|
2019-09-11 17:52:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-20 17:56:28 +00:00
|
|
|
private fun hideOnboardingIfNeeded() {
|
2020-01-21 13:23:14 +00:00
|
|
|
if (!onboarding.userHasBeenOnboarded()) {
|
|
|
|
onboarding.finish()
|
2022-03-07 01:13:19 +00:00
|
|
|
requireContext().components.appStore.dispatch(
|
|
|
|
AppAction.ModeChange(
|
2020-06-05 17:59:08 +00:00
|
|
|
mode = currentMode.getCurrentMode()
|
2020-02-22 05:04:43 +00:00
|
|
|
)
|
|
|
|
)
|
2020-01-21 13:23:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun hideOnboardingAndOpenSearch() {
|
|
|
|
hideOnboardingIfNeeded()
|
2021-04-06 14:27:11 +00:00
|
|
|
appBarLayout?.setExpanded(true, true)
|
2020-01-21 13:23:14 +00:00
|
|
|
navigateToSearch()
|
2019-09-23 16:33:55 +00:00
|
|
|
}
|
|
|
|
|
2022-03-29 12:28:40 +00:00
|
|
|
@VisibleForTesting
|
|
|
|
internal fun navigateToSearch() {
|
2020-09-24 20:46:42 +00:00
|
|
|
val directions =
|
2020-08-05 23:22:07 +00:00
|
|
|
HomeFragmentDirections.actionGlobalSearchDialog(
|
|
|
|
sessionId = null
|
|
|
|
)
|
2020-02-27 21:29:47 +00:00
|
|
|
|
2020-03-30 19:07:00 +00:00
|
|
|
nav(R.id.homeFragment, directions, getToolbarNavOptions(requireContext()))
|
2022-03-29 12:28:40 +00:00
|
|
|
|
|
|
|
Events.searchBarTapped.record(Events.SearchBarTappedExtra("HOME"))
|
2019-08-20 17:56:28 +00:00
|
|
|
}
|
|
|
|
|
2019-05-16 21:02:24 +00:00
|
|
|
private fun subscribeToTabCollections(): Observer<List<TabCollection>> {
|
2019-07-23 21:15:46 +00:00
|
|
|
return Observer<List<TabCollection>> {
|
2019-05-16 21:35:15 +00:00
|
|
|
requireComponents.core.tabCollectionStorage.cachedTabCollections = it
|
2022-03-07 01:13:19 +00:00
|
|
|
requireComponents.appStore.dispatch(AppAction.CollectionsChange(it))
|
2019-07-23 21:15:46 +00:00
|
|
|
}.also { observer ->
|
|
|
|
requireComponents.core.tabCollectionStorage.getCollections().observe(this, observer)
|
2019-05-16 21:02:24 +00:00
|
|
|
}
|
2019-12-30 18:12:16 +00:00
|
|
|
}
|
|
|
|
|
2019-12-05 03:06:05 +00:00
|
|
|
private fun registerCollectionStorageObserver() {
|
|
|
|
requireComponents.core.tabCollectionStorage.register(collectionStorageObserver, this)
|
2019-08-20 17:45:41 +00:00
|
|
|
}
|
|
|
|
|
2019-06-07 14:45:38 +00:00
|
|
|
private fun showRenamedSnackbar() {
|
2019-06-13 00:14:46 +00:00
|
|
|
view?.let { view ->
|
|
|
|
val string = view.context.getString(R.string.snackbar_collection_renamed)
|
2020-04-02 19:30:13 +00:00
|
|
|
FenixSnackbar.make(
|
|
|
|
view = view,
|
|
|
|
duration = Snackbar.LENGTH_LONG,
|
2020-04-13 19:16:01 +00:00
|
|
|
isDisplayedWithBrowserToolbar = false
|
2020-04-02 19:30:13 +00:00
|
|
|
)
|
2019-09-24 23:24:19 +00:00
|
|
|
.setText(string)
|
2020-02-10 12:45:41 +00:00
|
|
|
.setAnchorView(snackbarAnchorView)
|
2019-09-24 23:24:19 +00:00
|
|
|
.show()
|
2019-06-07 14:45:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-01 03:12:37 +00:00
|
|
|
private fun openTabsTray() {
|
2020-07-23 22:56:45 +00:00
|
|
|
findNavController().nav(
|
|
|
|
R.id.homeFragment,
|
2021-06-01 03:12:37 +00:00
|
|
|
HomeFragmentDirections.actionGlobalTabsTrayFragment()
|
2020-07-23 22:56:45 +00:00
|
|
|
)
|
2020-05-28 15:22:12 +00:00
|
|
|
}
|
|
|
|
|
2020-11-16 21:45:48 +00:00
|
|
|
// TODO use [FenixTabCounterToolbarButton] instead of [TabCounter]:
|
|
|
|
// https://github.com/mozilla-mobile/fenix/issues/16792
|
2020-07-06 11:25:19 +00:00
|
|
|
private fun updateTabCounter(browserState: BrowserState) {
|
|
|
|
val tabCount = if (browsingModeManager.mode.isPrivate) {
|
|
|
|
browserState.privateTabs.size
|
|
|
|
} else {
|
|
|
|
browserState.normalTabs.size
|
|
|
|
}
|
|
|
|
|
2021-08-17 07:43:57 +00:00
|
|
|
binding.tabButton.setCountWithAnimation(tabCount)
|
2022-06-03 21:04:50 +00:00
|
|
|
// The add_tabs_to_collections_button is added at runtime. We need to search for it in the same way.
|
|
|
|
sessionControlView?.view?.findViewById<MaterialButton>(R.id.add_tabs_to_collections_button)
|
|
|
|
?.isVisible = tabCount > 0
|
2020-07-06 11:25:19 +00:00
|
|
|
}
|
|
|
|
|
2022-08-25 16:20:23 +00:00
|
|
|
@VisibleForTesting
|
|
|
|
internal fun shouldEnableWallpaper() =
|
2022-05-04 18:10:57 +00:00
|
|
|
(activity as? HomeActivity)?.themeManager?.currentTheme?.isPrivate?.not() ?: false
|
2021-12-21 13:33:41 +00:00
|
|
|
|
2019-01-30 16:36:14 +00:00
|
|
|
companion object {
|
2020-07-22 17:57:41 +00:00
|
|
|
const val ALL_NORMAL_TABS = "all_normal"
|
|
|
|
const val ALL_PRIVATE_TABS = "all_private"
|
|
|
|
|
2020-07-20 17:48:16 +00:00
|
|
|
private const val FOCUS_ON_ADDRESS_BAR = "focusOnAddressBar"
|
2020-12-03 20:30:00 +00:00
|
|
|
|
2022-06-14 00:18:46 +00:00
|
|
|
private const val SCROLL_TO_COLLECTION = "scrollToCollection"
|
|
|
|
private const val ANIM_SCROLL_DELAY = 100L
|
|
|
|
|
2019-09-11 17:52:33 +00:00
|
|
|
private const val CFR_WIDTH_DIVIDER = 1.7
|
|
|
|
private const val CFR_Y_OFFSET = -20
|
2021-07-27 20:44:25 +00:00
|
|
|
|
2022-04-28 11:46:15 +00:00
|
|
|
// Sponsored top sites titles and search engine names used for filtering
|
|
|
|
const val AMAZON_SPONSORED_TITLE = "Amazon"
|
|
|
|
const val AMAZON_SEARCH_ENGINE_NAME = "Amazon.com"
|
|
|
|
const val EBAY_SPONSORED_TITLE = "eBay"
|
|
|
|
|
2021-07-27 20:44:25 +00:00
|
|
|
// Elevation for undo toasts
|
|
|
|
internal const val TOAST_ELEVATION = 80f
|
2019-05-24 23:12:50 +00:00
|
|
|
}
|
|
|
|
}
|