diff --git a/README.md b/README.md index de9d2d8c9..9a5408f79 100755 --- a/README.md +++ b/README.md @@ -45,9 +45,11 @@ implement all your UI in Kotlin with Jetpack Compose and MOKO resources. ## Requirements - Gradle version 7.5+ +- Kotlin 1.9.20+ - Android Gradle Plugin 7.4.2+ - Android API 16+ - iOS version 11.0+ +- Compose Multiplatform 1.6.0+ ## Installation diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6fd09d8e3..b978c1e1e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -kotlinVersion = "1.9.10" +kotlinVersion = "1.9.20" androidGradleVersion = "8.1.4" androidSdkCommonVersion = "31.1.2" @@ -14,7 +14,7 @@ androidAppCompatVersion = "1.6.1" composeUiVersion = "1.5.1" # jetbrains compose -composeJetbrainsVersion = "1.5.1" +composeJetbrainsVersion = "1.6.0" # jvm apacheCommonsTextVersion = "1.10.0" diff --git a/gradle/moko.versions.toml b/gradle/moko.versions.toml index 77fc98291..ea3d44ba1 100644 --- a/gradle/moko.versions.toml +++ b/gradle/moko.versions.toml @@ -1,5 +1,5 @@ [versions] -resourcesVersion = "0.24.0-beta-3" +resourcesVersion = "0.24.0-beta-4" [libraries] resources = { module = "dev.icerock.moko:resources", version.ref = "resourcesVersion" } diff --git a/resources-compose/src/jsMain/kotlin/dev/icerock/moko/resources/compose/StringDescExt.kt b/resources-compose/src/jsMain/kotlin/dev/icerock/moko/resources/compose/StringDescExt.kt index 4110a9bc9..0e846c7c3 100644 --- a/resources-compose/src/jsMain/kotlin/dev/icerock/moko/resources/compose/StringDescExt.kt +++ b/resources-compose/src/jsMain/kotlin/dev/icerock/moko/resources/compose/StringDescExt.kt @@ -11,6 +11,6 @@ import dev.icerock.moko.resources.desc.StringDesc @Composable actual fun StringDesc.localized(): String { return produceState("", this) { - value = localized() + value = toLocalizedString() }.value } diff --git a/resources-compose/src/jsMain/kotlin/dev/icerock/moko/resources/compose/StringResource.kt b/resources-compose/src/jsMain/kotlin/dev/icerock/moko/resources/compose/StringResource.kt index 575cef55f..bb94475cc 100644 --- a/resources-compose/src/jsMain/kotlin/dev/icerock/moko/resources/compose/StringResource.kt +++ b/resources-compose/src/jsMain/kotlin/dev/icerock/moko/resources/compose/StringResource.kt @@ -50,6 +50,6 @@ actual fun stringResource(resource: PluralsResource, quantity: Int, vararg args: @Composable private fun localized(stringDesc: StringDesc): String { return produceState(initialValue = "", stringDesc) { - value = stringDesc.localized() + value = stringDesc.toLocalizedString() }.value } diff --git a/resources-generator/src/main/kotlin/dev/icerock/gradle/MultiplatformResourcesPlugin.kt b/resources-generator/src/main/kotlin/dev/icerock/gradle/MultiplatformResourcesPlugin.kt index 8b755d998..f559e770c 100644 --- a/resources-generator/src/main/kotlin/dev/icerock/gradle/MultiplatformResourcesPlugin.kt +++ b/resources-generator/src/main/kotlin/dev/icerock/gradle/MultiplatformResourcesPlugin.kt @@ -17,7 +17,7 @@ import dev.icerock.gradle.generator.platform.apple.setupFatFrameworkTasks import dev.icerock.gradle.generator.platform.apple.setupFrameworkResources import dev.icerock.gradle.generator.platform.apple.setupTestsResources import dev.icerock.gradle.generator.platform.js.setupJsKLibResources -import dev.icerock.gradle.generator.platform.js.setupJsResources +import dev.icerock.gradle.generator.platform.js.setupJsResourcesWithLinkTask import dev.icerock.gradle.tasks.GenerateMultiplatformResourcesTask import dev.icerock.gradle.utils.kotlinSourceSetsObservable import org.gradle.api.Plugin @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile @@ -89,6 +90,10 @@ open class MultiplatformResourcesPlugin : Plugin { setupTestsResources(target = target) } + if (target is KotlinJsIrTarget) { + setupJsResourcesWithLinkTask(target = target, project = project) + } + target.compilations.configureEach { compilation -> compilation.kotlinSourceSetsObservable.forAll { sourceSet: KotlinSourceSet -> val genTaskProvider: TaskProvider = @@ -119,15 +124,12 @@ open class MultiplatformResourcesPlugin : Plugin { compilation.compileTaskProvider.configure { compileTask: KotlinCompilationTask<*> -> compileTask.dependsOn(genTaskProvider) + } + + if (target is KotlinJsIrTarget) { + compilation.compileTaskProvider.configure { compileTask -> + compileTask as Kotlin2JsCompile - if (compileTask is Kotlin2JsCompile) { - setupJsResources( - compileTask = compileTask, - resourcesGenerationDir = genTaskProvider.flatMap { - it.outputResourcesDir.asFile - }, - projectDir = project.provider { project.projectDir } - ) setupJsKLibResources( compileTask = compileTask, resourcesGenerationDir = genTaskProvider.flatMap { diff --git a/resources-generator/src/main/kotlin/dev/icerock/gradle/actions/js/CopyResourcesToExecutableAction.kt b/resources-generator/src/main/kotlin/dev/icerock/gradle/actions/js/CopyResourcesToExecutableAction.kt index 92d7a338b..003598e21 100644 --- a/resources-generator/src/main/kotlin/dev/icerock/gradle/actions/js/CopyResourcesToExecutableAction.kt +++ b/resources-generator/src/main/kotlin/dev/icerock/gradle/actions/js/CopyResourcesToExecutableAction.kt @@ -14,11 +14,11 @@ import org.jetbrains.kotlin.library.impl.KotlinLibraryLayoutImpl import java.io.File internal class CopyResourcesToExecutableAction( - private val resourcesGeneratedDir: Provider, + private val outputDir: Provider, private val projectDir: Provider ) : Action { override fun execute(task: Kotlin2JsCompile) { - val resourceDir = resourcesGeneratedDir.get() + val resourceDir = outputDir.get() task.klibs.forEach { dependency -> copyResourcesFromLibraries( @@ -28,17 +28,15 @@ internal class CopyResourcesToExecutableAction( ) } - generateWebpackConfig(resourceDir) + generateWebpackConfig() generateKarmaConfig() } - private fun generateWebpackConfig(resourcesOutput: File) { + private fun generateWebpackConfig() { val webpackDir = File(projectDir.get(), "webpack.config.d") webpackDir.mkdirs() val webpackConfig = File(webpackDir, "moko-resources-generated.js") - val webpackResourcesDir: String = resourcesOutput.absolutePath - .replace("\\", "\\\\") webpackConfig.writeText( // language=js @@ -48,16 +46,14 @@ internal class CopyResourcesToExecutableAction( const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); - const mokoResourcePath = path.resolve("$webpackResourcesDir"); - config.module.rules.push( { test: /\.(.*)/, resource: [ - path.resolve(mokoResourcePath, "assets"), - path.resolve(mokoResourcePath, "files"), - path.resolve(mokoResourcePath, "images"), - path.resolve(mokoResourcePath, "localization"), + path.resolve(__dirname, "kotlin/assets"), + path.resolve(__dirname, "kotlin/files"), + path.resolve(__dirname, "kotlin/images"), + path.resolve(__dirname, "kotlin/localization"), ], type: 'asset/resource' } @@ -68,7 +64,7 @@ internal class CopyResourcesToExecutableAction( { test: /\.css${'$'}/, resource: [ - path.resolve(mokoResourcePath, "fonts"), + path.resolve(__dirname, "kotlin/fonts"), ], use: ['style-loader', 'css-loader'] } @@ -78,13 +74,11 @@ internal class CopyResourcesToExecutableAction( { test: /\.(otf|ttf)?${'$'}/, resource: [ - path.resolve(mokoResourcePath, "fonts"), + path.resolve(__dirname, "kotlin/fonts"), ], type: 'asset/resource', } ) - - config.resolve.modules.push(mokoResourcePath); })(config); """.trimIndent() ) @@ -129,13 +123,16 @@ internal class CopyResourcesToExecutableAction( outputDir: File, logger: Logger ) { - if (inputFile.extension != "klib") return if (inputFile.exists().not()) return logger.info("copy resources from $inputFile into $outputDir") val klibKonan = org.jetbrains.kotlin.konan.file.File(inputFile.path) val klib = KotlinLibraryLayoutImpl(klib = klibKonan, component = "default") - val layout: KotlinLibraryLayout = klib.extractingToTemp + val layout: KotlinLibraryLayout = if (klib.isZipped) { + klib.extractingToTemp + } else { + klib + } try { File(layout.resourcesDir.path, "moko-resources-js").copyRecursively( diff --git a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/platform/js/JsSetupUtils.kt b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/platform/js/JsSetupUtils.kt index 10a73da19..1a3a3f693 100644 --- a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/platform/js/JsSetupUtils.kt +++ b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/platform/js/JsSetupUtils.kt @@ -7,29 +7,51 @@ package dev.icerock.gradle.generator.platform.js import dev.icerock.gradle.actions.js.CopyResourcesToExecutableAction import dev.icerock.gradle.actions.js.CopyResourcesToKLibAction import org.gradle.api.Action +import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.provider.Provider +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.targets.js.ir.JsIrBinary +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile import java.io.File internal fun setupJsKLibResources( compileTask: Kotlin2JsCompile, - resourcesGenerationDir: Provider + resourcesGenerationDir: Provider, ) { val copyResourcesToKLibAction = CopyResourcesToKLibAction(resourcesGenerationDir) @Suppress("UNCHECKED_CAST") compileTask.doLast(copyResourcesToKLibAction as Action) } -internal fun setupJsResources( - compileTask: Kotlin2JsCompile, - resourcesGenerationDir: Provider, - projectDir: Provider +internal fun setupJsExecutableResources( + linkTask: KotlinJsIrLink, + projectDir: Provider, ) { val copyResourcesAction = CopyResourcesToExecutableAction( - resourcesGeneratedDir = resourcesGenerationDir, + outputDir = linkTask.destinationDirectory.asFile, projectDir = projectDir ) + @Suppress("UNCHECKED_CAST") - compileTask.doLast(copyResourcesAction as Action) + linkTask.doLast(copyResourcesAction as Action) +} + +internal fun setupJsResourcesWithLinkTask( + target: KotlinJsIrTarget, + project: Project, +) { + target.compilations.withType().configureEach { compilation -> + compilation.binaries.withType().configureEach { binary: JsIrBinary -> + binary.linkTask.configure { linkTask -> + setupJsExecutableResources( + linkTask = linkTask, + projectDir = project.provider { project.projectDir } + ) + } + } + } } diff --git a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/asset/JsAssetResourceGenerator.kt b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/asset/JsAssetResourceGenerator.kt index d03af12be..a8b50d39e 100644 --- a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/asset/JsAssetResourceGenerator.kt +++ b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/asset/JsAssetResourceGenerator.kt @@ -25,7 +25,7 @@ internal class JsAssetResourceGenerator( val filePath: String = File(ASSETS_DIR, metadata.pathRelativeToBase.path).path .replace("\\", "/") - val requireDeclaration = """require("$filePath")""" + val requireDeclaration = """require("./$filePath")""" return CodeBlock.of( "AssetResource(originalPath = js(%S) as String, rawPath = %S)", requireDeclaration, diff --git a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/file/JsFileResourceGenerator.kt b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/file/JsFileResourceGenerator.kt index 295664b17..7e445dd16 100644 --- a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/file/JsFileResourceGenerator.kt +++ b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/file/JsFileResourceGenerator.kt @@ -22,7 +22,7 @@ internal class JsFileResourceGenerator( override fun imports(): List = emptyList() override fun generateInitializer(metadata: FileMetadata): CodeBlock { - val requireDeclaration = """require("$FILES_DIR/${metadata.filePath.name}")""" + val requireDeclaration = """require("./$FILES_DIR/${metadata.filePath.name}")""" return CodeBlock.of( "FileResource(fileUrl = js(%S) as String)", requireDeclaration diff --git a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/font/JsFontResourceGenerator.kt b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/font/JsFontResourceGenerator.kt index 79865deeb..f0d81df1d 100644 --- a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/font/JsFontResourceGenerator.kt +++ b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/font/JsFontResourceGenerator.kt @@ -27,7 +27,7 @@ internal class JsFontResourceGenerator( override fun imports(): List = emptyList() override fun generateInitializer(metadata: FontMetadata): CodeBlock { - val requireDeclaration = """require("$FONTS_DIR/${metadata.filePath.name}")""" + val requireDeclaration = """require("./$FONTS_DIR/${metadata.filePath.name}")""" return CodeBlock.of( "FontResource(fileUrl = js(%S) as String, fontFamily = %S)", requireDeclaration, @@ -36,6 +36,8 @@ internal class JsFontResourceGenerator( } override fun generateResourceFiles(data: List) { + if (data.isEmpty()) return + val fontsDir = File(resourcesGenerationDir, FONTS_DIR) fontsDir.mkdirs() @@ -93,7 +95,7 @@ internal class JsFontResourceGenerator( val addFontsFun: FunSpec = FunSpec.builder("addFontsToPage") .addCode( "js(%S)", - """require("$FONTS_DIR/$cssDeclarationsFileName")""" + """require("./$FONTS_DIR/$cssDeclarationsFileName")""" ).build() builder.addFunction(addFontsFun) } diff --git a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/image/JsImageResourceGenerator.kt b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/image/JsImageResourceGenerator.kt index 702bf9794..b5a40cfbd 100644 --- a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/image/JsImageResourceGenerator.kt +++ b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/image/JsImageResourceGenerator.kt @@ -37,8 +37,8 @@ internal class JsImageResourceGenerator( } } - val requireDeclaration: String = """require("$IMAGES_DIR/$fileName")""" - val darkRequireDeclaration: String = """require("$IMAGES_DIR/$darkFileName")""" + val requireDeclaration: String = """require("./$IMAGES_DIR/$fileName")""" + val darkRequireDeclaration: String = """require("./$IMAGES_DIR/$darkFileName")""" return if (darkFileName != null) { CodeBlock.of( diff --git a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/plural/JsPluralResourceGenerator.kt b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/plural/JsPluralResourceGenerator.kt index e0c26784d..8caba819c 100644 --- a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/plural/JsPluralResourceGenerator.kt +++ b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/plural/JsPluralResourceGenerator.kt @@ -59,7 +59,7 @@ internal class JsPluralResourceGenerator( builder.addSuperinterface(Constants.Js.loaderHolderName) builder.addJsFallbackProperty( - fallbackFilePath = LOCALIZATION_DIR + "/" + getFileNameForLanguage(LanguageType.Base) + fallbackFilePath = "./" + LOCALIZATION_DIR + "/" + getFileNameForLanguage(LanguageType.Base) ) builder.addJsSupportedLocalesProperty( bcpLangToPath = metadata.asSequence() @@ -69,7 +69,7 @@ internal class JsPluralResourceGenerator( LanguageType.fromLanguage(locale) }.filterIsInstance().map { language -> val fileName: String = getFileNameForLanguage(language) - language.toBcpString() to "$LOCALIZATION_DIR/$fileName" + language.toBcpString() to "./$LOCALIZATION_DIR/$fileName" }.toList() ) builder.addJsContainerStringsLoaderProperty() diff --git a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/string/JsStringResourceGenerator.kt b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/string/JsStringResourceGenerator.kt index 9920fa2d5..32b6991ed 100644 --- a/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/string/JsStringResourceGenerator.kt +++ b/resources-generator/src/main/kotlin/dev/icerock/gradle/generator/resources/string/JsStringResourceGenerator.kt @@ -59,7 +59,7 @@ internal class JsStringResourceGenerator( builder.addSuperinterface(Constants.Js.loaderHolderName) builder.addJsFallbackProperty( - fallbackFilePath = LOCALIZATION_DIR + "/" + getFileNameForLanguage(LanguageType.Base) + fallbackFilePath = "./" + LOCALIZATION_DIR + "/" + getFileNameForLanguage(LanguageType.Base) ) builder.addJsSupportedLocalesProperty( bcpLangToPath = metadata.asSequence() @@ -69,7 +69,7 @@ internal class JsStringResourceGenerator( LanguageType.fromLanguage(locale) }.filterIsInstance().map { language -> val fileName: String = getFileNameForLanguage(language) - language.toBcpString() to "$LOCALIZATION_DIR/$fileName" + language.toBcpString() to "./$LOCALIZATION_DIR/$fileName" }.toList() ) builder.addJsContainerStringsLoaderProperty() diff --git a/resources-generator/src/main/kotlin/dev/icerock/gradle/utils/StringExt.kt b/resources-generator/src/main/kotlin/dev/icerock/gradle/utils/StringExt.kt index b083db527..46d35250f 100644 --- a/resources-generator/src/main/kotlin/dev/icerock/gradle/utils/StringExt.kt +++ b/resources-generator/src/main/kotlin/dev/icerock/gradle/utils/StringExt.kt @@ -5,6 +5,7 @@ package dev.icerock.gradle.utils import dev.icerock.gradle.metadata.resource.ImageMetadata.Appearance +import kotlinx.serialization.json.JsonPrimitive import org.apache.commons.text.StringEscapeUtils import java.util.Locale @@ -49,25 +50,24 @@ internal val String.flatName: String get() = this.remove('.') internal fun String.convertXmlStringToAndroidLocalization(): String { - return convertXmlStringToLocalization().let { + return StringEscapeUtils.unescapeXml(this).let { + // Add mirroring for newline, without this android does flat string line + it.replace("\n", "\\n") + }.let { StringEscapeUtils.escapeXml11(it) } } internal fun String.convertXmlStringToLocalization(): String { return StringEscapeUtils.unescapeXml(this).let { - StringEscapeUtils.escapeEcmaScript(it) - } -} + val jsonPrimitive = JsonPrimitive(it) + // Usage of inner encode mechanism of Koltinx.Serialization + val stringValue: String = jsonPrimitive.toString() -internal val String.appearance: Appearance - get() { - return if (withoutScale.endsWith(suffix = Appearance.DARK.suffix, ignoreCase = true)) { - Appearance.DARK - } else { - Appearance.LIGHT - } + // Remove symbol ["] from start and end of string + stringValue.substring(1, stringValue.length - 1) } +} internal val String.withoutAppearance: String get() { diff --git a/resources-generator/src/test/kotlin/dev/icerock/gradle/generator/stringsGenerator/XmlStringsToPlatformRuTest.kt b/resources-generator/src/test/kotlin/dev/icerock/gradle/generator/stringsGenerator/XmlStringsToPlatformRuTest.kt new file mode 100644 index 000000000..5898230a2 --- /dev/null +++ b/resources-generator/src/test/kotlin/dev/icerock/gradle/generator/stringsGenerator/XmlStringsToPlatformRuTest.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2024 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. + */ + +package dev.icerock.gradle.generator.stringsGenerator + +import dev.icerock.gradle.utils.convertXmlStringToAndroidLocalization +import dev.icerock.gradle.utils.convertXmlStringToLocalization +import kotlin.test.Test +import kotlin.test.assertEquals + +class XmlStringsToPlatformRuTest { + @Test + fun newLineAndroid() { + assertEquals( + expected = """первая строка\nвторая строка""", + actual = "первая строка\nвторая строка".convertXmlStringToAndroidLocalization() + ) + } + + @Test + fun newLineOtherPlatforms() { + assertEquals( + expected = """первая строка\nвторая строка""", + actual = "первая строка\nвторая строка".convertXmlStringToLocalization() + ) + } + + @Test + fun textWithApostropheAndroid() { + assertEquals( + expected = """Я'ж купил новый 27 дюйм'ов монитор""", + actual = "Я'ж купил новый 27 дюйм'ов монитор".convertXmlStringToAndroidLocalization() + ) + } + + @Test + fun textWithApostropheOtherPlatforms() { + assertEquals( + expected = """Я'ж купил новый 27 дюйм'ов монитор""", + actual = "Я'ж купил новый 27 дюйм'ов монитор".convertXmlStringToLocalization() + ) + } + + @Test + fun textWithXmlTagsAndroid() { + assertEquals( + expected = """Текст with <b>жирный</b>, <i>курсив</i>, <u>подчеркнутый</u>""", + actual = "Текст with <b>жирный</b>, <i>курсив</i>, <u>подчеркнутый</u>".convertXmlStringToAndroidLocalization(), + ) + } + + @Test + fun textWithXmlTagsOtherPlatforms() { + assertEquals( + expected = """Текст с жирный, курсив, подчеркнутый""", + actual = "Текст с <b>жирный</b>, <i>курсив</i>, <u>подчеркнутый</u>".convertXmlStringToLocalization(), + ) + } +} diff --git a/resources-generator/src/test/kotlin/dev/icerock/gradle/generator/stringsGenerator/XmlStringsToPlatformTest.kt b/resources-generator/src/test/kotlin/dev/icerock/gradle/generator/stringsGenerator/XmlStringsToPlatformTest.kt index 601d71a15..5b76274db 100644 --- a/resources-generator/src/test/kotlin/dev/icerock/gradle/generator/stringsGenerator/XmlStringsToPlatformTest.kt +++ b/resources-generator/src/test/kotlin/dev/icerock/gradle/generator/stringsGenerator/XmlStringsToPlatformTest.kt @@ -29,7 +29,7 @@ class XmlStringsToPlatformTest { @Test fun separateSymbolsAndroid() { assertEquals( - expected = """\" \' % @ * & {}""", + expected = """" ' % @ * & {}""", actual = "\" ' % @ * & {}".convertXmlStringToAndroidLocalization() ) } @@ -37,7 +37,7 @@ class XmlStringsToPlatformTest { @Test fun separateSymbolsOtherPlatforms() { assertEquals( - expected = """\" \' % @ * & {}""", + expected = """\" ' % @ * & {}""", actual = "\" ' % @ * & {}".convertXmlStringToLocalization() ) } @@ -45,7 +45,7 @@ class XmlStringsToPlatformTest { @Test fun textWithApostropheAndroid() { assertEquals( - expected = """I\'m bought new monitor with 27 inch\'s""", + expected = """I'm bought new monitor with 27 inch's""", actual = "I'm bought new monitor with 27 inch's".convertXmlStringToAndroidLocalization() ) } @@ -53,7 +53,7 @@ class XmlStringsToPlatformTest { @Test fun textWithApostropheOtherPlatforms() { assertEquals( - expected = """I\'m bought new monitor with 27 inch\'s""", + expected = """I'm bought new monitor with 27 inch's""", actual = "I'm bought new monitor with 27 inch's".convertXmlStringToLocalization() ) } @@ -61,7 +61,7 @@ class XmlStringsToPlatformTest { @Test fun textWithXmlTagsAndroid() { assertEquals( - expected = """Text with <b>bold<\/b>, <i>italic<\/i>, <u>underline<\/u>""", + expected = """Text with <b>bold</b>, <i>italic</i>, <u>underline</u>""", actual = "Text with <b>bold</b>, <i>italic</i>, <u>underline</u>".convertXmlStringToAndroidLocalization(), ) } @@ -69,7 +69,7 @@ class XmlStringsToPlatformTest { @Test fun textWithXmlTagsOtherPlatforms() { assertEquals( - expected = """Text with bold<\/b>, italic<\/i>, underline<\/u>""", + expected = """Text with bold, italic, underline""", actual = "Text with <b>bold</b>, <i>italic</i>, <u>underline</u>".convertXmlStringToLocalization(), ) } diff --git a/resources/src/appleMain/kotlin/dev/icerock/moko/resources/FileResource.kt b/resources/src/appleMain/kotlin/dev/icerock/moko/resources/FileResource.kt index f79e5766c..fd3585e06 100644 --- a/resources/src/appleMain/kotlin/dev/icerock/moko/resources/FileResource.kt +++ b/resources/src/appleMain/kotlin/dev/icerock/moko/resources/FileResource.kt @@ -4,7 +4,6 @@ package dev.icerock.moko.resources -import kotlinx.cinterop.BetaInteropApi import kotlinx.cinterop.ExperimentalForeignApi import kotlinx.cinterop.ObjCObjectVar import kotlinx.cinterop.alloc @@ -13,15 +12,12 @@ import kotlinx.cinterop.ptr import kotlinx.cinterop.value import platform.Foundation.NSBundle import platform.Foundation.NSError -import platform.Foundation.NSString import platform.Foundation.NSURL -import platform.Foundation.NSUTF8StringEncoding -import platform.Foundation.stringWithContentsOfFile actual open class FileResource( val fileName: String, val extension: String, - val bundle: NSBundle = NSBundle.mainBundle + val bundle: NSBundle = NSBundle.mainBundle, ) { open val path: String get() = bundle.pathForResource( @@ -36,17 +32,13 @@ actual open class FileResource( subdirectory = "files" )!! - @OptIn(ExperimentalForeignApi::class, BetaInteropApi::class) + @OptIn(ExperimentalForeignApi::class) fun readText(): String { val filePath = path val (result: String?, error: NSError?) = memScoped { val p = alloc>() val result: String? = runCatching { - NSString.stringWithContentsOfFile( - path = filePath, - encoding = NSUTF8StringEncoding, - error = p.ptr - ) + readContentOfFile(filePath, p.ptr) }.getOrNull() result to p.value } @@ -55,3 +47,9 @@ actual open class FileResource( else return result!! } } + +@OptIn(ExperimentalForeignApi::class) +internal expect fun readContentOfFile( + filePath: String, + error: kotlinx.cinterop.CPointer>?, +): String? diff --git a/resources/src/iosMain/kotlin/dev/icerock/moko/resources/FileResource.ios.kt b/resources/src/iosMain/kotlin/dev/icerock/moko/resources/FileResource.ios.kt new file mode 100644 index 000000000..20a8ebad2 --- /dev/null +++ b/resources/src/iosMain/kotlin/dev/icerock/moko/resources/FileResource.ios.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2024 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. + */ + +package dev.icerock.moko.resources + +import kotlinx.cinterop.CPointer +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.ObjCObjectVar +import platform.Foundation.NSError +import platform.Foundation.NSString +import platform.Foundation.NSUTF8StringEncoding +import platform.Foundation.stringWithContentsOfFile + +@OptIn(ExperimentalForeignApi::class) +internal actual fun readContentOfFile( + filePath: String, + error: CPointer>?, +): String? { + return NSString.stringWithContentsOfFile( + path = filePath, + encoding = NSUTF8StringEncoding, + error = error + ) +} diff --git a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/CompositionStringDesc.kt b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/CompositionStringDesc.kt index f7619f5bc..bde831f5f 100644 --- a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/CompositionStringDesc.kt +++ b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/CompositionStringDesc.kt @@ -10,12 +10,12 @@ actual data class CompositionStringDesc actual constructor( val args: Iterable, val separator: String? ) : StringDesc { - override suspend fun localized(): String = args - .map { child -> child.localized() } + override suspend fun toLocalizedString(): String = args + .map { child -> child.toLocalizedString() } .joinToString(separator = separator ?: "") - override fun localized(provider: JsStringProvider): String = args + override fun toLocalizedString(provider: JsStringProvider): String = args .joinToString(separator = separator ?: "") { child -> - child.localized(provider) + child.toLocalizedString(provider) } } diff --git a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/PluralFormattedStringDesc.kt b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/PluralFormattedStringDesc.kt index 8982d1778..26375ac27 100644 --- a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/PluralFormattedStringDesc.kt +++ b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/PluralFormattedStringDesc.kt @@ -13,10 +13,10 @@ actual data class PluralFormattedStringDesc actual constructor( val args: List ) : StringDesc { - override suspend fun localized(): String = - localized(pluralsRes.loader.getOrLoad()) + override suspend fun toLocalizedString(): String = + toLocalizedString(pluralsRes.loader.getOrLoad()) - override fun localized(provider: JsStringProvider): String { + override fun toLocalizedString(provider: JsStringProvider): String { return pluralsRes.localized( provider = provider, locale = StringDesc.localeType.locale, diff --git a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/PluralStringDesc.kt b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/PluralStringDesc.kt index 4e685172f..5055264fc 100644 --- a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/PluralStringDesc.kt +++ b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/PluralStringDesc.kt @@ -12,10 +12,10 @@ actual data class PluralStringDesc actual constructor( val number: Int, ) : StringDesc { - override suspend fun localized(): String = - localized(pluralsRes.loader.getOrLoad()) + override suspend fun toLocalizedString(): String = + toLocalizedString(pluralsRes.loader.getOrLoad()) - override fun localized(provider: JsStringProvider): String { + override fun toLocalizedString(provider: JsStringProvider): String { return pluralsRes.localized( provider = provider, locale = StringDesc.localeType.locale, diff --git a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/RawStringDesc.kt b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/RawStringDesc.kt index 8606d2e7a..e6d50f7f0 100644 --- a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/RawStringDesc.kt +++ b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/RawStringDesc.kt @@ -9,6 +9,6 @@ import dev.icerock.moko.resources.provider.JsStringProvider actual data class RawStringDesc actual constructor( val string: String ) : StringDesc { - override suspend fun localized(): String = string - override fun localized(provider: JsStringProvider): String = string + override suspend fun toLocalizedString(): String = string + override fun toLocalizedString(provider: JsStringProvider): String = string } diff --git a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/ResourceFormattedStringDesc.kt b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/ResourceFormattedStringDesc.kt index 66d68f50a..0791c0eef 100644 --- a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/ResourceFormattedStringDesc.kt +++ b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/ResourceFormattedStringDesc.kt @@ -11,10 +11,10 @@ actual data class ResourceFormattedStringDesc actual constructor( val stringRes: StringResource, val args: List ) : StringDesc { - override suspend fun localized(): String = - localized(stringRes.loader.getOrLoad()) + override suspend fun toLocalizedString(): String = + toLocalizedString(stringRes.loader.getOrLoad()) - override fun localized(provider: JsStringProvider): String { + override fun toLocalizedString(provider: JsStringProvider): String { return stringRes.localized( provider = provider, locale = StringDesc.localeType.locale, diff --git a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/ResourceStringDesc.kt b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/ResourceStringDesc.kt index 45b0bb7f1..ba3320958 100644 --- a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/ResourceStringDesc.kt +++ b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/ResourceStringDesc.kt @@ -10,10 +10,10 @@ import dev.icerock.moko.resources.provider.JsStringProvider actual data class ResourceStringDesc actual constructor( val stringRes: StringResource ) : StringDesc { - override suspend fun localized(): String = - localized(stringRes.loader.getOrLoad()) + override suspend fun toLocalizedString(): String = + toLocalizedString(stringRes.loader.getOrLoad()) - override fun localized(provider: JsStringProvider): String { + override fun toLocalizedString(provider: JsStringProvider): String { return stringRes.localized( provider = provider, locale = StringDesc.localeType.locale diff --git a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/StringDesc.kt b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/StringDesc.kt index 2d6a76ecc..80f323e85 100644 --- a/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/StringDesc.kt +++ b/resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/StringDesc.kt @@ -8,8 +8,8 @@ import dev.icerock.moko.resources.internal.currentLocale import dev.icerock.moko.resources.provider.JsStringProvider actual interface StringDesc { - suspend fun localized(): String - fun localized(provider: JsStringProvider): String + suspend fun toLocalizedString(): String + fun toLocalizedString(provider: JsStringProvider): String actual sealed class LocaleType { abstract val locale: String diff --git a/resources/src/macosMain/kotlin/dev/icerock/moko/resources/FileResource.macos.kt b/resources/src/macosMain/kotlin/dev/icerock/moko/resources/FileResource.macos.kt new file mode 100644 index 000000000..20a8ebad2 --- /dev/null +++ b/resources/src/macosMain/kotlin/dev/icerock/moko/resources/FileResource.macos.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2024 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. + */ + +package dev.icerock.moko.resources + +import kotlinx.cinterop.CPointer +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.ObjCObjectVar +import platform.Foundation.NSError +import platform.Foundation.NSString +import platform.Foundation.NSUTF8StringEncoding +import platform.Foundation.stringWithContentsOfFile + +@OptIn(ExperimentalForeignApi::class) +internal actual fun readContentOfFile( + filePath: String, + error: CPointer>?, +): String? { + return NSString.stringWithContentsOfFile( + path = filePath, + encoding = NSUTF8StringEncoding, + error = error + ) +} diff --git a/resources/src/watchosMain/kotlin/dev/icerock/moko/resources/FileResource.watchos.kt b/resources/src/watchosMain/kotlin/dev/icerock/moko/resources/FileResource.watchos.kt new file mode 100644 index 000000000..8f31e0382 --- /dev/null +++ b/resources/src/watchosMain/kotlin/dev/icerock/moko/resources/FileResource.watchos.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2024 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. + */ + +package dev.icerock.moko.resources + +import kotlinx.cinterop.CPointer +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.ObjCObjectVar +import kotlinx.cinterop.UnsafeNumber +import platform.Foundation.NSError +import platform.Foundation.NSString +import platform.Foundation.NSUTF8StringEncoding +import platform.Foundation.stringWithContentsOfFile + +@OptIn(ExperimentalForeignApi::class, UnsafeNumber::class) +internal actual fun readContentOfFile( + filePath: String, + error: CPointer>?, +): String? { + return NSString.stringWithContentsOfFile( + path = filePath, + encoding = NSUTF8StringEncoding, + error = error + ) +} diff --git a/samples/android-mpp-app/app/build.gradle.kts b/samples/android-mpp-app/app/build.gradle.kts index faa2d5b9c..0ef351c3a 100644 --- a/samples/android-mpp-app/app/build.gradle.kts +++ b/samples/android-mpp-app/app/build.gradle.kts @@ -34,7 +34,6 @@ android { kotlin { androidTarget() - ios() } dependencies { diff --git a/samples/android-mpp-app/build.gradle.kts b/samples/android-mpp-app/build.gradle.kts index 0d4fb4b7c..e6def3e95 100644 --- a/samples/android-mpp-app/build.gradle.kts +++ b/samples/android-mpp-app/build.gradle.kts @@ -11,7 +11,7 @@ buildscript { } dependencies { classpath(moko.resourcesGradlePlugin) - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20") classpath("com.android.tools.build:gradle:8.1.0") } } diff --git a/samples/android-mpp-app/gradle.properties b/samples/android-mpp-app/gradle.properties index 418055514..c83450572 100755 --- a/samples/android-mpp-app/gradle.properties +++ b/samples/android-mpp-app/gradle.properties @@ -10,5 +10,3 @@ kotlin.mpp.androidSourceSetLayoutVersion=2 kotlin.mpp.androidGradlePluginCompatibility.nowarn=true android.useAndroidX=true - -xcodeproj=./sample/ios-app diff --git a/samples/android-mpp-app/gradle/wrapper/gradle-wrapper.properties b/samples/android-mpp-app/gradle/wrapper/gradle-wrapper.properties index 37aef8d3f..00affbfde 100755 --- a/samples/android-mpp-app/gradle/wrapper/gradle-wrapper.properties +++ b/samples/android-mpp-app/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ +#Wed May 08 12:37:24 KRAT 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/samples/cm-resources-sample/local-check.sh b/samples/cm-resources-sample/local-check.sh index 4a60f0320..c853ac55e 100755 --- a/samples/cm-resources-sample/local-check.sh +++ b/samples/cm-resources-sample/local-check.sh @@ -14,6 +14,9 @@ log "cm-resources-sample android success" ./gradlew clean jvmJar log "cm-resources-sample jvm success" +./gradlew clean jsBrowserDistribution +log "cm-resources-sample js success" + if ! command -v xcodebuild &> /dev/null then log "xcodebuild could not be found, skip ios checks" diff --git a/samples/compose-resources-gallery/gradle.properties b/samples/compose-resources-gallery/gradle.properties index dc3ec06d2..db3c8bd95 100644 --- a/samples/compose-resources-gallery/gradle.properties +++ b/samples/compose-resources-gallery/gradle.properties @@ -19,6 +19,6 @@ org.jetbrains.compose.experimental.uikit.enabled=true kotlin.mpp.androidSourceSetLayoutVersion=2 kotlin.mpp.androidGradlePluginCompatibility.nowarn=true -kotlin.version=1.9.21 +kotlin.version=1.9.23 agp.version=8.1.0 -compose.version=1.5.11 +compose.version=1.6.2 diff --git a/samples/compose-resources-gallery/local-check.sh b/samples/compose-resources-gallery/local-check.sh index 7473119a7..55587a35e 100755 --- a/samples/compose-resources-gallery/local-check.sh +++ b/samples/compose-resources-gallery/local-check.sh @@ -14,6 +14,9 @@ log "compose-resources-gallery android success" ./gradlew clean jvmJar log "compose-resources-gallery jvm success" +./gradlew clean jsBrowserDistribution +log "compose-resources-gallery js success" + if ! command -v xcodebuild &> /dev/null then echo "xcodebuild could not be found, skip ios checks" @@ -25,8 +28,7 @@ else ./gradlew clean compileKotlinIosX64 log "compose-resources-gallery ios success" - # rerun tasks because kotlinjs compilation broken with build cache :( - ./gradlew clean podspec build generateDummyFramework --rerun-tasks + ./gradlew clean podspec build generateDummyFramework log "compose-resources-gallery full build success" ( diff --git a/samples/compose-resources-gallery/shared/src/commonMain/moko-resources/ru/strings.xml b/samples/compose-resources-gallery/shared/src/commonMain/moko-resources/ru/strings.xml index fc63e02c2..0038ee622 100644 --- a/samples/compose-resources-gallery/shared/src/commonMain/moko-resources/ru/strings.xml +++ b/samples/compose-resources-gallery/shared/src/commonMain/moko-resources/ru/strings.xml @@ -1,4 +1,6 @@ Привет Мир moko-resources + Текст \n с " ' % @ * & {} сколько-то дюйм'ов + Текст с <b>жирный</b>, <i>курсив</i>, <u>подчеркивание</u> diff --git a/samples/compose-resources-gallery/webApp/src/jsMain/kotlin/com/icerockdev/web/Main.kt b/samples/compose-resources-gallery/webApp/src/jsMain/kotlin/com/icerockdev/web/Main.kt index 8e0e99d0e..d44f8de9c 100644 --- a/samples/compose-resources-gallery/webApp/src/jsMain/kotlin/com/icerockdev/web/Main.kt +++ b/samples/compose-resources-gallery/webApp/src/jsMain/kotlin/com/icerockdev/web/Main.kt @@ -7,13 +7,15 @@ package com.icerockdev.web import MainView import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier -import androidx.compose.ui.window.Window +import androidx.compose.ui.window.CanvasBasedWindow import org.jetbrains.skiko.wasm.onWasmReady +@OptIn(ExperimentalComposeUiApi::class) fun main() { onWasmReady { - Window("moko-resources") { + CanvasBasedWindow("moko-resources") { Column(modifier = Modifier.fillMaxSize()) { MainView() } diff --git a/samples/default-hierarchy-gallery-mobile/gradle/wrapper/gradle-wrapper.properties b/samples/default-hierarchy-gallery-mobile/gradle/wrapper/gradle-wrapper.properties index bdc9a83b1..e4787b36c 100755 --- a/samples/default-hierarchy-gallery-mobile/gradle/wrapper/gradle-wrapper.properties +++ b/samples/default-hierarchy-gallery-mobile/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ +#Mon May 06 16:40:02 KRAT 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/samples/default-hierarchy-gallery-mobile/ios-app/Podfile.lock b/samples/default-hierarchy-gallery-mobile/ios-app/Podfile.lock index 2dacbacb7..70c0bc1ec 100644 --- a/samples/default-hierarchy-gallery-mobile/ios-app/Podfile.lock +++ b/samples/default-hierarchy-gallery-mobile/ios-app/Podfile.lock @@ -13,4 +13,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 30d7a0645fcfdfc7d29c9d352fe92e63fe2a9f63 -COCOAPODS: 1.14.3 +COCOAPODS: 1.15.2 diff --git a/samples/default-hierarchy-gallery-mobile/local-check.sh b/samples/default-hierarchy-gallery-mobile/local-check.sh index 22a3c3dff..689541de1 100755 --- a/samples/default-hierarchy-gallery-mobile/local-check.sh +++ b/samples/default-hierarchy-gallery-mobile/local-check.sh @@ -21,14 +21,14 @@ else ./gradlew clean compileKotlinIosX64 log "default-hierarchy-gallery-mobile ios success" - ./gradlew clean podspec build generateDummyFramework --rerun-tasks + ./gradlew clean podspec build generateDummyFramework log "default-hierarchy-gallery-mobile full build success" ( cd ios-app && pod install && set -o pipefail && - xcodebuild -scheme TestProj -workspace TestProj.xcworkspace -configuration Debug -destination "generic/platform=iOS Simulator" build CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO | xcpretty + xcodebuild -scheme TestProj -workspace TestProj.xcworkspace -configuration Debug -sdk iphonesimulator -arch x86_64 build CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO | xcpretty ) log "default-hierarchy-gallery-mobile ios xcode success" fi diff --git a/samples/ios-static-xcframework/build.gradle.kts b/samples/ios-static-xcframework/build.gradle.kts index 37e7cc5c5..543494ca3 100644 --- a/samples/ios-static-xcframework/build.gradle.kts +++ b/samples/ios-static-xcframework/build.gradle.kts @@ -11,6 +11,6 @@ buildscript { } dependencies { classpath(moko.resourcesGradlePlugin) - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20") } } diff --git a/samples/resources-gallery/build.gradle.kts b/samples/resources-gallery/build.gradle.kts index 89b90cde8..6a6a8ed7e 100644 --- a/samples/resources-gallery/build.gradle.kts +++ b/samples/resources-gallery/build.gradle.kts @@ -15,8 +15,8 @@ buildscript { } dependencies { classpath(moko.resourcesGradlePlugin) - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10") - classpath("org.jetbrains.compose:compose-gradle-plugin:1.5.11") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.23") + classpath("org.jetbrains.compose:compose-gradle-plugin:1.6.1") classpath("com.android.tools.build:gradle:8.1.1") } } diff --git a/samples/resources-gallery/gradle/wrapper/gradle-wrapper.properties b/samples/resources-gallery/gradle/wrapper/gradle-wrapper.properties index bdc9a83b1..20b5ca1a3 100755 --- a/samples/resources-gallery/gradle/wrapper/gradle-wrapper.properties +++ b/samples/resources-gallery/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ +#Mon May 06 15:33:18 KRAT 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/samples/resources-gallery/ios-app/Podfile.lock b/samples/resources-gallery/ios-app/Podfile.lock index 2dacbacb7..70c0bc1ec 100644 --- a/samples/resources-gallery/ios-app/Podfile.lock +++ b/samples/resources-gallery/ios-app/Podfile.lock @@ -13,4 +13,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 30d7a0645fcfdfc7d29c9d352fe92e63fe2a9f63 -COCOAPODS: 1.14.3 +COCOAPODS: 1.15.2 diff --git a/samples/resources-gallery/local-check.sh b/samples/resources-gallery/local-check.sh index a79509b34..2e9edf642 100755 --- a/samples/resources-gallery/local-check.sh +++ b/samples/resources-gallery/local-check.sh @@ -14,6 +14,9 @@ log "resources-gallery android success" ./gradlew clean jvmJar log "resources-gallery jvm success" +./gradlew clean jsBrowserDistribution +log "resources-gallery js success" + if ! command -v xcodebuild &> /dev/null then log "xcodebuild could not be found, skip ios checks" @@ -24,8 +27,7 @@ else ./gradlew clean compileKotlinIosX64 log "resources-gallery ios success" - # rerun tasks because kotlinjs compilation broken with build cache :( - ./gradlew clean build --rerun-tasks + ./gradlew clean podspec build generateDummyFramework log "resources-gallery clean build success" ( diff --git a/samples/resources-gallery/macos-app/Podfile.lock b/samples/resources-gallery/macos-app/Podfile.lock index f5d63a12d..15c879c61 100644 --- a/samples/resources-gallery/macos-app/Podfile.lock +++ b/samples/resources-gallery/macos-app/Podfile.lock @@ -13,4 +13,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 6055317a84821966cb9ec76bbac09672d2f57bdf -COCOAPODS: 1.14.3 +COCOAPODS: 1.15.2 diff --git a/samples/resources-gallery/mpp-library/mpp_library.podspec b/samples/resources-gallery/mpp-library/mpp_library.podspec index b67455b55..e1ae3da47 100644 --- a/samples/resources-gallery/mpp-library/mpp_library.podspec +++ b/samples/resources-gallery/mpp-library/mpp_library.podspec @@ -11,6 +11,17 @@ Pod::Spec.new do |spec| + if !Dir.exist?('build/cocoapods/framework/MultiPlatformLibrary.framework') || Dir.empty?('build/cocoapods/framework/MultiPlatformLibrary.framework') + raise " + + Kotlin framework 'MultiPlatformLibrary' doesn't exist yet, so a proper Xcode project can't be generated. + 'pod install' should be executed after running ':generateDummyFramework' Gradle task: + + ./gradlew :mpp-library:generateDummyFramework + + Alternatively, proper pod installation is performed during Gradle sync in the IDE (if Podfile location is set)" + end + spec.pod_target_xcconfig = { 'KOTLIN_PROJECT_PATH' => ':mpp-library', 'PRODUCT_MODULE_NAME' => 'MultiPlatformLibrary', diff --git a/samples/resources-gallery/mpp-library/test-utils/src/jsMain/kotlin/StringDescExt.kt b/samples/resources-gallery/mpp-library/test-utils/src/jsMain/kotlin/StringDescExt.kt index 6fec58ce1..57880d661 100644 --- a/samples/resources-gallery/mpp-library/test-utils/src/jsMain/kotlin/StringDescExt.kt +++ b/samples/resources-gallery/mpp-library/test-utils/src/jsMain/kotlin/StringDescExt.kt @@ -4,4 +4,4 @@ import dev.icerock.moko.resources.desc.StringDesc -public actual suspend fun StringDesc.getString(): String = localized() +public actual suspend fun StringDesc.getString(): String = toLocalizedString() diff --git a/samples/resources-gallery/web-app/build.gradle.kts b/samples/resources-gallery/web-app/build.gradle.kts index 594c15c65..3abb9e945 100644 --- a/samples/resources-gallery/web-app/build.gradle.kts +++ b/samples/resources-gallery/web-app/build.gradle.kts @@ -17,6 +17,7 @@ kotlin { implementation(compose.html.core) implementation(compose.runtime) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0") } } } diff --git a/samples/resources-gallery/web-app/src/jsMain/kotlin/com/icerockdev/web/Main.kt b/samples/resources-gallery/web-app/src/jsMain/kotlin/com/icerockdev/web/Main.kt index 49ddb92fd..dae268c33 100644 --- a/samples/resources-gallery/web-app/src/jsMain/kotlin/com/icerockdev/web/Main.kt +++ b/samples/resources-gallery/web-app/src/jsMain/kotlin/com/icerockdev/web/Main.kt @@ -52,7 +52,7 @@ suspend fun main() { } } ) { - Text(Testing.getStringDesc().localized(strings)) + Text(Testing.getStringDesc().toLocalizedString(strings)) } Br() val color by remember(window) {