@momo-kits/native-kits 0.162.1-debug → 0.162.1-nativeimage.2-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/compose/build.gradle.kts +7 -2
- package/compose/build.gradle.kts.backup +65 -60
- package/compose/src/androidMain/kotlin/vn/momo/kits/components/NativeImage.android.kt +71 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +13 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/NativeImage.kt +74 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +5 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +4 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +46 -10
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +4 -2
- package/compose/src/iosMain/kotlin/vn/momo/kits/components/NativeImage.ios.kt +153 -0
- package/example/ios/Example.xcworkspace/xcuserdata/thanhle.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/example/ios/{Example.xcodeproj/xcuserdata/huynhdung.xcuserdatad → Example.xcworkspace/xcuserdata/thanhle.xcuserdatad}/xcschemes/xcschememanagement.plist +1 -10
- package/gradle/libs.versions.toml +2 -0
- package/gradle.properties +1 -1
- package/local.properties +2 -2
- package/package.json +1 -1
- package/publish.sh +2 -2
- package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/Pods-Example.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImage.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SkeletonUI.xcscheme +0 -58
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -46
- /package/example/ios/{Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad → Example.xcodeproj/xcuserdata/thanhle.xcuserdatad}/xcschemes/xcschememanagement.plist +0 -0
package/compose/build.gradle.kts
CHANGED
|
@@ -40,7 +40,7 @@ kotlin {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
cocoapods {
|
|
43
|
-
version = "0.
|
|
43
|
+
version = "0.162.1-nativeimage.2-debug"
|
|
44
44
|
summary = "IOS Shared module"
|
|
45
45
|
homepage = "https://momo.vn"
|
|
46
46
|
ios.deploymentTarget = "15.0"
|
|
@@ -55,6 +55,10 @@ kotlin {
|
|
|
55
55
|
version = "4.4.3"
|
|
56
56
|
extraOpts += listOf("-compiler-option", "-fmodules")
|
|
57
57
|
}
|
|
58
|
+
|
|
59
|
+
pod("SDWebImage") {
|
|
60
|
+
version = "~> 5.14.3"
|
|
61
|
+
}
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
sourceSets {
|
|
@@ -78,6 +82,7 @@ kotlin {
|
|
|
78
82
|
androidMain.dependencies {
|
|
79
83
|
implementation(libs.ktor.client.okhttp)
|
|
80
84
|
implementation(libs.airbnb.lottie)
|
|
85
|
+
implementation(libs.coil.gif)
|
|
81
86
|
}
|
|
82
87
|
iosMain.dependencies {
|
|
83
88
|
implementation(libs.ktor.client.darwin)
|
|
@@ -112,7 +117,7 @@ repositories {
|
|
|
112
117
|
maven { url = uri("https://maven.pkg.jetbrains.space/public/p/compose/dev") }
|
|
113
118
|
maven {
|
|
114
119
|
url = uri("https://gitlab.mservice.com.vn/api/v4/projects/5400/packages/maven")
|
|
115
|
-
credentials {username = "download_packages"; password = "gldt-bjDqLpU_sPcHDuXau2ws" }
|
|
120
|
+
credentials { username = "download_packages"; password = "gldt-bjDqLpU_sPcHDuXau2ws" }
|
|
116
121
|
}
|
|
117
122
|
maven {
|
|
118
123
|
url = uri("https://artifacts.mservice.com.vn/repository/maven-momo-app/")
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import com.vanniktech.maven.publish.JavadocJar
|
|
2
|
+
import com.vanniktech.maven.publish.KotlinMultiplatform
|
|
3
3
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|
4
4
|
|
|
5
5
|
plugins {
|
|
@@ -7,7 +7,7 @@ plugins {
|
|
|
7
7
|
alias(libs.plugins.android.library)
|
|
8
8
|
alias(libs.plugins.compose)
|
|
9
9
|
alias(libs.plugins.kotlin.compose.compiler)
|
|
10
|
-
|
|
10
|
+
alias(libs.plugins.vanniktech.mavenPublish)
|
|
11
11
|
id(libs.plugins.jetbrains.kotlin.cocoapods.get().pluginId)
|
|
12
12
|
kotlin("plugin.serialization")
|
|
13
13
|
}
|
|
@@ -40,7 +40,7 @@ kotlin {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
cocoapods {
|
|
43
|
-
version =
|
|
43
|
+
version = gitlabVersion
|
|
44
44
|
summary = "IOS Shared module"
|
|
45
45
|
homepage = "https://momo.vn"
|
|
46
46
|
ios.deploymentTarget = "15.0"
|
|
@@ -55,6 +55,10 @@ kotlin {
|
|
|
55
55
|
version = "4.4.3"
|
|
56
56
|
extraOpts += listOf("-compiler-option", "-fmodules")
|
|
57
57
|
}
|
|
58
|
+
|
|
59
|
+
pod("SDWebImage") {
|
|
60
|
+
version = "~> 5.14.3"
|
|
61
|
+
}
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
sourceSets {
|
|
@@ -78,6 +82,7 @@ kotlin {
|
|
|
78
82
|
androidMain.dependencies {
|
|
79
83
|
implementation(libs.ktor.client.okhttp)
|
|
80
84
|
implementation(libs.airbnb.lottie)
|
|
85
|
+
implementation(libs.coil.gif)
|
|
81
86
|
}
|
|
82
87
|
iosMain.dependencies {
|
|
83
88
|
implementation(libs.ktor.client.darwin)
|
|
@@ -86,14 +91,14 @@ kotlin {
|
|
|
86
91
|
}
|
|
87
92
|
|
|
88
93
|
android {
|
|
89
|
-
namespace = "
|
|
90
|
-
compileSdk =
|
|
94
|
+
namespace = "$gitlabGroup.$gitlabArtifactId"
|
|
95
|
+
compileSdk = libs.versions.android.compileSdk.get().toInt()
|
|
91
96
|
compileOptions {
|
|
92
97
|
sourceCompatibility = JavaVersion.VERSION_17
|
|
93
98
|
targetCompatibility = JavaVersion.VERSION_17
|
|
94
99
|
}
|
|
95
100
|
defaultConfig {
|
|
96
|
-
minSdk =
|
|
101
|
+
minSdk = libs.versions.android.minSdk.get().toInt()
|
|
97
102
|
}
|
|
98
103
|
}
|
|
99
104
|
|
|
@@ -112,7 +117,7 @@ repositories {
|
|
|
112
117
|
maven { url = uri("https://maven.pkg.jetbrains.space/public/p/compose/dev") }
|
|
113
118
|
maven {
|
|
114
119
|
url = uri("https://gitlab.mservice.com.vn/api/v4/projects/5400/packages/maven")
|
|
115
|
-
credentials {username = "download_packages"; password = "gldt-bjDqLpU_sPcHDuXau2ws" }
|
|
120
|
+
credentials { username = "download_packages"; password = "gldt-bjDqLpU_sPcHDuXau2ws" }
|
|
116
121
|
}
|
|
117
122
|
maven {
|
|
118
123
|
url = uri("https://artifacts.mservice.com.vn/repository/maven-momo-app/")
|
|
@@ -132,55 +137,55 @@ compose {
|
|
|
132
137
|
}
|
|
133
138
|
}
|
|
134
139
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
140
|
+
publishing {
|
|
141
|
+
repositories {
|
|
142
|
+
maven {
|
|
143
|
+
name = "${gitlabRepo}Packages"
|
|
144
|
+
credentials {
|
|
145
|
+
username = gitlabUser
|
|
146
|
+
password = gitlabKey
|
|
147
|
+
}
|
|
148
|
+
url = uri("$gitlabUrl")
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
mavenPublishing {
|
|
154
|
+
configure(
|
|
155
|
+
KotlinMultiplatform(
|
|
156
|
+
javadocJar = JavadocJar.Empty(),
|
|
157
|
+
sourcesJar = true,
|
|
158
|
+
androidVariantsToPublish = listOf("release")
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
repositories {
|
|
163
|
+
maven {
|
|
164
|
+
name = "${gitlabRepo}Packages"
|
|
165
|
+
credentials { username = gitlabUser; password = gitlabKey }
|
|
166
|
+
url = uri("$gitlabUrl")
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
coordinates(gitlabGroup.toString(), gitlabArtifactId, gitlabVersion.toString())
|
|
171
|
+
|
|
172
|
+
pom {
|
|
173
|
+
name = "$gitlabName Klib"
|
|
174
|
+
description = "$gitlabName"
|
|
175
|
+
url = "https://gitlab.mservice.com.vn"
|
|
176
|
+
licenses {
|
|
177
|
+
license {
|
|
178
|
+
name = "The Apache License, Version 2.0"
|
|
179
|
+
url = "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
|
180
|
+
distribution = "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
developers {
|
|
184
|
+
developer {
|
|
185
|
+
id = "kotlin-hands-on"
|
|
186
|
+
name = "Kotlin Developer Advocate"
|
|
187
|
+
url = "https://github.com/kotlin-hands-on/"
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import android.os.Build.VERSION.SDK_INT
|
|
4
|
+
import androidx.compose.foundation.layout.BoxScope
|
|
5
|
+
import androidx.compose.runtime.*
|
|
6
|
+
import androidx.compose.ui.Alignment
|
|
7
|
+
import androidx.compose.ui.Modifier
|
|
8
|
+
import androidx.compose.ui.platform.LocalContext
|
|
9
|
+
import androidx.compose.ui.unit.dp
|
|
10
|
+
import coil3.SingletonImageLoader
|
|
11
|
+
import coil3.compose.AsyncImage
|
|
12
|
+
import coil3.gif.AnimatedImageDecoder
|
|
13
|
+
import coil3.gif.GifDecoder
|
|
14
|
+
import vn.momo.kits.const.AppTheme
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@Composable
|
|
18
|
+
actual fun BoxScope.NativeImageWrapper(
|
|
19
|
+
urlToLoad: Any,
|
|
20
|
+
modifier: Modifier,
|
|
21
|
+
options: Options?,
|
|
22
|
+
loading: Boolean
|
|
23
|
+
) {
|
|
24
|
+
val imageOptions = remember(options) {
|
|
25
|
+
options ?: Options()
|
|
26
|
+
}
|
|
27
|
+
var imageState by remember { mutableStateOf(ImageState.Loading) }
|
|
28
|
+
val context = LocalContext.current
|
|
29
|
+
val gifEnabledLoader = remember(context) {
|
|
30
|
+
if (isGifImage(urlToLoad)) {
|
|
31
|
+
SingletonImageLoader.get(context).newBuilder()
|
|
32
|
+
.components {
|
|
33
|
+
if (SDK_INT >= 28) {
|
|
34
|
+
add(AnimatedImageDecoder.Factory())
|
|
35
|
+
} else {
|
|
36
|
+
add(GifDecoder.Factory())
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
.build()
|
|
40
|
+
} else {
|
|
41
|
+
SingletonImageLoader.get(context)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
AsyncImage(
|
|
45
|
+
modifier = Modifier.matchParentSize(),
|
|
46
|
+
model = urlToLoad,
|
|
47
|
+
imageLoader = gifEnabledLoader,
|
|
48
|
+
contentDescription = null,
|
|
49
|
+
contentScale = imageOptions.contentScale,
|
|
50
|
+
alignment = imageOptions.alignment,
|
|
51
|
+
colorFilter = imageOptions.effectiveColorFilter,
|
|
52
|
+
alpha = imageOptions.alpha,
|
|
53
|
+
onLoading = { imageState = ImageState.Loading },
|
|
54
|
+
onSuccess = { imageState = ImageState.Success },
|
|
55
|
+
onError = { imageState = ImageState.Error },
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
when (imageState) {
|
|
59
|
+
ImageState.Loading -> if (loading) Skeleton(cornerRadius = options?.skeletonCornerRadius ?: 0.dp)
|
|
60
|
+
ImageState.Error -> {
|
|
61
|
+
val theme = AppTheme.current
|
|
62
|
+
Icon(
|
|
63
|
+
source = "media_fail",
|
|
64
|
+
color = theme.colors.text.disable,
|
|
65
|
+
modifier = Modifier.align(Alignment.Center)
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
ImageState.Success -> {}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -2,20 +2,18 @@ package vn.momo.kits.components
|
|
|
2
2
|
|
|
3
3
|
import androidx.compose.foundation.border
|
|
4
4
|
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
5
|
-
import androidx.compose.runtime
|
|
6
|
-
import androidx.compose.runtime.getValue
|
|
7
|
-
import androidx.compose.runtime.mutableStateOf
|
|
8
|
-
import androidx.compose.runtime.remember
|
|
9
|
-
import androidx.compose.runtime.setValue
|
|
5
|
+
import androidx.compose.runtime.*
|
|
10
6
|
import androidx.compose.ui.Alignment
|
|
11
7
|
import androidx.compose.ui.Modifier
|
|
8
|
+
import androidx.compose.ui.graphics.Color
|
|
12
9
|
import androidx.compose.ui.graphics.ColorFilter
|
|
13
10
|
import androidx.compose.ui.graphics.DefaultAlpha
|
|
14
11
|
import androidx.compose.ui.graphics.painter.Painter
|
|
15
12
|
import androidx.compose.ui.layout.ContentScale
|
|
13
|
+
import androidx.compose.ui.platform.LocalDensity
|
|
16
14
|
import androidx.compose.ui.semantics.contentDescription
|
|
17
15
|
import androidx.compose.ui.semantics.semantics
|
|
18
|
-
import androidx.compose.ui.
|
|
16
|
+
import androidx.compose.ui.unit.Dp
|
|
19
17
|
import androidx.compose.ui.unit.dp
|
|
20
18
|
import coil3.compose.AsyncImage
|
|
21
19
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
@@ -28,7 +26,13 @@ data class Options(
|
|
|
28
26
|
val contentScale: ContentScale = ContentScale.Crop,
|
|
29
27
|
val colorFilter: ColorFilter? = null,
|
|
30
28
|
val alpha: Float = DefaultAlpha,
|
|
31
|
-
|
|
29
|
+
val skeletonCornerRadius: Dp = 0.dp,
|
|
30
|
+
val tint: Color? = null,
|
|
31
|
+
) {
|
|
32
|
+
|
|
33
|
+
val effectiveColorFilter: ColorFilter?
|
|
34
|
+
get() = tint?.let { ColorFilter.tint(it) } ?: colorFilter
|
|
35
|
+
}
|
|
32
36
|
|
|
33
37
|
enum class ImageState {
|
|
34
38
|
Loading, Success, Error
|
|
@@ -131,7 +135,7 @@ fun Image(
|
|
|
131
135
|
contentDescription = null,
|
|
132
136
|
contentScale = imageOptions.contentScale,
|
|
133
137
|
alignment = imageOptions.alignment,
|
|
134
|
-
colorFilter = imageOptions.
|
|
138
|
+
colorFilter = imageOptions.effectiveColorFilter,
|
|
135
139
|
alpha = imageOptions.alpha,
|
|
136
140
|
onLoading = { imageState = ImageState.Loading },
|
|
137
141
|
onSuccess = { imageState = ImageState.Success },
|
|
@@ -154,7 +158,7 @@ fun Image(
|
|
|
154
158
|
}
|
|
155
159
|
|
|
156
160
|
// Extracted URL processing logic for better performance
|
|
157
|
-
|
|
161
|
+
internal fun processImageUrl(url: String, maxWidth: androidx.compose.ui.unit.Dp, density: androidx.compose.ui.unit.Density): String {
|
|
158
162
|
val host = getHostFromUrl(url)
|
|
159
163
|
return if (host != null && supportedDomains.contains(host)) {
|
|
160
164
|
val widthPx = with(density) { maxWidth.roundToPx() }
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import androidx.compose.foundation.border
|
|
5
|
+
import androidx.compose.foundation.layout.BoxScope
|
|
6
|
+
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
7
|
+
import androidx.compose.runtime.Composable
|
|
8
|
+
import androidx.compose.runtime.remember
|
|
9
|
+
import androidx.compose.ui.Modifier
|
|
10
|
+
import androidx.compose.ui.platform.LocalDensity
|
|
11
|
+
import androidx.compose.ui.semantics.contentDescription
|
|
12
|
+
import androidx.compose.ui.semantics.semantics
|
|
13
|
+
import androidx.compose.ui.unit.dp
|
|
14
|
+
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
15
|
+
import vn.momo.kits.const.Colors
|
|
16
|
+
import vn.momo.kits.modifier.conditional
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
fun isGifImage(source: Any): Boolean {
|
|
20
|
+
if (source is String) {
|
|
21
|
+
return source.contains(".gif") ||
|
|
22
|
+
source.contains(".webp") ||
|
|
23
|
+
source.contains(".apng") ||
|
|
24
|
+
source.contains(".avif")
|
|
25
|
+
}
|
|
26
|
+
return false
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private val urlCache = mutableMapOf<String, String>()
|
|
30
|
+
|
|
31
|
+
@Composable
|
|
32
|
+
fun NativeImage(
|
|
33
|
+
source: Any,
|
|
34
|
+
modifier: Modifier = Modifier,
|
|
35
|
+
options: Options? = null,
|
|
36
|
+
loading: Boolean = true
|
|
37
|
+
) {
|
|
38
|
+
BoxWithConstraints(
|
|
39
|
+
modifier = modifier
|
|
40
|
+
.conditional(IsShowBaseLineDebug) {
|
|
41
|
+
border(1.dp, Colors.blue_03)
|
|
42
|
+
}
|
|
43
|
+
.semantics { contentDescription = "img|$source" },
|
|
44
|
+
) {
|
|
45
|
+
val density = LocalDensity.current
|
|
46
|
+
val urlToLoad = remember(source, maxWidth, maxHeight, density) {
|
|
47
|
+
when (source) {
|
|
48
|
+
is String -> {
|
|
49
|
+
// Check cache first
|
|
50
|
+
val cacheKey = "$source|${maxWidth}|${density.density}"
|
|
51
|
+
urlCache[cacheKey] ?: run {
|
|
52
|
+
val processedUrl = processImageUrl(source, maxWidth, density)
|
|
53
|
+
urlCache[cacheKey] = processedUrl
|
|
54
|
+
processedUrl
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
else -> source
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
NativeImageWrapper(urlToLoad, modifier, options, loading)
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@Composable
|
|
69
|
+
expect fun BoxScope.NativeImageWrapper(
|
|
70
|
+
urlToLoad: Any,
|
|
71
|
+
modifier: Modifier = Modifier,
|
|
72
|
+
options: Options? = null,
|
|
73
|
+
loading: Boolean = true,
|
|
74
|
+
)
|
|
@@ -11,12 +11,15 @@ import androidx.compose.foundation.border
|
|
|
11
11
|
import androidx.compose.foundation.layout.Box
|
|
12
12
|
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
13
13
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
14
|
+
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
14
15
|
import androidx.compose.runtime.Composable
|
|
15
16
|
import androidx.compose.runtime.remember
|
|
16
17
|
import androidx.compose.ui.Modifier
|
|
18
|
+
import androidx.compose.ui.draw.clip
|
|
17
19
|
import androidx.compose.ui.draw.drawBehind
|
|
18
20
|
import androidx.compose.ui.geometry.Offset
|
|
19
21
|
import androidx.compose.ui.graphics.Brush
|
|
22
|
+
import androidx.compose.ui.unit.Dp
|
|
20
23
|
import androidx.compose.ui.unit.dp
|
|
21
24
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
22
25
|
import vn.momo.kits.const.Colors
|
|
@@ -34,7 +37,7 @@ private const val SHADOW_BRUSH_PERCENTAGE = 0.6f
|
|
|
34
37
|
private const val DEFAULT_DURATION_MILLIS = 1000
|
|
35
38
|
|
|
36
39
|
@Composable
|
|
37
|
-
fun Skeleton() {
|
|
40
|
+
fun Skeleton(cornerRadius: Dp = 0.dp) {
|
|
38
41
|
BoxWithConstraints(modifier = Modifier.fillMaxSize()) {
|
|
39
42
|
// Memoize width calculation
|
|
40
43
|
val maxWidthValue = remember(maxWidth) { maxWidth.value.toInt() }
|
|
@@ -42,6 +45,7 @@ fun Skeleton() {
|
|
|
42
45
|
Box(
|
|
43
46
|
modifier = Modifier
|
|
44
47
|
.fillMaxSize()
|
|
48
|
+
.clip(RoundedCornerShape(cornerRadius))
|
|
45
49
|
.background(Colors.black_05)
|
|
46
50
|
.conditional(IsShowBaseLineDebug) {
|
|
47
51
|
border(1.dp, Colors.blue_03)
|
|
@@ -13,6 +13,7 @@ import vn.momo.kits.navigation.component.HeaderBackProps
|
|
|
13
13
|
import vn.momo.kits.navigation.component.HeaderRight
|
|
14
14
|
import vn.momo.kits.navigation.component.HeaderTitle
|
|
15
15
|
import vn.momo.kits.navigation.component.HeaderType
|
|
16
|
+
import vn.momo.kits.navigation.component.TitlePosition
|
|
16
17
|
|
|
17
18
|
class Navigation(
|
|
18
19
|
val id: Int = -1,
|
|
@@ -28,6 +29,7 @@ class Navigation(
|
|
|
28
29
|
hiddenBack: Boolean? = null,
|
|
29
30
|
headerBackProps: HeaderBackProps? = null,
|
|
30
31
|
headerTitle: HeaderTitle? = null,
|
|
32
|
+
titlePosition: TitlePosition? = null,
|
|
31
33
|
headerRight: HeaderRight? = null,
|
|
32
34
|
headerType: HeaderType? = null,
|
|
33
35
|
scrollData: ScrollData? = null,
|
|
@@ -43,6 +45,7 @@ class Navigation(
|
|
|
43
45
|
hiddenBack = hiddenBack ?: options.hiddenBack,
|
|
44
46
|
headerBackProps = headerBackProps ?: options.headerBackProps,
|
|
45
47
|
headerTitle = headerTitle ?: options.headerTitle,
|
|
48
|
+
titlePosition = titlePosition ?: options.titlePosition,
|
|
46
49
|
headerRight = headerRight ?: options.headerRight,
|
|
47
50
|
headerType = headerType ?: options.headerType,
|
|
48
51
|
scrollData = scrollData ?: options.scrollData,
|
|
@@ -77,6 +80,7 @@ data class NavigationOptions(
|
|
|
77
80
|
val hiddenBack: Boolean = false,
|
|
78
81
|
val headerBackProps: HeaderBackProps = HeaderBackProps(),
|
|
79
82
|
val headerTitle: HeaderTitle = HeaderTitle.Default("Stack"),
|
|
83
|
+
val titlePosition: TitlePosition = TitlePosition.LEFT,
|
|
80
84
|
val headerRight: HeaderRight = HeaderRight.Toolkit(),
|
|
81
85
|
val headerType: HeaderType = HeaderType.Default(),
|
|
82
86
|
val scrollData: ScrollData = ScrollData(),
|
|
@@ -376,7 +376,7 @@ fun SearchAnimated(
|
|
|
376
376
|
val minTopPadding = AppStatusBar.current
|
|
377
377
|
val maxTopPadding = AppStatusBar.current + HEADER_HEIGHT.dp
|
|
378
378
|
val minStartPadding = Spacing.M
|
|
379
|
-
val maxStartPadding = if (options.hiddenBack) Spacing.M else
|
|
379
|
+
val maxStartPadding = if (options.hiddenBack) Spacing.M else 48.dp // button back: size + left +right = 28 + 12 + 8 = 48
|
|
380
380
|
val minEndPadding = Spacing.M
|
|
381
381
|
val maxEndPadding = headerRightWidthDp + if (options.headerRight is HeaderRight.None) Spacing.M else Spacing.M * 2
|
|
382
382
|
|
|
@@ -6,7 +6,6 @@ import androidx.compose.foundation.border
|
|
|
6
6
|
import androidx.compose.foundation.layout.Arrangement
|
|
7
7
|
import androidx.compose.foundation.layout.Box
|
|
8
8
|
import androidx.compose.foundation.layout.Row
|
|
9
|
-
import androidx.compose.foundation.layout.RowScope
|
|
10
9
|
import androidx.compose.foundation.layout.Spacer
|
|
11
10
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
12
11
|
import androidx.compose.foundation.layout.height
|
|
@@ -23,6 +22,7 @@ import androidx.compose.ui.graphics.Brush
|
|
|
23
22
|
import androidx.compose.ui.graphics.Color
|
|
24
23
|
import androidx.compose.ui.layout.onGloballyPositioned
|
|
25
24
|
import androidx.compose.ui.platform.LocalDensity
|
|
25
|
+
import androidx.compose.ui.text.style.TextAlign
|
|
26
26
|
import androidx.compose.ui.unit.Dp
|
|
27
27
|
import androidx.compose.ui.unit.dp
|
|
28
28
|
import vn.momo.kits.components.Icon
|
|
@@ -44,6 +44,7 @@ import vn.momo.kits.navigation.getInputSearchType
|
|
|
44
44
|
|
|
45
45
|
const val HEADER_HEIGHT = 52
|
|
46
46
|
enum class InputSearchType { None, Header, Animated }
|
|
47
|
+
enum class TitlePosition { LEFT, CENTER }
|
|
47
48
|
|
|
48
49
|
@Composable
|
|
49
50
|
fun Header(onBackHandler: (() -> Unit)? = null) {
|
|
@@ -76,6 +77,13 @@ fun Header(onBackHandler: (() -> Unit)? = null) {
|
|
|
76
77
|
AppTheme.current.colors.background.surface
|
|
77
78
|
|
|
78
79
|
if (options.headerType == HeaderType.None) return
|
|
80
|
+
|
|
81
|
+
val titlePosition = options.titlePosition
|
|
82
|
+
val titleColor = headerColor.tintIconColor
|
|
83
|
+
.copy(alpha = if (inputSearchType == InputSearchType.Animated) 1f - animatedAlpha else 1f)
|
|
84
|
+
// Centered title needs a full-width overlay to stay screen-centered, not boxed between back button and header right.
|
|
85
|
+
val centerTitle = titlePosition == TitlePosition.CENTER && options.headerTitle is HeaderTitle.Default
|
|
86
|
+
|
|
79
87
|
Box(
|
|
80
88
|
Modifier.height(AppStatusBar.current + HEADER_HEIGHT.dp)
|
|
81
89
|
.fillMaxWidth()
|
|
@@ -101,20 +109,40 @@ fun Header(onBackHandler: (() -> Unit)? = null) {
|
|
|
101
109
|
onBackHandler?.invoke() ?: navigator.onBackSafe { }
|
|
102
110
|
}
|
|
103
111
|
)
|
|
104
|
-
Spacer(Modifier.width(Spacing.
|
|
112
|
+
Spacer(Modifier.width(Spacing.S))
|
|
105
113
|
}
|
|
106
114
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
115
|
+
if (centerTitle) {
|
|
116
|
+
Spacer(Modifier.weight(1f))
|
|
117
|
+
} else {
|
|
118
|
+
HeaderContent(
|
|
119
|
+
headerTitle = options.headerTitle,
|
|
120
|
+
tintIconColor = titleColor,
|
|
121
|
+
titlePosition = titlePosition,
|
|
122
|
+
modifier = Modifier.weight(1f)
|
|
123
|
+
)
|
|
124
|
+
}
|
|
112
125
|
Box(Modifier.onGloballyPositioned {
|
|
113
126
|
if(headerRightWidthPx.intValue != it.size.width) headerRightWidthPx.intValue = it.size.width
|
|
114
127
|
}){
|
|
115
128
|
HeaderRight(options.headerRight, options.tintColor, headerColor)
|
|
116
129
|
}
|
|
117
130
|
}
|
|
131
|
+
if (centerTitle) {
|
|
132
|
+
Box(
|
|
133
|
+
modifier = Modifier.height(HEADER_HEIGHT.dp)
|
|
134
|
+
.fillMaxWidth()
|
|
135
|
+
.padding(horizontal = Spacing.M),
|
|
136
|
+
contentAlignment = Alignment.Center
|
|
137
|
+
) {
|
|
138
|
+
HeaderContent(
|
|
139
|
+
headerTitle = options.headerTitle,
|
|
140
|
+
tintIconColor = titleColor,
|
|
141
|
+
titlePosition = titlePosition,
|
|
142
|
+
modifier = Modifier.fillMaxWidth()
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
118
146
|
VerticalShadow(opacity)
|
|
119
147
|
}
|
|
120
148
|
}
|
|
@@ -140,15 +168,23 @@ private fun BackButton(borderColor: Color, backgroundButton: Color, tintIconColo
|
|
|
140
168
|
}
|
|
141
169
|
|
|
142
170
|
@Composable
|
|
143
|
-
fun
|
|
171
|
+
fun HeaderContent(
|
|
172
|
+
headerTitle: HeaderTitle,
|
|
173
|
+
tintIconColor: Color,
|
|
174
|
+
titlePosition: TitlePosition = TitlePosition.LEFT,
|
|
175
|
+
modifier: Modifier = Modifier,
|
|
176
|
+
){
|
|
144
177
|
Box(
|
|
145
|
-
|
|
178
|
+
modifier = modifier,
|
|
179
|
+
contentAlignment = if (titlePosition == TitlePosition.CENTER) Alignment.Center else Alignment.CenterStart
|
|
146
180
|
) {
|
|
147
181
|
when (headerTitle){
|
|
148
182
|
is HeaderTitle.Default -> {
|
|
149
183
|
HeaderTitle(
|
|
150
184
|
title = headerTitle.title,
|
|
151
|
-
color = tintIconColor
|
|
185
|
+
color = tintIconColor,
|
|
186
|
+
modifier = Modifier.fillMaxWidth(fraction = if (titlePosition == TitlePosition.CENTER) 0.5f else 1f),
|
|
187
|
+
textAlign = if (titlePosition == TitlePosition.CENTER) TextAlign.Center else TextAlign.Start
|
|
152
188
|
)
|
|
153
189
|
}
|
|
154
190
|
is HeaderTitle.Journey -> {}
|
|
@@ -16,11 +16,13 @@ import vn.momo.kits.modifier.setAutomationId
|
|
|
16
16
|
fun HeaderTitle(
|
|
17
17
|
title: String = "",
|
|
18
18
|
color: Color? = null,
|
|
19
|
+
modifier: Modifier = Modifier.fillMaxWidth(),
|
|
20
|
+
textAlign: TextAlign = TextAlign.Start,
|
|
19
21
|
) {
|
|
20
22
|
Text(
|
|
21
|
-
modifier =
|
|
23
|
+
modifier = modifier.zIndex(1f).setAutomationId("title_navigation_header"),
|
|
22
24
|
text = title,
|
|
23
|
-
textAlign =
|
|
25
|
+
textAlign = textAlign,
|
|
24
26
|
style = Typography.actionSBold.copy(
|
|
25
27
|
fontSize = 15.sp,
|
|
26
28
|
lineHeight = 22.sp,
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.foundation.layout.BoxScope
|
|
4
|
+
import androidx.compose.runtime.*
|
|
5
|
+
import androidx.compose.ui.Alignment
|
|
6
|
+
import androidx.compose.ui.Modifier
|
|
7
|
+
import androidx.compose.ui.graphics.Color
|
|
8
|
+
import androidx.compose.ui.layout.ContentScale
|
|
9
|
+
import androidx.compose.ui.unit.dp
|
|
10
|
+
import androidx.compose.ui.viewinterop.UIKitInteropProperties
|
|
11
|
+
import androidx.compose.ui.viewinterop.UIKitView
|
|
12
|
+
import cocoapods.SDWebImage.*
|
|
13
|
+
|
|
14
|
+
import kotlinx.cinterop.ExperimentalForeignApi
|
|
15
|
+
import platform.Foundation.NSURL
|
|
16
|
+
import platform.UIKit.UIImageView
|
|
17
|
+
import platform.UIKit.UIViewContentMode
|
|
18
|
+
import vn.momo.kits.const.AppTheme
|
|
19
|
+
import vn.momo.kits.platform.toUIColor
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@OptIn(ExperimentalForeignApi::class)
|
|
23
|
+
private val sdImageOptions = SDWebImageRetryFailed or
|
|
24
|
+
SDWebImageContinueInBackground or
|
|
25
|
+
SDWebImageScaleDownLargeImages or
|
|
26
|
+
SDWebImageHighPriority
|
|
27
|
+
|
|
28
|
+
@OptIn(ExperimentalForeignApi::class)
|
|
29
|
+
@Composable
|
|
30
|
+
actual fun BoxScope.NativeImageWrapper(
|
|
31
|
+
urlToLoad: Any,
|
|
32
|
+
modifier: Modifier,
|
|
33
|
+
options: Options?,
|
|
34
|
+
loading: Boolean
|
|
35
|
+
) {
|
|
36
|
+
val imageOptions = remember(options) {
|
|
37
|
+
options ?: Options()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
var imageState by remember { mutableStateOf(ImageState.Loading) }
|
|
41
|
+
(urlToLoad as? String)?.let { urlString ->
|
|
42
|
+
val contentModeValue = remember(imageOptions.contentScale) {
|
|
43
|
+
imageOptions.contentScale.toUIViewContentMode()
|
|
44
|
+
}
|
|
45
|
+
key(urlString) {
|
|
46
|
+
val isGif = isGifImage(urlString)
|
|
47
|
+
val imageView: UIImageView = remember {
|
|
48
|
+
if (isGif) {
|
|
49
|
+
SDAnimatedImageView().apply {
|
|
50
|
+
shouldCustomLoopCount = false
|
|
51
|
+
shouldIncrementalLoad = true
|
|
52
|
+
// Free decoded frame buffers as soon as animation stops,
|
|
53
|
+
// important when many GIFs churn through a list.
|
|
54
|
+
clearBufferWhenStopped = true
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
UIImageView()
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
val loadImage: (Color?) -> Unit = { tint ->
|
|
63
|
+
imageState = ImageState.Loading
|
|
64
|
+
val context = tint?.let {
|
|
65
|
+
mapOf<Any?, Any?>(
|
|
66
|
+
SDWebImageContextImageTransformer to
|
|
67
|
+
SDImageTintTransformer.transformerWithColor(it.toUIColor()),
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
imageView.sd_setImageWithURL(
|
|
71
|
+
NSURL.URLWithString(urlString),
|
|
72
|
+
placeholderImage = null,
|
|
73
|
+
options = sdImageOptions,
|
|
74
|
+
context = context,
|
|
75
|
+
progress = null,
|
|
76
|
+
completed = { image, error, _, _ ->
|
|
77
|
+
imageState = if (image != null && error == null) {
|
|
78
|
+
ImageState.Success
|
|
79
|
+
} else {
|
|
80
|
+
ImageState.Error
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
val appliedTint = remember { mutableStateOf(imageOptions.tint) }
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
DisposableEffect(Unit) {
|
|
91
|
+
onDispose {
|
|
92
|
+
// Cancel the download and release the decoded image / frame
|
|
93
|
+
// buffers now, rather than waiting for the view to deallocate.
|
|
94
|
+
imageView.sd_cancelCurrentImageLoad()
|
|
95
|
+
imageView.stopAnimating()
|
|
96
|
+
imageView.image = null
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
LaunchedEffect(Unit) {
|
|
101
|
+
appliedTint.value = imageOptions.tint
|
|
102
|
+
loadImage(imageOptions.tint)
|
|
103
|
+
}
|
|
104
|
+
UIKitView(
|
|
105
|
+
modifier = Modifier.matchParentSize(),
|
|
106
|
+
properties = UIKitInteropProperties(
|
|
107
|
+
interactionMode = null
|
|
108
|
+
),
|
|
109
|
+
factory = {
|
|
110
|
+
imageView.apply {
|
|
111
|
+
this.contentMode = contentModeValue
|
|
112
|
+
setAlpha(imageOptions.alpha.toDouble())
|
|
113
|
+
translatesAutoresizingMaskIntoConstraints = true
|
|
114
|
+
sd_imageTransition = SDWebImageTransition.fadeTransitionWithDuration(0.3)
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
update = { view ->
|
|
118
|
+
view.contentMode = contentModeValue
|
|
119
|
+
view.setAlpha(imageOptions.alpha.toDouble())
|
|
120
|
+
|
|
121
|
+
if (appliedTint.value != imageOptions.tint) {
|
|
122
|
+
appliedTint.value = imageOptions.tint
|
|
123
|
+
loadImage(imageOptions.tint)
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
when (imageState) {
|
|
130
|
+
ImageState.Loading -> if (loading) Skeleton(cornerRadius = options?.skeletonCornerRadius ?: 0.dp)
|
|
131
|
+
ImageState.Error -> {
|
|
132
|
+
val theme = AppTheme.current
|
|
133
|
+
Icon(
|
|
134
|
+
source = "media_fail",
|
|
135
|
+
color = theme.colors.text.disable,
|
|
136
|
+
modifier = Modifier.align(Alignment.Center)
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
ImageState.Success -> {}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private fun ContentScale.toUIViewContentMode(): UIViewContentMode = when (this) {
|
|
146
|
+
ContentScale.Crop, ContentScale.FillWidth, ContentScale.FillHeight ->
|
|
147
|
+
UIViewContentMode.UIViewContentModeScaleAspectFill
|
|
148
|
+
|
|
149
|
+
ContentScale.Fit, ContentScale.Inside -> UIViewContentMode.UIViewContentModeScaleAspectFit
|
|
150
|
+
ContentScale.FillBounds -> UIViewContentMode.UIViewContentModeScaleToFill
|
|
151
|
+
ContentScale.None -> UIViewContentMode.UIViewContentModeCenter
|
|
152
|
+
else -> UIViewContentMode.UIViewContentModeScaleAspectFill
|
|
153
|
+
}
|
|
Binary file
|
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
3
|
<plist version="1.0">
|
|
4
|
-
<dict
|
|
5
|
-
<key>SchemeUserState</key>
|
|
6
|
-
<dict>
|
|
7
|
-
<key>Example.xcscheme_^#shared#^_</key>
|
|
8
|
-
<dict>
|
|
9
|
-
<key>orderHint</key>
|
|
10
|
-
<integer>0</integer>
|
|
11
|
-
</dict>
|
|
12
|
-
</dict>
|
|
13
|
-
</dict>
|
|
4
|
+
<dict />
|
|
14
5
|
</plist>
|
|
@@ -21,6 +21,7 @@ maxapi = "0.1.1"
|
|
|
21
21
|
vanniktechMavenPublish = "0.34.0"
|
|
22
22
|
kits = "0.159.1-beta.7"
|
|
23
23
|
nativemaxapi = "0.0.6"
|
|
24
|
+
coilGif = "2.6.0"
|
|
24
25
|
|
|
25
26
|
[libraries]
|
|
26
27
|
ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor-version" }
|
|
@@ -37,6 +38,7 @@ navigation-multiplatform = { module = "org.jetbrains.androidx.navigation:navigat
|
|
|
37
38
|
coil-multiplatform-core = { module = "io.coil-kt.coil3:coil-core", version.ref = "coil3-multiplatform" }
|
|
38
39
|
coil-multiplatform-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil3-multiplatform" }
|
|
39
40
|
coil-multiplatform-network-ktor = { module = "io.coil-kt.coil3:coil-network-ktor3", version.ref = "coil3-multiplatform" }
|
|
41
|
+
coil-gif = { module = "io.coil-kt.coil3:coil-gif", version.ref = "coil3-multiplatform" }
|
|
40
42
|
r8 = { module = "com.android.tools:r8", version.ref = "r8" }
|
|
41
43
|
airbnb-lottie = { group = "com.airbnb.android", name = "lottie-compose", version.ref = "airbnb-lottie" }
|
|
42
44
|
# AI-GENERATED START
|
package/gradle.properties
CHANGED
package/local.properties
CHANGED
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
# Location of the SDK. This is only used by Gradle.
|
|
5
5
|
# For customization when using a Version Control System, please read the
|
|
6
6
|
# header note.
|
|
7
|
-
#
|
|
8
|
-
sdk.dir=/Users/
|
|
7
|
+
#Tue Jun 17 09:25:26 ICT 2025
|
|
8
|
+
sdk.dir=/Users/thanhle/Library/Android/sdk
|
package/package.json
CHANGED
package/publish.sh
CHANGED
|
@@ -456,7 +456,7 @@ case "$PHASE" in
|
|
|
456
456
|
;;
|
|
457
457
|
"maven")
|
|
458
458
|
echo "Running PHASE 2 only: Publish to Maven"
|
|
459
|
-
|
|
459
|
+
phase_publish_maven
|
|
460
460
|
;;
|
|
461
461
|
"npm")
|
|
462
462
|
echo "Running PHASE 3 only: Publish to NPM"
|
|
@@ -465,7 +465,7 @@ case "$PHASE" in
|
|
|
465
465
|
"all")
|
|
466
466
|
echo "Running ALL PHASES"
|
|
467
467
|
phase_check_version
|
|
468
|
-
|
|
468
|
+
phase_publish_maven
|
|
469
469
|
phase_publish_npm
|
|
470
470
|
echo ""
|
|
471
471
|
echo "🎉 ALL PHASES COMPLETED SUCCESSFULLY!"
|
|
Binary file
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<Scheme
|
|
3
|
-
LastUpgradeVersion = "1600"
|
|
4
|
-
version = "1.3">
|
|
5
|
-
<BuildAction
|
|
6
|
-
parallelizeBuildables = "YES"
|
|
7
|
-
buildImplicitDependencies = "YES">
|
|
8
|
-
<BuildActionEntries>
|
|
9
|
-
<BuildActionEntry
|
|
10
|
-
buildForTesting = "YES"
|
|
11
|
-
buildForRunning = "YES"
|
|
12
|
-
buildForProfiling = "YES"
|
|
13
|
-
buildForArchiving = "YES"
|
|
14
|
-
buildForAnalyzing = "YES">
|
|
15
|
-
<BuildableReference
|
|
16
|
-
BuildableIdentifier = "primary"
|
|
17
|
-
BlueprintIdentifier = "3B6FB503A75BF5BC1FA6F30BC06B9D28"
|
|
18
|
-
BuildableName = "MoMoUIKits.framework"
|
|
19
|
-
BlueprintName = "MoMoUIKits"
|
|
20
|
-
ReferencedContainer = "container:Pods.xcodeproj">
|
|
21
|
-
</BuildableReference>
|
|
22
|
-
</BuildActionEntry>
|
|
23
|
-
</BuildActionEntries>
|
|
24
|
-
</BuildAction>
|
|
25
|
-
<TestAction
|
|
26
|
-
buildConfiguration = "Debug"
|
|
27
|
-
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
28
|
-
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
29
|
-
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
30
|
-
<Testables>
|
|
31
|
-
</Testables>
|
|
32
|
-
</TestAction>
|
|
33
|
-
<LaunchAction
|
|
34
|
-
buildConfiguration = "Debug"
|
|
35
|
-
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
36
|
-
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
37
|
-
launchStyle = "0"
|
|
38
|
-
useCustomWorkingDirectory = "NO"
|
|
39
|
-
ignoresPersistentStateOnLaunch = "NO"
|
|
40
|
-
debugDocumentVersioning = "YES"
|
|
41
|
-
debugServiceExtension = "internal"
|
|
42
|
-
allowLocationSimulation = "YES">
|
|
43
|
-
</LaunchAction>
|
|
44
|
-
<ProfileAction
|
|
45
|
-
buildConfiguration = "Release"
|
|
46
|
-
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
47
|
-
savedToolIdentifier = ""
|
|
48
|
-
useCustomWorkingDirectory = "NO"
|
|
49
|
-
debugDocumentVersioning = "YES">
|
|
50
|
-
</ProfileAction>
|
|
51
|
-
<AnalyzeAction
|
|
52
|
-
buildConfiguration = "Debug">
|
|
53
|
-
</AnalyzeAction>
|
|
54
|
-
<ArchiveAction
|
|
55
|
-
buildConfiguration = "Release"
|
|
56
|
-
revealArchiveInOrganizer = "YES">
|
|
57
|
-
</ArchiveAction>
|
|
58
|
-
</Scheme>
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<Scheme
|
|
3
|
-
LastUpgradeVersion = "1600"
|
|
4
|
-
version = "1.3">
|
|
5
|
-
<BuildAction
|
|
6
|
-
parallelizeBuildables = "YES"
|
|
7
|
-
buildImplicitDependencies = "YES">
|
|
8
|
-
<BuildActionEntries>
|
|
9
|
-
<BuildActionEntry
|
|
10
|
-
buildForTesting = "YES"
|
|
11
|
-
buildForRunning = "YES"
|
|
12
|
-
buildForProfiling = "YES"
|
|
13
|
-
buildForArchiving = "YES"
|
|
14
|
-
buildForAnalyzing = "YES">
|
|
15
|
-
<BuildableReference
|
|
16
|
-
BuildableIdentifier = "primary"
|
|
17
|
-
BlueprintIdentifier = "0AEE99A309977BD12A049FF48AF9BA4B"
|
|
18
|
-
BuildableName = "Pods_Example.framework"
|
|
19
|
-
BlueprintName = "Pods-Example"
|
|
20
|
-
ReferencedContainer = "container:Pods.xcodeproj">
|
|
21
|
-
</BuildableReference>
|
|
22
|
-
</BuildActionEntry>
|
|
23
|
-
</BuildActionEntries>
|
|
24
|
-
</BuildAction>
|
|
25
|
-
<TestAction
|
|
26
|
-
buildConfiguration = "Debug"
|
|
27
|
-
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
28
|
-
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
29
|
-
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
30
|
-
<Testables>
|
|
31
|
-
</Testables>
|
|
32
|
-
</TestAction>
|
|
33
|
-
<LaunchAction
|
|
34
|
-
buildConfiguration = "Debug"
|
|
35
|
-
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
36
|
-
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
37
|
-
launchStyle = "0"
|
|
38
|
-
useCustomWorkingDirectory = "NO"
|
|
39
|
-
ignoresPersistentStateOnLaunch = "NO"
|
|
40
|
-
debugDocumentVersioning = "YES"
|
|
41
|
-
debugServiceExtension = "internal"
|
|
42
|
-
allowLocationSimulation = "YES">
|
|
43
|
-
</LaunchAction>
|
|
44
|
-
<ProfileAction
|
|
45
|
-
buildConfiguration = "Release"
|
|
46
|
-
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
47
|
-
savedToolIdentifier = ""
|
|
48
|
-
useCustomWorkingDirectory = "NO"
|
|
49
|
-
debugDocumentVersioning = "YES">
|
|
50
|
-
</ProfileAction>
|
|
51
|
-
<AnalyzeAction
|
|
52
|
-
buildConfiguration = "Debug">
|
|
53
|
-
</AnalyzeAction>
|
|
54
|
-
<ArchiveAction
|
|
55
|
-
buildConfiguration = "Release"
|
|
56
|
-
revealArchiveInOrganizer = "YES">
|
|
57
|
-
</ArchiveAction>
|
|
58
|
-
</Scheme>
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<Scheme
|
|
3
|
-
LastUpgradeVersion = "1600"
|
|
4
|
-
version = "1.3">
|
|
5
|
-
<BuildAction
|
|
6
|
-
parallelizeBuildables = "YES"
|
|
7
|
-
buildImplicitDependencies = "YES">
|
|
8
|
-
<BuildActionEntries>
|
|
9
|
-
<BuildActionEntry
|
|
10
|
-
buildForTesting = "YES"
|
|
11
|
-
buildForRunning = "YES"
|
|
12
|
-
buildForProfiling = "YES"
|
|
13
|
-
buildForArchiving = "YES"
|
|
14
|
-
buildForAnalyzing = "YES">
|
|
15
|
-
<BuildableReference
|
|
16
|
-
BuildableIdentifier = "primary"
|
|
17
|
-
BlueprintIdentifier = "3847153A6E5EEFB86565BA840768F429"
|
|
18
|
-
BuildableName = "SDWebImage.framework"
|
|
19
|
-
BlueprintName = "SDWebImage"
|
|
20
|
-
ReferencedContainer = "container:Pods.xcodeproj">
|
|
21
|
-
</BuildableReference>
|
|
22
|
-
</BuildActionEntry>
|
|
23
|
-
</BuildActionEntries>
|
|
24
|
-
</BuildAction>
|
|
25
|
-
<TestAction
|
|
26
|
-
buildConfiguration = "Debug"
|
|
27
|
-
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
28
|
-
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
29
|
-
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
30
|
-
<Testables>
|
|
31
|
-
</Testables>
|
|
32
|
-
</TestAction>
|
|
33
|
-
<LaunchAction
|
|
34
|
-
buildConfiguration = "Debug"
|
|
35
|
-
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
36
|
-
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
37
|
-
launchStyle = "0"
|
|
38
|
-
useCustomWorkingDirectory = "NO"
|
|
39
|
-
ignoresPersistentStateOnLaunch = "NO"
|
|
40
|
-
debugDocumentVersioning = "YES"
|
|
41
|
-
debugServiceExtension = "internal"
|
|
42
|
-
allowLocationSimulation = "YES">
|
|
43
|
-
</LaunchAction>
|
|
44
|
-
<ProfileAction
|
|
45
|
-
buildConfiguration = "Release"
|
|
46
|
-
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
47
|
-
savedToolIdentifier = ""
|
|
48
|
-
useCustomWorkingDirectory = "NO"
|
|
49
|
-
debugDocumentVersioning = "YES">
|
|
50
|
-
</ProfileAction>
|
|
51
|
-
<AnalyzeAction
|
|
52
|
-
buildConfiguration = "Debug">
|
|
53
|
-
</AnalyzeAction>
|
|
54
|
-
<ArchiveAction
|
|
55
|
-
buildConfiguration = "Release"
|
|
56
|
-
revealArchiveInOrganizer = "YES">
|
|
57
|
-
</ArchiveAction>
|
|
58
|
-
</Scheme>
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<Scheme
|
|
3
|
-
LastUpgradeVersion = "1600"
|
|
4
|
-
version = "1.3">
|
|
5
|
-
<BuildAction
|
|
6
|
-
parallelizeBuildables = "YES"
|
|
7
|
-
buildImplicitDependencies = "YES">
|
|
8
|
-
<BuildActionEntries>
|
|
9
|
-
<BuildActionEntry
|
|
10
|
-
buildForTesting = "YES"
|
|
11
|
-
buildForRunning = "YES"
|
|
12
|
-
buildForProfiling = "YES"
|
|
13
|
-
buildForArchiving = "YES"
|
|
14
|
-
buildForAnalyzing = "YES">
|
|
15
|
-
<BuildableReference
|
|
16
|
-
BuildableIdentifier = "primary"
|
|
17
|
-
BlueprintIdentifier = "92EBFA3E7005B4C18A9C0B44324EB80F"
|
|
18
|
-
BuildableName = "SDWebImageSwiftUI.framework"
|
|
19
|
-
BlueprintName = "SDWebImageSwiftUI"
|
|
20
|
-
ReferencedContainer = "container:Pods.xcodeproj">
|
|
21
|
-
</BuildableReference>
|
|
22
|
-
</BuildActionEntry>
|
|
23
|
-
</BuildActionEntries>
|
|
24
|
-
</BuildAction>
|
|
25
|
-
<TestAction
|
|
26
|
-
buildConfiguration = "Debug"
|
|
27
|
-
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
28
|
-
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
29
|
-
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
30
|
-
<Testables>
|
|
31
|
-
</Testables>
|
|
32
|
-
</TestAction>
|
|
33
|
-
<LaunchAction
|
|
34
|
-
buildConfiguration = "Debug"
|
|
35
|
-
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
36
|
-
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
37
|
-
launchStyle = "0"
|
|
38
|
-
useCustomWorkingDirectory = "NO"
|
|
39
|
-
ignoresPersistentStateOnLaunch = "NO"
|
|
40
|
-
debugDocumentVersioning = "YES"
|
|
41
|
-
debugServiceExtension = "internal"
|
|
42
|
-
allowLocationSimulation = "YES">
|
|
43
|
-
</LaunchAction>
|
|
44
|
-
<ProfileAction
|
|
45
|
-
buildConfiguration = "Release"
|
|
46
|
-
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
47
|
-
savedToolIdentifier = ""
|
|
48
|
-
useCustomWorkingDirectory = "NO"
|
|
49
|
-
debugDocumentVersioning = "YES">
|
|
50
|
-
</ProfileAction>
|
|
51
|
-
<AnalyzeAction
|
|
52
|
-
buildConfiguration = "Debug">
|
|
53
|
-
</AnalyzeAction>
|
|
54
|
-
<ArchiveAction
|
|
55
|
-
buildConfiguration = "Release"
|
|
56
|
-
revealArchiveInOrganizer = "YES">
|
|
57
|
-
</ArchiveAction>
|
|
58
|
-
</Scheme>
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<Scheme
|
|
3
|
-
LastUpgradeVersion = "1600"
|
|
4
|
-
version = "1.3">
|
|
5
|
-
<BuildAction
|
|
6
|
-
parallelizeBuildables = "YES"
|
|
7
|
-
buildImplicitDependencies = "YES">
|
|
8
|
-
<BuildActionEntries>
|
|
9
|
-
<BuildActionEntry
|
|
10
|
-
buildForTesting = "YES"
|
|
11
|
-
buildForRunning = "YES"
|
|
12
|
-
buildForProfiling = "YES"
|
|
13
|
-
buildForArchiving = "YES"
|
|
14
|
-
buildForAnalyzing = "YES">
|
|
15
|
-
<BuildableReference
|
|
16
|
-
BuildableIdentifier = "primary"
|
|
17
|
-
BlueprintIdentifier = "6510766A9670BFA3B251E2A62446FC5D"
|
|
18
|
-
BuildableName = "SkeletonUI.framework"
|
|
19
|
-
BlueprintName = "SkeletonUI"
|
|
20
|
-
ReferencedContainer = "container:Pods.xcodeproj">
|
|
21
|
-
</BuildableReference>
|
|
22
|
-
</BuildActionEntry>
|
|
23
|
-
</BuildActionEntries>
|
|
24
|
-
</BuildAction>
|
|
25
|
-
<TestAction
|
|
26
|
-
buildConfiguration = "Debug"
|
|
27
|
-
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
28
|
-
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
29
|
-
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
30
|
-
<Testables>
|
|
31
|
-
</Testables>
|
|
32
|
-
</TestAction>
|
|
33
|
-
<LaunchAction
|
|
34
|
-
buildConfiguration = "Debug"
|
|
35
|
-
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
36
|
-
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
37
|
-
launchStyle = "0"
|
|
38
|
-
useCustomWorkingDirectory = "NO"
|
|
39
|
-
ignoresPersistentStateOnLaunch = "NO"
|
|
40
|
-
debugDocumentVersioning = "YES"
|
|
41
|
-
debugServiceExtension = "internal"
|
|
42
|
-
allowLocationSimulation = "YES">
|
|
43
|
-
</LaunchAction>
|
|
44
|
-
<ProfileAction
|
|
45
|
-
buildConfiguration = "Release"
|
|
46
|
-
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
47
|
-
savedToolIdentifier = ""
|
|
48
|
-
useCustomWorkingDirectory = "NO"
|
|
49
|
-
debugDocumentVersioning = "YES">
|
|
50
|
-
</ProfileAction>
|
|
51
|
-
<AnalyzeAction
|
|
52
|
-
buildConfiguration = "Debug">
|
|
53
|
-
</AnalyzeAction>
|
|
54
|
-
<ArchiveAction
|
|
55
|
-
buildConfiguration = "Release"
|
|
56
|
-
revealArchiveInOrganizer = "YES">
|
|
57
|
-
</ArchiveAction>
|
|
58
|
-
</Scheme>
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
-
<plist version="1.0">
|
|
4
|
-
<dict>
|
|
5
|
-
<key>SchemeUserState</key>
|
|
6
|
-
<dict>
|
|
7
|
-
<key>MoMoUIKits.xcscheme</key>
|
|
8
|
-
<dict>
|
|
9
|
-
<key>isShown</key>
|
|
10
|
-
<false />
|
|
11
|
-
<key>orderHint</key>
|
|
12
|
-
<integer>0</integer>
|
|
13
|
-
</dict>
|
|
14
|
-
<key>Pods-Example.xcscheme</key>
|
|
15
|
-
<dict>
|
|
16
|
-
<key>isShown</key>
|
|
17
|
-
<false />
|
|
18
|
-
<key>orderHint</key>
|
|
19
|
-
<integer>1</integer>
|
|
20
|
-
</dict>
|
|
21
|
-
<key>SDWebImage.xcscheme</key>
|
|
22
|
-
<dict>
|
|
23
|
-
<key>isShown</key>
|
|
24
|
-
<false />
|
|
25
|
-
<key>orderHint</key>
|
|
26
|
-
<integer>2</integer>
|
|
27
|
-
</dict>
|
|
28
|
-
<key>SDWebImageSwiftUI.xcscheme</key>
|
|
29
|
-
<dict>
|
|
30
|
-
<key>isShown</key>
|
|
31
|
-
<false />
|
|
32
|
-
<key>orderHint</key>
|
|
33
|
-
<integer>3</integer>
|
|
34
|
-
</dict>
|
|
35
|
-
<key>SkeletonUI.xcscheme</key>
|
|
36
|
-
<dict>
|
|
37
|
-
<key>isShown</key>
|
|
38
|
-
<false />
|
|
39
|
-
<key>orderHint</key>
|
|
40
|
-
<integer>4</integer>
|
|
41
|
-
</dict>
|
|
42
|
-
</dict>
|
|
43
|
-
<key>SuppressBuildableAutocreation</key>
|
|
44
|
-
<dict />
|
|
45
|
-
</dict>
|
|
46
|
-
</plist>
|