diff --git a/experimental/examples/minesweeper/.gitignore b/experimental/examples/minesweeper/.gitignore
index 639cdd514d..0903344480 100644
--- a/experimental/examples/minesweeper/.gitignore
+++ b/experimental/examples/minesweeper/.gitignore
@@ -1 +1,7 @@
local.properties
+iosApp/Podfile.lock
+iosApp/Pods/*
+iosApp/Minesweeper.xcworkspace/*
+iosApp/Minesweeper.xcodeproj/*
+!iosApp/Minesweeper.xcodeproj/project.pbxproj
+shared/shared.podspec
diff --git a/experimental/examples/minesweeper/.run/desktopApp.run.xml b/experimental/examples/minesweeper/.run/desktopApp.run.xml
new file mode 100644
index 0000000000..7af7e15f4b
--- /dev/null
+++ b/experimental/examples/minesweeper/.run/desktopApp.run.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ false
+
+
+
\ No newline at end of file
diff --git a/experimental/examples/minesweeper/.run/iosApp (Android Studio).run.xml b/experimental/examples/minesweeper/.run/iosApp (Android Studio).run.xml
new file mode 100644
index 0000000000..553dd92ab1
--- /dev/null
+++ b/experimental/examples/minesweeper/.run/iosApp (Android Studio).run.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/experimental/examples/minesweeper/.run/iosApp.run.xml b/experimental/examples/minesweeper/.run/iosApp.run.xml
new file mode 100644
index 0000000000..31a15653b2
--- /dev/null
+++ b/experimental/examples/minesweeper/.run/iosApp.run.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/experimental/examples/minesweeper/.run/jsApp.run.xml b/experimental/examples/minesweeper/.run/jsApp.run.xml
new file mode 100644
index 0000000000..6135d902e4
--- /dev/null
+++ b/experimental/examples/minesweeper/.run/jsApp.run.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ false
+
+
+
\ No newline at end of file
diff --git a/experimental/examples/minesweeper/README.md b/experimental/examples/minesweeper/README.md
index 94504bdf43..f03076ebf3 100644
--- a/experimental/examples/minesweeper/README.md
+++ b/experimental/examples/minesweeper/README.md
@@ -1,20 +1,36 @@
# Minesweeper
-A simple game powered by Compose Multiplatform
+A simple game powered by Compose Multiplatform.
-## Run native on MacOS
-`./gradlew runDebugExecutableMacosX64` (Works on Intel processors)
+Game can run on Android, iOS, desktop or in a browser.
+
+*Prerequisites*: to run on iOS and Android, you should have "Kotlin Multiplatform Mobile" plugin installed either
+ in Android Studio or in AppCode with [installed CocoaPods](https://kotlinlang.org/docs/native-cocoapods.html).
+
+
+## How to run
+
+Choose a run configuration for an appropriate target in IDE and run it.
+
+![run-configurations.png](run-configurations.png)
-## Run web assembly in browser
-`./gradlew jsBrowserDevelopmentRun`
+To run on iOS device, please correct `iosApp/Configuration/TeamId.xcconfig` with your Apple Team ID.
+Alternatively, you may setup signing within XCode opening `iosApp/Minesweeper.xcworkspace` and then
+using "Signing & Capabilities" tab of `Minesweeper` target.
-## Run on iOS simulator
-`./gradlew iosDeployIPhone8Debug`
-`./gradlew iosDeployIPadDebug`
+Then choose **iosApp** configuration in IDE and run it
+(may also be referred as `Minesweeper` in the Run Configurations or `iosApp (Android Studio)` for Android studio).
-## Run on iOS device
-- Read about iOS target in [falling-balls-mpp/README.md](../falling-balls-mpp/README.md)
-- `./gradlew iosDeployDeviceRelease`
+## Run on desktop via Gradle
+
+`./gradlew desktopApp:run`
+
+## Run JS in browser with WebAssembly Skia via Gradle
+
+`./gradlew jsApp:jsBrowserDevelopmentRun`
+
+## Run native on MacOS
+`./gradlew runDebugExecutableMacosX64` (Works on Intel processors)
## Credits
\ No newline at end of file
diff --git a/experimental/examples/minesweeper/androidApp/build.gradle.kts b/experimental/examples/minesweeper/androidApp/build.gradle.kts
new file mode 100644
index 0000000000..0c592a144c
--- /dev/null
+++ b/experimental/examples/minesweeper/androidApp/build.gradle.kts
@@ -0,0 +1,33 @@
+plugins {
+ kotlin("multiplatform")
+ id("com.android.application")
+ id("org.jetbrains.compose")
+}
+
+kotlin {
+ android()
+ sourceSets {
+ val androidMain by getting {
+ dependencies {
+ implementation(project(":shared"))
+ implementation("androidx.appcompat:appcompat:1.5.1")
+ implementation("androidx.activity:activity-compose:1.6.1")
+ }
+ }
+ }
+}
+
+android {
+ compileSdk = 33
+ defaultConfig {
+ applicationId = "org.jetbrains.ComposeMinesweeper"
+ minSdk = 24
+ targetSdk = 33
+ versionCode = 1
+ versionName = "1.0"
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+}
diff --git a/experimental/examples/minesweeper/src/androidMain/AndroidManifest.xml b/experimental/examples/minesweeper/androidApp/src/main/AndroidManifest.xml
similarity index 100%
rename from experimental/examples/minesweeper/src/androidMain/AndroidManifest.xml
rename to experimental/examples/minesweeper/androidApp/src/main/AndroidManifest.xml
diff --git a/experimental/examples/minesweeper/src/androidMain/kotlin/MainActivity.kt b/experimental/examples/minesweeper/androidApp/src/main/kotlin/MainActivity.kt
similarity index 89%
rename from experimental/examples/minesweeper/src/androidMain/kotlin/MainActivity.kt
rename to experimental/examples/minesweeper/androidApp/src/main/kotlin/MainActivity.kt
index e3b0d1e9f3..4970ea42ed 100644
--- a/experimental/examples/minesweeper/src/androidMain/kotlin/MainActivity.kt
+++ b/experimental/examples/minesweeper/androidApp/src/main/kotlin/MainActivity.kt
@@ -3,13 +3,13 @@ package org.jetbrains.minesweeper
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
-import Game
+import MainView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
- Game()
+ MainView()
}
}
}
diff --git a/experimental/examples/minesweeper/src/androidMain/res/values/strings.xml b/experimental/examples/minesweeper/androidApp/src/main/res/values/strings.xml
similarity index 100%
rename from experimental/examples/minesweeper/src/androidMain/res/values/strings.xml
rename to experimental/examples/minesweeper/androidApp/src/main/res/values/strings.xml
diff --git a/experimental/examples/minesweeper/build.gradle.kts b/experimental/examples/minesweeper/build.gradle.kts
index a5045597e5..0c00883af5 100644
--- a/experimental/examples/minesweeper/build.gradle.kts
+++ b/experimental/examples/minesweeper/build.gradle.kts
@@ -1,219 +1,18 @@
-import org.jetbrains.compose.compose
-import org.jetbrains.compose.desktop.application.dsl.TargetFormat
-import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
-import org.jetbrains.compose.experimental.dsl.IOSDevices
-
plugins {
- id("com.android.application")
- kotlin("multiplatform")
- id("org.jetbrains.compose")
-}
-
-version = "1.0-SNAPSHOT"
-
-repositories {
- mavenLocal()
- google()
- mavenCentral()
- maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
-}
-
-kotlin {
- android()
- jvm("desktop")
- js(IR) {
- browser()
- binaries.executable()
- }
- macosX64 {
- binaries {
- executable {
- entryPoint = "main"
- freeCompilerArgs += listOf(
- "-linker-option", "-framework", "-linker-option", "Metal"
- )
- }
- }
- }
- macosArm64 {
- binaries {
- executable {
- entryPoint = "main"
- freeCompilerArgs += listOf(
- "-linker-option", "-framework", "-linker-option", "Metal"
- )
- }
- }
- }
-
- // Workaround for an issue:
- // https://youtrack.jetbrains.com/issue/KT-53561/Invalid-LLVM-module-inlinable-function-call-in-a-function-with-debug-info-must-have-a-dbg-location
- // Compose compiler produces nodes without line information sometimes that provokes Kotlin native compiler to report errors.
- // TODO: remove workaround when switch to Kotlin 1.8
- val disableKonanVerification = "-Xverify-compiler=false"
-
- iosX64("uikitX64") {
- binaries {
- executable() {
- entryPoint = "main"
- freeCompilerArgs += listOf(
- "-linker-option", "-framework", "-linker-option", "Metal",
- "-linker-option", "-framework", "-linker-option", "CoreText",
- "-linker-option", "-framework", "-linker-option", "CoreGraphics",
- disableKonanVerification
- )
- }
- }
- }
- iosArm64("uikitArm64") {
- binaries {
- executable() {
- entryPoint = "main"
- freeCompilerArgs += listOf(
- "-linker-option", "-framework", "-linker-option", "Metal",
- "-linker-option", "-framework", "-linker-option", "CoreText",
- "-linker-option", "-framework", "-linker-option", "CoreGraphics",
- disableKonanVerification
- )
- }
- }
- }
-
- sourceSets {
- val commonMain by getting {
- dependencies {
- implementation(compose.ui)
- implementation(compose.foundation)
- implementation(compose.material)
- implementation(compose.runtime)
- implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3")
- }
- }
-
- val commonTest by getting {
- dependencies {
- implementation(kotlin("test-common"))
- implementation(kotlin("test-annotations-common"))
- }
- }
-
- val androidMain by getting {
- dependsOn(commonMain)
- kotlin.srcDirs("src/jvmMain/kotlin")
- dependencies {
- implementation("androidx.appcompat:appcompat:1.5.1")
- implementation("androidx.activity:activity-compose:1.5.0")
- }
- }
-
- val desktopMain by getting {
- dependencies {
- implementation(compose.desktop.currentOs)
- }
- }
-
- val jsMain by getting {
- dependencies {
- implementation(compose.web.core)
- }
- }
-
- val nativeMain by creating {
- dependsOn(commonMain)
- }
- val macosMain by creating {
- dependsOn(nativeMain)
- }
- val macosX64Main by getting {
- dependsOn(macosMain)
- }
- val macosArm64Main by getting {
- dependsOn(macosMain)
- }
- val uikitMain by creating {
- dependsOn(nativeMain)
- }
- val uikitX64Main by getting {
- dependsOn(uikitMain)
- }
- val uikitArm64Main by getting {
- dependsOn(uikitMain)
- }
- }
-}
-
-compose.desktop {
- application {
- mainClass = "Main_desktopKt"
- nativeDistributions {
- targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
- packageName = "Minesweeper"
- packageVersion = "1.0.0"
-
- windows {
- menuGroup = "Compose Examples"
- // see https://wixtoolset.org/documentation/manual/v3/howtos/general/generate_guids.html
- upgradeUuid = "2bf169f9-d851-49f0-b3a1-308966d473ca"
- }
- }
- }
-}
-
-compose.experimental {
- web.application {}
- uikit.application {
- bundleIdPrefix = "org.jetbrains"
- projectName = "ComposeMinesweeper"
- deployConfigurations {
- simulator("IPhone8") {
- //Usage: ./gradlew iosDeployIPhone8Debug
- device = IOSDevices.IPHONE_8
- }
- simulator("IPad") {
- //Usage: ./gradlew iosDeployIPadDebug
- device = IOSDevices.IPAD_MINI_6th_Gen
- }
- connectedDevice("Device") {
- //First need specify your teamId here, or in local.properties (compose.ios.teamId=***)
- //teamId="***"
- //Usage: ./gradlew iosDeployDeviceRelease
- }
- }
- }
-}
-
-tasks.withType {
- kotlinOptions.jvmTarget = "11"
-}
-
-// a temporary workaround for a bug in jsRun invocation - see https://youtrack.jetbrains.com/issue/KT-48273
-afterEvaluate {
- rootProject.extensions.configure {
- versions.webpackDevServer.version = "4.0.0"
- versions.webpackCli.version = "4.9.0"
- nodeVersion = "16.0.0"
- }
-}
-
-android {
- compileSdk = 32
-
- defaultConfig {
- minSdk = 26
- targetSdk = 32
- }
-
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
-
- sourceSets {
- named("main") {
- manifest.srcFile("src/androidMain/AndroidManifest.xml")
- res.srcDirs("src/androidMain/res", "src/commonMain/resources")
- }
+ // this is necessary to avoid the plugins to be loaded multiple times
+ // in each subproject's classloader
+ kotlin("jvm") apply false
+ kotlin("multiplatform") apply false
+ kotlin("android") apply false
+ id("com.android.application") apply false
+ id("com.android.library") apply false
+ id("org.jetbrains.compose") apply false
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
}
diff --git a/experimental/examples/minesweeper/desktopApp/build.gradle.kts b/experimental/examples/minesweeper/desktopApp/build.gradle.kts
new file mode 100644
index 0000000000..730a5109ad
--- /dev/null
+++ b/experimental/examples/minesweeper/desktopApp/build.gradle.kts
@@ -0,0 +1,35 @@
+import org.jetbrains.compose.desktop.application.dsl.TargetFormat
+
+plugins {
+ kotlin("multiplatform")
+ id("org.jetbrains.compose")
+}
+
+kotlin {
+ jvm {}
+ sourceSets {
+ val jvmMain by getting {
+ dependencies {
+ implementation(compose.desktop.currentOs)
+ implementation(project(":shared"))
+ }
+ }
+ }
+}
+
+compose.desktop {
+ application {
+ mainClass = "MainKt"
+ nativeDistributions {
+ targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
+ packageName = "Minesweeper"
+ packageVersion = "1.0.0"
+
+ windows {
+ menuGroup = "Compose Examples"
+ // see https://wixtoolset.org/documentation/manual/v3/howtos/general/generate_guids.html
+ upgradeUuid = "2bf169f9-d851-49f0-b3a1-308966d473ca"
+ }
+ }
+ }
+}
diff --git a/experimental/examples/minesweeper/desktopApp/src/jvmMain/kotlin/Main.kt b/experimental/examples/minesweeper/desktopApp/src/jvmMain/kotlin/Main.kt
new file mode 100644
index 0000000000..732c30af6a
--- /dev/null
+++ b/experimental/examples/minesweeper/desktopApp/src/jvmMain/kotlin/Main.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
+ */
+
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.window.*
+
+fun main() = application {
+ val windowState = rememberWindowState()
+
+ Window(
+ onCloseRequest = ::exitApplication,
+ resizable = false,
+ title = "Minesweeper",
+ icon = painterResource("assets/mine.png"),
+ state = windowState
+ ) {
+ MainView(windowState)
+ }
+}
\ No newline at end of file
diff --git a/experimental/examples/minesweeper/gradle.properties b/experimental/examples/minesweeper/gradle.properties
index e6fa271a3c..ea83c74d6a 100644
--- a/experimental/examples/minesweeper/gradle.properties
+++ b/experimental/examples/minesweeper/gradle.properties
@@ -1,17 +1,17 @@
-compose.version=1.3.0-alpha01-dev827
-kotlin.version=1.7.10
-agp.version=7.0.4
-org.gradle.jvmargs=-Xmx3g
kotlin.code.style=official
+xcodeproj=./iosApp
+kotlin.native.cocoapods.generate.wrapper=true
+android.useAndroidX=true
+org.gradle.jvmargs=-Xmx3g
+org.jetbrains.compose.experimental.jscanvas.enabled=true
+org.jetbrains.compose.experimental.macos.enabled=true
+org.jetbrains.compose.experimental.uikit.enabled=true
kotlin.native.cacheKind=none
kotlin.native.useEmbeddableCompilerJar=true
kotlin.native.enableDependencyPropagation=false
kotlin.mpp.enableGranularSourceSetsMetadata=true
# Enable kotlin/native experimental memory model
kotlin.native.binary.memoryModel=experimental
-compose.desktop.verbose=true
-android.useAndroidX=true
-kotlin.js.webpack.major.version=4
-org.jetbrains.compose.experimental.jscanvas.enabled=true
-org.jetbrains.compose.experimental.macos.enabled=true
-org.jetbrains.compose.experimental.uikit.enabled=true
+kotlin.version=1.7.20
+agp.version=7.1.3
+compose.version=1.3.0-beta04-dev885
diff --git a/experimental/examples/minesweeper/iosApp/Configuration/TeamId.xcconfig b/experimental/examples/minesweeper/iosApp/Configuration/TeamId.xcconfig
new file mode 100644
index 0000000000..bf06eb27e9
--- /dev/null
+++ b/experimental/examples/minesweeper/iosApp/Configuration/TeamId.xcconfig
@@ -0,0 +1 @@
+TEAM_ID=
diff --git a/experimental/examples/minesweeper/iosApp/Minesweeper.xcodeproj/project.pbxproj b/experimental/examples/minesweeper/iosApp/Minesweeper.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..af3f99d747
--- /dev/null
+++ b/experimental/examples/minesweeper/iosApp/Minesweeper.xcodeproj/project.pbxproj
@@ -0,0 +1,398 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 50;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 2152FB042600AC8F00CF470E /* iosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iosApp.swift */; };
+ C1FC908188C4E8695729CB06 /* Pods_Minesweeper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DE96E47030356CE6AD9794A /* Pods_Minesweeper.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 1EB65E27D2C0F884D0A1A133 /* Pods-Minesweeper.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Minesweeper.debug.xcconfig"; path = "Target Support Files/Pods-Minesweeper/Pods-Minesweeper.debug.xcconfig"; sourceTree = ""; };
+ 2152FB032600AC8F00CF470E /* iosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iosApp.swift; sourceTree = ""; };
+ 3D7A606AB0AD7636269BD9D0 /* Pods-Minesweeper.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Minesweeper.release.xcconfig"; path = "Target Support Files/Pods-Minesweeper/Pods-Minesweeper.release.xcconfig"; sourceTree = ""; };
+ 7555FF7B242A565900829871 /* Minesweeper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Minesweeper.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 8DE96E47030356CE6AD9794A /* Pods_Minesweeper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Minesweeper.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ AB3632DC29227652001CCB65 /* TeamId.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = TeamId.xcconfig; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 9964867F0862B4D9FB6ABFC7 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C1FC908188C4E8695729CB06 /* Pods_Minesweeper.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 7555FF72242A565900829871 = {
+ isa = PBXGroup;
+ children = (
+ AB1DB47929225F7C00F7AF9C /* Configuration */,
+ 7555FF7D242A565900829871 /* iosApp */,
+ 7555FF7C242A565900829871 /* Products */,
+ E1DAFBE8E1CFC0878361EF0E /* Pods */,
+ B62309C7396AD7BF607A63B2 /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ 7555FF7C242A565900829871 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 7555FF7B242A565900829871 /* Minesweeper.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 7555FF7D242A565900829871 /* iosApp */ = {
+ isa = PBXGroup;
+ children = (
+ 7555FF8C242A565B00829871 /* Info.plist */,
+ 2152FB032600AC8F00CF470E /* iosApp.swift */,
+ );
+ path = iosApp;
+ sourceTree = "";
+ };
+ AB1DB47929225F7C00F7AF9C /* Configuration */ = {
+ isa = PBXGroup;
+ children = (
+ AB3632DC29227652001CCB65 /* TeamId.xcconfig */,
+ );
+ path = Configuration;
+ sourceTree = "";
+ };
+ B62309C7396AD7BF607A63B2 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 8DE96E47030356CE6AD9794A /* Pods_Minesweeper.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ E1DAFBE8E1CFC0878361EF0E /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 1EB65E27D2C0F884D0A1A133 /* Pods-Minesweeper.debug.xcconfig */,
+ 3D7A606AB0AD7636269BD9D0 /* Pods-Minesweeper.release.xcconfig */,
+ );
+ path = Pods;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 7555FF7A242A565900829871 /* Minesweeper */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "Minesweeper" */;
+ buildPhases = (
+ E8D673591E7196AEA2EA10E2 /* [CP] Check Pods Manifest.lock */,
+ 7555FF77242A565900829871 /* Sources */,
+ 7555FF79242A565900829871 /* Resources */,
+ 9964867F0862B4D9FB6ABFC7 /* Frameworks */,
+ AC9253D086E81B65FAE159E1 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Minesweeper;
+ productName = iosApp;
+ productReference = 7555FF7B242A565900829871 /* Minesweeper.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 7555FF73242A565900829871 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 1130;
+ LastUpgradeCheck = 1130;
+ ORGANIZATIONNAME = org.jetbrains;
+ TargetAttributes = {
+ 7555FF7A242A565900829871 = {
+ CreatedOnToolsVersion = 11.3.1;
+ };
+ };
+ };
+ buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "Minesweeper" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 7555FF72242A565900829871;
+ productRefGroup = 7555FF7C242A565900829871 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 7555FF7A242A565900829871 /* Minesweeper */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 7555FF79242A565900829871 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ AC9253D086E81B65FAE159E1 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Minesweeper/Pods-Minesweeper-resources-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Copy Pods Resources";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Minesweeper/Pods-Minesweeper-resources-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Minesweeper/Pods-Minesweeper-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ E8D673591E7196AEA2EA10E2 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-Minesweeper-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 7555FF77242A565900829871 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2152FB042600AC8F00CF470E /* iosApp.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 7555FFA3242A565B00829871 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = AB3632DC29227652001CCB65 /* TeamId.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 14.1;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ 7555FFA4242A565B00829871 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = AB3632DC29227652001CCB65 /* TeamId.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 14.1;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 7555FFA6242A565B00829871 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 1EB65E27D2C0F884D0A1A133 /* Pods-Minesweeper.debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_ASSET_PATHS = "";
+ DEVELOPMENT_TEAM = "${TEAM_ID}";
+ ENABLE_PREVIEWS = YES;
+ INFOPLIST_FILE = iosApp/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 14.1;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "org.jetbrains.Minesweeper${TEAM_ID}";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 7555FFA7242A565B00829871 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 3D7A606AB0AD7636269BD9D0 /* Pods-Minesweeper.release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_ASSET_PATHS = "";
+ DEVELOPMENT_TEAM = "${TEAM_ID}";
+ ENABLE_PREVIEWS = YES;
+ INFOPLIST_FILE = iosApp/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 14.1;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "org.jetbrains.Minesweeper${TEAM_ID}";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 7555FF76242A565900829871 /* Build configuration list for PBXProject "Minesweeper" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 7555FFA3242A565B00829871 /* Debug */,
+ 7555FFA4242A565B00829871 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "Minesweeper" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 7555FFA6242A565B00829871 /* Debug */,
+ 7555FFA7242A565B00829871 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 7555FF73242A565900829871 /* Project object */;
+}
diff --git a/experimental/examples/minesweeper/iosApp/Podfile b/experimental/examples/minesweeper/iosApp/Podfile
new file mode 100644
index 0000000000..43dcabd199
--- /dev/null
+++ b/experimental/examples/minesweeper/iosApp/Podfile
@@ -0,0 +1,5 @@
+target 'Minesweeper' do
+ use_frameworks!
+ platform :ios, '14.1'
+ pod 'shared', :path => '../shared'
+end
\ No newline at end of file
diff --git a/experimental/examples/minesweeper/iosApp/iosApp/Info.plist b/experimental/examples/minesweeper/iosApp/iosApp/Info.plist
new file mode 100644
index 0000000000..9a269f5eaa
--- /dev/null
+++ b/experimental/examples/minesweeper/iosApp/iosApp/Info.plist
@@ -0,0 +1,48 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ $(PRODUCT_BUNDLE_PACKAGE_TYPE)
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UIApplicationSceneManifest
+
+ UIApplicationSupportsMultipleScenes
+
+
+ UILaunchScreen
+
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/experimental/examples/minesweeper/iosApp/iosApp/iosApp.swift b/experimental/examples/minesweeper/iosApp/iosApp/iosApp.swift
new file mode 100644
index 0000000000..b42016a6fc
--- /dev/null
+++ b/experimental/examples/minesweeper/iosApp/iosApp/iosApp.swift
@@ -0,0 +1,15 @@
+import UIKit
+import shared
+
+@UIApplicationMain
+class AppDelegate: UIResponder, UIApplicationDelegate {
+ var window: UIWindow?
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ window = UIWindow(frame: UIScreen.main.bounds)
+ let mainViewController = Main_iosKt.MainViewController()
+ window?.rootViewController = mainViewController
+ window?.makeKeyAndVisible()
+ return true
+ }
+}
diff --git a/experimental/examples/minesweeper/jsApp/build.gradle.kts b/experimental/examples/minesweeper/jsApp/build.gradle.kts
new file mode 100644
index 0000000000..99f2073a62
--- /dev/null
+++ b/experimental/examples/minesweeper/jsApp/build.gradle.kts
@@ -0,0 +1,23 @@
+plugins {
+ kotlin("multiplatform")
+ id("org.jetbrains.compose")
+}
+
+kotlin {
+ js(IR) {
+ browser()
+ binaries.executable()
+ }
+ sourceSets {
+ val jsMain by getting {
+ dependencies {
+ implementation(project(":shared"))
+ }
+ }
+ }
+}
+
+compose.experimental {
+ web.application {}
+}
+
diff --git a/experimental/examples/minesweeper/jsApp/src/jsMain/kotlin/main.js.kt b/experimental/examples/minesweeper/jsApp/src/jsMain/kotlin/main.js.kt
new file mode 100644
index 0000000000..b36b64e9ad
--- /dev/null
+++ b/experimental/examples/minesweeper/jsApp/src/jsMain/kotlin/main.js.kt
@@ -0,0 +1,16 @@
+ /*
+ * Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
+ */
+
+import androidx.compose.ui.window.Window
+import org.jetbrains.skiko.wasm.onWasmReady
+
+
+fun main() {
+ onWasmReady {
+ Window("Minesweeper") {
+ MainView()
+ }
+ }
+}
diff --git a/experimental/examples/minesweeper/src/desktopMain/resources/assets/clock.png b/experimental/examples/minesweeper/jsApp/src/jsMain/resources/assets/clock.png
similarity index 100%
rename from experimental/examples/minesweeper/src/desktopMain/resources/assets/clock.png
rename to experimental/examples/minesweeper/jsApp/src/jsMain/resources/assets/clock.png
diff --git a/experimental/examples/minesweeper/src/desktopMain/resources/assets/flag.png b/experimental/examples/minesweeper/jsApp/src/jsMain/resources/assets/flag.png
similarity index 100%
rename from experimental/examples/minesweeper/src/desktopMain/resources/assets/flag.png
rename to experimental/examples/minesweeper/jsApp/src/jsMain/resources/assets/flag.png
diff --git a/experimental/examples/minesweeper/src/desktopMain/resources/assets/mine.png b/experimental/examples/minesweeper/jsApp/src/jsMain/resources/assets/mine.png
similarity index 100%
rename from experimental/examples/minesweeper/src/desktopMain/resources/assets/mine.png
rename to experimental/examples/minesweeper/jsApp/src/jsMain/resources/assets/mine.png
diff --git a/experimental/examples/minesweeper/src/jsMain/resources/index.html b/experimental/examples/minesweeper/jsApp/src/jsMain/resources/index.html
similarity index 85%
rename from experimental/examples/minesweeper/src/jsMain/resources/index.html
rename to experimental/examples/minesweeper/jsApp/src/jsMain/resources/index.html
index c0a74e6acf..9dd212786b 100644
--- a/experimental/examples/minesweeper/src/jsMain/resources/index.html
+++ b/experimental/examples/minesweeper/jsApp/src/jsMain/resources/index.html
@@ -11,6 +11,6 @@
-
+