Skip to content

Commit 44248ea

Browse files
authored
Solivagant (#70)
* basic desktop * ktlint * basic android * basic android
1 parent 5b42e39 commit 44248ea

File tree

83 files changed

+338
-2027
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+338
-2027
lines changed

.editorconfig

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,20 @@ insert_final_newline=true
88
[*.{kt,kts}]
99
ij_kotlin_imports_layout=*
1010
ij_continuation_indent_size=4
11+
ij_kotlin_allow_trailing_comma_on_call_site=true
12+
ij_kotlin_allow_trailing_comma=true
1113
ktlint_standard_filename=disabled
1214
ktlint_standard_package-name=disabled
1315
ktlint_standard_property-naming=disabled
1416
ktlint_standard_function-naming=disabled
15-
filename=disabled
16-
ktlint_experimental=enabled
17+
ktlint_experimental=disabled
1718
ktlint_code_style=ktlint_official
19+
ktlint_standard_argument-list-wrapping=disabled
20+
ktlint_standard_multiline-expression-wrapping=disabled
21+
ktlint_standard_string-template-indent=disabled
22+
max_line_length=120
1823
[*.kts]
19-
ktlint_standard_function-literal=disabled
24+
max_line_length=400
25+
ktlint_standard_chain-wrapping=disabled
2026
[*.xml]
2127
indent_size=4

README.md

Lines changed: 1 addition & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -71,138 +71,10 @@ is configured correctly:
7171
[✓] Android Studio
7272
[✓] Xcode
7373
[✓] Cocoapods
74-
74+
7575
Conclusion:
7676
✓ Your system is ready for Kotlin Multiplatform Mobile development!
7777
```
7878

7979
Otherwise, KDoctor will highlight which parts of your setup still need to be configured and will suggest a way to fix
8080
them.
81-
82-
#### Examine the project structure
83-
84-
Open the project in Android Studio and switch the view from **Android** to **Project** to see all the files and targets
85-
belonging to the project
86-
87-
##### `desktopApp`
88-
89-
This is a Kotlin module that builds into a desktop application. It uses Gradle as the build system. The `desktopApp`
90-
module depends on and uses the `shared` module as a regular library.
91-
92-
##### `androidApp`
93-
94-
This is a Kotlin module that builds into an Android application. It uses Gradle as the build system.
95-
The `androidApp` module depends on and uses the `shared` module as a regular Android library.
96-
97-
##### `iosApp`
98-
99-
This is an Xcode project that builds into an iOS application.
100-
It depends on and uses the `shared` module as a CocoaPods dependency.
101-
102-
### Run your application
103-
104-
#### On desktop
105-
106-
To run your desktop application in Android Studio, select `desktopApp` in the list of run configurations and click **Run**:
107-
108-
<img src="readme_images/run_on_desktop.png" height="60px"><br />
109-
110-
You can also run Gradle tasks in the terminal:
111-
112-
* `./gradlew run` to run application
113-
* `./gradlew package` to store native distribution into `build/compose/binaries`
114-
115-
#### On Android
116-
117-
To run your application on an Android emulator:
118-
119-
1. Ensure you have an Android virtual device available.
120-
Otherwise, [create one](https://developer.android.com/studio/run/managing-avds#createavd).
121-
2. In the list of run configurations, select `androidApp`.
122-
3. Choose your virtual device and click **Run**:
123-
124-
<img src="readme_images/run_on_android.png" height="60px"><br />
125-
126-
<details>
127-
<summary>Alternatively, use Gradle</summary>
128-
129-
To install an Android application on a real Android device or an emulator, run `./gradlew installDebug` in the terminal.
130-
131-
</details>
132-
133-
#### On iOS
134-
135-
##### Running on a simulator
136-
137-
To run your application on an iOS simulator in Android Studio, modify the `iosApp` run configuration:
138-
139-
1. In the list of run configurations, select **Edit Configurations**:
140-
141-
<img src="readme_images/edit_run_config.png" height="200px">
142-
143-
2. Navigate to **iOS Application** | **iosApp**.
144-
3. In the **Execution target** list, select your target device. Click **OK**:
145-
146-
<img src="readme_images/target_device.png" height="400px">
147-
148-
4. The `iosApp` run configuration is now available. Click **Run** next to your virtual device
149-
150-
##### Running on a real iOS device
151-
152-
You can run your Compose Multiplatform application on a real iOS device for free.
153-
To do so, you'll need the following:
154-
155-
* The `TEAM_ID` associated with your [Apple ID](https://support.apple.com/en-us/HT204316)
156-
* The iOS device registered in Xcode
157-
158-
> **Note**
159-
> Before you continue, we suggest creating a simple "Hello, world!" project in Xcode to ensure you can successfully run
160-
> apps on your device.
161-
> You can follow the instructions below or watch
162-
> this [Stanford CS193P lecture recording](https://youtu.be/bqu6BquVi2M?start=716&end=1399).
163-
164-
<details>
165-
<summary>How to create and run a simple project in Xcode</summary>
166-
167-
1. On the Xcode welcome screen, select **Create a new project in Xcode**.
168-
2. On the **iOS** tab, choose the **App** template. Click **Next**.
169-
3. Specify the product name and keep other settings default. Click **Next**.
170-
4. Select where to store the project on your computer and click **Create**. You'll see an app that displays "Hello,
171-
world!" on the device screen.
172-
5. At the top of your Xcode screen, click on the device name near the **Run** button.
173-
6. Plug your device into the computer. You'll see this device in the list of run options.
174-
7. Choose your device and click **Run**.
175-
176-
</details>
177-
178-
###### Finding your Team ID
179-
180-
In the terminal, run `kdoctor --team-ids` to find your Team ID.
181-
KDoctor will list all Team IDs currently configured on your system, for example:
182-
183-
```text
184-
3ABC246XYZ (Max Sample)
185-
ZABCW6SXYZ (SampleTech Inc.)
186-
```
187-
188-
<details>
189-
<summary>Alternative way to find your Team ID</summary>
190-
191-
If KDoctor doesn't work for you, try this alternative method:
192-
193-
1. In Android Studio, run the `iosApp` configuration with the selected real device. The build should fail.
194-
2. Go to Xcode and select **Open a project or file**.
195-
3. Navigate to the `iosApp/iosApp.xcworkspace` file of your project.
196-
4. In the left-hand menu, select `iosApp`.
197-
5. Navigate to **Signing & Capabilities**.
198-
6. In the **Team** list, select your team.
199-
200-
If you haven't set up your team yet, use the **Add account** option and follow the steps.
201-
202-
</details>
203-
204-
To run the application, set the `TEAM_ID`:
205-
206-
1. In the template, navigate to the `iosApp/Configuration/Config.xcconfig` file.
207-
2. Set your `TEAM_ID`.
208-
3. Re-open the project in Android Studio. It should show the registered iOS device in the `iosApp` run configuration.

androidApp/src/androidMain/kotlin/com/hoc081098/compose_multiplatform_kmpviewmodel_sample/MainActivity.kt

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import android.os.Bundle
44
import androidx.activity.compose.setContent
55
import androidx.appcompat.app.AppCompatActivity
66
import androidx.compose.runtime.remember
7-
import com.freeletics.khonshu.navigation.compose.NavHost
87
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.common_ui.theme.AppTheme
98
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.koin_compose_utils.koinInjectSetMultibinding
10-
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.navigation_shared.SearchPhotoRoute
9+
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.navigation_shared.SearchPhotoScreenRoute
10+
import com.hoc081098.solivagant.navigation.NavDestination
11+
import com.hoc081098.solivagant.navigation.NavHost
1112
import io.github.aakira.napier.Napier
13+
import kotlinx.collections.immutable.toImmutableSet
1214

1315
class MainActivity : AppCompatActivity() {
1416
override fun onCreate(savedInstanceState: Bundle?) {
@@ -17,17 +19,12 @@ class MainActivity : AppCompatActivity() {
1719
setContent {
1820
AppTheme {
1921
NavHost(
20-
startRoute = SearchPhotoRoute as com.freeletics.khonshu.navigation.NavRoot,
21-
destinations = koinInjectSetMultibinding(AllDestinationsQualifier),
22-
destinationChangedCallback =
23-
remember {
24-
{ route ->
25-
Napier.d(
26-
message = "Destination changed: $route",
27-
tag = "MainActivity",
28-
)
29-
}
30-
},
22+
startRoute = SearchPhotoScreenRoute,
23+
destinations = koinInjectSetMultibinding<NavDestination>(AllDestinationsQualifier)
24+
.let { remember(it) { it.toImmutableSet() } },
25+
destinationChangedCallback = { route ->
26+
Napier.d(message = "Destination changed: $route", tag = "MainActivity")
27+
},
3128
)
3229
}
3330
}
Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
package com.hoc081098.compose_multiplatform_kmpviewmodel_sample
22

33
import androidx.compose.runtime.Stable
4-
import androidx.compose.runtime.remember
5-
import com.freeletics.khonshu.navigation.NavEventNavigator
6-
import com.freeletics.khonshu.navigation.compose.NavDestination
7-
import com.freeletics.khonshu.navigation.compose.NavigationSetup
8-
import com.freeletics.khonshu.navigation.compose.ScreenDestination
94
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.koin_utils.declareSetMultibinding
105
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.koin_utils.intoSetMultibinding
11-
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.navigation_shared.PhotoDetailRoute
12-
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.navigation_shared.SearchPhotoRoute
6+
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.navigation_shared.PhotoDetailScreenRoute
7+
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.navigation_shared.SearchPhotoScreenRoute
138
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.photo_detail.PhotoDetailScreen
149
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.search_photo.SearchPhotoScreen
15-
import org.koin.compose.koinInject
10+
import com.hoc081098.solivagant.navigation.NavDestination
11+
import com.hoc081098.solivagant.navigation.NavEventNavigator
12+
import com.hoc081098.solivagant.navigation.ScreenDestination
1613
import org.koin.core.module.dsl.singleOf
1714
import org.koin.core.qualifier.qualifier
1815
import org.koin.dsl.module
@@ -29,39 +26,20 @@ val NavigationModule =
2926
declareSetMultibinding<NavDestination>(qualifier = AllDestinationsQualifier)
3027

3128
intoSetMultibinding(
32-
key = SearchPhotoRoute::class.java,
29+
key = SearchPhotoScreenRoute::class.java,
3330
multibindingQualifier = AllDestinationsQualifier,
3431
) {
35-
ScreenDestination<SearchPhotoRoute> { route ->
36-
val navigator = koinInject<NavEventNavigator>()
37-
38-
NavigationSetup(navigator)
39-
40-
SearchPhotoScreen(
41-
route = route,
42-
navigateToPhotoDetail =
43-
remember(navigator) {
44-
{
45-
navigator.navigateTo(PhotoDetailRoute(id = it))
46-
}
47-
},
48-
)
32+
ScreenDestination<SearchPhotoScreenRoute> {
33+
SearchPhotoScreen(route = it)
4934
}
5035
}
5136

5237
intoSetMultibinding(
53-
key = PhotoDetailRoute::class.java,
38+
key = PhotoDetailScreenRoute::class.java,
5439
multibindingQualifier = AllDestinationsQualifier,
5540
) {
56-
ScreenDestination<PhotoDetailRoute> { route ->
57-
val navigator = koinInject<NavEventNavigator>()
58-
59-
NavigationSetup(navigator)
60-
61-
PhotoDetailScreen(
62-
route = route,
63-
onNavigationBack = remember(navigator) { navigator::navigateBack },
64-
)
41+
ScreenDestination<PhotoDetailScreenRoute> {
42+
PhotoDetailScreen(route = it)
6543
}
6644
}
6745
}

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ plugins {
2323

2424
allprojects {
2525
configurations.all {
26-
resolutionStrategy.eachDependency { ->
26+
resolutionStrategy.eachDependency {
2727
if (requested.group == "io.github.hoc081098") {
2828
// Check for updates every build
2929
resolutionStrategy.cacheChangingModulesFor(30, TimeUnit.MINUTES)

core/common_ui_shared/src/commonMain/kotlin/com/hoc081098/compose_multiplatform_kmpviewmodel_sample/common_ui/theme/Theme.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,7 @@ private val DarkColors =
7878
@Composable
7979
fun AppTheme(
8080
useDarkTheme: Boolean = isSystemInDarkTheme(),
81-
content:
82-
@Composable()
83-
() -> Unit,
81+
content: @Composable () -> Unit,
8482
) {
8583
val colors =
8684
if (!useDarkTheme) {

core/navigation_shared/build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ kotlin {
5252
sourceSets {
5353
val commonMain by getting {
5454
dependencies {
55-
api(projects.libraries.navigation)
5655
compileOnly("org.jetbrains.compose.runtime:runtime:${org.jetbrains.compose.ComposeBuildConfig.composeVersion}")
56+
57+
api(libs.solivagant.navigation)
5758
}
5859
}
5960
val commonTest by getting {
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
package com.hoc081098.compose_multiplatform_kmpviewmodel_sample.navigation_shared
22

33
import androidx.compose.runtime.Immutable
4-
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.navigation.NavRoot
5-
import com.hoc081098.compose_multiplatform_kmpviewmodel_sample.navigation.NavRoute
64
import com.hoc081098.kmp.viewmodel.parcelable.Parcelize
5+
import com.hoc081098.solivagant.navigation.NavRoot
6+
import com.hoc081098.solivagant.navigation.NavRoute
77

88
@Immutable
99
@Parcelize
10-
data object SearchPhotoRoute : NavRoute, NavRoot
10+
data object SearchPhotoScreenRoute : NavRoot
1111

1212
@Immutable
1313
@Parcelize
14-
data class PhotoDetailRoute(
14+
data class PhotoDetailScreenRoute(
1515
val id: String,
1616
) : NavRoute

desktopApp/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ kotlin {
4343
implementation(projects.libraries.koinUtils)
4444
implementation(projects.libraries.koinComposeUtils)
4545
implementation(projects.libraries.coroutinesUtils)
46-
implementation(projects.libraries.navigation)
4746

4847
// Feature modules
4948
implementation(projects.features.featureSearchPhotoShared)

0 commit comments

Comments
 (0)