Fixes #26029: Add wallpaper state to AppStore

This commit is contained in:
MatthewTighe 2022-07-15 14:26:43 -07:00 committed by mergify[bot]
parent a167194697
commit 767d604315
8 changed files with 109 additions and 9 deletions

View File

@ -168,6 +168,7 @@ class Components(private val context: Context) {
strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
WallpaperManager(
settings,
appStore,
WallpaperDownloader(context, core.client),
WallpaperFileManager(context.filesDir),
currentLocale

View File

@ -21,6 +21,7 @@ import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem
import org.mozilla.fenix.library.history.PendingDeletionHistory
import org.mozilla.fenix.gleanplumb.Message
import org.mozilla.fenix.gleanplumb.MessagingState
import org.mozilla.fenix.wallpapers.Wallpaper
/**
* [Action] implementation related to [AppStore].
@ -146,4 +147,19 @@ sealed class AppAction : Action {
*/
data class MessageDismissed(val message: Message) : MessagingAction()
}
/**
* [Action]s related to interactions with the wallpapers feature.
*/
sealed class WallpaperAction : AppAction() {
/**
* Indicates that a different [wallpaper] was selected.
*/
data class UpdateCurrentWallpaper(val wallpaper: Wallpaper) : WallpaperAction()
/**
* Indicates that the list of potential wallpapers has changed.
*/
data class UpdateAvailableWallpapers(val wallpapers: List<Wallpaper>) : WallpaperAction()
}
}

View File

@ -22,6 +22,7 @@ import org.mozilla.fenix.home.recenttabs.RecentTab
import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem
import org.mozilla.fenix.library.history.PendingDeletionHistory
import org.mozilla.fenix.gleanplumb.MessagingState
import org.mozilla.fenix.wallpapers.WallpaperState
/**
* Value type that represents the state of the tabs tray.
@ -68,4 +69,5 @@ data class AppState(
val pocketSponsoredStories: List<PocketSponsoredStory> = emptyList(),
val messaging: MessagingState = MessagingState(),
val pendingDeletionHistoryItems: Set<PendingDeletionHistory> = emptySet(),
val wallpaperState: WallpaperState = WallpaperState.default
) : State

View File

@ -202,6 +202,14 @@ internal object AppStoreReducer {
is AppAction.UndoPendingDeletionSet ->
state.copy(pendingDeletionHistoryItems = state.pendingDeletionHistoryItems - action.historyItems)
is AppAction.WallpaperAction.UpdateCurrentWallpaper ->
state.copy(
wallpaperState = state.wallpaperState.copy(currentWallpaper = action.wallpaper)
)
is AppAction.WallpaperAction.UpdateAvailableWallpapers ->
state.copy(
wallpaperState = state.wallpaperState.copy(availableWallpapers = action.wallpapers)
)
}
}

View File

@ -46,7 +46,10 @@ import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import mozilla.components.browser.menu.view.MenuButton
import mozilla.components.browser.state.selector.findTab
@ -66,6 +69,7 @@ import mozilla.components.feature.top.sites.TopSitesFrecencyConfig
import mozilla.components.feature.top.sites.TopSitesProviderConfig
import mozilla.components.lib.state.ext.consumeFlow
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.lib.state.ext.flow
import mozilla.components.service.glean.private.NoExtras
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import mozilla.components.support.ktx.android.content.res.resolveAttribute
@ -390,6 +394,7 @@ class HomeFragment : Fragment() {
binding.root.doOnPreDraw {
requireComponents.appStore.dispatch(AppAction.UpdateFirstFrameDrawn(drawn = true))
}
// DO NOT MOVE ANYTHING BELOW THIS addMarker CALL!
requireComponents.core.engine.profiler?.addMarker(
MarkersFragmentLifecycleCallbacks.MARKER_NAME, profilerStartTime, "HomeFragment.onCreateView",
@ -401,7 +406,6 @@ class HomeFragment : Fragment() {
super.onConfigurationChanged(newConfig)
getMenuButton()?.dismissMenu()
displayWallpaperIfEnabled()
}
/**
@ -958,12 +962,20 @@ class HomeFragment : Fragment() {
private fun displayWallpaperIfEnabled() {
if (shouldEnableWallpaper()) {
val wallpaperManger = requireComponents.wallpaperManager
// We only want to update the wallpaper when it's different from the default one
// as the default is applied already on xml by default.
if (wallpaperManger.currentWallpaper != WallpaperManager.defaultWallpaper) {
wallpaperManger.updateWallpaper(binding.wallpaperImageView, wallpaperManger.currentWallpaper)
}
requireComponents.appStore.flow()
.ifChanged { state -> state.wallpaperState.currentWallpaper }
.onEach { state ->
// We only want to update the wallpaper when it's different from the default one
// as the default is applied already on xml by default.
val currentWallpaper = state.wallpaperState.currentWallpaper
if (currentWallpaper != WallpaperManager.defaultWallpaper) {
requireComponents.wallpaperManager.updateWallpaper(
binding.wallpaperImageView,
currentWallpaper
)
}
}
.launchIn(viewLifecycleOwner.lifecycleScope)
}
}

View File

@ -19,6 +19,8 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import mozilla.components.support.base.log.logger.Logger
import org.mozilla.fenix.R
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.perf.runBlockingIncrement
import org.mozilla.fenix.utils.Settings
import java.io.File
@ -30,6 +32,7 @@ import java.util.Date
@Suppress("TooManyFunctions")
class WallpaperManager(
private val settings: Settings,
private val appStore: AppStore,
private val downloader: WallpaperDownloader,
private val fileManager: WallpaperFileManager,
private val currentLocale: String,
@ -40,10 +43,14 @@ class WallpaperManager(
val wallpapers = allWallpapers
.filter(::filterExpiredRemoteWallpapers)
.filter(::filterPromotionalWallpapers)
.also {
appStore.dispatch(AppAction.WallpaperAction.UpdateAvailableWallpapers(it))
}
var currentWallpaper: Wallpaper = getCurrentWallpaperFromSettings()
set(value) {
settings.currentWallpaper = value.name
appStore.dispatch(AppAction.WallpaperAction.UpdateCurrentWallpaper(value))
field = value
}
@ -96,6 +103,8 @@ class WallpaperManager(
values.first()
} else {
values[index]
}.also {
appStore.dispatch(AppAction.WallpaperAction.UpdateCurrentWallpaper(it))
}
}
@ -122,6 +131,8 @@ class WallpaperManager(
wallpapers.find { it.name == currentWallpaper }
?: fileManager.lookupExpiredWallpaper(currentWallpaper)
?: defaultWallpaper
}.also {
appStore.dispatch(AppAction.WallpaperAction.UpdateCurrentWallpaper(it))
}
}

View File

@ -0,0 +1,23 @@
/* 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.wallpapers
/**
* Represents all state related to the Wallpapers feature.
*
* @property currentWallpaper The currently selected [Wallpaper].
* @property availableWallpapers The full list of wallpapers that can be selected.
*/
data class WallpaperState(
val currentWallpaper: Wallpaper,
val availableWallpapers: List<Wallpaper>,
) {
companion object {
val default = WallpaperState(
currentWallpaper = Wallpaper.Default,
availableWallpapers = listOf()
)
}
}

View File

@ -8,10 +8,12 @@ import io.mockk.mockk
import io.mockk.runs
import io.mockk.slot
import kotlinx.coroutines.test.runTest
import mozilla.components.support.test.libstate.ext.waitUntilIdle
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.utils.Settings
import java.util.Calendar
import java.util.Date
@ -30,18 +32,22 @@ class WallpaperManagerTest {
every { clean(any(), any()) } just runs
}
private val appStore = AppStore()
@Test
fun `WHEN wallpaper set THEN current wallpaper updated in settings`() {
fun `WHEN wallpaper set THEN current wallpaper updated in settings and dispatched to store`() {
val currentCaptureSlot = slot<String>()
every { mockSettings.currentWallpaper } returns ""
every { mockSettings.currentWallpaper = capture(currentCaptureSlot) } just runs
val updatedName = "new name"
val updatedWallpaper = Wallpaper.Local.Firefox(updatedName, drawableId = 0)
val wallpaperManager = WallpaperManager(mockSettings, mockk(), mockFileManager, "en-US", listOf())
val wallpaperManager = WallpaperManager(mockSettings, appStore, mockk(), mockFileManager, "en-US", listOf())
wallpaperManager.currentWallpaper = updatedWallpaper
assertEquals(updatedWallpaper.name, currentCaptureSlot.captured)
appStore.waitUntilIdle()
assertEquals(updatedWallpaper, appStore.state.wallpaperState.currentWallpaper)
}
@Test
@ -52,6 +58,7 @@ class WallpaperManagerTest {
}
val wallpaperManager = WallpaperManager(
mockSettings,
appStore,
mockDownloader,
mockFileManager,
"en-US",
@ -72,6 +79,7 @@ class WallpaperManagerTest {
}
val wallpaperManager = WallpaperManager(
mockSettings,
appStore,
mockDownloader,
mockFileManager,
"en-CA",
@ -94,6 +102,7 @@ class WallpaperManagerTest {
val fakeRemoteWallpapers = fakePromoWallpapers + fakeNonPromoWallpapers
val wallpaperManager = WallpaperManager(
mockSettings,
appStore,
mockDownloader,
mockFileManager,
"en-CA",
@ -116,6 +125,7 @@ class WallpaperManagerTest {
val activeRemoteWallpaper = makeFakeRemoteWallpaper(TimeRelation.LATER, "expired")
val wallpaperManager = WallpaperManager(
mockSettings,
appStore,
mockDownloader,
mockFileManager,
"en-US",
@ -137,6 +147,7 @@ class WallpaperManagerTest {
val wallpaperManager = WallpaperManager(
mockSettings,
appStore,
mockDownloader,
mockFileManager,
"en-US",
@ -157,6 +168,7 @@ class WallpaperManagerTest {
val wallpaperManager = WallpaperManager(
mockSettings,
appStore,
mockDownloader,
mockFileManager,
"en-US",
@ -193,6 +205,21 @@ class WallpaperManagerTest {
assertFalse(result)
}
@Test
fun `WHEN manager initialized THEN available wallpapers are dispatched to store`() {
every { mockSettings.currentWallpaper } returns WallpaperManager.defaultWallpaper.name
val wallpaperManager = WallpaperManager(
mockSettings,
appStore,
mockDownloader,
mockFileManager,
"en-US",
)
appStore.waitUntilIdle()
assertEquals(wallpaperManager.wallpapers, appStore.state.wallpaperState.availableWallpapers)
}
private enum class TimeRelation {
BEFORE,
NOW,