@momo-kits/native-kits 0.152.4-beta.3 → 0.152.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -6
- package/shared/build.gradle.kts +74 -0
- package/CODE_OF_CONDUCT.md +0 -133
- package/CONTRIBUTING.md +0 -114
- package/LICENSE +0 -20
- package/README.md +0 -7
- package/build.gradle.kts +0 -32
- package/compose/MoMoComposeKits.podspec +0 -54
- package/compose/build.gradle.kts +0 -149
- package/compose/src/androidMain/AndroidManifest.xml +0 -2
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -105
- package/compose/src/commonMain/composeResources/files/lottie_circle_loader.json +0 -1
- package/compose/src/commonMain/composeResources/font/momosignature.otf +0 -0
- package/compose/src/commonMain/composeResources/font/momotrustdisplay.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_black.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_black.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_bold.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_heavy.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_light.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_medium.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_regular.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_semibold.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_thin.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_thin.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.ttf +0 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +0 -57
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -201
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -222
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -48
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +0 -86
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +0 -76
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +0 -76
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +0 -306
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -33
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +0 -715
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -214
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -236
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +0 -69
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +0 -77
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +0 -27
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +0 -334
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +0 -345
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -90
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +0 -131
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +0 -543
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +0 -23
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +0 -69
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +0 -143
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +0 -179
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +0 -111
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +0 -384
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +0 -160
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +0 -234
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +0 -223
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +0 -232
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -236
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +0 -228
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +0 -364
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +0 -50
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +0 -34
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +0 -85
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +0 -33
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -338
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +0 -95
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +0 -64
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +0 -89
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +0 -91
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +0 -86
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +0 -84
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +0 -208
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +0 -172
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +0 -199
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +0 -29
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +0 -237
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +0 -191
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +0 -306
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +0 -12
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +0 -13
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +0 -191
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +0 -258
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +0 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +0 -35
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +0 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -59
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -68
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +0 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -49
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +0 -51
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +0 -232
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +0 -111
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +0 -94
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -159
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +0 -232
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScaleSizeScope.kt +0 -17
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +0 -459
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +0 -169
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +0 -216
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +0 -86
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +0 -180
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +0 -251
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +0 -80
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +0 -306
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +0 -31
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +0 -385
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -38
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +0 -1329
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +0 -62
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -88
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -144
- package/gradle.properties +0 -19
- package/gradlew +0 -240
- package/gradlew.bat +0 -91
- package/ios/Application/ApplicationEnvironment.swift +0 -50
- package/ios/Application/Components.swift +0 -263
- package/ios/Application/ComposeApi.swift +0 -22
- package/ios/Application/FloatingButton.swift +0 -172
- package/ios/Application/HeaderRight.swift +0 -271
- package/ios/Application/Screen.swift +0 -249
- package/ios/Badge/BadgeDot.swift +0 -31
- package/ios/Button/Button.swift +0 -211
- package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +0 -126
- package/ios/Checkbox/Checkbox.swift +0 -81
- package/ios/Chip/Chip.swift +0 -96
- package/ios/Colors+Radius+Spacing/Colors.swift +0 -172
- package/ios/Colors+Radius+Spacing/Radius.swift +0 -22
- package/ios/Colors+Radius+Spacing/Spacing.swift +0 -12
- package/ios/Extensions/Color++.swift +0 -25
- package/ios/Icon/Icon.swift +0 -51
- package/ios/Image/Image.swift +0 -70
- package/ios/Input/Input.swift +0 -207
- package/ios/Input/InputPhoneNumber.swift +0 -176
- package/ios/Input/InputSearch.swift +0 -238
- package/ios/Input/InputTextArea.swift +0 -242
- package/ios/Lottie/LottieView.swift +0 -86
- package/ios/OTPKeyboard/KeyboardButton.swift +0 -41
- package/ios/OTPKeyboard/OTPKeyboard.swift +0 -145
- package/ios/Popup/PopupDisplay.swift +0 -284
- package/ios/Popup/PopupInput.swift +0 -96
- package/ios/Popup/PopupPromotion.swift +0 -73
- package/ios/PopupView/FullscreenPopup.swift +0 -251
- package/ios/PopupView/Modifiers.swift +0 -158
- package/ios/PopupView/PopupView.swift +0 -289
- package/ios/PopupView/Utils++.swift +0 -281
- package/ios/ScrollIndicator/ScrollIndicator.swift +0 -110
- package/ios/Swipeable/SwipeCell.swift +0 -278
- package/ios/Swipeable/SwipeCellModel.swift +0 -86
- package/ios/Switch/Switch.swift +0 -44
- package/ios/Template/Logo/Logo.swift +0 -75
- package/ios/Template/TrustBanner/TrustBanner.swift +0 -120
- package/ios/Theme.md +0 -18
- package/ios/Typography/Text.swift +0 -140
- package/ios/Typography/Typography.swift +0 -95
- package/ios/native-kits.podspec +0 -18
- package/settings.gradle.kts +0 -25
|
@@ -1,543 +0,0 @@
|
|
|
1
|
-
package vn.momo.kits.components
|
|
2
|
-
|
|
3
|
-
import androidx.compose.animation.core.AnimationState
|
|
4
|
-
import androidx.compose.animation.core.VectorConverter
|
|
5
|
-
import androidx.compose.animation.core.animateTo
|
|
6
|
-
import androidx.compose.animation.core.spring
|
|
7
|
-
import androidx.compose.foundation.OverscrollEffect
|
|
8
|
-
import androidx.compose.material.ExperimentalMaterialApi
|
|
9
|
-
import androidx.compose.runtime.Stable
|
|
10
|
-
import androidx.compose.runtime.State
|
|
11
|
-
import androidx.compose.runtime.getValue
|
|
12
|
-
import androidx.compose.runtime.mutableStateOf
|
|
13
|
-
import androidx.compose.runtime.setValue
|
|
14
|
-
import androidx.compose.ui.Modifier
|
|
15
|
-
import androidx.compose.ui.geometry.Offset
|
|
16
|
-
import androidx.compose.ui.geometry.Rect
|
|
17
|
-
import androidx.compose.ui.geometry.Size
|
|
18
|
-
import androidx.compose.ui.geometry.toRect
|
|
19
|
-
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
|
|
20
|
-
import androidx.compose.ui.graphics.drawscope.clipRect
|
|
21
|
-
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
|
22
|
-
import androidx.compose.ui.input.pointer.PointerEvent
|
|
23
|
-
import androidx.compose.ui.input.pointer.PointerEventPass
|
|
24
|
-
import androidx.compose.ui.input.pointer.PointerEventType
|
|
25
|
-
import androidx.compose.ui.layout.Measurable
|
|
26
|
-
import androidx.compose.ui.layout.MeasureResult
|
|
27
|
-
import androidx.compose.ui.layout.MeasureScope
|
|
28
|
-
import androidx.compose.ui.node.DelegatableNode
|
|
29
|
-
import androidx.compose.ui.node.DrawModifierNode
|
|
30
|
-
import androidx.compose.ui.node.LayoutAwareModifierNode
|
|
31
|
-
import androidx.compose.ui.node.LayoutModifierNode
|
|
32
|
-
import androidx.compose.ui.node.PointerInputModifierNode
|
|
33
|
-
import androidx.compose.ui.unit.Constraints
|
|
34
|
-
import androidx.compose.ui.unit.Density
|
|
35
|
-
import androidx.compose.ui.unit.Dp
|
|
36
|
-
import androidx.compose.ui.unit.IntOffset
|
|
37
|
-
import androidx.compose.ui.unit.IntSize
|
|
38
|
-
import androidx.compose.ui.unit.Velocity
|
|
39
|
-
import androidx.compose.ui.unit.dp
|
|
40
|
-
import androidx.compose.ui.unit.round
|
|
41
|
-
import androidx.compose.ui.unit.toOffset
|
|
42
|
-
import androidx.compose.ui.unit.toSize
|
|
43
|
-
import kotlinx.coroutines.CoroutineScope
|
|
44
|
-
import kotlinx.coroutines.cancel
|
|
45
|
-
import kotlinx.coroutines.isActive
|
|
46
|
-
import kotlin.coroutines.coroutineContext
|
|
47
|
-
import kotlin.math.abs
|
|
48
|
-
import kotlin.math.sign
|
|
49
|
-
|
|
50
|
-
private enum class CupertinoScrollSource {
|
|
51
|
-
DRAG, FLING
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
private enum class CupertinoOverscrollDirection {
|
|
55
|
-
UNKNOWN, VERTICAL, HORIZONTAL
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
private enum class CupertinoSpringAnimationReason {
|
|
59
|
-
FLING_FROM_OVERSCROLL, POSSIBLE_SPRING_IN_THE_END
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
private data class CupertinoOverscrollAvailableDelta(
|
|
64
|
-
|
|
65
|
-
val availableDelta: Float,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
val newOverscrollValue: Float
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
data class PullToRefreshCustomState(
|
|
72
|
-
val refreshingState: State<Boolean>,
|
|
73
|
-
val onRefresh: () -> Unit,
|
|
74
|
-
val threadHold: Dp = 140.dp,
|
|
75
|
-
val refreshOffset: Dp = 100.dp,
|
|
76
|
-
val sendHaptic: (() -> Unit)? = null,
|
|
77
|
-
) {
|
|
78
|
-
val position = mutableStateOf(0f)
|
|
79
|
-
|
|
80
|
-
fun updatePercentage(percentage: Float) {
|
|
81
|
-
position.value = percentage.coerceIn(0f, 1f)
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* CupertinoOverscrollEffect
|
|
87
|
-
*
|
|
88
|
-
* @param density to be taken into consideration during computations;
|
|
89
|
-
* Cupertino formulas use DPs, and scroll machinery uses raw values.
|
|
90
|
-
*
|
|
91
|
-
* @param applyClip Some consumers of overscroll effect apply clip by themselves and some don't,
|
|
92
|
-
* thus this flag is needed to update our modifier chain and make the clipping correct in every case while avoiding redundancy
|
|
93
|
-
*/
|
|
94
|
-
internal class CupertinoOverscrollEffect(
|
|
95
|
-
val pullRefreshState: PullToRefreshCustomState? = null,
|
|
96
|
-
private val density: Float,
|
|
97
|
-
val applyClip: Boolean
|
|
98
|
-
) : OverscrollEffect {
|
|
99
|
-
/*
|
|
100
|
-
* Direction of scrolling for this overscroll effect, derived from arguments during
|
|
101
|
-
* [applyToScroll] calls. Technically this effect supports both dimensions, but current API requires
|
|
102
|
-
* that different stages of animations spawned by this effect for both dimensions
|
|
103
|
-
* end at the same time, which is not the case:
|
|
104
|
-
* Spring->Fling->Spring, Fling->Spring, Spring->Fling effects can have different timing per dimension
|
|
105
|
-
* (see Notes of https://github.com/JetBrains/compose-multiplatform-core/pull/609),
|
|
106
|
-
* which is not possible to express without changing API. Hence this effect will be fixed to latest
|
|
107
|
-
* received delta.
|
|
108
|
-
*/
|
|
109
|
-
private var direction: CupertinoOverscrollDirection = CupertinoOverscrollDirection.UNKNOWN
|
|
110
|
-
|
|
111
|
-
/*
|
|
112
|
-
* Size of container is taking into consideration when computing rubber banding
|
|
113
|
-
*/
|
|
114
|
-
private var scrollSize: Size = Size.Zero
|
|
115
|
-
|
|
116
|
-
/*
|
|
117
|
-
* Current offset in overscroll area
|
|
118
|
-
* Negative for bottom-right
|
|
119
|
-
* Positive for top-left
|
|
120
|
-
* Zero if within the scrollable range
|
|
121
|
-
* It will be mapped to the actual visible offset using the rubber banding rule inside
|
|
122
|
-
* [Modifier.offset] within [effectModifier]
|
|
123
|
-
*/
|
|
124
|
-
private var overscrollOffsetState = mutableStateOf(Offset.Zero)
|
|
125
|
-
private var overscrollOffset: Offset
|
|
126
|
-
get() = overscrollOffsetState.value
|
|
127
|
-
set(value) {
|
|
128
|
-
overscrollOffsetState.value = value
|
|
129
|
-
drawCallScheduledByOffsetChange = true
|
|
130
|
-
}
|
|
131
|
-
private var drawCallScheduledByOffsetChange = true
|
|
132
|
-
|
|
133
|
-
private var lastFlingUnconsumedDelta: Offset = Offset.Zero
|
|
134
|
-
private val visibleOverscrollOffset: IntOffset
|
|
135
|
-
get() = overscrollOffsetState.value.rubberBanded().round()
|
|
136
|
-
|
|
137
|
-
override val isInProgress: Boolean
|
|
138
|
-
get() =
|
|
139
|
-
// If visible overscroll offset has at least one pixel
|
|
140
|
-
// this effect is considered to be in progress
|
|
141
|
-
visibleOverscrollOffset.toOffset().getDistance() > 0.5f
|
|
142
|
-
|
|
143
|
-
@OptIn(ExperimentalMaterialApi::class)
|
|
144
|
-
private val overscrollNode = CupertinoOverscrollNode(
|
|
145
|
-
pullRefreshState = pullRefreshState,
|
|
146
|
-
offset = { visibleOverscrollOffset },
|
|
147
|
-
onNodeRemeasured = { scrollSize = it.toSize() },
|
|
148
|
-
onDraw = ::onDraw,
|
|
149
|
-
applyClip = applyClip
|
|
150
|
-
)
|
|
151
|
-
override val node: DelegatableNode get() = overscrollNode
|
|
152
|
-
|
|
153
|
-
private fun onDraw() {
|
|
154
|
-
// Fix an issue where scrolling was cancelled but the overscroll effect was not completed.
|
|
155
|
-
// Reset the overscroll effect when no ongoing animation or interaction is applied.
|
|
156
|
-
if (!drawCallScheduledByOffsetChange && isInProgress && overscrollNode.pointersDown == 0) {
|
|
157
|
-
overscrollOffsetState.value = Offset.Zero
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
drawCallScheduledByOffsetChange = false
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
private fun NestedScrollSource.toCupertinoScrollSource(): CupertinoScrollSource? =
|
|
164
|
-
when (this) {
|
|
165
|
-
NestedScrollSource.UserInput -> CupertinoScrollSource.DRAG
|
|
166
|
-
NestedScrollSource.SideEffect -> CupertinoScrollSource.FLING
|
|
167
|
-
else -> null
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/*
|
|
171
|
-
* Takes input scroll delta, current overscroll value, and scroll source, return [CupertinoOverscrollAvailableDelta]
|
|
172
|
-
*/
|
|
173
|
-
@Stable
|
|
174
|
-
private fun availableDelta(
|
|
175
|
-
delta: Float,
|
|
176
|
-
overscroll: Float,
|
|
177
|
-
source: CupertinoScrollSource
|
|
178
|
-
): CupertinoOverscrollAvailableDelta {
|
|
179
|
-
// if source is fling:
|
|
180
|
-
// 1. no delta will be consumed
|
|
181
|
-
// 2. overscroll will stay the same
|
|
182
|
-
if (source == CupertinoScrollSource.FLING) {
|
|
183
|
-
return CupertinoOverscrollAvailableDelta(delta, overscroll)
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
val newOverscroll = overscroll + delta
|
|
187
|
-
|
|
188
|
-
return if (delta >= 0f && overscroll <= 0f) {
|
|
189
|
-
if (newOverscroll > 0f) {
|
|
190
|
-
CupertinoOverscrollAvailableDelta(newOverscroll, 0f)
|
|
191
|
-
} else {
|
|
192
|
-
CupertinoOverscrollAvailableDelta(0f, newOverscroll)
|
|
193
|
-
}
|
|
194
|
-
} else if (delta <= 0f && overscroll >= 0f) {
|
|
195
|
-
if (newOverscroll < 0f) {
|
|
196
|
-
CupertinoOverscrollAvailableDelta(newOverscroll, 0f)
|
|
197
|
-
} else {
|
|
198
|
-
CupertinoOverscrollAvailableDelta(0f, newOverscroll)
|
|
199
|
-
}
|
|
200
|
-
} else {
|
|
201
|
-
CupertinoOverscrollAvailableDelta(0f, newOverscroll)
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/*
|
|
206
|
-
* Returns the amount of scroll delta available after user performed scroll inside overscroll area
|
|
207
|
-
* It will update [overscroll] resulting in visual change because of [Modifier.offset] depending on it
|
|
208
|
-
*/
|
|
209
|
-
private fun availableDelta(delta: Offset, source: CupertinoScrollSource): Offset {
|
|
210
|
-
val (x, overscrollX) = availableDelta(delta.x, overscrollOffset.x, source)
|
|
211
|
-
val (y, overscrollY) = availableDelta(delta.y, overscrollOffset.y, source)
|
|
212
|
-
println("availableDelta delta=${delta.y} consumed y=$y overscrollY=$overscrollY source=${source}")
|
|
213
|
-
overscrollOffset = Offset(overscrollX, overscrollY)
|
|
214
|
-
|
|
215
|
-
return Offset(x, y)
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/*
|
|
219
|
-
* Semantics of this method match the [OverscrollEffect.applyToScroll] one,
|
|
220
|
-
* The only difference is NestedScrollSource being remapped to CupertinoScrollSource to narrow
|
|
221
|
-
* processed states invariant
|
|
222
|
-
*/
|
|
223
|
-
private fun applyToScroll(
|
|
224
|
-
delta: Offset,
|
|
225
|
-
source: CupertinoScrollSource,
|
|
226
|
-
performScroll: (Offset) -> Offset
|
|
227
|
-
): Offset {
|
|
228
|
-
// Calculate how much delta is available after being consumed by scrolling inside overscroll area
|
|
229
|
-
val deltaLeftForPerformScroll = availableDelta(delta, source)
|
|
230
|
-
|
|
231
|
-
// Then pass remaining delta to scroll closure
|
|
232
|
-
val deltaConsumedByPerformScroll = performScroll(deltaLeftForPerformScroll)
|
|
233
|
-
|
|
234
|
-
// Delta which is left after `performScroll` was invoked with availableDelta
|
|
235
|
-
val unconsumedDelta = deltaLeftForPerformScroll - deltaConsumedByPerformScroll
|
|
236
|
-
|
|
237
|
-
return when (source) {
|
|
238
|
-
CupertinoScrollSource.DRAG -> {
|
|
239
|
-
// [unconsumedDelta] is going into overscroll again in case a user drags and hits the
|
|
240
|
-
// overscroll->content->overscroll or content->overscroll scenario within single frame
|
|
241
|
-
overscrollOffset += unconsumedDelta
|
|
242
|
-
lastFlingUnconsumedDelta = Offset.Zero
|
|
243
|
-
delta - unconsumedDelta
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
CupertinoScrollSource.FLING -> {
|
|
247
|
-
// If unconsumedDelta is not Zero, [CupertinoOverscrollEffect] will cancel fling and
|
|
248
|
-
// start spring animation instead
|
|
249
|
-
lastFlingUnconsumedDelta = unconsumedDelta
|
|
250
|
-
delta - unconsumedDelta
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
override fun applyToScroll(
|
|
256
|
-
delta: Offset,
|
|
257
|
-
source: NestedScrollSource,
|
|
258
|
-
performScroll: (Offset) -> Offset
|
|
259
|
-
): Offset {
|
|
260
|
-
springAnimationScope?.cancel()
|
|
261
|
-
springAnimationScope = null
|
|
262
|
-
|
|
263
|
-
direction = direction.combinedWith(delta.toCupertinoOverscrollDirection())
|
|
264
|
-
|
|
265
|
-
return source.toCupertinoScrollSource()?.let {
|
|
266
|
-
applyToScroll(delta, it, performScroll)
|
|
267
|
-
} ?: performScroll(delta)
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
override suspend fun applyToFling(
|
|
271
|
-
velocity: Velocity,
|
|
272
|
-
performFling: suspend (Velocity) -> Velocity
|
|
273
|
-
) {
|
|
274
|
-
val availableFlingVelocity = playInitialSpringAnimationIfNeeded(velocity)
|
|
275
|
-
val velocityConsumedByFling = performFling(availableFlingVelocity)
|
|
276
|
-
val postFlingVelocity = availableFlingVelocity - velocityConsumedByFling
|
|
277
|
-
|
|
278
|
-
val unconsumedDelta = lastFlingUnconsumedDelta.toFloat()
|
|
279
|
-
if (unconsumedDelta == 0f && overscrollOffset == Offset.Zero) {
|
|
280
|
-
return
|
|
281
|
-
}
|
|
282
|
-
applyPullToRefresh()
|
|
283
|
-
|
|
284
|
-
playSpringAnimation(
|
|
285
|
-
unconsumedDelta,
|
|
286
|
-
postFlingVelocity.toFloat(),
|
|
287
|
-
CupertinoSpringAnimationReason.POSSIBLE_SPRING_IN_THE_END
|
|
288
|
-
)
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
private fun applyPullToRefresh() {
|
|
292
|
-
val (isRefresh, refresh, threshHold, _, sendHaptic) = pullRefreshState ?: return
|
|
293
|
-
val overscrollY = overscrollOffset.y
|
|
294
|
-
if (isRefresh.value || overscrollY < threshHold.value * density) return
|
|
295
|
-
refresh.invoke()
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
private fun Offset.toCupertinoOverscrollDirection(): CupertinoOverscrollDirection {
|
|
299
|
-
val hasXPart = abs(x) > 0f
|
|
300
|
-
val hasYPart = abs(y) > 0f
|
|
301
|
-
|
|
302
|
-
return if (hasXPart xor hasYPart) {
|
|
303
|
-
if (hasXPart) {
|
|
304
|
-
CupertinoOverscrollDirection.HORIZONTAL
|
|
305
|
-
} else {
|
|
306
|
-
// hasYPart != hasXPart and hasXPart is false
|
|
307
|
-
CupertinoOverscrollDirection.VERTICAL
|
|
308
|
-
}
|
|
309
|
-
} else {
|
|
310
|
-
// hasXPart and hasYPart are equal
|
|
311
|
-
CupertinoOverscrollDirection.UNKNOWN
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
private fun CupertinoOverscrollDirection.combinedWith(other: CupertinoOverscrollDirection): CupertinoOverscrollDirection =
|
|
316
|
-
when (this) {
|
|
317
|
-
CupertinoOverscrollDirection.UNKNOWN -> when (other) {
|
|
318
|
-
CupertinoOverscrollDirection.UNKNOWN -> CupertinoOverscrollDirection.UNKNOWN
|
|
319
|
-
CupertinoOverscrollDirection.VERTICAL -> CupertinoOverscrollDirection.VERTICAL
|
|
320
|
-
CupertinoOverscrollDirection.HORIZONTAL -> CupertinoOverscrollDirection.HORIZONTAL
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
CupertinoOverscrollDirection.VERTICAL -> when (other) {
|
|
324
|
-
CupertinoOverscrollDirection.UNKNOWN, CupertinoOverscrollDirection.VERTICAL -> CupertinoOverscrollDirection.VERTICAL
|
|
325
|
-
CupertinoOverscrollDirection.HORIZONTAL -> CupertinoOverscrollDirection.HORIZONTAL
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
CupertinoOverscrollDirection.HORIZONTAL -> when (other) {
|
|
329
|
-
CupertinoOverscrollDirection.UNKNOWN, CupertinoOverscrollDirection.HORIZONTAL -> CupertinoOverscrollDirection.HORIZONTAL
|
|
330
|
-
CupertinoOverscrollDirection.VERTICAL -> CupertinoOverscrollDirection.VERTICAL
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
private fun Velocity.toFloat(): Float =
|
|
335
|
-
toOffset().toFloat()
|
|
336
|
-
|
|
337
|
-
private fun Float.toVelocity(): Velocity =
|
|
338
|
-
toOffset().toVelocity()
|
|
339
|
-
|
|
340
|
-
private fun Offset.toFloat(): Float =
|
|
341
|
-
when (direction) {
|
|
342
|
-
CupertinoOverscrollDirection.UNKNOWN -> 0f
|
|
343
|
-
CupertinoOverscrollDirection.VERTICAL -> y
|
|
344
|
-
CupertinoOverscrollDirection.HORIZONTAL -> x
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
private fun Float.toOffset(): Offset =
|
|
348
|
-
when (direction) {
|
|
349
|
-
CupertinoOverscrollDirection.UNKNOWN -> Offset.Zero
|
|
350
|
-
CupertinoOverscrollDirection.VERTICAL -> Offset(0f, this)
|
|
351
|
-
CupertinoOverscrollDirection.HORIZONTAL -> Offset(this, 0f)
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
private suspend fun playInitialSpringAnimationIfNeeded(initialVelocity: Velocity): Velocity {
|
|
355
|
-
val velocity = initialVelocity.toFloat()
|
|
356
|
-
val overscroll = overscrollOffset.toFloat()
|
|
357
|
-
|
|
358
|
-
return if ((velocity <= 0f && overscroll > 0f) || (velocity >= 0f && overscroll < 0f)) {
|
|
359
|
-
playSpringAnimation(
|
|
360
|
-
unconsumedDelta = 0f,
|
|
361
|
-
velocity,
|
|
362
|
-
CupertinoSpringAnimationReason.FLING_FROM_OVERSCROLL
|
|
363
|
-
).toVelocity()
|
|
364
|
-
} else {
|
|
365
|
-
initialVelocity
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
private var springAnimationScope: CoroutineScope? = null
|
|
370
|
-
|
|
371
|
-
private suspend fun playSpringAnimation(
|
|
372
|
-
unconsumedDelta: Float,
|
|
373
|
-
initialVelocity: Float,
|
|
374
|
-
reason: CupertinoSpringAnimationReason
|
|
375
|
-
): Float {
|
|
376
|
-
val initialValue = overscrollOffset.toFloat() + unconsumedDelta
|
|
377
|
-
val initialSign = sign(initialValue)
|
|
378
|
-
var currentVelocity = initialVelocity
|
|
379
|
-
|
|
380
|
-
// All input values are divided by density so all internal calculations are performed as if
|
|
381
|
-
// they operated on DPs. Callback value is then scaled back to raw pixels.
|
|
382
|
-
val visibilityThreshold = 0.5f / density
|
|
383
|
-
|
|
384
|
-
val spec = when (reason) {
|
|
385
|
-
CupertinoSpringAnimationReason.FLING_FROM_OVERSCROLL -> {
|
|
386
|
-
spring(
|
|
387
|
-
stiffness = 300f,
|
|
388
|
-
visibilityThreshold = visibilityThreshold
|
|
389
|
-
)
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
CupertinoSpringAnimationReason.POSSIBLE_SPRING_IN_THE_END -> {
|
|
393
|
-
spring(
|
|
394
|
-
stiffness = 120f,
|
|
395
|
-
visibilityThreshold = visibilityThreshold
|
|
396
|
-
)
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
springAnimationScope?.cancel()
|
|
401
|
-
springAnimationScope = CoroutineScope(coroutineContext)
|
|
402
|
-
springAnimationScope?.run {
|
|
403
|
-
AnimationState(
|
|
404
|
-
Float.VectorConverter,
|
|
405
|
-
initialValue / density,
|
|
406
|
-
initialVelocity / density
|
|
407
|
-
).animateTo(
|
|
408
|
-
targetValue = 0f,
|
|
409
|
-
animationSpec = spec
|
|
410
|
-
) {
|
|
411
|
-
overscrollOffset = pullRefreshState?.let { (refreshing, _, _, refreshOffset) ->
|
|
412
|
-
if (!refreshing.value) return@let null
|
|
413
|
-
value.coerceAtLeast(refreshOffset.value * density).toOffset()
|
|
414
|
-
} ?: (value * density).toOffset()
|
|
415
|
-
currentVelocity = velocity * density
|
|
416
|
-
|
|
417
|
-
// If it was fling from overscroll, cancel animation and return velocity
|
|
418
|
-
if (reason == CupertinoSpringAnimationReason.FLING_FROM_OVERSCROLL &&
|
|
419
|
-
initialSign != 0f &&
|
|
420
|
-
sign(value) != initialSign
|
|
421
|
-
) {
|
|
422
|
-
this.cancelAnimation()
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
springAnimationScope = null
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
if (coroutineContext.isActive) {
|
|
429
|
-
// The spring is critically damped, so in case spring-fling-spring sequence is slightly
|
|
430
|
-
// offset and velocity is of the opposite sign, it will end up with no animation
|
|
431
|
-
overscrollOffset = Offset.Zero
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
if (reason == CupertinoSpringAnimationReason.POSSIBLE_SPRING_IN_THE_END) {
|
|
435
|
-
currentVelocity = 0f
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
return currentVelocity
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
private fun Offset.rubberBanded(): Offset {
|
|
442
|
-
if (scrollSize.width == 0f || scrollSize.height == 0f) {
|
|
443
|
-
return Offset.Zero
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
val dpOffset = this / density
|
|
447
|
-
val dpSize = scrollSize / density
|
|
448
|
-
|
|
449
|
-
return Offset(
|
|
450
|
-
rubberBandedValue(dpOffset.x, dpSize.width, RUBBER_BAND_COEFFICIENT),
|
|
451
|
-
rubberBandedValue(dpOffset.y, dpSize.height, RUBBER_BAND_COEFFICIENT)
|
|
452
|
-
) * density
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
/*
|
|
456
|
-
* Maps raw delta offset [value] on an axis within scroll container with [dimension]
|
|
457
|
-
* to actual visible offset
|
|
458
|
-
*/
|
|
459
|
-
private fun rubberBandedValue(value: Float, dimension: Float, coefficient: Float) =
|
|
460
|
-
sign(value) * (1f - (1f / (abs(value) * coefficient / dimension + 1f))) * dimension
|
|
461
|
-
|
|
462
|
-
companion object Companion {
|
|
463
|
-
private const val RUBBER_BAND_COEFFICIENT = 0.55f
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
private class CupertinoOverscrollNode @OptIn(ExperimentalMaterialApi::class) constructor(
|
|
468
|
-
val pullRefreshState: PullToRefreshCustomState?,
|
|
469
|
-
val offset: Density.() -> IntOffset,
|
|
470
|
-
val onNodeRemeasured: (IntSize) -> Unit,
|
|
471
|
-
val onDraw: () -> Unit,
|
|
472
|
-
val applyClip: Boolean
|
|
473
|
-
) : Modifier.Node(),
|
|
474
|
-
LayoutModifierNode,
|
|
475
|
-
LayoutAwareModifierNode,
|
|
476
|
-
DrawModifierNode,
|
|
477
|
-
PointerInputModifierNode {
|
|
478
|
-
override fun onRemeasured(size: IntSize) = onNodeRemeasured(size)
|
|
479
|
-
|
|
480
|
-
var pointersDown by mutableStateOf(0)
|
|
481
|
-
|
|
482
|
-
override fun onPointerEvent(
|
|
483
|
-
pointerEvent: PointerEvent,
|
|
484
|
-
pass: PointerEventPass,
|
|
485
|
-
bounds: IntSize
|
|
486
|
-
) {
|
|
487
|
-
if (pass == PointerEventPass.Final) {
|
|
488
|
-
if (pointerEvent.type == PointerEventType.Press) {
|
|
489
|
-
pointersDown++
|
|
490
|
-
} else if (pointerEvent.type == PointerEventType.Release) {
|
|
491
|
-
pointersDown--
|
|
492
|
-
// assert(pointersDown >= 0) { "pointersDown cannot be negative" }
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
override fun onCancelPointerInput() {
|
|
498
|
-
pointersDown = 0
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
override fun ContentDrawScope.draw() {
|
|
502
|
-
onDraw()
|
|
503
|
-
if (applyClip) {
|
|
504
|
-
val bounds = Rect(-offset().toOffset(), size)
|
|
505
|
-
val rect = size.toRect().intersect(bounds)
|
|
506
|
-
clipRect(
|
|
507
|
-
left = rect.left,
|
|
508
|
-
top = rect.top,
|
|
509
|
-
right = rect.right,
|
|
510
|
-
bottom = rect.bottom,
|
|
511
|
-
) { this@draw.drawContent() }
|
|
512
|
-
} else {
|
|
513
|
-
this@draw.drawContent()
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
override fun MeasureScope.measure(
|
|
518
|
-
measurable: Measurable,
|
|
519
|
-
constraints: Constraints
|
|
520
|
-
): MeasureResult {
|
|
521
|
-
val placeable = measurable.measure(constraints)
|
|
522
|
-
return layout(placeable.width, placeable.height) {
|
|
523
|
-
var position = offset()
|
|
524
|
-
|
|
525
|
-
with(pullRefreshState) {
|
|
526
|
-
this ?: return@with
|
|
527
|
-
if (refreshingState.value) {
|
|
528
|
-
position = position.copy(
|
|
529
|
-
y = position.y.coerceAtLeast(refreshOffset.roundToPx())
|
|
530
|
-
)
|
|
531
|
-
}
|
|
532
|
-
updatePercentage(position.y / refreshOffset.toPx())
|
|
533
|
-
}
|
|
534
|
-
placeable.placeWithLayer(position)
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
private fun Velocity.toOffset(): Offset =
|
|
540
|
-
Offset(x, y)
|
|
541
|
-
|
|
542
|
-
private fun Offset.toVelocity(): Velocity =
|
|
543
|
-
Velocity(x, y)
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
package vn.momo.kits.components
|
|
2
|
-
|
|
3
|
-
import androidx.compose.foundation.background
|
|
4
|
-
import androidx.compose.foundation.layout.Box
|
|
5
|
-
import androidx.compose.foundation.layout.fillMaxWidth
|
|
6
|
-
import androidx.compose.foundation.layout.height
|
|
7
|
-
import androidx.compose.foundation.layout.padding
|
|
8
|
-
import androidx.compose.runtime.Composable
|
|
9
|
-
import androidx.compose.ui.Modifier
|
|
10
|
-
import androidx.compose.ui.unit.dp
|
|
11
|
-
import vn.momo.kits.const.AppTheme
|
|
12
|
-
import vn.momo.kits.const.Spacing
|
|
13
|
-
|
|
14
|
-
@Composable
|
|
15
|
-
fun Divider() {
|
|
16
|
-
Box(
|
|
17
|
-
modifier = Modifier
|
|
18
|
-
.fillMaxWidth()
|
|
19
|
-
.height(1.dp)
|
|
20
|
-
.background(color = AppTheme.current.colors.border.default)
|
|
21
|
-
.padding(vertical = Spacing.XS)
|
|
22
|
-
)
|
|
23
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
package vn.momo.kits.components
|
|
2
|
-
|
|
3
|
-
import androidx.compose.foundation.layout.Box
|
|
4
|
-
import androidx.compose.foundation.layout.size
|
|
5
|
-
import androidx.compose.runtime.Composable
|
|
6
|
-
import androidx.compose.runtime.remember
|
|
7
|
-
import androidx.compose.ui.Modifier
|
|
8
|
-
import androidx.compose.ui.graphics.Color
|
|
9
|
-
import androidx.compose.ui.graphics.ColorFilter
|
|
10
|
-
import androidx.compose.ui.layout.ContentScale
|
|
11
|
-
import androidx.compose.ui.semantics.contentDescription
|
|
12
|
-
import androidx.compose.ui.semantics.semantics
|
|
13
|
-
import androidx.compose.ui.unit.Dp
|
|
14
|
-
import androidx.compose.ui.unit.dp
|
|
15
|
-
import coil3.compose.AsyncImage
|
|
16
|
-
import coil3.compose.LocalPlatformContext
|
|
17
|
-
import coil3.request.ImageRequest
|
|
18
|
-
import vn.momo.kits.const.AppTheme
|
|
19
|
-
import vn.momo.kits.utils.Icons
|
|
20
|
-
import vn.momo.kits.utils.noThemeIcons
|
|
21
|
-
|
|
22
|
-
@Composable
|
|
23
|
-
fun Icon(
|
|
24
|
-
source: String,
|
|
25
|
-
size: Dp = 24.dp,
|
|
26
|
-
color: Color? = AppTheme.current.colors.text.default,
|
|
27
|
-
modifier: Modifier = Modifier,
|
|
28
|
-
) {
|
|
29
|
-
// decode image without downscaling it
|
|
30
|
-
val context = LocalPlatformContext.current
|
|
31
|
-
|
|
32
|
-
val iconUrl = remember(source) {
|
|
33
|
-
if (source.contains("https")) {
|
|
34
|
-
source
|
|
35
|
-
} else {
|
|
36
|
-
Icons[source] ?: ""
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
val iconColor = remember(color) {
|
|
41
|
-
if (noThemeIcons.contains(source)) null else color
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
val colorFilter = remember(iconColor) {
|
|
45
|
-
iconColor?.let { ColorFilter.tint(it) }
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
val contentDesc = remember(iconUrl) { "img|$iconUrl" }
|
|
49
|
-
|
|
50
|
-
Box(
|
|
51
|
-
modifier = modifier
|
|
52
|
-
.size(size)
|
|
53
|
-
.semantics { contentDescription = contentDesc }
|
|
54
|
-
) {
|
|
55
|
-
AsyncImage(
|
|
56
|
-
modifier = Modifier.matchParentSize(),
|
|
57
|
-
model = ImageRequest.Builder(context)
|
|
58
|
-
.data(iconUrl)
|
|
59
|
-
.size(
|
|
60
|
-
coil3.size.Dimension.Undefined,
|
|
61
|
-
coil3.size.Dimension.Undefined
|
|
62
|
-
)
|
|
63
|
-
.build(),
|
|
64
|
-
contentDescription = null,
|
|
65
|
-
contentScale = ContentScale.Fit,
|
|
66
|
-
colorFilter = colorFilter,
|
|
67
|
-
)
|
|
68
|
-
}
|
|
69
|
-
}
|