-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Closes #26750: add Wallpapers Onboarding dialog #26758
Changes from 2 commits
4d4b533
014e8db
ef7e05c
75e90df
32beec8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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]. | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: a period at the end of this comment for consistency |
||
*/ | ||
fun showWallpapersOnboardingDialog(state: WallpaperState): Boolean | ||
} | ||
|
||
interface CustomizeHomeIteractor { | ||
|
@@ -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) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, it will be. but There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think in general there is a future opportunity to solidify our work around when different onboarding items are shown. That said, I think this solution would work for now given the details @mavduevskiy has listed and our time constraints. |
||
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 | ||
|
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") | ||
MatthewTighe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 | ||
MatthewTighe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
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.subList(0, THUMBNAILS_COUNT) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
}.value ?: listOf() | ||
val currentWallpaper = appStore.observeAsComposableState { state -> | ||
state.wallpaperState.currentWallpaper | ||
}.value ?: Wallpaper.Default | ||
|
||
val coroutineScope = rememberCoroutineScope() | ||
|
||
WallpaperOnboarding( | ||
wallpapers = wallpapers, | ||
currentWallpaper = currentWallpaper, | ||
onCloseClicked = { dismiss() }, | ||
onBottomButtonClicked = { | ||
val directions = NavGraphDirections.actionGlobalWallpaperSettingsFragment() | ||
findNavController().navigate(directions) | ||
}, | ||
loadWallpaperResource = { wallpaperUseCases.loadThumbnail(it) }, | ||
onSelectWallpaper = { | ||
coroutineScope.launch { wallpaperUseCases.selectWallpaper(it) } | ||
}, | ||
) | ||
} | ||
} | ||
} | ||
|
||
companion object { | ||
const val THUMBNAILS_COUNT = 6 | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Add a new line above to separate the description and @param