Skip to content

Commit 757d59e

Browse files
committed
Merge branch 'master' into feature/kotlin-2.0.20
2 parents a6b4fd0 + cdb0327 commit 757d59e

14 files changed

Lines changed: 216 additions & 28 deletions

File tree

.github/workflows/code-quality.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ jobs:
2323
uses: JetBrains/qodana-action@v2024.1
2424
with:
2525
args: -v,${{ steps.get-java-home-11.outputs.JAVA_HOME_11_X64 }}:/root/.jdks/jdk11
26+
post-pr-comment: false
2627
env:
2728
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ but not all targets support AndroidX and/or SwiftUI interop:
2424
The latest version of the library uses Kotlin version `2.0.0`.
2525
Compatibility versions for older and/or preview Kotlin versions are also available:
2626

27-
| Version | Version suffix | Kotlin | Coroutines | AndroidX Lifecycle |
28-
|--------------|-------------------|:---------:|:----------:|:------------------:|
29-
| **_latest_** | **_no suffix_** | **2.0.0** | **1.8.1** | **2.8.0** |
30-
| 1.0.0-BETA-2 | _no suffix_ | 1.9.24 | 1.8.1 | 2.8.0 |
27+
| Version | Version suffix | Kotlin | Coroutines | AndroidX Lifecycle |
28+
|--------------|----------------------|:------------:|:----------:|:------------------:|
29+
| _latest_ | -kotlin-2.0.20-Beta1 | 2.0.20-Beta1 | 1.9.0-RC | 2.8.0 |
30+
| **_latest_** | **_no suffix_** | **2.0.0** | **1.8.1** | **2.8.0** |
31+
| 1.0.0-BETA-2 | _no suffix_ | 1.9.24 | 1.8.1 | 2.8.0 |
3132

3233
## Kotlin
3334

gradle/libs.versions.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ android-library = { id = "com.android.library", version.ref = "android" }
3333

3434
# Sample plugins
3535
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
36+
jetbrains-compose = { id = "org.jetbrains.compose", version = "1.6.11" }
3637
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
3738
android-application = { id = "com.android.application", version.ref = "android" }
3839
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }

sample/androidApp/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ dependencies {
4242
implementation(libs.androidx.compose.foundation)
4343
implementation(libs.androidx.compose.material)
4444
implementation(libs.androidx.fragment.ktx)
45+
implementation(libs.androidx.lifecycle.viewmodel.compose)
4546
}

sample/androidApp/src/main/java/com/rickclephas/kmp/observableviewmodel/sample/ComposeFragment.kt

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@ import android.os.Bundle
44
import android.view.LayoutInflater
55
import android.view.View
66
import android.view.ViewGroup
7-
import androidx.compose.material.Text
7+
import androidx.compose.foundation.layout.*
8+
import androidx.compose.material.*
89
import androidx.compose.runtime.Composable
10+
import androidx.compose.runtime.collectAsState
11+
import androidx.compose.runtime.getValue
12+
import androidx.compose.ui.Alignment
13+
import androidx.compose.ui.Modifier
914
import androidx.compose.ui.platform.ComposeView
10-
import androidx.compose.ui.tooling.preview.Preview
15+
import androidx.compose.ui.unit.dp
16+
import androidx.compose.ui.unit.sp
1117
import androidx.fragment.app.Fragment
12-
import com.rickclephas.kmp.observableviewmodel.sample.shared.Greeting
18+
import androidx.lifecycle.viewmodel.compose.viewModel
19+
import com.rickclephas.kmp.observableviewmodel.sample.shared.TimeTravelViewModel
1320

1421
class ComposeFragment: Fragment() {
1522

@@ -19,18 +26,55 @@ class ComposeFragment: Fragment() {
1926
savedInstanceState: Bundle?
2027
): View = ComposeView(requireContext()).apply {
2128
setContent {
22-
Greeting(Greeting().greeting())
29+
Surface {
30+
TimeTravelScreen()
31+
}
2332
}
2433
}
25-
}
2634

27-
@Composable
28-
fun Greeting(text: String) {
29-
Text(text = text)
30-
}
35+
@Composable
36+
private fun TimeTravelScreen(viewModel: TimeTravelViewModel = viewModel()) {
37+
Column(verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) {
38+
Text("Actual time:")
39+
val actualTime by viewModel.actualTime.collectAsState()
40+
Text(actualTime, fontSize = 20.sp)
41+
42+
Spacer(modifier = Modifier.height(24.dp))
43+
44+
Text("Travel effect:")
45+
val travelEffect by viewModel.travelEffect.collectAsState()
46+
Text(travelEffect.toString(), fontSize = 20.sp)
47+
48+
Spacer(modifier = Modifier.height(24.dp))
49+
50+
Text("Current time:")
51+
val currentTime by viewModel.currentTime.collectAsState()
52+
Text(currentTime, fontSize = 20.sp)
53+
54+
Spacer(modifier = Modifier.height(24.dp))
3155

32-
@Preview
33-
@Composable
34-
fun DefaultPreview() {
35-
Greeting("Hello, Android!")
56+
val isFixedTime by viewModel.isFixedTime.collectAsState()
57+
Row(verticalAlignment = Alignment.CenterVertically) {
58+
Checkbox(isFixedTime, { isChecked ->
59+
when (isChecked) {
60+
true -> viewModel.stopTime()
61+
false -> viewModel.startTime()
62+
}
63+
})
64+
Text("Fixed time")
65+
}
66+
67+
Spacer(modifier = Modifier.height(24.dp))
68+
69+
Button(viewModel::timeTravel) {
70+
Text("Time travel")
71+
}
72+
73+
Spacer(modifier = Modifier.height(24.dp))
74+
75+
Button(viewModel::resetTime) {
76+
Text("Reset")
77+
}
78+
}
79+
}
3680
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.rickclephas.kmp.observableviewmodel.sample
2+
3+
import android.os.Bundle
4+
import android.view.LayoutInflater
5+
import android.view.View
6+
import android.view.ViewGroup
7+
import androidx.compose.ui.platform.ComposeView
8+
import androidx.fragment.app.Fragment
9+
import androidx.lifecycle.viewmodel.compose.viewModel
10+
import com.rickclephas.kmp.observableviewmodel.sample.shared.TimeTravelScreen
11+
12+
class ComposeMPFragment: Fragment() {
13+
14+
override fun onCreateView(
15+
inflater: LayoutInflater,
16+
container: ViewGroup?,
17+
savedInstanceState: Bundle?
18+
): View = ComposeView(requireContext()).apply {
19+
setContent {
20+
TimeTravelScreen(viewModel())
21+
}
22+
}
23+
}

sample/androidApp/src/main/java/com/rickclephas/kmp/observableviewmodel/sample/PickerFragment.kt

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,25 @@ class PickerFragment: Fragment(R.layout.fragment_picker) {
1919
val view = super.onCreateView(inflater, container, savedInstanceState) ?: return null
2020

2121
view.findViewById<Button>(R.id.viewButton).setOnClickListener {
22-
parentFragmentManager.commit {
23-
replace<ViewFragment>(R.id.fragmentContainerView)
24-
setReorderingAllowed(true)
25-
addToBackStack(null)
26-
}
22+
navigate<ViewFragment>()
2723
}
2824

2925
view.findViewById<Button>(R.id.composeButton).setOnClickListener {
30-
parentFragmentManager.commit {
31-
replace<ComposeFragment>(R.id.fragmentContainerView)
32-
setReorderingAllowed(true)
33-
addToBackStack(null)
34-
}
26+
navigate<ComposeFragment>()
27+
}
28+
29+
view.findViewById<Button>(R.id.composeMPButton).setOnClickListener {
30+
navigate<ComposeMPFragment>()
3531
}
3632

3733
return view
3834
}
35+
36+
private inline fun <reified T: Fragment> navigate() {
37+
parentFragmentManager.commit {
38+
replace<T>(R.id.fragmentContainerView)
39+
setReorderingAllowed(true)
40+
addToBackStack(null)
41+
}
42+
}
3943
}

sample/androidApp/src/main/res/layout/fragment_picker.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,12 @@
2222
android:text="Compose"
2323
tools:ignore="HardcodedText" />
2424

25+
<Button
26+
android:id="@+id/composeMPButton"
27+
android:layout_width="wrap_content"
28+
android:layout_height="wrap_content"
29+
android:layout_marginTop="24dp"
30+
android:text="Compose MP"
31+
tools:ignore="HardcodedText" />
32+
2533
</LinearLayout>

sample/iosApp/KMPObservableViewModelSample.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
1DCF89AB2933929400A4C54A /* KMPObservableViewModelSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 1DCF89AA2933929400A4C54A /* KMPObservableViewModelSwiftUI */; };
1818
1DDAF2202935470A0049C114 /* KMPObservableViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDAF21F2935470A0049C114 /* KMPObservableViewModel.swift */; };
1919
1DDAF222293548A60049C114 /* TimeTravelViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDAF221293548A60049C114 /* TimeTravelViewModel.swift */; };
20+
1DF227B02C2856BC00D8B3A7 /* ContentViewMP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DF227AF2C2856BC00D8B3A7 /* ContentViewMP.swift */; };
2021
/* End PBXBuildFile section */
2122

2223
/* Begin PBXContainerItemProxy section */
@@ -51,6 +52,7 @@
5152
1DCF89A82933928600A4C54A /* KMP-ObservableViewModel */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "KMP-ObservableViewModel"; path = ../..; sourceTree = "<group>"; };
5253
1DDAF21F2935470A0049C114 /* KMPObservableViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPObservableViewModel.swift; sourceTree = "<group>"; };
5354
1DDAF221293548A60049C114 /* TimeTravelViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeTravelViewModel.swift; sourceTree = "<group>"; };
55+
1DF227AF2C2856BC00D8B3A7 /* ContentViewMP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentViewMP.swift; sourceTree = "<group>"; };
5456
/* End PBXFileReference section */
5557

5658
/* Begin PBXFrameworksBuildPhase section */
@@ -110,6 +112,7 @@
110112
1D44EF7D292C066C00465C43 /* Preview Content */,
111113
1DDAF21F2935470A0049C114 /* KMPObservableViewModel.swift */,
112114
1DDAF221293548A60049C114 /* TimeTravelViewModel.swift */,
115+
1DF227AF2C2856BC00D8B3A7 /* ContentViewMP.swift */,
113116
);
114117
path = KMPObservableViewModelSample;
115118
sourceTree = "<group>";
@@ -314,6 +317,7 @@
314317
1DDAF2202935470A0049C114 /* KMPObservableViewModel.swift in Sources */,
315318
1DDAF222293548A60049C114 /* TimeTravelViewModel.swift in Sources */,
316319
1D44EF7A292C066B00465C43 /* ContentView.swift in Sources */,
320+
1DF227B02C2856BC00D8B3A7 /* ContentViewMP.swift in Sources */,
317321
1D44EF78292C066B00465C43 /* KMPObservableViewModelSampleApp.swift in Sources */,
318322
);
319323
runOnlyForDeploymentPostprocessing = 0;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// ContentViewMP.swift
3+
// KMPObservableViewModelSample
4+
//
5+
// Created by Rick Clephas on 23/06/2024.
6+
//
7+
8+
import SwiftUI
9+
import KMPObservableViewModelSampleShared
10+
11+
struct ContentViewMP: UIViewControllerRepresentable {
12+
13+
@StateObject var viewModel = TimeTravelViewModel()
14+
15+
func makeUIViewController(context: Context) -> some UIViewController {
16+
TimeTravelViewControllerKt.TimeTravelViewController(viewModel: viewModel)
17+
}
18+
19+
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
20+
21+
}
22+
}

0 commit comments

Comments
 (0)