• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 package com.android.wallpaper.picker.customization.ui.viewmodel
19 
20 import android.os.Bundle
21 import androidx.annotation.VisibleForTesting
22 import androidx.lifecycle.AbstractSavedStateViewModelFactory
23 import androidx.lifecycle.SavedStateHandle
24 import androidx.lifecycle.ViewModel
25 import androidx.savedstate.SavedStateRegistryOwner
26 import com.android.wallpaper.picker.undo.domain.interactor.UndoInteractor
27 import com.android.wallpaper.picker.undo.ui.viewmodel.UndoViewModel
28 import kotlinx.coroutines.flow.Flow
29 import kotlinx.coroutines.flow.MutableStateFlow
30 import kotlinx.coroutines.flow.asStateFlow
31 import kotlinx.coroutines.flow.map
32 
33 /** Models UI state for the customization picker. */
34 class CustomizationPickerViewModel
35 @VisibleForTesting
36 constructor(
37     undoInteractor: UndoInteractor,
38     private val savedStateHandle: SavedStateHandle,
39 ) : ViewModel() {
40 
41     val undo: UndoViewModel =
42         UndoViewModel(
43             interactor = undoInteractor,
44         )
45 
46     private val _isOnLockScreen = MutableStateFlow(true)
47     /** Whether we are on the lock screen. If `false`, we are on the home screen. */
48     val isOnLockScreen: Flow<Boolean> = _isOnLockScreen.asStateFlow()
49 
50     /** A view-model for the "lock screen" tab. */
51     val lockScreenTab: Flow<CustomizationPickerTabViewModel> =
52         isOnLockScreen.map { onLockScreen ->
53             CustomizationPickerTabViewModel(
54                 isSelected = onLockScreen,
55                 onClicked =
56                     if (!onLockScreen) {
57                         {
58                             _isOnLockScreen.value = true
59                             savedStateHandle[KEY_SAVED_STATE_IS_ON_LOCK_SCREEN] = true
60                         }
61                     } else {
62                         null
63                     }
64             )
65         }
66     /** A view-model for the "home screen" tab. */
67     val homeScreenTab: Flow<CustomizationPickerTabViewModel> =
68         isOnLockScreen.map { onLockScreen ->
69             CustomizationPickerTabViewModel(
70                 isSelected = !onLockScreen,
71                 onClicked =
72                     if (onLockScreen) {
73                         {
74                             _isOnLockScreen.value = false
75                             savedStateHandle[KEY_SAVED_STATE_IS_ON_LOCK_SCREEN] = false
76                         }
77                     } else {
78                         null
79                     }
80             )
81         }
82 
83     init {
84         savedStateHandle.get<Boolean>(KEY_SAVED_STATE_IS_ON_LOCK_SCREEN)?.let {
85             _isOnLockScreen.value = it
86         }
87     }
88 
89     /**
90      * Sets the initial screen we should be on, unless there's already a selected screen from a
91      * previous saved state, in which case we ignore the passed-in one.
92      */
93     fun setInitialScreen(onLockScreen: Boolean) {
94         _isOnLockScreen.value =
95             savedStateHandle[KEY_SAVED_STATE_IS_ON_LOCK_SCREEN]
96                 ?: run {
97                     savedStateHandle[KEY_SAVED_STATE_IS_ON_LOCK_SCREEN] = onLockScreen
98                     onLockScreen
99                 }
100     }
101 
102     companion object {
103         @JvmStatic
104         fun newFactory(
105             owner: SavedStateRegistryOwner,
106             defaultArgs: Bundle? = null,
107             undoInteractor: UndoInteractor,
108         ): AbstractSavedStateViewModelFactory =
109             object : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
110                 @Suppress("UNCHECKED_CAST")
111                 override fun <T : ViewModel> create(
112                     key: String,
113                     modelClass: Class<T>,
114                     handle: SavedStateHandle,
115                 ): T {
116                     return CustomizationPickerViewModel(
117                         undoInteractor = undoInteractor,
118                         savedStateHandle = handle,
119                     )
120                         as T
121                 }
122             }
123 
124         private const val KEY_SAVED_STATE_IS_ON_LOCK_SCREEN = "is_on_lock_screen"
125     }
126 }
127