1 /*
<lambda>null2  * Copyright (C) 2023 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 package com.android.wallpaper.picker.preview.ui.binder
17 
18 import android.content.Context
19 import android.content.res.Configuration
20 import android.view.View
21 import androidx.lifecycle.Lifecycle
22 import androidx.lifecycle.LifecycleOwner
23 import androidx.lifecycle.lifecycleScope
24 import androidx.lifecycle.repeatOnLifecycle
25 import com.android.systemui.monet.ColorScheme
26 import com.android.wallpaper.picker.customization.animation.view.LoadingAnimation
27 import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_APPLIED
28 import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_APPLY_FAILED
29 import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_APPLY_IN_PROGRESS
30 import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_DOWNLOAD_FAILED
31 import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_READY
32 import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
33 import com.android.wallpaper.util.ResourceUtils
34 import kotlinx.coroutines.launch
35 
36 object PreviewEffectsLoadingBinder {
37     interface Binding {
38         fun destroy()
39     }
40 
41     fun bind(
42         view: View,
43         viewModel: WallpaperPreviewViewModel,
44         viewLifecycleOwner: LifecycleOwner,
45     ): Binding {
46         var loadingAnimation: LoadingAnimation? = null
47         val job =
48             viewLifecycleOwner.lifecycleScope.launch {
49                 viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) {
50                     loadingAnimation = getLoadingAnimation(view)
51                     viewModel.imageEffectsModel.collect { model ->
52                         if (model.status == EFFECT_APPLY_IN_PROGRESS) {
53                             loadingAnimation?.playLoadingAnimation(seed = null)
54                         } else if (
55                             model.status == EFFECT_APPLIED ||
56                                 model.status == EFFECT_READY ||
57                                 model.status == EFFECT_DOWNLOAD_FAILED ||
58                                 model.status == EFFECT_APPLY_FAILED
59                         ) {
60                             // Play reveal animation whether applying the effect succeeded or
61                             // failed.
62                             loadingAnimation?.playRevealAnimation()
63                         }
64                     }
65                 }
66                 loadingAnimation?.cancel()
67                 loadingAnimation = null
68             }
69         return object : Binding {
70             override fun destroy() {
71                 job.cancel()
72                 loadingAnimation?.cancel()
73                 loadingAnimation = null
74             }
75         }
76     }
77 
78     private fun getLoadingAnimation(view: View): LoadingAnimation {
79         val context: Context = view.context
80         val loadingAnimation =
81             LoadingAnimation(
82                 revealOverlay = view,
83                 revealType = LoadingAnimation.RevealType.FADE,
84                 timeOutDuration = null
85             )
86         val colorAccent = ResourceUtils.getColorAttr(context, android.R.attr.colorAccent)
87         val isDarkTheme =
88             (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) ==
89                 Configuration.UI_MODE_NIGHT_YES
90         loadingAnimation.updateColor(ColorScheme(colorAccent, isDarkTheme))
91         return loadingAnimation
92     }
93 }
94