Skip to content

Commit

Permalink
Adds a couple extra example projects, improves documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
cjbrooks12 committed Oct 5, 2023
1 parent f816903 commit 2ba9b04
Show file tree
Hide file tree
Showing 83 changed files with 12,244 additions and 127 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,4 @@ build/
.DS_Store

examples/web/src/jsMain/resources/bgg/hot/*
docs/src/orchid/resources/assets/example/distributions/**/*
docs/src/orchid/resources/assets/examples/**/*
2 changes: 2 additions & 0 deletions ballast-debugger-ui/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ kotlin {

val commonMain by getting {
dependencies {
implementation(compose.materialIconsExtended)

// Ktor websocket server
implementation(libs.kotlinx.datetime)
implementation(libs.bundles.ktorEmbeddedServer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,17 @@ object SettingsUi {
Text("All Components - Include SavedStateAdapter")
}

CheckboxArea(
checked = uiState.modifiedSettings.allComponentsIncludesComposeUi,
onCheckedChange = {
postInput(
SettingsUiContract.Inputs.UpdateSettings { copy(allComponentsIncludesComposeUi = it) }
)
},
) {
Text("All Components - Include Compose UI")
}

CheckboxArea(
checked = uiState.modifiedSettings.useDataObjects,
onCheckedChange = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class BallastUi : BaseTemplateCreator<BallastUi.UiTemplate>(
.addTemplate(UiTemplate.InputHandler)
.addTemplate(UiTemplate.EventHandler)
.addTemplate(UiTemplate.SavedStateAdapter)
.addTemplate(UiTemplate.ComposeUi)
.addTemplate(defaultViewModelItem)
.addKind("All components", KotlinIcons.SCRIPT, "Internal_Ui_All")
}
Expand Down Expand Up @@ -71,6 +72,9 @@ class BallastUi : BaseTemplateCreator<BallastUi.UiTemplate>(
if (settings.allComponentsIncludesSavedStateAdapter) {
this += UiTemplate.SavedStateAdapter
}
if (settings.allComponentsIncludesComposeUi) {
this += UiTemplate.ComposeUi
}
}
}
else -> null
Expand All @@ -88,6 +92,7 @@ class BallastUi : BaseTemplateCreator<BallastUi.UiTemplate>(
data object InputHandler : UiTemplate("UiInputHandler", "InputHandler", "InputHandler", KotlinIcons.CLASS)
data object EventHandler : UiTemplate("UiEventHandler", "EventHandler", "EventHandler", KotlinIcons.CLASS)
data object SavedStateAdapter : UiTemplate("UiSavedStateAdapter", "SavedStateAdapter", "SavedStateAdapter", KotlinIcons.CLASS)
data object ComposeUi : UiTemplate("ComposeUi", "ComposeUi", "ComposeUi", KotlinIcons.OBJECT)
class ViewModel(templateName: String) : UiTemplate(templateName, "ViewModel", "ViewModel", KotlinIcons.CLASS)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ interface IntellijPluginMutableSettings : IntellijPluginSettings {
override var baseViewModelType: BallastViewModel.ViewModelTemplate
override var allComponentsIncludesViewModel: Boolean
override var allComponentsIncludesSavedStateAdapter: Boolean
override var allComponentsIncludesComposeUi: Boolean
override var defaultVisibility: BallastViewModel.DefaultVisibility
override var useDataObjects: Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class IntellijPluginPersistentSettings :
override var baseViewModelType: BallastViewModel.ViewModelTemplate by enum(null, defaults.baseViewModelType, BallastViewModel.ViewModelTemplate::valueOf)
override var allComponentsIncludesViewModel: Boolean by boolean(null, defaults.allComponentsIncludesViewModel)
override var allComponentsIncludesSavedStateAdapter: Boolean by boolean(null, defaults.allComponentsIncludesSavedStateAdapter)
override var allComponentsIncludesComposeUi: Boolean by boolean(null, defaults.allComponentsIncludesComposeUi)
override var defaultVisibility: BallastViewModel.DefaultVisibility by enum(null, defaults.defaultVisibility, BallastViewModel.DefaultVisibility::valueOf)
override var useDataObjects: Boolean by boolean(null, defaults.useDataObjects)

Expand All @@ -77,6 +78,7 @@ class IntellijPluginPersistentSettings :
this.baseViewModelType = settings.baseViewModelType
this.allComponentsIncludesViewModel = settings.allComponentsIncludesViewModel
this.allComponentsIncludesSavedStateAdapter = settings.allComponentsIncludesSavedStateAdapter
this.allComponentsIncludesComposeUi = settings.allComponentsIncludesComposeUi
this.defaultVisibility = settings.defaultVisibility
this.useDataObjects = settings.useDataObjects
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ data class IntellijPluginSettingsDefaults(
override val baseViewModelType: BallastViewModel.ViewModelTemplate = BallastViewModel.ViewModelTemplate.Basic,
override val allComponentsIncludesViewModel: Boolean = true,
override val allComponentsIncludesSavedStateAdapter: Boolean = false,
override val allComponentsIncludesComposeUi: Boolean = false,
override val defaultVisibility: BallastViewModel.DefaultVisibility = BallastViewModel.DefaultVisibility.Default,
override val useDataObjects: Boolean = false,
) : IntellijPluginSettings
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ data class IntellijPluginSettingsSnapshot(
override val baseViewModelType: BallastViewModel.ViewModelTemplate,
override val allComponentsIncludesViewModel: Boolean,
override val allComponentsIncludesSavedStateAdapter: Boolean,
override val allComponentsIncludesComposeUi: Boolean,
override val defaultVisibility: BallastViewModel.DefaultVisibility,
override val useDataObjects: Boolean,
) : IntellijPluginSettings {
Expand Down Expand Up @@ -58,6 +59,7 @@ data class IntellijPluginSettingsSnapshot(
baseViewModelType = settings.baseViewModelType,
allComponentsIncludesViewModel = settings.allComponentsIncludesViewModel,
allComponentsIncludesSavedStateAdapter = settings.allComponentsIncludesSavedStateAdapter,
allComponentsIncludesComposeUi = settings.allComponentsIncludesComposeUi,
defaultVisibility = settings.defaultVisibility,
useDataObjects = settings.useDataObjects,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface TemplatesSettings {
val baseViewModelType: BallastViewModel.ViewModelTemplate
val allComponentsIncludesViewModel: Boolean
val allComponentsIncludesSavedStateAdapter: Boolean
val allComponentsIncludesComposeUi: Boolean
val defaultVisibility: BallastViewModel.DefaultVisibility
val useDataObjects: Boolean
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}
#end

import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import com.copperleaf.ballast.BallastViewModelConfiguration
import com.copperleaf.ballast.build
import com.copperleaf.ballast.core.BasicViewModel
import com.copperleaf.ballast.withViewModel

#parse("File Header.java")
${classVisibility}object ${featureName}Ui {

@Composable
${classVisibility}fun Content() {
val viewModelCoroutineScope = rememberCoroutineScope()
val vm: ${featureName}ViewModel = remember(viewModelCoroutineScope) {
BasicViewModel(
coroutineScope = viewModelCoroutineScope,
config = BallastViewModelConfiguration.Builder()
.withViewModel(
initialState = ${featureName}Contract.State(),
inputHandler = ${featureName}InputHandler(),
)
.build(),
eventHandler = ${featureName}EventHandler(),
)
}
val uiState by remember { vm.observeStates() }.collectAsState()

Content(uiState) { vm.trySend(it) }
}

@Composable
${classVisibility}fun Content(
uiState: ${featureName}Contract.State,
postInput: (${featureName}Contract.Inputs) -> Unit,
) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package com.copperleaf.ballast.navigation.routing

import com.copperleaf.ballast.navigation.internal.EnumRoutingTable
import com.copperleaf.ballast.navigation.internal.directionsInternal
import kotlin.enums.EnumEntries
import kotlin.properties.PropertyDelegateProvider

public typealias Backstack<T> = List<Destination<T>>
Expand Down Expand Up @@ -670,3 +671,17 @@ public fun <T> RoutingTable.Companion.fromEnum(
routes = routesSortedByWeight,
)
}


public fun <T> RoutingTable.Companion.fromEnum(
enumValues: EnumEntries<T>,
): RoutingTable<T> where T : Enum<T>, T : Route {
check(enumValues.isNotEmpty()) { "RoutingTable enum values cannot be empty" }

val routesSortedByWeight: List<T> = enumValues
.sortedByDescending { it.matcher.weight }

return EnumRoutingTable(
routes = routesSortedByWeight,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.copperleaf.ballast.navigation.routing.directions
import com.copperleaf.ballast.navigation.routing.isStatic
import com.copperleaf.ballast.plusAssign
import com.copperleaf.ballast.withViewModel
import kotlin.jvm.JvmName

// Configure Router ViewModel
// ---------------------------------------------------------------------------------------------------------------------
Expand All @@ -29,10 +30,59 @@ import com.copperleaf.ballast.withViewModel
* initial route using a [BootstrapInterceptor]. You may wish to keep this value as `null` to load the initial route
* from some other means.
*/
@JvmName("withRouter_initialRoute")
public fun <T : Route> BallastViewModelConfiguration.Builder.withRouter(
routingTable: RoutingTable<T>,
initialRoute: T?,
): RouterBuilder<T> {
return this.withRouter(
routingTable = routingTable,
getInitialRoute = initialRoute?.let {
{
it
}
}
)
}

/**
* Configure a ViewModel to be used as a Router. If [initialRoute] is provided, it will be automatically set as the
* initial route using a [BootstrapInterceptor]. You may wish to keep this value as `null` to load the initial route
* from some other means.
*/
@JvmName("withRouter_getInitialRoute")
public fun <T : Route> BallastViewModelConfiguration.Builder.withRouter(
routingTable: RoutingTable<T>,
getInitialRoute: (() -> T)?,
): RouterBuilder<T> {
return this
.withRouter(
routingTable = routingTable,
getInitialDestinationUrl = getInitialRoute?.let { initialRouteFn ->
{
val initialRoute = initialRouteFn.invoke()
check(initialRoute.isStatic()) {
"For a Route to be used as a Start Destination, it must be fully static. All path segments and " +
"declared query parameters must either be static or optional."
}
initialRoute.directions().build()
}
}
)
}

/**
* Configure a ViewModel to be used as a Router. If [initialRoute] is provided, it will be automatically set as the
* initial route using a [BootstrapInterceptor]. You may wish to keep this value as `null` to load the initial route
* from some other means.
*/
@JvmName("withRouter_getInitialDestinationUrl")
public fun <T : Route> BallastViewModelConfiguration.Builder.withRouter(
routingTable: RoutingTable<T>,
getInitialDestinationUrl: (() -> String)?,
): RouterBuilder<T> {
val initialDestinationUrl = getInitialDestinationUrl?.invoke()

return this
.withViewModel(
initialState = RouterContract.State(routingTable = routingTable),
Expand All @@ -42,14 +92,9 @@ public fun <T : Route> BallastViewModelConfiguration.Builder.withRouter(
.apply {
this.inputStrategy = FifoInputStrategy.typed()

initialRoute?.let { initialRoute ->
check(initialRoute.isStatic()) {
"For a Route to be used as a Start Destination, it must be fully static. All path segments and " +
"declared query parameters must either be static or optional."
}

initialDestinationUrl?.let { initialDestinationUrl ->
this += BootstrapInterceptor {
RouterContract.Inputs.GoToDestination<T>(initialRoute.directions().build())
RouterContract.Inputs.GoToDestination<T>(initialDestinationUrl)
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ plugins {
apiValidation {
ignoredProjects.addAll(
listOf(
// "docs",
"docs",
"android",
"desktop",
"web",
"counter",
"ballast-idea-plugin",
)
)
Expand Down
24 changes: 21 additions & 3 deletions docs/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,27 @@ val orchidBuild by tasks
val orchidDeploy by tasks
val processOrchidResources by tasks

val copyExampleComposeWebSources by tasks.registering(Copy::class) {
from(project.rootDir.resolve("examples/web/build/dist/js/productionExecutable"))
into(project.projectDir.resolve("src/orchid/resources/assets/example/distributions"))
val exampleProjects = listOf(
"web",
"counter",
)

exampleProjects.forEach { exampleProjectName ->
tasks.register("copyExample${exampleProjectName.capitalize()}Sources", Copy::class) {
val sourceDir = project.rootDir.resolve("examples/$exampleProjectName/build/dist/js/productionExecutable")
val destinationDir = project.projectDir.resolve("src/orchid/resources/assets/examples/$exampleProjectName")

onlyIf { sourceDir.exists() }

from(sourceDir)
into(destinationDir)
}
}

val copyExampleComposeWebSources by tasks.registering {
exampleProjects.forEach {exampleProjectName ->
dependsOn("copyExample${exampleProjectName.capitalize()}Sources")
}
}
orchidServe.dependsOn(copyExampleComposeWebSources)
orchidBuild.dependsOn(copyExampleComposeWebSources)
Expand Down
Loading

0 comments on commit 2ba9b04

Please sign in to comment.