@momo-kits/native-kits 0.160.1-scrolltotop.21 → 0.160.1-scrolltotop.22-debug
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/build.gradle.kts +11 -0
- package/compose/build.gradle.kts +180 -0
- package/compose/build.gradle.kts.backup +180 -0
- package/compose/compose.podspec +47 -0
- package/compose/src/androidMain/kotlin/vn/momo/kits/navigation/ScrollToTop.android.kt +9 -0
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +117 -0
- 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 +57 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +109 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +201 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +222 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +48 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +86 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +76 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +76 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +305 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +33 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +720 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +121 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +403 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +69 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +157 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +85 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +32 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +340 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +198 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +357 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +123 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +94 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +136 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +224 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +543 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +23 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +76 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +148 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +188 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +116 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +452 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +172 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +255 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +235 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +233 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +259 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +241 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +364 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +108 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +56 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +41 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +92 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +40 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +352 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +103 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +338 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +70 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +87 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +17 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +96 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +348 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +256 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +494 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +131 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +215 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +96 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +531 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +92 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +130 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +214 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +590 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +177 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +192 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +205 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +29 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +239 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +191 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +306 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +12 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +16 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +188 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +285 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +2 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +35 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +2 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +57 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +68 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +11 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +14 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +50 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +51 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +253 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +133 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +100 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +141 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +333 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScrollToTop.kt +11 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +566 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +161 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +243 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +86 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +187 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +279 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +80 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +306 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +32 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +370 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +131 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +167 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +58 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +1329 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +62 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +15 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +105 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +147 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +180 -0
- package/gradle/libs.versions.toml +58 -0
- package/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/gradle/wrapper/gradle-wrapper.properties +8 -0
- package/gradle.properties +26 -0
- package/gradlew +252 -0
- package/gradlew.bat +94 -0
- package/local.properties +8 -0
- package/package.json +1 -1
- package/settings.gradle.kts +52 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
package vn.momo.kits.utils
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.Composable
|
|
4
|
+
import androidx.compose.runtime.LaunchedEffect
|
|
5
|
+
import androidx.compose.runtime.MutableState
|
|
6
|
+
import androidx.compose.runtime.getValue
|
|
7
|
+
import androidx.compose.runtime.mutableStateOf
|
|
8
|
+
import androidx.compose.runtime.remember
|
|
9
|
+
import org.jetbrains.compose.resources.DrawableResource
|
|
10
|
+
import org.jetbrains.compose.resources.InternalResourceApi
|
|
11
|
+
import org.jetbrains.compose.resources.ResourceItem
|
|
12
|
+
import org.jetbrains.compose.resources.readResourceBytes
|
|
13
|
+
|
|
14
|
+
@OptIn(InternalResourceApi::class)
|
|
15
|
+
@Composable
|
|
16
|
+
fun getResource(name: String): DrawableResource {
|
|
17
|
+
return DrawableResource(
|
|
18
|
+
"drawable:$name",
|
|
19
|
+
setOf(ResourceItem(setOf(), "drawable/$name", -1, -1))
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@OptIn(InternalResourceApi::class)
|
|
24
|
+
@Composable
|
|
25
|
+
fun readJson(name: String): String {
|
|
26
|
+
val path = name.plus(".json")
|
|
27
|
+
|
|
28
|
+
val jsonContent by rememberState(path, { "" }) {
|
|
29
|
+
val cached = resourceCache.getOrPut(path) {
|
|
30
|
+
val content = try {
|
|
31
|
+
readResourceBytes(path).decodeToString()
|
|
32
|
+
} catch (_: Exception) {
|
|
33
|
+
""
|
|
34
|
+
}
|
|
35
|
+
ResourceCache.JSON(content)
|
|
36
|
+
} as ResourceCache.JSON
|
|
37
|
+
|
|
38
|
+
cached.json
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return jsonContent
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
private val resourceCache = mutableMapOf<String, ResourceCache>()
|
|
46
|
+
|
|
47
|
+
private sealed interface ResourceCache {
|
|
48
|
+
class JSON(val json: String) : ResourceCache
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@Composable
|
|
52
|
+
fun <T> rememberState(
|
|
53
|
+
key: Any,
|
|
54
|
+
getDefault: () -> T,
|
|
55
|
+
block: suspend () -> T
|
|
56
|
+
): MutableState<T> {
|
|
57
|
+
val state = remember(key) { mutableStateOf(getDefault()) }
|
|
58
|
+
LaunchedEffect(key) {
|
|
59
|
+
state.value = block()
|
|
60
|
+
}
|
|
61
|
+
return state
|
|
62
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
package vn.momo.kits.utils
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.Composable
|
|
4
|
+
import vn.momo.kits.application.LocalComponentInformation
|
|
5
|
+
|
|
6
|
+
@Composable
|
|
7
|
+
fun getComponentId(
|
|
8
|
+
componentName: String? = null,
|
|
9
|
+
accessibilityLabel: String? = null,
|
|
10
|
+
): String {
|
|
11
|
+
val componentInformation = LocalComponentInformation.current
|
|
12
|
+
if (accessibilityLabel != null) return accessibilityLabel
|
|
13
|
+
if (componentInformation?.componentId != null) return componentInformation.componentId
|
|
14
|
+
return ""
|
|
15
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
package vn.momo.kits.utils
|
|
2
|
+
|
|
3
|
+
import androidx.compose.foundation.layout.WindowInsets
|
|
4
|
+
import androidx.compose.foundation.layout.asPaddingValues
|
|
5
|
+
import androidx.compose.foundation.layout.systemBars
|
|
6
|
+
import androidx.compose.runtime.Composable
|
|
7
|
+
import androidx.compose.ui.Modifier
|
|
8
|
+
import androidx.compose.ui.composed
|
|
9
|
+
import androidx.compose.ui.draw.drawBehind
|
|
10
|
+
import androidx.compose.ui.geometry.Offset
|
|
11
|
+
import androidx.compose.ui.graphics.Color
|
|
12
|
+
import androidx.compose.ui.platform.LocalDensity
|
|
13
|
+
import androidx.compose.ui.unit.Dp
|
|
14
|
+
import androidx.compose.ui.unit.dp
|
|
15
|
+
import androidx.compose.ui.unit.min
|
|
16
|
+
import vn.momo.kits.const.AppNavigationBar
|
|
17
|
+
import vn.momo.kits.const.AppStatusBar
|
|
18
|
+
import vn.momo.kits.platform.getPlatformName
|
|
19
|
+
import kotlin.math.abs
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
internal fun Modifier.bottomBorder(strokeWidth: Dp, color: Color) = composed(
|
|
23
|
+
factory = {
|
|
24
|
+
val density = LocalDensity.current
|
|
25
|
+
val strokeWidthPx = density.run { strokeWidth.toPx() }
|
|
26
|
+
if (strokeWidth > 0.dp) {
|
|
27
|
+
Modifier.drawBehind {
|
|
28
|
+
val width = size.width
|
|
29
|
+
val height = size.height - strokeWidthPx / 2
|
|
30
|
+
|
|
31
|
+
drawLine(
|
|
32
|
+
color = color,
|
|
33
|
+
start = Offset(x = 0f, y = height),
|
|
34
|
+
end = Offset(x = width, y = height),
|
|
35
|
+
strokeWidth = strokeWidthPx
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
Modifier
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
inline fun <T> Boolean.ifTrue(trueCase: T, falseCase: T): T = if (this) trueCase else falseCase
|
|
45
|
+
inline fun <T> String.ifNotNull(trueCase: T, falseCase: T): T =
|
|
46
|
+
if (this.isBlank()) falseCase else trueCase
|
|
47
|
+
|
|
48
|
+
fun formatNumberToMoney(number: Long, currency: String = "đ"): String {
|
|
49
|
+
if (number == 0L) {
|
|
50
|
+
return "0$currency"
|
|
51
|
+
}
|
|
52
|
+
val array = mutableListOf<Char>()
|
|
53
|
+
var result = ""
|
|
54
|
+
var isNegative = false
|
|
55
|
+
|
|
56
|
+
if (number < 0) {
|
|
57
|
+
isNegative = true
|
|
58
|
+
}
|
|
59
|
+
val numberString = abs(number).toString() // Convert to Int to avoid decimal places
|
|
60
|
+
if (numberString.length < 3) {
|
|
61
|
+
return numberString + currency
|
|
62
|
+
}
|
|
63
|
+
var count = 0
|
|
64
|
+
for (i in numberString.length - 1 downTo 0) {
|
|
65
|
+
count += 1
|
|
66
|
+
array.add(numberString[i])
|
|
67
|
+
if (count == 3 && i >= 1) {
|
|
68
|
+
array.add('.')
|
|
69
|
+
count = 0
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
for (i in array.size - 1 downTo 0) {
|
|
74
|
+
result += array[i]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (isNegative) {
|
|
78
|
+
result = "-$result"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return result + currency
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@Composable
|
|
85
|
+
fun getAppStatusBarHeight(): Dp {
|
|
86
|
+
return if (AppStatusBar.current == 0.dp) {
|
|
87
|
+
WindowInsets.systemBars.asPaddingValues().calculateTopPadding()
|
|
88
|
+
} else {
|
|
89
|
+
AppStatusBar.current
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@Composable
|
|
94
|
+
fun getNavigationBarHeight(): Dp {
|
|
95
|
+
return if (AppNavigationBar.current == 0.dp) {
|
|
96
|
+
val systemBottomPadding = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
|
|
97
|
+
if (getPlatformName() == "iOS") {
|
|
98
|
+
min(systemBottomPadding, 21.dp)
|
|
99
|
+
} else {
|
|
100
|
+
systemBottomPadding
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
AppNavigationBar.current
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
package vn.momo.kits.navigation
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.Composable
|
|
4
|
+
import androidx.compose.runtime.DisposableEffect
|
|
5
|
+
import kotlinx.cinterop.*
|
|
6
|
+
import platform.Foundation.NSNotification
|
|
7
|
+
import platform.Foundation.NSNotificationCenter
|
|
8
|
+
import platform.Foundation.NSOperationQueue
|
|
9
|
+
import platform.darwin.NSObjectProtocol
|
|
10
|
+
import platform.objc.*
|
|
11
|
+
import kotlin.time.Clock
|
|
12
|
+
import kotlin.time.ExperimentalTime
|
|
13
|
+
|
|
14
|
+
@OptIn(ExperimentalForeignApi::class)
|
|
15
|
+
private val replacementHandleTap = staticCFunction<COpaquePointer, COpaquePointer, COpaquePointer?, Unit> { _, _, _ ->
|
|
16
|
+
NSNotificationCenter.defaultCenter.postNotificationName("statusBarSelected", null)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@OptIn(ExperimentalForeignApi::class, BetaInteropApi::class)
|
|
20
|
+
private object StatusBarSwizzleManager {
|
|
21
|
+
var originalHandleTapImp: CPointer<CFunction<() -> Unit>>? = null
|
|
22
|
+
var swizzleInstalled = false
|
|
23
|
+
var observerCount = 0
|
|
24
|
+
|
|
25
|
+
fun install() {
|
|
26
|
+
try {
|
|
27
|
+
if (swizzleInstalled) return
|
|
28
|
+
// objc_getClass returns Any? in the binding, but the underlying value is
|
|
29
|
+
// the ObjC Class metaobject — safe to cast to ObjCClass for the other
|
|
30
|
+
// runtime calls that require it.
|
|
31
|
+
val cls = objc_getClass("UIStatusBarManager") as? ObjCClass ?: run {
|
|
32
|
+
log("swizzle skipped: UIStatusBarManager class not found")
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
val selector = sel_registerName("handleTapAction:") ?: run {
|
|
36
|
+
log("swizzle skipped: handleTapAction: selector unavailable")
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
val method = class_getInstanceMethod(cls, selector) ?: run {
|
|
40
|
+
log("swizzle skipped: handleTapAction: method not found")
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
// Capture original IMP so we can restore it on uninstall.
|
|
44
|
+
originalHandleTapImp = method_getImplementation(method)
|
|
45
|
+
val typeEncoding = method_getTypeEncoding(method)?.toKString()
|
|
46
|
+
class_replaceMethod(cls, selector, replacementHandleTap.reinterpret(), typeEncoding)
|
|
47
|
+
swizzleInstalled = true
|
|
48
|
+
log("UIStatusBarManager handleTapAction: replaced (originalImp captured)")
|
|
49
|
+
} catch (e: Throwable) {
|
|
50
|
+
log("install error: ${e.message}")
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
fun uninstall() {
|
|
55
|
+
try {
|
|
56
|
+
if (!swizzleInstalled) return
|
|
57
|
+
val original = originalHandleTapImp ?: run {
|
|
58
|
+
log("uninstall skipped: no original IMP captured")
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
val cls = objc_getClass("UIStatusBarManager") as? ObjCClass ?: return
|
|
62
|
+
val selector = sel_registerName("handleTapAction:") ?: return
|
|
63
|
+
val method = class_getInstanceMethod(cls, selector) ?: return
|
|
64
|
+
method_setImplementation(method, original)
|
|
65
|
+
originalHandleTapImp = null
|
|
66
|
+
swizzleInstalled = false
|
|
67
|
+
log("UIStatusBarManager handleTapAction: original IMP restored")
|
|
68
|
+
} catch (e: Throwable) {
|
|
69
|
+
log("uninstall error: ${e.message}")
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
private class StatusBarObserver {
|
|
76
|
+
private var token: NSObjectProtocol? = null
|
|
77
|
+
fun acquire(callback: (() -> Unit)?) {
|
|
78
|
+
if (token != null) {
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
if (StatusBarSwizzleManager.observerCount == 0) {
|
|
82
|
+
StatusBarSwizzleManager.install()
|
|
83
|
+
}
|
|
84
|
+
token = NSNotificationCenter.defaultCenter.addObserverForName(
|
|
85
|
+
name = "statusBarSelected",
|
|
86
|
+
`object` = null,
|
|
87
|
+
queue = NSOperationQueue.mainQueue,
|
|
88
|
+
) { _: NSNotification? ->
|
|
89
|
+
log("statusBar tap notification → ScrollToTopRegistry.trigger()")
|
|
90
|
+
callback?.invoke()
|
|
91
|
+
}
|
|
92
|
+
StatusBarSwizzleManager.observerCount++
|
|
93
|
+
log("observerCount acquire ${StatusBarSwizzleManager.observerCount}")
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
fun release() {
|
|
98
|
+
if (token == null) return
|
|
99
|
+
token?.let { NSNotificationCenter.defaultCenter.removeObserver(it) }
|
|
100
|
+
token = null
|
|
101
|
+
StatusBarSwizzleManager.observerCount--
|
|
102
|
+
if (StatusBarSwizzleManager.observerCount == 0) {
|
|
103
|
+
StatusBarSwizzleManager.uninstall()
|
|
104
|
+
}
|
|
105
|
+
log("observerCount release ${StatusBarSwizzleManager.observerCount}")
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private const val TAG = "[ScrollToTop]"
|
|
110
|
+
|
|
111
|
+
private fun Any.tag(): String = "${this::class.simpleName ?: "Any"}@${hashCode().toString(16)}"
|
|
112
|
+
|
|
113
|
+
@OptIn(ExperimentalTime::class)
|
|
114
|
+
private fun ts(): String {
|
|
115
|
+
val ms = Clock.System.now().toEpochMilliseconds()
|
|
116
|
+
val s = ms / 1000
|
|
117
|
+
val hh = ((s / 3600) % 24).toString().padStart(2, '0')
|
|
118
|
+
val mm = ((s / 60) % 60).toString().padStart(2, '0')
|
|
119
|
+
val ss = (s % 60).toString().padStart(2, '0')
|
|
120
|
+
val mmm = (ms % 1000).toString().padStart(3, '0')
|
|
121
|
+
return "$hh:$mm:$ss.$mmm"
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private fun log(msg: String) = println("${ts()} $TAG $msg")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@Composable
|
|
128
|
+
internal actual fun RegisterScrollToTop(callback: (() -> Unit)?) {
|
|
129
|
+
DisposableEffect(callback) {
|
|
130
|
+
val acquired = callback != null
|
|
131
|
+
val statusBarObserver = StatusBarObserver()
|
|
132
|
+
if (acquired) {
|
|
133
|
+
statusBarObserver.acquire { callback?.invoke() }
|
|
134
|
+
}
|
|
135
|
+
onDispose {
|
|
136
|
+
if (acquired) statusBarObserver.release()
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
internal actual fun onNavigatorEntered(navigator: Navigator) {
|
|
142
|
+
StatusBarSwizzleManager.install()
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
internal actual fun onNavigatorExited(navigator: Navigator) {
|
|
146
|
+
StatusBarSwizzleManager.uninstall()
|
|
147
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
package vn.momo.kits.platform
|
|
2
|
+
|
|
3
|
+
import androidx.compose.foundation.layout.Box
|
|
4
|
+
import androidx.compose.foundation.layout.WindowInsets
|
|
5
|
+
import androidx.compose.foundation.layout.asPaddingValues
|
|
6
|
+
import androidx.compose.foundation.layout.fillMaxSize
|
|
7
|
+
import androidx.compose.foundation.layout.systemBars
|
|
8
|
+
import androidx.compose.runtime.Composable
|
|
9
|
+
import androidx.compose.runtime.CompositionLocalProvider
|
|
10
|
+
import androidx.compose.runtime.LaunchedEffect
|
|
11
|
+
import androidx.compose.runtime.getValue
|
|
12
|
+
import androidx.compose.runtime.mutableStateOf
|
|
13
|
+
import androidx.compose.runtime.remember
|
|
14
|
+
import androidx.compose.runtime.setValue
|
|
15
|
+
import androidx.compose.ui.ExperimentalComposeUiApi
|
|
16
|
+
import androidx.compose.ui.InternalComposeUiApi
|
|
17
|
+
import androidx.compose.ui.Modifier
|
|
18
|
+
import androidx.compose.ui.backhandler.LocalCompatNavigationEventDispatcherOwner
|
|
19
|
+
import androidx.compose.ui.graphics.Color
|
|
20
|
+
import androidx.compose.ui.graphics.NativePaint
|
|
21
|
+
import androidx.compose.ui.graphics.toArgb
|
|
22
|
+
import androidx.compose.ui.semantics.SemanticsPropertyKey
|
|
23
|
+
import androidx.compose.ui.semantics.semantics
|
|
24
|
+
import androidx.compose.ui.unit.Dp
|
|
25
|
+
import androidx.compose.ui.unit.dp
|
|
26
|
+
import androidx.compose.ui.viewinterop.UIKitInteropProperties
|
|
27
|
+
import androidx.compose.ui.viewinterop.UIKitView
|
|
28
|
+
import cocoapods.lottie_ios.CompatibleAnimation
|
|
29
|
+
import cocoapods.lottie_ios.CompatibleAnimationKeypath
|
|
30
|
+
import cocoapods.lottie_ios.CompatibleAnimationView
|
|
31
|
+
import kotlinx.cinterop.ExperimentalForeignApi
|
|
32
|
+
import kotlinx.cinterop.get
|
|
33
|
+
import kotlinx.cinterop.memScoped
|
|
34
|
+
import androidx.navigationevent.NavigationEventDispatcher
|
|
35
|
+
import androidx.navigationevent.NavigationEventDispatcherOwner
|
|
36
|
+
import org.jetbrains.skia.FilterBlurMode
|
|
37
|
+
import org.jetbrains.skia.MaskFilter
|
|
38
|
+
import platform.Foundation.NSBundle
|
|
39
|
+
import platform.UIKit.UIColor
|
|
40
|
+
import platform.UIKit.UIDevice
|
|
41
|
+
import platform.UIKit.UIScreen
|
|
42
|
+
|
|
43
|
+
actual fun getPlatformName(): String = "iOS"
|
|
44
|
+
|
|
45
|
+
@OptIn(ExperimentalForeignApi::class)
|
|
46
|
+
@Composable
|
|
47
|
+
actual fun getScreenDimensions(): ScreenDimension = memScoped {
|
|
48
|
+
val config = UIScreen.mainScreen.bounds.ptr[0]
|
|
49
|
+
return ScreenDimension(
|
|
50
|
+
config.size.width.toInt(),
|
|
51
|
+
config.size.height.toInt()
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
actual fun NativePaint.setMaskFilter(blurRadius: Float) {
|
|
56
|
+
this.maskFilter = MaskFilter.makeBlur(FilterBlurMode.NORMAL, blurRadius / 2, true)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@Composable
|
|
60
|
+
actual fun getStatusBarHeight(): Dp {
|
|
61
|
+
return WindowInsets.systemBars.asPaddingValues().calculateTopPadding()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@Composable
|
|
65
|
+
actual fun BackHandler(enabled: Boolean, onBack: () -> Unit) {
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@OptIn(InternalComposeUiApi::class)
|
|
69
|
+
@Composable
|
|
70
|
+
actual fun ProvideNavigationEventDispatcherOwner(content: @Composable () -> Unit) {
|
|
71
|
+
val navigationEventDispatcherOwner = remember {
|
|
72
|
+
object : NavigationEventDispatcherOwner {
|
|
73
|
+
override val navigationEventDispatcher = NavigationEventDispatcher().apply {
|
|
74
|
+
isEnabled = false
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
CompositionLocalProvider(
|
|
80
|
+
LocalCompatNavigationEventDispatcherOwner provides navigationEventDispatcherOwner,
|
|
81
|
+
content = content
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@Composable
|
|
86
|
+
actual fun getScreenHeight(): Dp {
|
|
87
|
+
return getScreenDimensions().height.dp
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
actual fun getOSVersion(): OSVersion = OSVersion.IOS(
|
|
91
|
+
major = UIDevice.currentDevice.systemVersion.substringBefore(".").toIntOrNull() ?: 0
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
@OptIn(ExperimentalForeignApi::class, ExperimentalComposeUiApi::class)
|
|
95
|
+
@Composable
|
|
96
|
+
actual fun LottieAnimation(
|
|
97
|
+
path: String,
|
|
98
|
+
tintColor: Color?,
|
|
99
|
+
bgColor: Color?,
|
|
100
|
+
placedAsOverlay: Boolean,
|
|
101
|
+
modifier: Modifier
|
|
102
|
+
) {
|
|
103
|
+
var animation by remember { mutableStateOf<CompatibleAnimation?>(null) }
|
|
104
|
+
|
|
105
|
+
LaunchedEffect(Unit) {
|
|
106
|
+
animation = CompatibleAnimation(name = "compose-resources/composeResources/vn.momo.compose.resources/".plus(path), subdirectory = null, NSBundle.mainBundle)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
when (val value = animation) {
|
|
110
|
+
null -> {
|
|
111
|
+
Box(modifier)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
else -> {
|
|
115
|
+
Box(modifier) {
|
|
116
|
+
UIKitView(
|
|
117
|
+
modifier = Modifier.fillMaxSize(),
|
|
118
|
+
properties = UIKitInteropProperties(placedAsOverlay = placedAsOverlay),
|
|
119
|
+
factory = {
|
|
120
|
+
CompatibleAnimationView(value).apply {
|
|
121
|
+
translatesAutoresizingMaskIntoConstraints = true
|
|
122
|
+
|
|
123
|
+
setBackgroundColor(bgColor?.toUIColor() ?: UIColor.clearColor)
|
|
124
|
+
|
|
125
|
+
setLoopAnimationCount(-1.0)
|
|
126
|
+
setAnimationSpeed(1.0)
|
|
127
|
+
|
|
128
|
+
if (tintColor != null) {
|
|
129
|
+
val uiColor = tintColor.toUIColor()
|
|
130
|
+
setColorValue(uiColor,
|
|
131
|
+
CompatibleAnimationKeypath("**.Fill 1.Color")
|
|
132
|
+
)
|
|
133
|
+
setColorValue(uiColor, CompatibleAnimationKeypath("**.Fill.Color"))
|
|
134
|
+
setColorValue(uiColor, CompatibleAnimationKeypath("**.Color"))
|
|
135
|
+
setColorValue(uiColor, CompatibleAnimationKeypath("**.Stroke 1.Color"))
|
|
136
|
+
setColorValue(uiColor, CompatibleAnimationKeypath("**.Stroke.Color"))
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
play()
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
update = { view ->
|
|
144
|
+
view.setBackgroundColor(bgColor?.toUIColor() ?: UIColor.clearColor)
|
|
145
|
+
|
|
146
|
+
if (tintColor != null) {
|
|
147
|
+
val uiColor = tintColor.toUIColor()
|
|
148
|
+
|
|
149
|
+
view.setColorValue(uiColor, CompatibleAnimationKeypath("**.Fill 1.Color"))
|
|
150
|
+
view.setColorValue(uiColor, CompatibleAnimationKeypath("**.Fill.Color"))
|
|
151
|
+
view.setColorValue(uiColor, CompatibleAnimationKeypath("**.Color"))
|
|
152
|
+
view.setColorValue(uiColor, CompatibleAnimationKeypath("**.Stroke 1.Color"))
|
|
153
|
+
view.setColorValue(uiColor, CompatibleAnimationKeypath("**.Stroke.Color"))
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
fun Color.toUIColor(): UIColor {
|
|
163
|
+
val argb = this.toArgb()
|
|
164
|
+
|
|
165
|
+
val a = ((argb shr 24) and 0xFF) / 255.0
|
|
166
|
+
val r = ((argb shr 16) and 0xFF) / 255.0
|
|
167
|
+
val g = ((argb shr 8) and 0xFF) / 255.0
|
|
168
|
+
val b = (argb and 0xFF) / 255.0
|
|
169
|
+
|
|
170
|
+
return UIColor(
|
|
171
|
+
red = r,
|
|
172
|
+
green = g,
|
|
173
|
+
blue = b,
|
|
174
|
+
alpha = a
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
actual fun NativePaint.setColor(color: Color){
|
|
179
|
+
this.color = color.toArgb()
|
|
180
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[versions]
|
|
2
|
+
android-compileSdk = "36"
|
|
3
|
+
android-minSdk = "24"
|
|
4
|
+
android-targetSdk = "36"
|
|
5
|
+
ktor-version = "3.0.0-rc-1"
|
|
6
|
+
coroutines = "1.9.0"
|
|
7
|
+
kotlin = "2.3.10"
|
|
8
|
+
kSerialize = "1.7.1"
|
|
9
|
+
compose = "1.10.3"
|
|
10
|
+
navigation-multiplatform = "2.9.2"
|
|
11
|
+
coil3-multiplatform = "3.0.0-alpha10"
|
|
12
|
+
androidGradlePlugin = "8.13.2"
|
|
13
|
+
r8 = "8.9.35"
|
|
14
|
+
kotlinx-datetime = "0.7.1"
|
|
15
|
+
airbnb-lottie = "5.2.0"
|
|
16
|
+
androidx-activity = "1.9.1"
|
|
17
|
+
androidx-appcompat = "1.7.0"
|
|
18
|
+
material = "1.10.0"
|
|
19
|
+
maxapi = "0.1.1"
|
|
20
|
+
vanniktechMavenPublish = "0.34.0"
|
|
21
|
+
kits = "0.159.1-beta.7"
|
|
22
|
+
nativemaxapi = "0.0.6"
|
|
23
|
+
|
|
24
|
+
[libraries]
|
|
25
|
+
ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor-version" }
|
|
26
|
+
ktor-client-darwin = { group = "io.ktor", name = "ktor-client-darwin", version.ref = "ktor-version" }
|
|
27
|
+
ktor-client-okhttp = { group = "io.ktor", name = "ktor-client-okhttp", version.ref = "ktor-version" }
|
|
28
|
+
jetbrains-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutines" }
|
|
29
|
+
jetbrains-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutines" }
|
|
30
|
+
jetbrains-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutines" }
|
|
31
|
+
jetbrains-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization", version.ref = "kSerialize" }
|
|
32
|
+
jetbrains-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kSerialize" }
|
|
33
|
+
kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinx-datetime" }
|
|
34
|
+
compose-ui-backhandler = { module = "org.jetbrains.compose.ui:ui-backhandler", version.ref = "compose" }
|
|
35
|
+
navigation-multiplatform = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "navigation-multiplatform" }
|
|
36
|
+
coil-multiplatform-core = { module = "io.coil-kt.coil3:coil-core", version.ref = "coil3-multiplatform" }
|
|
37
|
+
coil-multiplatform-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil3-multiplatform" }
|
|
38
|
+
coil-multiplatform-network-ktor = { module = "io.coil-kt.coil3:coil-network-ktor3", version.ref = "coil3-multiplatform" }
|
|
39
|
+
r8 = { module = "com.android.tools:r8", version.ref = "r8" }
|
|
40
|
+
airbnb-lottie = { group = "com.airbnb.android", name = "lottie-compose", version.ref = "airbnb-lottie" }
|
|
41
|
+
native-max-api = { group = "vn.momo.maxapi", name = "NativeMaxApi", version.ref = "nativemaxapi" }
|
|
42
|
+
kits = { module = "vn.momo.kits:kits", version.ref = "kits" }
|
|
43
|
+
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
|
|
44
|
+
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
|
|
45
|
+
material = { module = "com.google.android.material:material", version.ref = "material" }
|
|
46
|
+
|
|
47
|
+
[plugins]
|
|
48
|
+
jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
|
49
|
+
jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
|
50
|
+
jetbrains-kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
|
|
51
|
+
jetbrains-kotlin-cocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" }
|
|
52
|
+
jetbrains-kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
|
53
|
+
jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
|
54
|
+
kotlin-compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
|
55
|
+
compose = { id = "org.jetbrains.compose", version.ref = "compose" }
|
|
56
|
+
android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" }
|
|
57
|
+
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
|
|
58
|
+
vanniktech-mavenPublish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktechMavenPublish" }
|
|
Binary file
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#Thu Jul 31 17:05:40 ICT 2025
|
|
2
|
+
distributionBase=GRADLE_USER_HOME
|
|
3
|
+
distributionPath=wrapper/dists
|
|
4
|
+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
|
|
5
|
+
networkTimeout=10000
|
|
6
|
+
validateDistributionUrl=true
|
|
7
|
+
zipStoreBase=GRADLE_USER_HOME
|
|
8
|
+
zipStorePath=wrapper/dists
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#Kotlin
|
|
2
|
+
kotlin.code.style=official
|
|
3
|
+
kotlin.daemon.jvmargs=-Xmx6144M
|
|
4
|
+
|
|
5
|
+
#Gradle
|
|
6
|
+
org.gradle.jvmargs=-Xmx8192M -Dfile.encoding=UTF-8
|
|
7
|
+
org.gradle.configuration-cache=false
|
|
8
|
+
org.gradle.caching=true
|
|
9
|
+
|
|
10
|
+
#Android
|
|
11
|
+
android.nonTransitiveRClass=true
|
|
12
|
+
android.useAndroidX=true
|
|
13
|
+
|
|
14
|
+
#KMP
|
|
15
|
+
kotlin.apple.xcodeCompatibility.nowarn=true
|
|
16
|
+
|
|
17
|
+
# Publishing
|
|
18
|
+
name="ComposeKits"
|
|
19
|
+
group=vn.momo.kits
|
|
20
|
+
artifact.id=kits
|
|
21
|
+
version=0.160.1-scrolltotop.22
|
|
22
|
+
|
|
23
|
+
repo=GitLab
|
|
24
|
+
url=https://gitlab.mservice.com.vn/api/v4/projects/5400/packages/maven
|
|
25
|
+
gitlab.user=upload_packages
|
|
26
|
+
gitlab.password=gldt-CtTSGmzz57sUL9cnjdaQ
|