1 /* 2 * Copyright (C) 2025 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 package com.android.systemui.statusbar.notification.row.ui.viewmodel 18 19 import android.graphics.drawable.Drawable 20 import android.view.View 21 import androidx.compose.animation.core.tween 22 import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi 23 import androidx.compose.material3.MotionScheme 24 import androidx.compose.runtime.getValue 25 import androidx.compose.runtime.mutableStateOf 26 import androidx.compose.runtime.setValue 27 import androidx.compose.ui.unit.dp 28 import com.android.compose.animation.scene.MutableSceneTransitionLayoutState 29 import com.android.compose.animation.scene.SceneTransitionLayoutState 30 import com.android.compose.animation.scene.transitions 31 import com.android.systemui.notifications.ui.composable.row.BundleHeader 32 import kotlinx.coroutines.CoroutineScope 33 34 interface BundleHeaderViewModel { 35 val titleText: String 36 val numberOfChildren: Int? 37 val bundleIcon: Drawable? 38 val previewIcons: List<Drawable> 39 40 val state: SceneTransitionLayoutState 41 42 val hasUnreadMessages: Boolean 43 val backgroundDrawable: Drawable? 44 onHeaderClickednull45 fun onHeaderClicked(scope: CoroutineScope) 46 } 47 48 class BundleHeaderViewModelImpl : BundleHeaderViewModel { 49 override var titleText by mutableStateOf("") 50 override var numberOfChildren by mutableStateOf<Int?>(1) 51 override var hasUnreadMessages by mutableStateOf(true) 52 override var bundleIcon by mutableStateOf<Drawable?>(null) 53 override var previewIcons by mutableStateOf(listOf<Drawable>()) 54 override var backgroundDrawable by mutableStateOf<Drawable?>(null) 55 56 var onExpandClickListener: View.OnClickListener? = null 57 58 @OptIn(ExperimentalMaterial3ExpressiveApi::class) 59 override var state: MutableSceneTransitionLayoutState = 60 MutableSceneTransitionLayoutState( 61 BundleHeader.Scenes.Collapsed, 62 MotionScheme.standard(), 63 transitions { 64 from(BundleHeader.Scenes.Collapsed, to = BundleHeader.Scenes.Expanded) { 65 spec = tween(500) 66 translate(BundleHeader.Elements.PreviewIcon3, x = 32.dp) 67 translate(BundleHeader.Elements.PreviewIcon2, x = 16.dp) 68 fade(BundleHeader.Elements.PreviewIcon1) 69 fade(BundleHeader.Elements.PreviewIcon2) 70 fade(BundleHeader.Elements.PreviewIcon3) 71 } 72 }, 73 ) 74 75 override fun onHeaderClicked(scope: CoroutineScope) { 76 val targetScene = 77 when (state.currentScene) { 78 BundleHeader.Scenes.Collapsed -> BundleHeader.Scenes.Expanded 79 BundleHeader.Scenes.Expanded -> BundleHeader.Scenes.Collapsed 80 else -> error("Unknown Scene") 81 } 82 state.setTargetScene(targetScene, scope) 83 84 onExpandClickListener?.onClick(null) 85 hasUnreadMessages = false 86 } 87 } 88