@momo-kits/native-kits 0.163.1-beta.3-debug → 0.163.1-beta.5-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/CLAUDE.md +1 -1
- package/compose/build.gradle.kts +2 -1
- package/compose/build.gradle.kts.backup +1 -0
- package/compose/compose.podspec +1 -1
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +7 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +8 -10
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +3 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +56 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +11 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +40 -55
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +69 -26
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +3 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +21 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +3 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +22 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +28 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +4 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +112 -115
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +11 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +3 -4
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +3 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +2 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +9 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +66 -0
- package/gradle/libs.versions.toml +2 -0
- package/gradle.properties +1 -1
- package/ios/Application/ApplicationEnvironment.swift +11 -1
- package/ios/Application/Components.swift +34 -44
- package/ios/Application/FloatingButton.swift +10 -9
- package/ios/Application/HeaderRight.swift +79 -45
- package/ios/Application/Navigation/BottomTab/BottomTab.swift +103 -0
- package/ios/Application/Navigation/BottomTab/BottomTabBar.swift +215 -0
- package/ios/Application/Navigation/BottomTab/CurvedContainer.swift +65 -0
- package/ios/Application/Navigation/HeaderBackProps.swift +66 -0
- package/ios/Application/Navigation/HeaderTitle.swift +57 -0
- package/ios/Application/Navigation/HeaderUser.swift +209 -0
- package/ios/Application/Navigation/NavigationContainer.swift +176 -0
- package/ios/Application/Navigation/NavigationOptions.swift +109 -0
- package/ios/Application/Navigation/Navigator.swift +364 -0
- package/ios/Application/Navigation/Overplay/BottomSheet.swift +188 -0
- package/ios/Application/Navigation/Overplay/ModalScreen.swift +68 -0
- package/ios/Application/Navigation/Overplay/SnackBar.swift +144 -0
- package/ios/Application/Navigation/component/Header.swift +178 -0
- package/ios/Application/Navigation/component/HeaderBackground.swift +83 -0
- package/ios/Application/Navigation/component/HeaderColor.swift +65 -0
- package/ios/Application/Screen.swift +2 -1
- package/ios/Application/StackScreen.swift +453 -0
- package/ios/Avatar/Avatar.swift +193 -0
- package/ios/Badge/Badge.swift +11 -14
- package/ios/Badge/BadgeRibbon.swift +12 -21
- package/ios/BaselineView/BaselineView.swift +163 -0
- package/ios/Button/Button.swift +61 -22
- package/ios/Carousel/Carousel.swift +181 -0
- package/ios/Checkbox/Checkbox.swift +14 -13
- package/ios/Chip/Chip.swift +23 -9
- package/ios/Collapse/Collapse.swift +182 -0
- package/ios/Colors+Radius+Spacing/Colors.swift +12 -12
- package/ios/Colors+Radius+Spacing/Theme.swift +295 -0
- package/ios/DateTimePicker/DateTimePicker.swift +210 -0
- package/ios/DateTimePicker/DateTimePickerTypes.swift +55 -0
- package/ios/DateTimePicker/DateTimePickerUtils.swift +167 -0
- package/ios/DateTimePicker/WheelPicker.swift +161 -0
- package/ios/Divider/Divider.swift +16 -0
- package/ios/Extensions/Color++.swift +32 -0
- package/ios/Icon/Icon.swift +6 -1
- package/ios/IconButton/IconButton.swift +112 -0
- package/ios/Input/Input.swift +41 -25
- package/ios/Input/InputPhoneNumber.swift +20 -19
- package/ios/Input/InputSearch.swift +100 -47
- package/ios/Input/InputTextArea.swift +66 -40
- package/ios/InputDropDown/InputDropDown.swift +198 -0
- package/ios/InputMoney/InputMoney.swift +335 -0
- package/ios/InputOTP/InputOTP.swift +210 -0
- package/ios/Loader/Loader.swift +113 -0
- package/ios/MoMoUIKits.podspec +5 -0
- package/ios/Pagination/PaginationDot.swift +61 -0
- package/ios/Pagination/PaginationNumber.swift +35 -0
- package/ios/Pagination/PaginationScroll.swift +101 -0
- package/ios/Pagination/PaginationWhiteDot.swift +37 -0
- package/ios/Popup/PopupDisplay.swift +8 -16
- package/ios/Popup/PopupInput.swift +2 -8
- package/ios/Popup/PopupNotify.swift +219 -0
- package/ios/ProgressInfo/ProgressInfo.swift +294 -0
- package/ios/Radio/Radio.swift +70 -0
- package/ios/Rating/Rating.swift +82 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/AccentColor.colorset/Contents.json +11 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Background.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Border.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Card.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Contents.json +6 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Error.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Primary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryDark.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryLight.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Success.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Text.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/TextSecondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/Contents.json +9 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-default.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-disable.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-pressed.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-selected.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-surface.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-tonal.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-default.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-disable.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/gradient.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/primary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-container.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-primary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-default.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-disable.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-hint.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-secondary.colorset/Contents.json +38 -0
- package/ios/Resources/MoMoUIKitsColors.xcassets/Warning.colorset/Contents.json +38 -0
- package/ios/Skeleton/Skeleton.swift +99 -0
- package/ios/Slider/Slider.swift +237 -0
- package/ios/Stepper/Stepper.swift +220 -0
- package/ios/Steps/Steps.swift +451 -0
- package/ios/SuggestAction/SuggestAction.swift +97 -0
- package/ios/Swipeable/SwipeCell.swift +185 -0
- package/ios/Swipeable/SwipeCellModel.swift +21 -0
- package/ios/TabView/TabView.swift +530 -0
- package/ios/Tag/Tag.swift +98 -0
- package/ios/Title/Title.swift +269 -0
- package/ios/Tooltip/Tooltip.swift +482 -0
- package/ios/Typography/FontScaleStore.swift +19 -0
- package/ios/Typography/Text.swift +86 -17
- package/ios/Typography/Typography.swift +12 -14
- package/ios/Uploader/Uploader.swift +183 -0
- package/ios/native-kits.podspec +61 -8
- package/ios-demo/MoMoUIKitsDemo.podspec +20 -0
- package/ios-demo/README.md +120 -0
- package/ios-demo/Resources/dot_loading.json +558 -0
- package/ios-demo/Resources/icon.json +4052 -0
- package/ios-demo/Resources/lottie_circle_loader.json +1 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/DemoScaffold.swift +48 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsBadgeDemoView.swift +25 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsButtonDemoView.swift +26 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsCheckboxDemoView.swift +19 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsChipDemoView.swift +33 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsInputDemoView.swift +48 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsPopupDemoView.swift +21 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsRadioDemoView.swift +17 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsTypographyDemoView.swift +28 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoContext.swift +31 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoFactory.swift +24 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AnimatedHeaderDemo.swift +110 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +93 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +269 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BaselineView.swift +117 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BottomTabDemo.swift +89 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +100 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +126 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +63 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +20 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +93 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +107 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +124 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +14 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/HeaderUserDemo.swift +49 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +278 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +58 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +78 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +138 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +111 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +136 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +107 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +73 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +100 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +32 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +57 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +70 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +227 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +72 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +175 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +121 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +76 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +89 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +32 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +56 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +32 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +150 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +138 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +103 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +94 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +79 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +152 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +33 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +190 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +34 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +182 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +109 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +187 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +87 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +131 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +51 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +15 -0
- package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +73 -0
- package/package.json +1 -1
- package/publish.sh +50 -0
- package/scripts/gen-ios-color.mjs +136 -0
- package/example/ios/Example.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
- package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -5
- 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/ios/Application/FontScaleStore.swift +0 -59
package/CLAUDE.md
CHANGED
|
@@ -40,7 +40,7 @@ Publishing is automated (`publish.sh` + GitLab CI on `[ci build]` / `main`). Do
|
|
|
40
40
|
## Architecture essentials
|
|
41
41
|
|
|
42
42
|
- **Entry point:** wrap content in `NavigationContainer(...)` from `navigation/`. It builds the `Navigator`, takes a host-supplied `Localize` (falls back to an empty one), and provides the CompositionLocals below. **Do not use** `ApplicationContainer` (`application/NavigationContainer.kt`) — deprecated and does **not** wire `LocalLocalize` / `LocalNavigator` / `LocalMaxApi`.
|
|
43
|
-
- **Configuration flows via CompositionLocals**, not params. Public ones: `AppTheme`, `AppStatusBar`, `AppNavigationBar` (`const/Theme.kt`); `ApplicationContext`, `AppConfig`, `AppLanguage`, `LocalLocalize
|
|
43
|
+
- **Configuration flows via CompositionLocals**, not params. Public ones: `AppTheme`, `AppStatusBar`, `AppNavigationBar` (`const/Theme.kt`); `ApplicationContext`, `AppConfig`, `AppLanguage`, `LocalLocalize` (`application/`); `LocalNavigator`, `LocalMaxApi` (`navigation/`). Read with `X.current`.
|
|
44
44
|
- **Platform code** goes through `expect`/`actual` in `platform/` — never reference Android/iOS APIs from `commonMain` directly.
|
|
45
45
|
- **Native bridge:** `IMaxApi` (`vn.momo.maxapi`, exposed as `LocalMaxApi`) is the host-app bridge (dismiss, tracking, device info, language).
|
|
46
46
|
- Navigation uses a runtime `DynamicScreenRegistry`; overlays (modal/bottom-sheet/snackbar) go through `Navigator` + `OverplayComponentRegistry`.
|
package/compose/build.gradle.kts
CHANGED
|
@@ -40,7 +40,7 @@ kotlin {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
cocoapods {
|
|
43
|
-
version = "0.163.1-beta.
|
|
43
|
+
version = "0.163.1-beta.5-debug"
|
|
44
44
|
summary = "IOS Shared module"
|
|
45
45
|
homepage = "https://momo.vn"
|
|
46
46
|
ios.deploymentTarget = "15.0"
|
|
@@ -77,6 +77,7 @@ kotlin {
|
|
|
77
77
|
implementation(libs.kotlinx.datetime)
|
|
78
78
|
api(libs.native.max.api)
|
|
79
79
|
implementation(libs.compottie)
|
|
80
|
+
implementation(libs.gif.image)
|
|
80
81
|
}
|
|
81
82
|
androidMain.dependencies {
|
|
82
83
|
implementation(libs.ktor.client.okhttp)
|
package/compose/compose.podspec
CHANGED
|
@@ -28,7 +28,9 @@ data class MiniAppContext(
|
|
|
28
28
|
val providerId: String = "",
|
|
29
29
|
val permissions: List<Map<String, Any>>? = emptyList(),
|
|
30
30
|
val features: FeatureFlags? = null,
|
|
31
|
-
val
|
|
31
|
+
val scaleSizeMaxRate: Float? = null,
|
|
32
|
+
val userScaleRate: Float? = null,
|
|
33
|
+
val useOSScaleRate: Boolean? = null,
|
|
32
34
|
) {
|
|
33
35
|
companion object {
|
|
34
36
|
|
|
@@ -60,7 +62,9 @@ data class MiniAppContext(
|
|
|
60
62
|
providerId = parent.providerId.ifBlank { child.providerId },
|
|
61
63
|
permissions = if (!parent.permissions.isNullOrEmpty()) parent.permissions else child.permissions,
|
|
62
64
|
features = mergeFeatureFlags(parent.features, child.features),
|
|
63
|
-
|
|
65
|
+
scaleSizeMaxRate = parent.scaleSizeMaxRate ?: child.scaleSizeMaxRate,
|
|
66
|
+
userScaleRate = parent.userScaleRate ?: child.userScaleRate,
|
|
67
|
+
useOSScaleRate = parent.useOSScaleRate ?: child.useOSScaleRate,
|
|
64
68
|
)
|
|
65
69
|
}
|
|
66
70
|
|
|
@@ -98,11 +102,5 @@ val LocalComponentInformation = staticCompositionLocalOf<ComponentInformation?>
|
|
|
98
102
|
null
|
|
99
103
|
}
|
|
100
104
|
|
|
101
|
-
@
|
|
102
|
-
|
|
103
|
-
val useOSFontScale: Boolean = true,
|
|
104
|
-
val userScaleRate: Float? = null,
|
|
105
|
-
val osFontScale: Float? = null,
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
val LocalFontScaleConfig = staticCompositionLocalOf { FontScaleConfig() }
|
|
105
|
+
@Deprecated("Max font scale is fixed at MAX_FONT_SCALE (1.5); this CompositionLocal is no longer read.")
|
|
106
|
+
val ScaleSizeMaxRate = staticCompositionLocalOf<Float?> { null }
|
|
@@ -7,6 +7,7 @@ import androidx.compose.ui.Modifier
|
|
|
7
7
|
import androidx.compose.ui.unit.Dp
|
|
8
8
|
import vn.momo.kits.const.*
|
|
9
9
|
import vn.momo.kits.modifier.DeprecatedModifier
|
|
10
|
+
import vn.momo.kits.platform.ProvideOsFontScale
|
|
10
11
|
import vn.momo.kits.platform.getStatusBarHeight
|
|
11
12
|
|
|
12
13
|
@Deprecated("Use IMaxApi instead", ReplaceWith("IMaxApi"))
|
|
@@ -93,6 +94,7 @@ fun ApplicationContainer(
|
|
|
93
94
|
|
|
94
95
|
val appStatusBarHeight = statusBarHeight ?: getStatusBarHeight()
|
|
95
96
|
|
|
97
|
+
ProvideOsFontScale {
|
|
96
98
|
CompositionLocalProvider(
|
|
97
99
|
AppTheme provides appTheme,
|
|
98
100
|
PlatformApi provides composeApi,
|
|
@@ -103,5 +105,6 @@ fun ApplicationContainer(
|
|
|
103
105
|
content()
|
|
104
106
|
}
|
|
105
107
|
}
|
|
108
|
+
}
|
|
106
109
|
|
|
107
110
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
package vn.momo.kits.application
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.Composable
|
|
4
|
+
import androidx.compose.runtime.CompositionLocalProvider
|
|
5
|
+
import androidx.compose.runtime.LaunchedEffect
|
|
6
|
+
import androidx.compose.runtime.remember
|
|
7
|
+
import vn.momo.kits.const.AppTheme
|
|
8
|
+
import vn.momo.kits.const.Theme
|
|
9
|
+
import vn.momo.kits.navigation.LocalMaxApi
|
|
10
|
+
import vn.momo.kits.platform.ProvideOsFontScale
|
|
11
|
+
import vn.momo.maxapi.IMaxApi
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@Composable
|
|
15
|
+
fun WidgetContainer(
|
|
16
|
+
theme: Theme? = null,
|
|
17
|
+
miniAppContext: MiniAppContext? = null,
|
|
18
|
+
maxApi: IMaxApi? = null,
|
|
19
|
+
localize: Localize? = null,
|
|
20
|
+
content: @Composable () -> Unit,
|
|
21
|
+
) {
|
|
22
|
+
val parentContext = LocalContext.current
|
|
23
|
+
val mergedContext = remember(parentContext, miniAppContext) {
|
|
24
|
+
MiniAppContext.merge(parentContext, miniAppContext)
|
|
25
|
+
}
|
|
26
|
+
val resolvedTheme = theme ?: AppTheme.current
|
|
27
|
+
val resolvedLocalize = localize ?: LocalLocalize.current
|
|
28
|
+
val resolvedMaxApi = maxApi ?: LocalMaxApi.current
|
|
29
|
+
|
|
30
|
+
LaunchedEffect(resolvedMaxApi, localize) {
|
|
31
|
+
val api = resolvedMaxApi ?: return@LaunchedEffect
|
|
32
|
+
val target = localize ?: return@LaunchedEffect
|
|
33
|
+
runCatching {
|
|
34
|
+
api.getLanguage(callback = { data ->
|
|
35
|
+
if (parseLanguage(data) == Localize.EN) target.changeLanguage(Localize.EN)
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
ProvideOsFontScale {
|
|
41
|
+
CompositionLocalProvider(
|
|
42
|
+
AppTheme provides resolvedTheme,
|
|
43
|
+
LocalContext provides mergedContext,
|
|
44
|
+
LocalLocalize provides resolvedLocalize,
|
|
45
|
+
LocalMaxApi provides resolvedMaxApi,
|
|
46
|
+
) {
|
|
47
|
+
content()
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private fun parseLanguage(raw: Map<String, Any?>?): String? {
|
|
53
|
+
val code = (raw?.get("response") as? String)?.trim()?.lowercase()
|
|
54
|
+
if (code.isNullOrEmpty()) return null
|
|
55
|
+
return if (code.startsWith(Localize.EN)) Localize.EN else Localize.VI
|
|
56
|
+
}
|
|
@@ -95,11 +95,13 @@ private fun getStyle(size: Size): TextStyle {
|
|
|
95
95
|
return styleCache[size] ?: Typography.actionDefaultBold
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
@InternalApi
|
|
99
|
+
fun getIconSize(size: Size): Dp = iconSizeCache[size] ?: 24.dp
|
|
99
100
|
private fun getIconSpace(size: Size): Dp = iconSpaceCache[size] ?: Spacing.S
|
|
100
101
|
|
|
102
|
+
@InternalApi
|
|
101
103
|
@Composable
|
|
102
|
-
|
|
104
|
+
fun getTextColor(loading: Boolean, type: ButtonType): Color {
|
|
103
105
|
val theme = AppTheme.current
|
|
104
106
|
|
|
105
107
|
return remember(type, theme, loading) {
|
|
@@ -140,7 +142,6 @@ fun RenderIcon(
|
|
|
140
142
|
useTintColor: Boolean = true,
|
|
141
143
|
icon: String = "",
|
|
142
144
|
forceLoading: Boolean = false,
|
|
143
|
-
bgColor: Color? = null,
|
|
144
145
|
textColor: Color? = null,
|
|
145
146
|
) {
|
|
146
147
|
val iconSize = remember(size) { getIconSize(size) }
|
|
@@ -156,9 +157,10 @@ fun RenderIcon(
|
|
|
156
157
|
Box(modifier) {
|
|
157
158
|
LottieAnimation(
|
|
158
159
|
modifier = Modifier.size(iconSize),
|
|
159
|
-
bgColor =
|
|
160
|
+
bgColor = null,
|
|
160
161
|
tintColor = color,
|
|
161
|
-
path = "files/lottie_circle_loader"
|
|
162
|
+
path = "files/lottie_circle_loader",
|
|
163
|
+
useCompose = true
|
|
162
164
|
)
|
|
163
165
|
}
|
|
164
166
|
} else if (icon.isNotEmpty()) {
|
|
@@ -183,8 +185,9 @@ private fun shouldLoadingOnLeft(iconLeft: String, iconRight: String): Boolean {
|
|
|
183
185
|
}
|
|
184
186
|
}
|
|
185
187
|
|
|
188
|
+
@InternalApi
|
|
186
189
|
@Composable
|
|
187
|
-
|
|
190
|
+
fun getTypeStyle(
|
|
188
191
|
type: ButtonType,
|
|
189
192
|
color: Color? = AppTheme.current.colors.primary,
|
|
190
193
|
size: Size,
|
|
@@ -219,8 +222,9 @@ internal fun getTypeStyle(
|
|
|
219
222
|
}
|
|
220
223
|
}
|
|
221
224
|
|
|
225
|
+
@InternalApi
|
|
222
226
|
@Composable
|
|
223
|
-
|
|
227
|
+
fun getButtonBackgroundColor(
|
|
224
228
|
loading: Boolean,
|
|
225
229
|
type: ButtonType
|
|
226
230
|
): Color {
|
|
@@ -336,7 +340,6 @@ fun Button(
|
|
|
336
340
|
useTintColor = useTintColor,
|
|
337
341
|
icon = iconLeft,
|
|
338
342
|
forceLoading = loading && loadingOnLeft,
|
|
339
|
-
bgColor = bgColor,
|
|
340
343
|
textColor = textColor
|
|
341
344
|
)
|
|
342
345
|
RenderTitle(size, title, textColor = textColor)
|
|
@@ -346,7 +349,6 @@ fun Button(
|
|
|
346
349
|
useTintColor = useTintColor,
|
|
347
350
|
icon = iconRight,
|
|
348
351
|
forceLoading = loading && !loadingOnLeft,
|
|
349
|
-
bgColor = bgColor,
|
|
350
352
|
textColor = textColor
|
|
351
353
|
)
|
|
352
354
|
}
|
|
@@ -5,6 +5,7 @@ import androidx.compose.foundation.border
|
|
|
5
5
|
import androidx.compose.foundation.clickable
|
|
6
6
|
import androidx.compose.foundation.layout.Box
|
|
7
7
|
import androidx.compose.foundation.layout.size
|
|
8
|
+
import androidx.compose.foundation.shape.CircleShape
|
|
8
9
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
9
10
|
import androidx.compose.runtime.Composable
|
|
10
11
|
import androidx.compose.runtime.remember
|
|
@@ -12,6 +13,7 @@ import androidx.compose.ui.Alignment
|
|
|
12
13
|
import androidx.compose.ui.Modifier
|
|
13
14
|
import androidx.compose.ui.draw.clip
|
|
14
15
|
import androidx.compose.ui.graphics.Color
|
|
16
|
+
import androidx.compose.ui.graphics.Shape
|
|
15
17
|
import androidx.compose.ui.unit.Dp
|
|
16
18
|
import androidx.compose.ui.unit.dp
|
|
17
19
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
@@ -21,69 +23,58 @@ import vn.momo.kits.const.Radius
|
|
|
21
23
|
import vn.momo.kits.modifier.conditional
|
|
22
24
|
|
|
23
25
|
data class IconSpecs(
|
|
24
|
-
val
|
|
25
|
-
val
|
|
26
|
-
val radius: Dp,
|
|
27
|
-
val size: Dp
|
|
26
|
+
val box: Dp,
|
|
27
|
+
val icon: Dp,
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
enum class IconSize(val value: IconSpecs) {
|
|
31
|
-
LARGE(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
radius = Radius.XL,
|
|
35
|
-
width = 48.dp,
|
|
36
|
-
size = 48.dp
|
|
37
|
-
)
|
|
38
|
-
),
|
|
39
|
-
SMALL(
|
|
40
|
-
IconSpecs(
|
|
41
|
-
height = 40.dp,
|
|
42
|
-
radius = Radius.XL,
|
|
43
|
-
width = 40.dp,
|
|
44
|
-
size = 40.dp
|
|
45
|
-
)
|
|
46
|
-
)
|
|
31
|
+
LARGE(IconSpecs(box = 48.dp, icon = 24.dp)),
|
|
32
|
+
MEDIUM(IconSpecs(box = 36.dp, icon = 16.dp)),
|
|
33
|
+
SMALL(IconSpecs(box = 28.dp, icon = 16.dp)),
|
|
47
34
|
}
|
|
48
35
|
|
|
49
|
-
|
|
50
|
-
|
|
36
|
+
enum class IconShape {
|
|
37
|
+
CIRCLE,
|
|
38
|
+
SQUARE,
|
|
39
|
+
}
|
|
51
40
|
|
|
52
|
-
//
|
|
53
|
-
private val
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
41
|
+
// Square keeps an 8dp rounded corner; circle is fully rounded regardless of size.
|
|
42
|
+
private val squareShape = RoundedCornerShape(Radius.S)
|
|
43
|
+
|
|
44
|
+
private fun IconShape.toShape(): Shape = when (this) {
|
|
45
|
+
IconShape.CIRCLE -> CircleShape
|
|
46
|
+
IconShape.SQUARE -> squareShape
|
|
47
|
+
}
|
|
57
48
|
|
|
58
49
|
@Composable
|
|
59
|
-
internal fun getIconStyle(type: ButtonType, color: Color? = null): Modifier {
|
|
50
|
+
internal fun getIconStyle(type: ButtonType, shape: Shape, color: Color? = null): Modifier {
|
|
60
51
|
val theme = AppTheme.current
|
|
61
52
|
|
|
62
|
-
return remember(type, color, theme) {
|
|
53
|
+
return remember(type, shape, color, theme) {
|
|
63
54
|
when (type) {
|
|
64
55
|
ButtonType.DISABLED -> Modifier
|
|
65
|
-
.background(theme.colors.background.disable,
|
|
66
|
-
.border(0.dp, Color.Unspecified,
|
|
56
|
+
.background(theme.colors.background.disable, shape)
|
|
57
|
+
.border(0.dp, Color.Unspecified, shape)
|
|
67
58
|
|
|
68
59
|
ButtonType.PRIMARY -> Modifier
|
|
69
|
-
.background(theme.colors.primary,
|
|
70
|
-
.border(0.dp, Color.Unspecified,
|
|
60
|
+
.background(theme.colors.primary, shape)
|
|
61
|
+
.border(0.dp, Color.Unspecified, shape)
|
|
71
62
|
|
|
72
63
|
ButtonType.SECONDARY -> Modifier
|
|
73
|
-
.background(theme.colors.background.surface,
|
|
74
|
-
.border(1.dp, theme.colors.border.default,
|
|
64
|
+
.background(theme.colors.background.surface, shape)
|
|
65
|
+
.border(1.dp, theme.colors.border.default, shape)
|
|
75
66
|
|
|
76
67
|
ButtonType.OUTLINE -> Modifier
|
|
77
|
-
.background(theme.colors.background.surface,
|
|
78
|
-
.border(1.dp, color ?: theme.colors.primary,
|
|
68
|
+
.background(theme.colors.background.surface, shape)
|
|
69
|
+
.border(1.dp, color ?: theme.colors.primary, shape)
|
|
79
70
|
|
|
80
71
|
ButtonType.TONAL -> Modifier
|
|
81
|
-
.background(theme.colors.background.tonal,
|
|
82
|
-
.border(0.dp, Color.Unspecified,
|
|
72
|
+
.background(theme.colors.background.tonal, shape)
|
|
73
|
+
.border(0.dp, Color.Unspecified, shape)
|
|
83
74
|
|
|
84
75
|
ButtonType.DANGER -> Modifier
|
|
85
|
-
.background(theme.colors.error.primary,
|
|
86
|
-
.border(0.dp, Color.Unspecified,
|
|
76
|
+
.background(theme.colors.error.primary, shape)
|
|
77
|
+
.border(0.dp, Color.Unspecified, shape)
|
|
87
78
|
|
|
88
79
|
ButtonType.TEXT -> Modifier
|
|
89
80
|
}
|
|
@@ -103,38 +94,32 @@ fun IconButton(
|
|
|
103
94
|
onClick: () -> Unit,
|
|
104
95
|
type: ButtonType = ButtonType.PRIMARY,
|
|
105
96
|
size: IconSize = IconSize.SMALL,
|
|
97
|
+
shape: IconShape = IconShape.CIRCLE,
|
|
106
98
|
icon: String = "",
|
|
107
99
|
) {
|
|
108
|
-
|
|
109
|
-
val iconSize = remember(size) {
|
|
110
|
-
iconSizeMap[size] ?: 16.dp
|
|
111
|
-
}
|
|
100
|
+
val specs = size.value
|
|
112
101
|
|
|
113
|
-
// Memoize enabled state
|
|
114
102
|
val isEnabled = remember(type) {
|
|
115
103
|
type != ButtonType.DISABLED
|
|
116
104
|
}
|
|
117
105
|
|
|
118
|
-
|
|
119
|
-
val radius = remember(size) {
|
|
120
|
-
size.value.radius
|
|
121
|
-
}
|
|
106
|
+
val boxShape = remember(shape) { shape.toShape() }
|
|
122
107
|
|
|
123
108
|
Box(
|
|
124
109
|
modifier = Modifier
|
|
125
|
-
.size(
|
|
126
|
-
.then(getIconStyle(type))
|
|
110
|
+
.size(specs.box)
|
|
111
|
+
.then(getIconStyle(type, boxShape))
|
|
127
112
|
.conditional(IsShowBaseLineDebug) {
|
|
128
113
|
border(1.dp, Colors.blue_03)
|
|
129
114
|
}
|
|
130
|
-
.clip(
|
|
115
|
+
.clip(boxShape)
|
|
131
116
|
.clickable(enabled = isEnabled, onClick = onClick),
|
|
132
117
|
contentAlignment = Alignment.Center
|
|
133
118
|
) {
|
|
134
119
|
Icon(
|
|
135
120
|
source = icon,
|
|
136
121
|
color = getIconColor(type),
|
|
137
|
-
size =
|
|
122
|
+
size = specs.icon,
|
|
138
123
|
)
|
|
139
124
|
}
|
|
140
|
-
}
|
|
125
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
package vn.momo.kits.components
|
|
2
2
|
|
|
3
3
|
import androidx.compose.foundation.border
|
|
4
|
+
import androidx.compose.foundation.layout.Box
|
|
4
5
|
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
6
|
+
import androidx.compose.foundation.layout.fillMaxSize
|
|
5
7
|
import androidx.compose.runtime.Composable
|
|
6
8
|
import androidx.compose.runtime.getValue
|
|
7
9
|
import androidx.compose.runtime.mutableStateOf
|
|
@@ -17,10 +19,12 @@ import androidx.compose.ui.semantics.contentDescription
|
|
|
17
19
|
import androidx.compose.ui.semantics.semantics
|
|
18
20
|
import androidx.compose.ui.platform.LocalDensity
|
|
19
21
|
import androidx.compose.ui.unit.dp
|
|
20
|
-
import coil3.compose.AsyncImage
|
|
22
|
+
import coil3.compose.AsyncImage as CoilAsyncImage
|
|
21
23
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
22
24
|
import vn.momo.kits.const.AppTheme
|
|
23
25
|
import vn.momo.kits.const.Colors
|
|
26
|
+
import vn.momo.kits.gifimage.GifImage
|
|
27
|
+
import vn.momo.kits.gifimage.GifImageState
|
|
24
28
|
import vn.momo.kits.modifier.conditional
|
|
25
29
|
|
|
26
30
|
data class Options(
|
|
@@ -73,6 +77,19 @@ private fun getHostFromUrl(url: String): String? {
|
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
|
|
80
|
+
private fun isGifUrl(url: String): Boolean {
|
|
81
|
+
val path = url.substringBefore('#').substringBefore('?')
|
|
82
|
+
return path.endsWith(".gif", ignoreCase = true)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private fun GifImageState.toImageState(): ImageState {
|
|
86
|
+
return when (this) {
|
|
87
|
+
GifImageState.Success -> ImageState.Success
|
|
88
|
+
GifImageState.Error -> ImageState.Error
|
|
89
|
+
GifImageState.Loading -> ImageState.Loading
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
76
93
|
// Optimized query parameter appending
|
|
77
94
|
private fun appendSizeQueryParam(url: String, value: String): String {
|
|
78
95
|
val fragmentIndex = url.indexOf('#')
|
|
@@ -95,12 +112,12 @@ fun Image(
|
|
|
95
112
|
modifier: Modifier = Modifier,
|
|
96
113
|
options: Options? = null,
|
|
97
114
|
loading: Boolean = true,
|
|
115
|
+
onStateChanged: (ImageState) -> Unit = {},
|
|
98
116
|
) {
|
|
99
117
|
val imageOptions = remember(options) {
|
|
100
118
|
options ?: Options()
|
|
101
119
|
}
|
|
102
120
|
|
|
103
|
-
var imageState by remember { mutableStateOf(ImageState.Loading) }
|
|
104
121
|
val density = LocalDensity.current
|
|
105
122
|
|
|
106
123
|
BoxWithConstraints(
|
|
@@ -121,34 +138,46 @@ fun Image(
|
|
|
121
138
|
processedUrl
|
|
122
139
|
}
|
|
123
140
|
}
|
|
124
|
-
else -> source
|
|
141
|
+
else -> source.toString()
|
|
125
142
|
}
|
|
126
143
|
}
|
|
127
144
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
145
|
+
var imageState by remember(urlToLoad) { mutableStateOf(ImageState.Loading) }
|
|
146
|
+
fun updateImageState(state: ImageState) {
|
|
147
|
+
imageState = state
|
|
148
|
+
onStateChanged(state)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (isGifUrl(urlToLoad)) {
|
|
152
|
+
GifImage(
|
|
153
|
+
modifier = Modifier.matchParentSize(),
|
|
154
|
+
url = urlToLoad,
|
|
155
|
+
contentDescription = null,
|
|
156
|
+
contentScale = imageOptions.contentScale,
|
|
157
|
+
alignment = imageOptions.alignment,
|
|
158
|
+
colorFilter = imageOptions.colorFilter,
|
|
159
|
+
alpha = imageOptions.alpha,
|
|
160
|
+
onStateChanged = { updateImageState(it.toImageState()) },
|
|
161
|
+
)
|
|
162
|
+
} else {
|
|
163
|
+
CoilAsyncImage(
|
|
164
|
+
modifier = Modifier.matchParentSize(),
|
|
165
|
+
model = urlToLoad,
|
|
166
|
+
contentDescription = null,
|
|
167
|
+
contentScale = imageOptions.contentScale,
|
|
168
|
+
alignment = imageOptions.alignment,
|
|
169
|
+
colorFilter = imageOptions.colorFilter,
|
|
170
|
+
alpha = imageOptions.alpha,
|
|
171
|
+
onLoading = { updateImageState(ImageState.Loading) },
|
|
172
|
+
onSuccess = { updateImageState(ImageState.Success) },
|
|
173
|
+
onError = { updateImageState(ImageState.Error) },
|
|
174
|
+
)
|
|
175
|
+
}
|
|
140
176
|
|
|
141
177
|
when (imageState) {
|
|
142
|
-
ImageState.Loading -> if (loading) Skeleton()
|
|
143
|
-
ImageState.Error -> {
|
|
144
|
-
val theme = AppTheme.current
|
|
145
|
-
Icon(
|
|
146
|
-
source = "media_fail",
|
|
147
|
-
color = theme.colors.text.disable,
|
|
148
|
-
modifier = Modifier.align(Alignment.Center)
|
|
149
|
-
)
|
|
150
|
-
}
|
|
151
178
|
ImageState.Success -> {}
|
|
179
|
+
ImageState.Error -> ImageError()
|
|
180
|
+
ImageState.Loading -> if (loading) Skeleton()
|
|
152
181
|
}
|
|
153
182
|
}
|
|
154
183
|
}
|
|
@@ -156,7 +185,7 @@ fun Image(
|
|
|
156
185
|
// Extracted URL processing logic for better performance
|
|
157
186
|
private fun processImageUrl(url: String, maxWidth: androidx.compose.ui.unit.Dp, density: androidx.compose.ui.unit.Density): String {
|
|
158
187
|
val host = getHostFromUrl(url)
|
|
159
|
-
return if (host != null && supportedDomains.contains(host)) {
|
|
188
|
+
return if (!isGifUrl(url) && host != null && supportedDomains.contains(host)) {
|
|
160
189
|
val widthPx = with(density) { maxWidth.roundToPx() }
|
|
161
190
|
val pixelRatio = density.density
|
|
162
191
|
val pixelFitForWidth = widthPx * pixelRatio
|
|
@@ -167,6 +196,20 @@ private fun processImageUrl(url: String, maxWidth: androidx.compose.ui.unit.Dp,
|
|
|
167
196
|
}
|
|
168
197
|
}
|
|
169
198
|
|
|
199
|
+
@Composable
|
|
200
|
+
private fun ImageError() {
|
|
201
|
+
val theme = AppTheme.current
|
|
202
|
+
Box(
|
|
203
|
+
modifier = Modifier.fillMaxSize(),
|
|
204
|
+
contentAlignment = Alignment.Center
|
|
205
|
+
) {
|
|
206
|
+
Icon(
|
|
207
|
+
source = "media_fail",
|
|
208
|
+
color = theme.colors.text.disable,
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
170
213
|
@Composable
|
|
171
214
|
fun Image(
|
|
172
215
|
source: Painter,
|
|
@@ -185,4 +228,4 @@ fun Image(
|
|
|
185
228
|
colorFilter = colorFilter,
|
|
186
229
|
alpha = alpha,
|
|
187
230
|
)
|
|
188
|
-
}
|
|
231
|
+
}
|
|
@@ -21,9 +21,11 @@ import androidx.compose.ui.unit.sp
|
|
|
21
21
|
import androidx.compose.ui.zIndex
|
|
22
22
|
import vn.momo.kits.application.IsShowBaseLineDebug
|
|
23
23
|
import vn.momo.kits.const.*
|
|
24
|
+
import vn.momo.kits.modifier.InternalApi
|
|
24
25
|
import vn.momo.kits.modifier.conditional
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
@InternalApi
|
|
28
|
+
const val MAX_LENGTH = 300
|
|
27
29
|
internal val DEFAULT_HEIGHT = 104.dp
|
|
28
30
|
|
|
29
31
|
@Composable
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package vn.momo.kits.components
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.Composable
|
|
4
|
+
import androidx.compose.runtime.CompositionLocalProvider
|
|
5
|
+
import vn.momo.kits.application.ScaleSizeMaxRate
|
|
6
|
+
|
|
7
|
+
@Deprecated(
|
|
8
|
+
"Max font scale is fixed at MAX_FONT_SCALE (1.5); this override is no longer applied. Remove the wrapper.",
|
|
9
|
+
ReplaceWith("content()"),
|
|
10
|
+
)
|
|
11
|
+
@Composable
|
|
12
|
+
fun ScaleSizeScope(
|
|
13
|
+
scaleSizeMaxRate: Float? = null,
|
|
14
|
+
content: @Composable () -> Unit
|
|
15
|
+
) {
|
|
16
|
+
CompositionLocalProvider(
|
|
17
|
+
ScaleSizeMaxRate provides scaleSizeMaxRate,
|
|
18
|
+
) {
|
|
19
|
+
content()
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -36,7 +36,6 @@ fun Text(
|
|
|
36
36
|
softWrap: Boolean = true,
|
|
37
37
|
accessibilityId: String? = null,
|
|
38
38
|
inlineContent: Map<String, InlineTextContent> = mapOf(),
|
|
39
|
-
userScaleRate: Float? = null,
|
|
40
39
|
) {
|
|
41
40
|
Text(
|
|
42
41
|
text = AnnotatedString(text),
|
|
@@ -53,8 +52,7 @@ fun Text(
|
|
|
53
52
|
letterSpacing = letterSpacing,
|
|
54
53
|
softWrap = softWrap,
|
|
55
54
|
accessibilityId = accessibilityId,
|
|
56
|
-
inlineContent = inlineContent
|
|
57
|
-
userScaleRate = userScaleRate
|
|
55
|
+
inlineContent = inlineContent
|
|
58
56
|
)
|
|
59
57
|
}
|
|
60
58
|
|
|
@@ -76,14 +74,13 @@ fun Text(
|
|
|
76
74
|
softWrap: Boolean = true,
|
|
77
75
|
accessibilityId: String? = null,
|
|
78
76
|
inlineContent: Map<String, InlineTextContent> = mapOf(),
|
|
79
|
-
userScaleRate: Float? = null,
|
|
80
77
|
) {
|
|
81
78
|
// Cache theme access to avoid repeated lookups
|
|
82
79
|
val theme = AppTheme.current
|
|
83
80
|
|
|
84
81
|
// Call @Composable functions directly in composable context
|
|
85
|
-
val scaledFontSize = scaleSize(style.fontSize
|
|
86
|
-
val scaledLineHeight = scaleSize(style.lineHeight
|
|
82
|
+
val scaledFontSize = scaleSize(style.fontSize)
|
|
83
|
+
val scaledLineHeight = scaleSize(style.lineHeight)
|
|
87
84
|
val fontFamilyResult = getFontFamily(fontFamily ?: theme.font, style.fontWeight)
|
|
88
85
|
|
|
89
86
|
// Now memoize the results
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package vn.momo.kits.const
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.getValue
|
|
4
|
+
import androidx.compose.runtime.mutableStateOf
|
|
5
|
+
import androidx.compose.runtime.setValue
|
|
6
|
+
|
|
7
|
+
// App-wide font-scale holder. The kit is sandboxed and can't read the host cache directly, so the
|
|
8
|
+
// host (which sees both core and this kit) seeds this once at startup and pushes runtime updates into
|
|
9
|
+
// it. scaleSize() reads it as the fallback, so every screen — including direct NavigationContainer
|
|
10
|
+
// screens with no host-pushed MiniAppContext — scales with no per-render prop and no async flicker.
|
|
11
|
+
// Backed by snapshot state: writes recompose text automatically.
|
|
12
|
+
object KitFontScale {
|
|
13
|
+
var userScaleRate by mutableStateOf(1f)
|
|
14
|
+
private set
|
|
15
|
+
var useOSScaleRate by mutableStateOf(true)
|
|
16
|
+
private set
|
|
17
|
+
|
|
18
|
+
fun update(userScaleRate: Float, useOSScaleRate: Boolean) {
|
|
19
|
+
this.userScaleRate = userScaleRate
|
|
20
|
+
this.useOSScaleRate = useOSScaleRate
|
|
21
|
+
}
|
|
22
|
+
}
|