Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Commit

Permalink
Closes #26750: add Wallpapers Onboarding dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
mike a authored and mergify[bot] committed Sep 12, 2022
1 parent 9361543 commit 65bee4b
Show file tree
Hide file tree
Showing 24 changed files with 360 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class FeatureSettingsHelper {
private var isRecentlyVisitedFeatureEnabled: Boolean = settings.historyMetadataUIFeature
private var isUserKnowsAboutPwasTrue: Boolean = settings.userKnowsAboutPwas
private var isTCPCFREnabled: Boolean = settings.shouldShowTotalCookieProtectionCFR
private var isWallpaperOnboardingEnabled: Boolean = settings.showWallpaperOnboarding

fun setPocketEnabled(enabled: Boolean) {
settings.showPocketRecommendationsFeature = enabled
Expand All @@ -28,6 +29,10 @@ class FeatureSettingsHelper {
settings.shouldShowJumpBackInCFR = enabled
}

fun setShowWallpaperOnboarding(enabled: Boolean) {
settings.showWallpaperOnboarding = enabled
}

fun setRecentTabsFeatureEnabled(enabled: Boolean) {
settings.showRecentTabsFeature = enabled
}
Expand Down Expand Up @@ -65,5 +70,6 @@ class FeatureSettingsHelper {
settings.historyMetadataUIFeature = isRecentlyVisitedFeatureEnabled
settings.userKnowsAboutPwas = isUserKnowsAboutPwasTrue
settings.shouldShowTotalCookieProtectionCFR = isTCPCFREnabled
settings.showWallpaperOnboarding = isWallpaperOnboardingEnabled
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class CrashReportingTest {
fun setUp() {
featureSettingsHelper.setJumpBackCFREnabled(false)
featureSettingsHelper.setPocketEnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)

mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
mockWebServer = MockWebServer().apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ class HomeScreenTest {
@Test
fun dismissOnboardingUsingHelpTest() {
featureSettingsHelper.setJumpBackCFREnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)

homeScreen {
verifyWelcomeHeader()
Expand Down Expand Up @@ -200,6 +201,7 @@ class HomeScreenTest {
fun verifyCustomizeHomepageTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
featureSettingsHelper.setJumpBackCFREnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)

navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class NoNetworkAccessStartupTests {
@Before
fun setUp() {
featureSettingsHelper.setTCPCFREnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)
}

@After
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class SearchTest {
featureSettingsHelper.setJumpBackCFREnabled(false)
featureSettingsHelper.setTCPCFREnabled(false)
featureSettingsHelper.setPocketEnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)
}

@After
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class SettingsBasicsTest {

featureSettingsHelper.setJumpBackCFREnabled(false)
featureSettingsHelper.setTCPCFREnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)
}

@After
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class SettingsHomepageTest {
}
featureSettingsHelper.setJumpBackCFREnabled(false)
featureSettingsHelper.setTCPCFREnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)
}

@After
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class SettingsPrivacyTest {

featureSettingsHelper.setJumpBackCFREnabled(false)
featureSettingsHelper.setTCPCFREnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)
featureSettingsHelper.disablePwaCFR(true)

if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class SettingsSearchTest {
start()
}
featureSettingsHelper.setJumpBackCFREnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)
}

@After
Expand Down
1 change: 1 addition & 0 deletions app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ class SmokeTest {
// disabling the new homepage pop-up that interferes with the tests.
featureSettingsHelper.setJumpBackCFREnabled(false)
featureSettingsHelper.setTCPCFREnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)

mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
mockWebServer = MockWebServer().apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class StrictEnhancedTrackingProtectionTest {
featureSettingsHelper.setStrictETPEnabled()
featureSettingsHelper.setJumpBackCFREnabled(false)
featureSettingsHelper.setTCPCFREnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)
}

@After
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class TabbedBrowsingTest {
// disabling the new homepage pop-up that interferes with the tests.
featureSettingsHelper.setJumpBackCFREnabled(false)
featureSettingsHelper.setTCPCFREnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)

mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
mockWebServer = MockWebServer().apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class TopSitesTest {

featureSettingsHelper.setJumpBackCFREnabled(false)
featureSettingsHelper.setTCPCFREnabled(false)
featureSettingsHelper.setShowWallpaperOnboarding(false)
}

@After
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,12 @@ import org.mozilla.fenix.gleanplumb.MessageController
import org.mozilla.fenix.home.HomeFragment
import org.mozilla.fenix.home.HomeFragmentDirections
import org.mozilla.fenix.home.Mode
import org.mozilla.fenix.onboarding.WallpaperOnboardingDialogFragment
import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.settings.SupportUtils.SumoTopic.PRIVATE_BROWSING_MYTHS
import org.mozilla.fenix.utils.Settings
import org.mozilla.fenix.wallpapers.Wallpaper
import org.mozilla.fenix.wallpapers.WallpaperState
import mozilla.components.feature.tab.collections.Tab as ComponentTab

/**
Expand Down Expand Up @@ -197,6 +200,11 @@ interface SessionControlController {
*/
fun handleCustomizeHomeTapped()

/**
* @see [OnboardingInteractor.showWallpapersOnboardingDialog]
*/
fun handleShowWallpapersOnboardingDialog(state: WallpaperState): Boolean

/**
* @see [SessionControlInteractor.reportSessionMetrics]
*/
Expand Down Expand Up @@ -501,6 +509,19 @@ class DefaultSessionControlController(
HomeScreen.customizeHomeClicked.record(NoExtras())
}

override fun handleShowWallpapersOnboardingDialog(state: WallpaperState): Boolean {
if (state.availableWallpapers.all { it.thumbnailFileState == Wallpaper.ImageFileState.Downloaded } &&
state.availableWallpapers.size >= WallpaperOnboardingDialogFragment.THUMBNAILS_COUNT
) {
navController.nav(
R.id.homeFragment,
HomeFragmentDirections.actionGlobalWallpaperOnboardingDialog(),
)
return true
}
return false
}

override fun handleReadPrivacyNoticeClicked() {
activity.openToBrowserAndLoad(
searchTermOrURL = SupportUtils.getMozillaPageUrl(SupportUtils.MozillaPage.PRIVATE_NOTICE),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem.RecentHistoryGrou
import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem.RecentHistoryHighlight
import org.mozilla.fenix.home.recentvisits.controller.RecentVisitsController
import org.mozilla.fenix.home.recentvisits.interactor.RecentVisitsInteractor
import org.mozilla.fenix.wallpapers.WallpaperState

/**
* Interface for tab related actions in the [SessionControlInteractor].
Expand Down Expand Up @@ -162,6 +163,15 @@ interface OnboardingInteractor {
* Opens a custom tab to privacy notice url. Called when a user clicks on the "read our privacy notice" button.
*/
fun onReadPrivacyNoticeClicked()

/**
* Show Wallpapers onboarding dialog to onboard users about the feature if conditions are met.
* Returns true if the call has been passed down to the controller.
*
* @param state The wallpaper state.
* @return Whether the onboarding dialog is currently shown.
*/
fun showWallpapersOnboardingDialog(state: WallpaperState): Boolean
}

interface CustomizeHomeIteractor {
Expand Down Expand Up @@ -322,6 +332,10 @@ class SessionControlInteractor(
controller.handleReadPrivacyNoticeClicked()
}

override fun showWallpapersOnboardingDialog(state: WallpaperState): Boolean {
return controller.handleShowWallpapersOnboardingDialog(state)
}

override fun onToggleCollectionExpanded(collection: TabCollection, expand: Boolean) {
controller.handleToggleCollectionExpanded(collection, expand)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,28 +199,43 @@ class SessionControlView(

val view: RecyclerView = containerView as RecyclerView

// We want to limit feature recommendations to one per HomePage visit.
var featureRecommended = false

private val sessionControlAdapter = SessionControlAdapter(
interactor,
viewLifecycleOwner,
containerView.context.components,
)

init {
@Suppress("NestedBlockDepth")
view.apply {
adapter = sessionControlAdapter
layoutManager = object : LinearLayoutManager(containerView.context) {
override fun onLayoutCompleted(state: RecyclerView.State?) {
super.onLayoutCompleted(state)

if (!context.settings().showHomeOnboardingDialog && (
context.settings().showSyncCFR ||
context.settings().shouldShowJumpBackInCFR
)
) {
HomeCFRPresenter(
context = context,
recyclerView = view,
).show()
if (!featureRecommended && !context.settings().showHomeOnboardingDialog) {
if (!context.settings().showHomeOnboardingDialog && (
context.settings().showSyncCFR ||
context.settings().shouldShowJumpBackInCFR
)
) {
featureRecommended = HomeCFRPresenter(
context = context,
recyclerView = view,
).show()
}

if (!context.settings().shouldShowJumpBackInCFR &&
context.settings().showWallpaperOnboarding &&
!featureRecommended
) {
featureRecommended = interactor.showWallpapersOnboardingDialog(
context.components.appStore.state.wallpaperState,
)
}
}

// We want some parts of the home screen UI to be rendered first if they are
Expand Down
16 changes: 10 additions & 6 deletions app/src/main/java/org/mozilla/fenix/onboarding/HomeCFRPresenter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,17 @@ class HomeCFRPresenter(
* Determine the CFR to be shown on the Home screen and show a CFR for the resultant view
* if any.
*/
fun show() {
when (val result = getCFRToShow()) {
is Result.SyncedTab -> showSyncedTabCFR(view = result.view)
is Result.JumpBackIn -> showJumpBackInCFR(view = result.view)
else -> {
// no-op
fun show(): Boolean {
return when (val result = getCFRToShow()) {
is Result.SyncedTab -> {
showSyncedTabCFR(view = result.view)
true
}
is Result.JumpBackIn -> {
showJumpBackInCFR(view = result.view)
true
}
else -> false
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */

package org.mozilla.fenix.onboarding

import android.annotation.SuppressLint
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.navigation.fragment.findNavController
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.coroutines.launch
import mozilla.components.lib.state.ext.observeAsComposableState
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.wallpapers.Wallpaper
import org.mozilla.fenix.wallpapers.WallpaperOnboarding

/**
* Dialog displaying the wallpapers onboarding.
*/
@OptIn(ExperimentalMaterialApi::class)
class WallpaperOnboardingDialogFragment : BottomSheetDialogFragment() {
private val appStore by lazy {
requireComponents.appStore
}

private val wallpaperUseCases by lazy {
requireComponents.useCases.wallpaperUseCases
}

@SuppressLint("SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.WallpaperOnboardingDialogStyle)
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}

override fun onDestroy() {
super.onDestroy()
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
requireContext().settings().showWallpaperOnboarding = false
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View = ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)

setContent {
FirefoxTheme {
val wallpapers = appStore.observeAsComposableState { state ->
state.wallpaperState.availableWallpapers.take(THUMBNAILS_COUNT)
}.value ?: listOf()
val currentWallpaper = appStore.observeAsComposableState { state ->
state.wallpaperState.currentWallpaper
}.value ?: Wallpaper.Default

val coroutineScope = rememberCoroutineScope()

WallpaperOnboarding(
wallpapers = wallpapers,
currentWallpaper = currentWallpaper,
onCloseClicked = { dismiss() },
onExploreMoreButtonClicked = {
val directions = NavGraphDirections.actionGlobalWallpaperSettingsFragment()
findNavController().navigate(directions)
},
loadWallpaperResource = { wallpaperUseCases.loadThumbnail(it) },
onSelectWallpaper = {
coroutineScope.launch { wallpaperUseCases.selectWallpaper(it) }
},
)
}
}
}

companion object {
const val THUMBNAILS_COUNT = 6
}
}
Loading

0 comments on commit 65bee4b

Please sign in to comment.