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.customization.picker.clock.ui.binder
17 
18 import android.content.Context
19 import android.content.res.Configuration
20 import androidx.core.content.ContextCompat
21 import androidx.core.view.isVisible
22 import androidx.lifecycle.Lifecycle
23 import androidx.lifecycle.LifecycleEventObserver
24 import androidx.lifecycle.LifecycleOwner
25 import androidx.lifecycle.lifecycleScope
26 import androidx.lifecycle.repeatOnLifecycle
27 import com.android.customization.picker.clock.ui.view.ClockCarouselView
28 import com.android.customization.picker.clock.ui.view.ClockViewFactory
29 import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
30 import com.android.wallpaper.picker.customization.ui.section.ScreenPreviewClickView
31 import kotlinx.coroutines.flow.combine
32 import kotlinx.coroutines.launch
33 
34 object ClockCarouselViewBinder {
35 
36     @JvmStatic
37     fun bind(
38         context: Context,
39         carouselView: ClockCarouselView,
40         screenPreviewClickView: ScreenPreviewClickView,
41         viewModel: ClockCarouselViewModel,
42         clockViewFactory: ClockViewFactory,
43         lifecycleOwner: LifecycleOwner,
44         isTwoPaneAndSmallWidth: Boolean,
45     ) {
46         carouselView.setClockViewFactory(clockViewFactory)
47         carouselView.isVisible = true
48         clockViewFactory.updateRegionDarkness()
49         val carouselAccessibilityDelegate =
50             CarouselAccessibilityDelegate(
51                 context,
52                 scrollForwardCallback = {
53                     // Callback code for scrolling forward
54                     carouselView.transitionToNext()
55                 },
56                 scrollBackwardCallback = {
57                     // Callback code for scrolling backward
58                     carouselView.transitionToPrevious()
59                 }
60             )
61         lifecycleOwner.lifecycleScope.launch {
62             lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
63                 launch {
64                     combine(viewModel.selectedClockSize, viewModel.allClocks, ::Pair).collect {
65                         (size, allClocks) ->
66                         carouselView.setUpClockCarouselView(
67                             clockSize = size,
68                             clocks = allClocks,
69                             onClockSelected = { clock ->
70                                 viewModel.setSelectedClock(clock.clockId)
71                             },
72                             isTwoPaneAndSmallWidth = isTwoPaneAndSmallWidth,
73                         )
74                         carouselView.accessibilityDelegate = carouselAccessibilityDelegate
75                         screenPreviewClickView.setOnSideClickedListener { isStart ->
76                             if (isStart) carouselView.scrollToPrevious()
77                             else carouselView.scrollToNext()
78                         }
79                     }
80                 }
81 
82                 launch {
83                     viewModel.allClocks.collect {
84                         it.forEach { clock -> clockViewFactory.updateTimeFormat(clock.clockId) }
85                     }
86                 }
87 
88                 launch {
89                     viewModel.selectedIndex.collect { selectedIndex ->
90                         carouselAccessibilityDelegate.contentDescriptionOfSelectedClock =
91                             carouselView.getContentDescription(selectedIndex)
92                         carouselView.setSelectedClockIndex(selectedIndex)
93                     }
94                 }
95 
96                 launch {
97                     viewModel.seedColor.collect { clockViewFactory.updateColorForAllClocks(it) }
98                 }
99 
100                 launch {
101                     val night =
102                         (context.resources.configuration.uiMode and
103                             Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES)
104                     viewModel.getClockCardColorResId(night).collect {
105                         carouselView.setCarouselCardColor(ContextCompat.getColor(context, it))
106                     }
107                 }
108             }
109         }
110 
111         lifecycleOwner.lifecycle.addObserver(
112             LifecycleEventObserver { source, event ->
113                 when (event) {
114                     Lifecycle.Event.ON_RESUME -> {
115                         clockViewFactory.registerTimeTicker(source)
116                     }
117                     Lifecycle.Event.ON_PAUSE -> {
118                         clockViewFactory.unregisterTimeTicker(source)
119                     }
120                     else -> {}
121                 }
122             }
123         )
124     }
125 }
126