turbo-native-initializer 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/README.md +11 -0
- data/lib/turbo_native_initializer/generator.rb +4 -4
- data/lib/turbo_native_initializer/templates/android_stack/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/native/NativeFragment.kt.tt +25 -0
- data/lib/turbo_native_initializer/templates/android_stack/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/native/NumbersFragment.kt.tt +40 -0
- data/lib/turbo_native_initializer/templates/android_stack/app/src/main/java/dev/hotwire/turbo/turbonativeproject/main/MainSessionNavHostFragment.kt.tt +2 -1
- data/lib/turbo_native_initializer/templates/android_stack/base/app/build.gradle.kts.tt +16 -3
- data/lib/turbo_native_initializer/templates/android_stack/base/app/src/main/assets/json/configuration.json +2 -1
- data/lib/turbo_native_initializer/templates/android_stack/base/app/src/main/res/layout/fragment_native.xml +36 -0
- data/lib/turbo_native_initializer/templates/android_tabs/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/native/NativeFragment.kt.tt +25 -0
- data/lib/turbo_native_initializer/templates/android_tabs/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/native/NumbersFragment.kt.tt +40 -0
- data/lib/turbo_native_initializer/templates/android_tabs/app/src/main/java/dev/hotwire/turbo/turbonativeproject/main/BaseSessionNavHostFragment.kt.tt +2 -1
- data/lib/turbo_native_initializer/templates/android_tabs/base/app/build.gradle.kts.tt +16 -3
- data/lib/turbo_native_initializer/templates/android_tabs/base/app/src/main/assets/json/configuration.json +2 -1
- data/lib/turbo_native_initializer/templates/android_tabs/base/app/src/main/res/layout/fragment_native.xml +36 -0
- data/lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Configuration/path-configuration.json +2 -1
- data/lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Controllers/NumbersViewController.swift +31 -0
- data/lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Controllers/TurboNavigationController.swift +1 -1
- data/lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject.xcodeproj/project.pbxproj.tt +4 -0
- data/lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Configuration/path-configuration.json +2 -1
- data/lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Controllers/NumbersViewController.swift +31 -0
- data/lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Controllers/TurboNavigationController.swift +2 -2
- data/lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject.xcodeproj/project.pbxproj.tt +4 -0
- data/lib/turbo_native_initializer/version.rb +1 -1
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87f651e0de673db040c8ed9f369d404b8f08946654c721329d07bfd9cbbc0149
|
4
|
+
data.tar.gz: ec47793c2bf2370f5cd4390bcf45a8ef14bad81ff70f0f3c4ba6cb1d3bb8c980
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40079d2dc7c716940cf72a536304801180f62c509a8d64e6bf7bcdd4cf4f5179f52b1e2213f57ac7e9fb4e1865c02a45f8ba8e123813fbff92e3f541090909a8
|
7
|
+
data.tar.gz: 0bebf193304c04ed0ddaa53340fb4d0c9f4d46209471f18f883a9e0df83ec8038b2a16544372d2b704d421119519552b01c0641cd0f82181615287db906724e0
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.0.3] - 2023-09-08
|
4
|
+
|
5
|
+
- Add a Swift UI native screen
|
6
|
+
- Add a jetpack compose screen
|
7
|
+
- Fix android package
|
8
|
+
|
9
|
+
## [0.0.2] - 2023-09-07
|
10
|
+
|
3
11
|
- Fix android tab navigation
|
4
12
|
- General cleanup
|
5
13
|
|
6
|
-
## [0.0.1] - 2023-09-
|
14
|
+
## [0.0.1] - 2023-09-06
|
7
15
|
|
8
16
|
- Initial release
|
data/README.md
CHANGED
@@ -2,6 +2,17 @@
|
|
2
2
|
|
3
3
|
A turbo native project generator for iOS and Android.
|
4
4
|
|
5
|
+
## Differences when compared to the demos
|
6
|
+
|
7
|
+
- Added SwiftUI error screen. (iOS)
|
8
|
+
- Added SwiftUI numbers screen. (iOS)
|
9
|
+
- Added Jetpack Compose numbers screen. (Android)
|
10
|
+
- Added UIAlertController to handle `turbo-native-confirm`. (iOS)
|
11
|
+
- Added presentations `clear-all`, `replace-all`, `replace`, `pop`, `refresh`, and `none`. (iOS)
|
12
|
+
- Added visitable property in order to avoid visits. (iOS)
|
13
|
+
- Added full screen option to modals. (iOS/Android)
|
14
|
+
- Added support for tab navigation. (iOS/Android)
|
15
|
+
|
5
16
|
## Installation
|
6
17
|
|
7
18
|
```
|
@@ -36,14 +36,14 @@ module TurboNativeInitializer
|
|
36
36
|
"#{options[:platform]}_#{options[:navigation]}"
|
37
37
|
end
|
38
38
|
|
39
|
-
def package_path
|
40
|
-
options[:package].split(".").join("/")
|
41
|
-
end
|
42
|
-
|
43
39
|
def package_name
|
44
40
|
"#{options[:package]}.#{name.downcase}"
|
45
41
|
end
|
46
42
|
|
43
|
+
def package_path
|
44
|
+
package_name.split(".").join("/")
|
45
|
+
end
|
46
|
+
|
47
47
|
def bundle_identifier
|
48
48
|
"#{options[:package]}.#{name}"
|
49
49
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
package <%= package_name %>.features.native
|
2
|
+
|
3
|
+
import android.view.LayoutInflater
|
4
|
+
import android.view.View
|
5
|
+
import android.view.ViewGroup
|
6
|
+
import androidx.compose.runtime.Composable
|
7
|
+
import androidx.compose.ui.platform.ComposeView
|
8
|
+
import androidx.compose.ui.platform.ViewCompositionStrategy
|
9
|
+
import dev.hotwire.turbo.fragments.TurboFragment
|
10
|
+
import <%= package_name %>.R
|
11
|
+
import <%= package_name %>.base.NavDestination
|
12
|
+
|
13
|
+
abstract class NativeFragment : TurboFragment(), NavDestination {
|
14
|
+
fun setContent(inflater: LayoutInflater, container: ViewGroup?, content: @Composable () -> Unit): View? {
|
15
|
+
val root = inflater.inflate(R.layout.fragment_native, container, false)
|
16
|
+
val composeView = root.findViewById<ComposeView>(R.id.compose_view)
|
17
|
+
|
18
|
+
composeView.apply {
|
19
|
+
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
20
|
+
setContent { content.invoke() }
|
21
|
+
}
|
22
|
+
|
23
|
+
return root
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
package <%= package_name %>.features.native
|
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.foundation.lazy.LazyColumn
|
8
|
+
import androidx.compose.material3.Divider
|
9
|
+
import androidx.compose.material3.ListItem
|
10
|
+
import androidx.compose.material3.Text
|
11
|
+
import dev.hotwire.turbo.nav.TurboNavGraphDestination
|
12
|
+
import androidx.compose.runtime.Composable
|
13
|
+
import androidx.compose.ui.tooling.preview.Preview
|
14
|
+
|
15
|
+
@TurboNavGraphDestination(uri = "turbo://fragment/numbers")
|
16
|
+
class NumbersFragment : NativeFragment() {
|
17
|
+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
18
|
+
return setContent(inflater, container) {
|
19
|
+
NumbersList()
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
@Composable
|
25
|
+
fun NumbersList() {
|
26
|
+
val numbers = 1..100
|
27
|
+
|
28
|
+
LazyColumn {
|
29
|
+
items(numbers.count()) { index ->
|
30
|
+
ListItem(headlineContent = { Text("Row number ${index + 1}") })
|
31
|
+
Divider()
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
@Preview
|
37
|
+
@Composable
|
38
|
+
fun PreviewNumbersList() {
|
39
|
+
NumbersList()
|
40
|
+
}
|
@@ -4,6 +4,7 @@ import android.webkit.WebView
|
|
4
4
|
import androidx.appcompat.app.AppCompatActivity
|
5
5
|
import androidx.fragment.app.Fragment
|
6
6
|
import dev.hotwire.turbo.config.TurboPathConfiguration
|
7
|
+
import <%= package_name %>.features.native.NumbersFragment
|
7
8
|
import <%= package_name %>.features.web.WebFragment
|
8
9
|
import <%= package_name %>.features.web.WebHomeFragment
|
9
10
|
import <%= package_name %>.features.web.WebModalFragment
|
@@ -21,7 +22,7 @@ class MainSessionNavHostFragment : TurboSessionNavHostFragment() {
|
|
21
22
|
get() = listOf()
|
22
23
|
|
23
24
|
override val registeredFragments: List<KClass<out Fragment>>
|
24
|
-
get() = listOf(WebFragment::class, WebHomeFragment::class, WebModalFragment::class)
|
25
|
+
get() = listOf(WebFragment::class, WebHomeFragment::class, WebModalFragment::class, NumbersFragment::class)
|
25
26
|
|
26
27
|
override val pathConfigurationLocation: TurboPathConfiguration.Location
|
27
28
|
get() = TurboPathConfiguration.Location(assetFilePath = "json/configuration.json")
|
@@ -13,8 +13,6 @@ android {
|
|
13
13
|
targetSdk = 33
|
14
14
|
versionCode = 1
|
15
15
|
versionName = "1.0"
|
16
|
-
|
17
|
-
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
18
16
|
}
|
19
17
|
|
20
18
|
buildTypes {
|
@@ -33,12 +31,27 @@ android {
|
|
33
31
|
kotlinOptions {
|
34
32
|
jvmTarget = "1.8"
|
35
33
|
}
|
34
|
+
buildFeatures {
|
35
|
+
compose = true
|
36
|
+
}
|
37
|
+
composeOptions {
|
38
|
+
kotlinCompilerExtensionVersion = "1.5.2"
|
39
|
+
}
|
36
40
|
}
|
37
|
-
|
38
41
|
dependencies {
|
42
|
+
// Android
|
39
43
|
implementation("androidx.core:core-ktx:1.9.0")
|
40
44
|
implementation("androidx.appcompat:appcompat:1.6.1")
|
41
45
|
implementation("androidx.browser:browser:1.5.0")
|
42
46
|
implementation("com.google.android.material:material:1.9.0")
|
47
|
+
|
48
|
+
// Jetpack Compose
|
49
|
+
implementation(platform("androidx.compose:compose-bom:2023.06.01"))
|
50
|
+
implementation("androidx.compose.material3:material3")
|
51
|
+
implementation("androidx.compose.ui:ui-tooling-preview")
|
52
|
+
debugImplementation("androidx.compose.ui:ui-tooling")
|
53
|
+
implementation("androidx.activity:activity-compose:1.7.2")
|
54
|
+
|
55
|
+
// Turbo Android
|
43
56
|
implementation("dev.hotwire:turbo:7.0.0")
|
44
57
|
}
|
@@ -6,6 +6,7 @@
|
|
6
6
|
{ "patterns": ["/recede_historical_location"], "properties": { "presentation": "pop" } },
|
7
7
|
{ "patterns": ["/resume_historical_location"], "properties": { "presentation": "none" } },
|
8
8
|
{ "patterns": ["^/$"], "properties": { "uri": "turbo://fragment/web/home", "presentation": "replace_all" } },
|
9
|
-
{ "patterns": ["/new$", "/edit$", "/signin$"], "properties": { "context": "modal", "uri": "turbo://fragment/web/modal" } }
|
9
|
+
{ "patterns": ["/new$", "/edit$", "/signin$"], "properties": { "context": "modal", "uri": "turbo://fragment/web/modal" } },
|
10
|
+
{ "patterns": ["/numbers$"], "properties": { "uri": "turbo://fragment/numbers", "title": "Numbers" } }
|
10
11
|
]
|
11
12
|
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<androidx.constraintlayout.widget.ConstraintLayout
|
3
|
+
xmlns:android="http://schemas.android.com/apk/res/android"
|
4
|
+
xmlns:app="http://schemas.android.com/apk/res-auto"
|
5
|
+
android:layout_width="match_parent"
|
6
|
+
android:layout_height="match_parent">
|
7
|
+
|
8
|
+
<com.google.android.material.appbar.AppBarLayout
|
9
|
+
android:id="@+id/app_bar"
|
10
|
+
android:layout_width="match_parent"
|
11
|
+
android:layout_height="56dp"
|
12
|
+
app:layout_constraintEnd_toEndOf="parent"
|
13
|
+
app:layout_constraintStart_toStartOf="parent"
|
14
|
+
app:layout_constraintTop_toTopOf="parent">
|
15
|
+
|
16
|
+
<FrameLayout
|
17
|
+
android:layout_width="match_parent"
|
18
|
+
android:layout_height="match_parent">
|
19
|
+
|
20
|
+
<com.google.android.material.appbar.MaterialToolbar
|
21
|
+
android:id="@+id/toolbar"
|
22
|
+
android:layout_width="match_parent"
|
23
|
+
android:layout_height="wrap_content" />
|
24
|
+
|
25
|
+
</FrameLayout>
|
26
|
+
|
27
|
+
</com.google.android.material.appbar.AppBarLayout>
|
28
|
+
|
29
|
+
<androidx.compose.ui.platform.ComposeView
|
30
|
+
android:id="@+id/compose_view"
|
31
|
+
android:layout_width="match_parent"
|
32
|
+
android:layout_height="0dp"
|
33
|
+
app:layout_constraintBottom_toBottomOf="parent"
|
34
|
+
app:layout_constraintTop_toBottomOf="@+id/app_bar" />
|
35
|
+
|
36
|
+
</androidx.constraintlayout.widget.ConstraintLayout>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
package <%= package_name %>.features.native
|
2
|
+
|
3
|
+
import android.view.LayoutInflater
|
4
|
+
import android.view.View
|
5
|
+
import android.view.ViewGroup
|
6
|
+
import androidx.compose.runtime.Composable
|
7
|
+
import androidx.compose.ui.platform.ComposeView
|
8
|
+
import androidx.compose.ui.platform.ViewCompositionStrategy
|
9
|
+
import dev.hotwire.turbo.fragments.TurboFragment
|
10
|
+
import <%= package_name %>.R
|
11
|
+
import <%= package_name %>.base.NavDestination
|
12
|
+
|
13
|
+
abstract class NativeFragment : TurboFragment(), NavDestination {
|
14
|
+
fun setContent(inflater: LayoutInflater, container: ViewGroup?, content: @Composable () -> Unit): View? {
|
15
|
+
val root = inflater.inflate(R.layout.fragment_native, container, false)
|
16
|
+
val composeView = root.findViewById<ComposeView>(R.id.compose_view)
|
17
|
+
|
18
|
+
composeView.apply {
|
19
|
+
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
20
|
+
setContent { content.invoke() }
|
21
|
+
}
|
22
|
+
|
23
|
+
return root
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
package <%= package_name %>.features.native
|
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.foundation.lazy.LazyColumn
|
8
|
+
import androidx.compose.material3.Divider
|
9
|
+
import androidx.compose.material3.ListItem
|
10
|
+
import androidx.compose.material3.Text
|
11
|
+
import dev.hotwire.turbo.nav.TurboNavGraphDestination
|
12
|
+
import androidx.compose.runtime.Composable
|
13
|
+
import androidx.compose.ui.tooling.preview.Preview
|
14
|
+
|
15
|
+
@TurboNavGraphDestination(uri = "turbo://fragment/numbers")
|
16
|
+
class NumbersFragment : NativeFragment() {
|
17
|
+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
18
|
+
return setContent(inflater, container) {
|
19
|
+
NumbersList()
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
@Composable
|
25
|
+
fun NumbersList() {
|
26
|
+
val numbers = 1..100
|
27
|
+
|
28
|
+
LazyColumn {
|
29
|
+
items(numbers.count()) { index ->
|
30
|
+
ListItem(headlineContent = { Text("Row number ${index + 1}") })
|
31
|
+
Divider()
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
@Preview
|
37
|
+
@Composable
|
38
|
+
fun PreviewNumbersList() {
|
39
|
+
NumbersList()
|
40
|
+
}
|
@@ -4,6 +4,7 @@ import android.webkit.WebView
|
|
4
4
|
import androidx.appcompat.app.AppCompatActivity
|
5
5
|
import androidx.fragment.app.Fragment
|
6
6
|
import dev.hotwire.turbo.config.TurboPathConfiguration
|
7
|
+
import <%= package_name %>.features.native.NumbersFragment
|
7
8
|
import <%= package_name %>.features.web.WebFragment
|
8
9
|
import <%= package_name %>.features.web.WebHomeFragment
|
9
10
|
import <%= package_name %>.features.web.WebModalFragment
|
@@ -15,7 +16,7 @@ abstract class BaseSessionNavHostFragment : TurboSessionNavHostFragment() {
|
|
15
16
|
get() = listOf()
|
16
17
|
|
17
18
|
override val registeredFragments: List<KClass<out Fragment>>
|
18
|
-
get() = listOf(WebFragment::class, WebHomeFragment::class, WebModalFragment::class)
|
19
|
+
get() = listOf(WebFragment::class, WebHomeFragment::class, WebModalFragment::class, NumbersFragment::class)
|
19
20
|
|
20
21
|
override val pathConfigurationLocation: TurboPathConfiguration.Location
|
21
22
|
get() = TurboPathConfiguration.Location(assetFilePath = "json/configuration.json")
|
@@ -13,8 +13,6 @@ android {
|
|
13
13
|
targetSdk = 33
|
14
14
|
versionCode = 1
|
15
15
|
versionName = "1.0"
|
16
|
-
|
17
|
-
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
18
16
|
}
|
19
17
|
|
20
18
|
buildTypes {
|
@@ -33,12 +31,27 @@ android {
|
|
33
31
|
kotlinOptions {
|
34
32
|
jvmTarget = "1.8"
|
35
33
|
}
|
34
|
+
buildFeatures {
|
35
|
+
compose = true
|
36
|
+
}
|
37
|
+
composeOptions {
|
38
|
+
kotlinCompilerExtensionVersion = "1.5.2"
|
39
|
+
}
|
36
40
|
}
|
37
|
-
|
38
41
|
dependencies {
|
42
|
+
// Android
|
39
43
|
implementation("androidx.core:core-ktx:1.9.0")
|
40
44
|
implementation("androidx.appcompat:appcompat:1.6.1")
|
41
45
|
implementation("androidx.browser:browser:1.5.0")
|
42
46
|
implementation("com.google.android.material:material:1.9.0")
|
47
|
+
|
48
|
+
// Jetpack Compose
|
49
|
+
implementation(platform("androidx.compose:compose-bom:2023.06.01"))
|
50
|
+
implementation("androidx.compose.material3:material3")
|
51
|
+
implementation("androidx.compose.ui:ui-tooling-preview")
|
52
|
+
debugImplementation("androidx.compose.ui:ui-tooling")
|
53
|
+
implementation("androidx.activity:activity-compose:1.7.2")
|
54
|
+
|
55
|
+
// Turbo Android
|
43
56
|
implementation("dev.hotwire:turbo:7.0.0")
|
44
57
|
}
|
@@ -6,6 +6,7 @@
|
|
6
6
|
{ "patterns": ["/recede_historical_location"], "properties": { "presentation": "pop" } },
|
7
7
|
{ "patterns": ["/resume_historical_location"], "properties": { "presentation": "none" } },
|
8
8
|
{ "patterns": ["^/$"], "properties": { "uri": "turbo://fragment/web/home", "presentation": "replace_all" } },
|
9
|
-
{ "patterns": ["/new$", "/edit$"], "properties": { "context": "modal", "uri": "turbo://fragment/web/modal" } }
|
9
|
+
{ "patterns": ["/new$", "/edit$"], "properties": { "context": "modal", "uri": "turbo://fragment/web/modal" } },
|
10
|
+
{ "patterns": ["/numbers$"], "properties": { "uri": "turbo://fragment/numbers", "title": "Numbers" } }
|
10
11
|
]
|
11
12
|
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<androidx.constraintlayout.widget.ConstraintLayout
|
3
|
+
xmlns:android="http://schemas.android.com/apk/res/android"
|
4
|
+
xmlns:app="http://schemas.android.com/apk/res-auto"
|
5
|
+
android:layout_width="match_parent"
|
6
|
+
android:layout_height="match_parent">
|
7
|
+
|
8
|
+
<com.google.android.material.appbar.AppBarLayout
|
9
|
+
android:id="@+id/app_bar"
|
10
|
+
android:layout_width="match_parent"
|
11
|
+
android:layout_height="56dp"
|
12
|
+
app:layout_constraintEnd_toEndOf="parent"
|
13
|
+
app:layout_constraintStart_toStartOf="parent"
|
14
|
+
app:layout_constraintTop_toTopOf="parent">
|
15
|
+
|
16
|
+
<FrameLayout
|
17
|
+
android:layout_width="match_parent"
|
18
|
+
android:layout_height="match_parent">
|
19
|
+
|
20
|
+
<com.google.android.material.appbar.MaterialToolbar
|
21
|
+
android:id="@+id/toolbar"
|
22
|
+
android:layout_width="match_parent"
|
23
|
+
android:layout_height="wrap_content" />
|
24
|
+
|
25
|
+
</FrameLayout>
|
26
|
+
|
27
|
+
</com.google.android.material.appbar.AppBarLayout>
|
28
|
+
|
29
|
+
<androidx.compose.ui.platform.ComposeView
|
30
|
+
android:id="@+id/compose_view"
|
31
|
+
android:layout_width="match_parent"
|
32
|
+
android:layout_height="0dp"
|
33
|
+
app:layout_constraintBottom_toBottomOf="parent"
|
34
|
+
app:layout_constraintTop_toBottomOf="@+id/app_bar" />
|
35
|
+
|
36
|
+
</androidx.constraintlayout.widget.ConstraintLayout>
|
@@ -5,6 +5,7 @@
|
|
5
5
|
{ "patterns": ["/recede_historical_location"], "properties": { "presentation": "pop", "visitable": false } },
|
6
6
|
{ "patterns": ["/resume_historical_location"], "properties": { "presentation": "none", "visitable": false } },
|
7
7
|
{ "patterns": ["^/$"], "properties": { "presentation": "replace-all" } },
|
8
|
-
{ "patterns": ["/new$", "/edit$", "/signin$"], "properties": { "presentation": "modal" } }
|
8
|
+
{ "patterns": ["/new$", "/edit$", "/signin$"], "properties": { "presentation": "modal" } },
|
9
|
+
{ "patterns": ["/numbers$"], "properties": { "view-controller": "numbers" } }
|
9
10
|
]
|
10
11
|
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import SwiftUI
|
2
|
+
|
3
|
+
class NumbersViewController: UIHostingController<NumbersView> {
|
4
|
+
init() {
|
5
|
+
super.init(rootView: NumbersView())
|
6
|
+
}
|
7
|
+
|
8
|
+
required init(coder aDecoder: NSCoder) {
|
9
|
+
fatalError("init(coder:) has not been implemented")
|
10
|
+
}
|
11
|
+
|
12
|
+
override func viewDidLoad() {
|
13
|
+
super.viewDidLoad(); title = "Numbers"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
struct NumbersView: View {
|
18
|
+
private let numbers = 1 ... 100
|
19
|
+
|
20
|
+
var body: some View {
|
21
|
+
List(numbers, id: \.self) { number in
|
22
|
+
Text("Row \(number)")
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
struct NumbersView_Preview: PreviewProvider {
|
28
|
+
static var previews: some View {
|
29
|
+
NumbersView()
|
30
|
+
}
|
31
|
+
}
|
@@ -75,7 +75,7 @@ extension TurboNavigationController {
|
|
75
75
|
if let viewController = properties["view-controller"] as? String {
|
76
76
|
switch viewController {
|
77
77
|
case "numbers":
|
78
|
-
|
78
|
+
return NumbersViewController()
|
79
79
|
default:
|
80
80
|
assertionFailure("Invalid view controller, defaulting to WebView")
|
81
81
|
}
|
@@ -18,6 +18,7 @@
|
|
18
18
|
5DCC50EE2A95A27600B529A0 /* ErrorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DCC50ED2A95A27600B529A0 /* ErrorPresenter.swift */; };
|
19
19
|
5DCC50F12A95A66700B529A0 /* Turbo in Frameworks */ = {isa = PBXBuildFile; productRef = 5DCC50F02A95A66700B529A0 /* Turbo */; };
|
20
20
|
5DCC50F32A95A7E600B529A0 /* <%= name %>.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DCC50F22A95A7E600B529A0 /* <%= name %>.swift */; };
|
21
|
+
5DDD58812AA9A8BE00FAC961 /* NumbersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DDD58802AA9A8BE00FAC961 /* NumbersViewController.swift */; };
|
21
22
|
/* End PBXBuildFile section */
|
22
23
|
|
23
24
|
/* Begin PBXFileReference section */
|
@@ -33,6 +34,7 @@
|
|
33
34
|
5DCC50E92A95A19600B529A0 /* path-configuration.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "path-configuration.json"; sourceTree = "<group>"; };
|
34
35
|
5DCC50ED2A95A27600B529A0 /* ErrorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorPresenter.swift; sourceTree = "<group>"; };
|
35
36
|
5DCC50F22A95A7E600B529A0 /* <%= name %>.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = <%= name %>.swift; sourceTree = "<group>"; };
|
37
|
+
5DDD58802AA9A8BE00FAC961 /* NumbersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumbersViewController.swift; sourceTree = "<group>"; };
|
36
38
|
/* End PBXFileReference section */
|
37
39
|
|
38
40
|
/* Begin PBXFrameworksBuildPhase section */
|
@@ -90,6 +92,7 @@
|
|
90
92
|
5DCC50ED2A95A27600B529A0 /* ErrorPresenter.swift */,
|
91
93
|
5DCC50E72A95A0D900B529A0 /* TurboNavigationController.swift */,
|
92
94
|
5DCC50D72A959DF900B529A0 /* ViewController.swift */,
|
95
|
+
5DDD58802AA9A8BE00FAC961 /* NumbersViewController.swift */,
|
93
96
|
);
|
94
97
|
path = Controllers;
|
95
98
|
sourceTree = "<group>";
|
@@ -192,6 +195,7 @@
|
|
192
195
|
buildActionMask = 2147483647;
|
193
196
|
files = (
|
194
197
|
5DCC50D82A959DF900B529A0 /* ViewController.swift in Sources */,
|
198
|
+
5DDD58812AA9A8BE00FAC961 /* NumbersViewController.swift in Sources */,
|
195
199
|
5DCC50D42A959DF900B529A0 /* AppDelegate.swift in Sources */,
|
196
200
|
5DCC50E82A95A0D900B529A0 /* TurboNavigationController.swift in Sources */,
|
197
201
|
5DCC50D62A959DF900B529A0 /* SceneDelegate.swift in Sources */,
|
@@ -5,6 +5,7 @@
|
|
5
5
|
{ "patterns": ["/recede_historical_location"], "properties": { "presentation": "pop", "visitable": false } },
|
6
6
|
{ "patterns": ["/resume_historical_location"], "properties": { "presentation": "none", "visitable": false } },
|
7
7
|
{ "patterns": ["^/$"], "properties": { "presentation": "replace-all" } },
|
8
|
-
{ "patterns": ["/new$", "/edit$"], "properties": { "presentation": "modal" } }
|
8
|
+
{ "patterns": ["/new$", "/edit$"], "properties": { "presentation": "modal" } },
|
9
|
+
{ "patterns": ["/numbers$"], "properties": { "view-controller": "numbers" } }
|
9
10
|
]
|
10
11
|
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import SwiftUI
|
2
|
+
|
3
|
+
class NumbersViewController: UIHostingController<NumbersView> {
|
4
|
+
init() {
|
5
|
+
super.init(rootView: NumbersView())
|
6
|
+
}
|
7
|
+
|
8
|
+
required init(coder aDecoder: NSCoder) {
|
9
|
+
fatalError("init(coder:) has not been implemented")
|
10
|
+
}
|
11
|
+
|
12
|
+
override func viewDidLoad() {
|
13
|
+
super.viewDidLoad(); title = "Numbers"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
struct NumbersView: View {
|
18
|
+
private let numbers = 1 ... 100
|
19
|
+
|
20
|
+
var body: some View {
|
21
|
+
List(numbers, id: \.self) { number in
|
22
|
+
Text("Row \(number)")
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
struct NumbersView_Preview: PreviewProvider {
|
28
|
+
static var previews: some View {
|
29
|
+
NumbersView()
|
30
|
+
}
|
31
|
+
}
|
@@ -75,7 +75,7 @@ extension TurboNavigationController {
|
|
75
75
|
if let viewController = properties["view-controller"] as? String {
|
76
76
|
switch viewController {
|
77
77
|
case "numbers":
|
78
|
-
|
78
|
+
return NumbersViewController()
|
79
79
|
default:
|
80
80
|
assertionFailure("Invalid view controller, defaulting to WebView")
|
81
81
|
}
|
@@ -87,7 +87,7 @@ extension TurboNavigationController {
|
|
87
87
|
private func navigate(to viewController: UIViewController, action: VisitAction, properties: PathProperties = [:], animated: Bool = true) {
|
88
88
|
let modalNavController = UINavigationController(rootViewController: viewController)
|
89
89
|
modalNavController.modalPresentationStyle = .fullScreen
|
90
|
-
|
90
|
+
|
91
91
|
if isModal(properties) {
|
92
92
|
present(modalNavController, animated: animated)
|
93
93
|
} else if isClearAll(properties) {
|
data/lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject.xcodeproj/project.pbxproj.tt
CHANGED
@@ -18,6 +18,7 @@
|
|
18
18
|
5DCC50EE2A95A27600B529A0 /* ErrorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DCC50ED2A95A27600B529A0 /* ErrorPresenter.swift */; };
|
19
19
|
5DCC50F12A95A66700B529A0 /* Turbo in Frameworks */ = {isa = PBXBuildFile; productRef = 5DCC50F02A95A66700B529A0 /* Turbo */; };
|
20
20
|
5DCC50F32A95A7E600B529A0 /* <%= name %>.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DCC50F22A95A7E600B529A0 /* <%= name %>.swift */; };
|
21
|
+
5DDD58812AA9A8BE00FAC961 /* NumbersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DDD58802AA9A8BE00FAC961 /* NumbersViewController.swift */; };
|
21
22
|
/* End PBXBuildFile section */
|
22
23
|
|
23
24
|
/* Begin PBXFileReference section */
|
@@ -33,6 +34,7 @@
|
|
33
34
|
5DCC50E92A95A19600B529A0 /* path-configuration.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "path-configuration.json"; sourceTree = "<group>"; };
|
34
35
|
5DCC50ED2A95A27600B529A0 /* ErrorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorPresenter.swift; sourceTree = "<group>"; };
|
35
36
|
5DCC50F22A95A7E600B529A0 /* <%= name %>.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = <%= name %>.swift; sourceTree = "<group>"; };
|
37
|
+
5DDD58802AA9A8BE00FAC961 /* NumbersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumbersViewController.swift; sourceTree = "<group>"; };
|
36
38
|
/* End PBXFileReference section */
|
37
39
|
|
38
40
|
/* Begin PBXFrameworksBuildPhase section */
|
@@ -90,6 +92,7 @@
|
|
90
92
|
5DCC50ED2A95A27600B529A0 /* ErrorPresenter.swift */,
|
91
93
|
5DCC50E72A95A0D900B529A0 /* TurboNavigationController.swift */,
|
92
94
|
5DCC50D72A959DF900B529A0 /* ViewController.swift */,
|
95
|
+
5DDD58802AA9A8BE00FAC961 /* NumbersViewController.swift */,
|
93
96
|
);
|
94
97
|
path = Controllers;
|
95
98
|
sourceTree = "<group>";
|
@@ -192,6 +195,7 @@
|
|
192
195
|
buildActionMask = 2147483647;
|
193
196
|
files = (
|
194
197
|
5DCC50D82A959DF900B529A0 /* ViewController.swift in Sources */,
|
198
|
+
5DDD58812AA9A8BE00FAC961 /* NumbersViewController.swift in Sources */,
|
195
199
|
5DCC50D42A959DF900B529A0 /* AppDelegate.swift in Sources */,
|
196
200
|
5DCC50E82A95A0D900B529A0 /* TurboNavigationController.swift in Sources */,
|
197
201
|
5DCC50D62A959DF900B529A0 /* SceneDelegate.swift in Sources */,
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbo-native-initializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nixon
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-09-
|
11
|
+
date: 2023-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -42,6 +42,8 @@ files:
|
|
42
42
|
- lib/turbo_native_initializer.rb
|
43
43
|
- lib/turbo_native_initializer/generator.rb
|
44
44
|
- lib/turbo_native_initializer/templates/android_stack/app/src/main/java/dev/hotwire/turbo/turbonativeproject/base/NavDestination.kt.tt
|
45
|
+
- lib/turbo_native_initializer/templates/android_stack/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/native/NativeFragment.kt.tt
|
46
|
+
- lib/turbo_native_initializer/templates/android_stack/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/native/NumbersFragment.kt.tt
|
45
47
|
- lib/turbo_native_initializer/templates/android_stack/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/web/WebFragment.kt.tt
|
46
48
|
- lib/turbo_native_initializer/templates/android_stack/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/web/WebHomeFragment.kt.tt
|
47
49
|
- lib/turbo_native_initializer/templates/android_stack/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/web/WebModalFragment.kt.tt
|
@@ -62,6 +64,7 @@ files:
|
|
62
64
|
- lib/turbo_native_initializer/templates/android_stack/base/app/src/main/res/drawable/ic_close.xml
|
63
65
|
- lib/turbo_native_initializer/templates/android_stack/base/app/src/main/res/drawable/ic_launcher_foreground.xml
|
64
66
|
- lib/turbo_native_initializer/templates/android_stack/base/app/src/main/res/layout/activity_main.xml.tt
|
67
|
+
- lib/turbo_native_initializer/templates/android_stack/base/app/src/main/res/layout/fragment_native.xml
|
65
68
|
- lib/turbo_native_initializer/templates/android_stack/base/app/src/main/res/layout/fragment_web_home.xml
|
66
69
|
- lib/turbo_native_initializer/templates/android_stack/base/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
|
67
70
|
- lib/turbo_native_initializer/templates/android_stack/base/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
|
@@ -82,6 +85,8 @@ files:
|
|
82
85
|
- lib/turbo_native_initializer/templates/android_stack/base/local.properties
|
83
86
|
- lib/turbo_native_initializer/templates/android_stack/base/settings.gradle.kts.tt
|
84
87
|
- lib/turbo_native_initializer/templates/android_tabs/app/src/main/java/dev/hotwire/turbo/turbonativeproject/base/NavDestination.kt.tt
|
88
|
+
- lib/turbo_native_initializer/templates/android_tabs/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/native/NativeFragment.kt.tt
|
89
|
+
- lib/turbo_native_initializer/templates/android_tabs/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/native/NumbersFragment.kt.tt
|
85
90
|
- lib/turbo_native_initializer/templates/android_tabs/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/web/WebFragment.kt.tt
|
86
91
|
- lib/turbo_native_initializer/templates/android_tabs/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/web/WebHomeFragment.kt.tt
|
87
92
|
- lib/turbo_native_initializer/templates/android_tabs/app/src/main/java/dev/hotwire/turbo/turbonativeproject/features/web/WebModalFragment.kt.tt
|
@@ -106,6 +111,7 @@ files:
|
|
106
111
|
- lib/turbo_native_initializer/templates/android_tabs/base/app/src/main/res/drawable/ic_launcher_foreground.xml
|
107
112
|
- lib/turbo_native_initializer/templates/android_tabs/base/app/src/main/res/drawable/ic_settings.xml
|
108
113
|
- lib/turbo_native_initializer/templates/android_tabs/base/app/src/main/res/layout/activity_main.xml.tt
|
114
|
+
- lib/turbo_native_initializer/templates/android_tabs/base/app/src/main/res/layout/fragment_native.xml
|
109
115
|
- lib/turbo_native_initializer/templates/android_tabs/base/app/src/main/res/layout/fragment_web_home.xml
|
110
116
|
- lib/turbo_native_initializer/templates/android_tabs/base/app/src/main/res/menu/bottom_navigation_menu.xml
|
111
117
|
- lib/turbo_native_initializer/templates/android_tabs/base/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
|
@@ -133,6 +139,7 @@ files:
|
|
133
139
|
- lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Configuration/Info.plist
|
134
140
|
- lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Configuration/path-configuration.json
|
135
141
|
- lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Controllers/ErrorPresenter.swift
|
142
|
+
- lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Controllers/NumbersViewController.swift
|
136
143
|
- lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Controllers/TurboNavigationController.swift
|
137
144
|
- lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Controllers/ViewController.swift
|
138
145
|
- lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Delegates/AppDelegate.swift
|
@@ -153,6 +160,7 @@ files:
|
|
153
160
|
- lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Configuration/Info.plist
|
154
161
|
- lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Configuration/path-configuration.json
|
155
162
|
- lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Controllers/ErrorPresenter.swift
|
163
|
+
- lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Controllers/NumbersViewController.swift
|
156
164
|
- lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Controllers/TurboNavigationController.swift
|
157
165
|
- lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Controllers/ViewController.swift
|
158
166
|
- lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Delegates/AppDelegate.swift
|