From f1c4082bba9b5e83507f0f832b4e77c431ce10f9 Mon Sep 17 00:00:00 2001 From: Matthew Tighe Date: Thu, 13 Jan 2022 15:30:13 -0800 Subject: [PATCH] [fenix] closes https://github.com/mozilla-mobile/fenix/issues/22831: add wallpaper settings screen (https://github.com/mozilla-mobile/fenix/pull/23145) * closes https://github.com/mozilla-mobile/fenix/issues/22831: add wallpaper settings screen * address PR and UX feedback * rebase upstream and adjust settings correctly --- .../fenix/settings/HomeSettingsFragment.kt | 11 ++ .../settings/wallpaper/WallpaperSettings.kt | 142 ++++++++++++++++++ .../wallpaper/WallpaperSettingsFragment.kt | 49 ++++++ .../org/mozilla/fenix/wallpapers/Wallpaper.kt | 4 +- .../fenix/wallpapers/WallpaperManager.kt | 1 + app/src/main/res/navigation/nav_graph.xml | 14 +- app/src/main/res/values/preference_keys.xml | 1 + app/src/main/res/values/strings.xml | 6 + app/src/main/res/xml/home_preferences.xml | 5 + 9 files changed, 230 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/org/mozilla/fenix/settings/wallpaper/WallpaperSettings.kt create mode 100644 app/src/main/java/org/mozilla/fenix/settings/wallpaper/WallpaperSettingsFragment.kt diff --git a/app/src/main/java/org/mozilla/fenix/settings/HomeSettingsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/HomeSettingsFragment.kt index 370d2fb142..12e80364fe 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/HomeSettingsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/HomeSettingsFragment.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.settings import android.os.Bundle +import androidx.navigation.findNavController import androidx.preference.Preference import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat @@ -69,6 +70,16 @@ class HomeSettingsFragment : PreferenceFragmentCompat() { val openingScreenAfterFourHours = requirePreference(R.string.pref_key_start_on_home_after_four_hours) + requirePreference(R.string.pref_key_wallpapers).apply { + setOnPreferenceClickListener { + view?.findNavController()?.navigate( + HomeSettingsFragmentDirections.actionHomeSettingsFragmentToWallpaperSettingsFragment() + ) + true + } + isVisible = FeatureFlags.showWallpapers + } + requirePreference(R.string.pref_key_start_on_home_category).isVisible = FeatureFlags.showStartOnHomeSettings diff --git a/app/src/main/java/org/mozilla/fenix/settings/wallpaper/WallpaperSettings.kt b/app/src/main/java/org/mozilla/fenix/settings/wallpaper/WallpaperSettings.kt new file mode 100644 index 0000000000..2a353db562 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/settings/wallpaper/WallpaperSettings.kt @@ -0,0 +1,142 @@ +/* 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.settings.wallpaper + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.Image +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.GridCells +import androidx.compose.foundation.lazy.LazyVerticalGrid +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Surface +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import org.mozilla.fenix.R +import org.mozilla.fenix.theme.FirefoxTheme +import org.mozilla.fenix.wallpapers.Wallpaper + +/** + * The screen for controlling settings around Wallpapers. + * + * @param wallpapers Wallpapers to add to grid. + * @param selectedWallpaper The currently selected wallpaper. + * @param onSelectWallpaper Action to take when a new wallpaper is selected. + */ +@Composable +fun WallpaperSettings( + wallpapers: List, + selectedWallpaper: Wallpaper, + onSelectWallpaper: (Wallpaper) -> Unit, +) { + Surface(color = FirefoxTheme.colors.layer2) { + WallpaperThumbnails( + wallpapers = wallpapers, + selectedWallpaper = selectedWallpaper, + onSelectWallpaper = onSelectWallpaper + ) + } +} + +/** + * A grid of selectable wallpaper thumbnails. + * + * @param wallpapers Wallpapers to add to grid. + * @param selectedWallpaper The currently selected wallpaper. + * @param numColumns The number of columns that will occupy the grid. + * @param onSelectWallpaper Action to take when a new wallpaper is selected. + */ +@OptIn(ExperimentalFoundationApi::class) +@Composable +private fun WallpaperThumbnails( + wallpapers: List, + selectedWallpaper: Wallpaper, + numColumns: Int = 3, + onSelectWallpaper: (Wallpaper) -> Unit, +) { + LazyVerticalGrid( + cells = GridCells.Fixed(numColumns), + modifier = Modifier.padding(vertical = 30.dp, horizontal = 20.dp) + ) { + items(wallpapers) { wallpaper -> + WallpaperThumbnailItem( + wallpaper = wallpaper, + isSelected = selectedWallpaper == wallpaper, + onSelect = onSelectWallpaper + ) + } + } +} + +/** + * A single wallpaper thumbnail. + * + * @param wallpaper The wallpaper to display. + * @param isSelected Whether the wallpaper is currently selected. + * @param aspectRatio The ratio of height to width of the thumbnail. + * @param onSelect Action to take when this wallpaper is selected. + */ +@Composable +private fun WallpaperThumbnailItem( + wallpaper: Wallpaper, + isSelected: Boolean, + aspectRatio: Float = 1.1f, + onSelect: (Wallpaper) -> Unit +) { + val thumbnailShape = RoundedCornerShape(8.dp) + val border = if (isSelected) { + Modifier.border( + BorderStroke(width = 2.dp, color = FirefoxTheme.colors.borderAccent), + thumbnailShape + ) + } else { + Modifier + } + + Surface( + elevation = 4.dp, + shape = thumbnailShape, + color = FirefoxTheme.colors.layer1, + modifier = Modifier + .fillMaxWidth() + .aspectRatio(aspectRatio) + .padding(4.dp) + .then(border) + .clickable { onSelect(wallpaper) } + ) { + if (wallpaper != Wallpaper.NONE) { + val contentDescription = stringResource( + R.string.wallpapers_item_name_content_description, wallpaper.name + ) + Image( + painterResource(id = wallpaper.drawable), + contentScale = ContentScale.FillBounds, + contentDescription = contentDescription, + modifier = Modifier.fillMaxSize() + ) + } + } +} + +@Preview +@Composable +private fun WallpaperThumbnailsPreview() { + WallpaperSettings( + wallpapers = Wallpaper.values().toList(), + onSelectWallpaper = {}, + selectedWallpaper = Wallpaper.NONE + ) +} diff --git a/app/src/main/java/org/mozilla/fenix/settings/wallpaper/WallpaperSettingsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/wallpaper/WallpaperSettingsFragment.kt new file mode 100644 index 0000000000..2613ade085 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/settings/wallpaper/WallpaperSettingsFragment.kt @@ -0,0 +1,49 @@ +/* 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.settings.wallpaper + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.platform.ViewCompositionStrategy +import androidx.fragment.app.Fragment +import org.mozilla.fenix.ext.requireComponents +import org.mozilla.fenix.theme.FirefoxTheme +import org.mozilla.fenix.wallpapers.Wallpaper + +class WallpaperSettingsFragment : Fragment() { + private val wallpaperManager by lazy { + requireComponents.wallpaperManager + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return ComposeView(requireContext()).apply { + setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) + setContent { + FirefoxTheme { + var currentWallpaper by remember { mutableStateOf(wallpaperManager.currentWallpaper) } + WallpaperSettings( + wallpapers = Wallpaper.values().toList(), + selectedWallpaper = currentWallpaper, + onSelectWallpaper = { selectedWallpaper: Wallpaper -> + currentWallpaper = selectedWallpaper + wallpaperManager.currentWallpaper = selectedWallpaper + } + ) + } + } + } + } +} diff --git a/app/src/main/java/org/mozilla/fenix/wallpapers/Wallpaper.kt b/app/src/main/java/org/mozilla/fenix/wallpapers/Wallpaper.kt index 98792e054e..d4ea9c652c 100644 --- a/app/src/main/java/org/mozilla/fenix/wallpapers/Wallpaper.kt +++ b/app/src/main/java/org/mozilla/fenix/wallpapers/Wallpaper.kt @@ -10,7 +10,7 @@ import org.mozilla.fenix.R * A enum that represents the available wallpapers and their states. */ enum class Wallpaper(val drawable: Int, val isDark: Boolean) { + NONE(drawable = R.attr.homeBackground, isDark = false), FIRST(drawable = R.drawable.wallpaper_1, isDark = true), - SECOND(drawable = R.drawable.wallpaper_2, isDark = false), - NONE(drawable = R.attr.homeBackground, isDark = false); + SECOND(drawable = R.drawable.wallpaper_2, isDark = false); } diff --git a/app/src/main/java/org/mozilla/fenix/wallpapers/WallpaperManager.kt b/app/src/main/java/org/mozilla/fenix/wallpapers/WallpaperManager.kt index 1192cbe595..920b8e9ef3 100644 --- a/app/src/main/java/org/mozilla/fenix/wallpapers/WallpaperManager.kt +++ b/app/src/main/java/org/mozilla/fenix/wallpapers/WallpaperManager.kt @@ -71,6 +71,7 @@ class WallpaperManager(private val settings: Settings) { ) { settings.shouldUseDarkTheme = useDarkTheme settings.shouldUseLightTheme = useLightTheme + settings.shouldFollowDeviceTheme = false } /** diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index 821bdb8735..9a3440f784 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -620,7 +620,19 @@ + android:label="@string/preferences_home_2"> + + + pref_key_adjust_creative + pref_key_wallpapers pref_key_current_wallpaper pref_key_encryption_key_generated diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8d19ffa9cf..7fae7d7cc3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -452,6 +452,12 @@ Recent searches Pocket + + Wallpapers + + + + Wallpaper Item: %1$s diff --git a/app/src/main/res/xml/home_preferences.xml b/app/src/main/res/xml/home_preferences.xml index 97ce95c858..136a065d4e 100644 --- a/app/src/main/res/xml/home_preferences.xml +++ b/app/src/main/res/xml/home_preferences.xml @@ -29,6 +29,11 @@ android:title="@string/customize_toggle_pocket" app:isPreferenceVisible="false" /> + +