1 /*
<lambda>null2  * Copyright (C) 2024 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.notifications.ui.composable
18 
19 import androidx.compose.foundation.gestures.Orientation
20 import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
21 import com.android.compose.nestedscroll.PriorityNestedScrollConnection
22 
23 /**
24  * A [NestedScrollConnection] that listens for all vertical scroll events and responds in the
25  * following way:
26  * - If you **scroll up**, it **first brings the [scrimOffset]** back to the [minScrimOffset] and
27  *   then allows scrolling of the children (usually the content).
28  * - If you **scroll down**, it **first allows scrolling of the children** (usually the content) and
29  *   then resets the [scrimOffset] to [maxScrimOffset].
30  */
31 fun NotificationScrimNestedScrollConnection(
32     scrimOffset: () -> Float,
33     snapScrimOffset: (Float) -> Unit,
34     animateScrimOffset: (Float) -> Unit,
35     minScrimOffset: () -> Float,
36     maxScrimOffset: Float,
37     contentHeight: () -> Float,
38     minVisibleScrimHeight: () -> Float,
39     isCurrentGestureOverscroll: () -> Boolean,
40     onStart: (Float) -> Unit = {},
<lambda>null41     onStop: (Float) -> Unit = {},
42 ): PriorityNestedScrollConnection {
43     return PriorityNestedScrollConnection(
44         orientation = Orientation.Vertical,
45         // scrolling up and inner content is taller than the scrim, so scrim needs to
46         // expand; content can scroll once scrim is at the minScrimOffset.
offsetBeforeStartnull47         canStartPreScroll = { offsetAvailable, offsetBeforeStart ->
48             offsetAvailable < 0 &&
49                 offsetBeforeStart == 0f &&
50                 contentHeight() > minVisibleScrimHeight() &&
51                 scrimOffset() > minScrimOffset()
52         },
53         // scrolling down and content is done scrolling to top. After that, the scrim
54         // needs to collapse; collapse the scrim until it is at the maxScrimOffset.
offsetAvailablenull55         canStartPostScroll = { offsetAvailable, _ ->
56             offsetAvailable > 0 && (scrimOffset() < maxScrimOffset || isCurrentGestureOverscroll())
57         },
<lambda>null58         canStartPostFling = { false },
<lambda>null59         canContinueScroll = {
60             val currentHeight = scrimOffset()
61             minScrimOffset() < currentHeight && currentHeight < maxScrimOffset
62         },
63         canScrollOnFling = true,
offsetAvailablenull64         onStart = { offsetAvailable -> onStart(offsetAvailable) },
offsetAvailablenull65         onScroll = { offsetAvailable ->
66             val currentHeight = scrimOffset()
67             val amountConsumed =
68                 if (offsetAvailable > 0) {
69                     val amountLeft = maxScrimOffset - currentHeight
70                     offsetAvailable.coerceAtMost(amountLeft)
71                 } else {
72                     val amountLeft = minScrimOffset() - currentHeight
73                     offsetAvailable.coerceAtLeast(amountLeft)
74                 }
75             snapScrimOffset(currentHeight + amountConsumed)
76             amountConsumed
77         },
78         // Don't consume the velocity on pre/post fling
velocityAvailablenull79         onStop = { velocityAvailable ->
80             onStop(velocityAvailable)
81             if (scrimOffset() < minScrimOffset()) {
82                 animateScrimOffset(minScrimOffset())
83             }
84             0f
85         },
86     )
87 }
88