mirror of
https://github.com/InsanusMokrassar/KotlinPublicationScriptsBuilder.git
synced 2026-10-25 13:46:58 +00:00
total rework
This commit is contained in:
1 parent
53a76c7a73
commit
8430e68167
69 files changed
+904
-1586
No files matched your search
@@ -5,18 +5,26 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.inmo.kmppscriptbuilder.core.models.Config
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultDivider
|
||||
|
||||
expect object BuilderViewDrawer : Drawer<BuilderView>
|
||||
@Composable
|
||||
expect fun TopAppBar(
|
||||
config: Config,
|
||||
saveAvailable: Boolean,
|
||||
onSaveAvailable: (Boolean) -> Unit,
|
||||
onNewConfig: (Config) -> Unit
|
||||
)
|
||||
|
||||
class BuilderView : View() {
|
||||
internal val projectTypeView = ProjectTypeView()
|
||||
internal val mavenInfoView = MavenInfoView()
|
||||
internal val licensesView = LicensesView()
|
||||
internal val projectTypeView by mutableStateOf(ProjectTypeView())
|
||||
internal val mavenInfoView by mutableStateOf(MavenInfoView())
|
||||
internal val licensesView by mutableStateOf(LicensesView())
|
||||
|
||||
internal var saveAvailableState by mutableStateOf(false)
|
||||
var config: Config
|
||||
get() = Config(licensesView.licenses, mavenInfoView.mavenConfig, projectTypeView.projectType)
|
||||
get() {
|
||||
return Config(licensesView.licenses, mavenInfoView.mavenConfig, projectTypeView.projectType)
|
||||
}
|
||||
set(value) {
|
||||
licensesView.licenses = value.licenses
|
||||
mavenInfoView.mavenConfig = value.mavenConfig
|
||||
@@ -26,6 +34,20 @@ class BuilderView : View() {
|
||||
|
||||
@Composable
|
||||
override fun build() {
|
||||
with(BuilderViewDrawer) { draw() }
|
||||
TopAppBar(
|
||||
config,
|
||||
saveAvailableState,
|
||||
{
|
||||
saveAvailableState = it
|
||||
}
|
||||
) {
|
||||
config = it
|
||||
}
|
||||
|
||||
projectTypeView.build()
|
||||
DefaultDivider()
|
||||
licensesView.build()
|
||||
DefaultDivider()
|
||||
mavenInfoView.build()
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.inmo.kmppscriptbuilder.core.models.Developer
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonTextField
|
||||
|
||||
class DeveloperState(
|
||||
id: String = "",
|
||||
@@ -21,11 +23,32 @@ class DeveloperState(
|
||||
private fun Developer.toDeveloperState() = DeveloperState(id, name, eMail)
|
||||
|
||||
class DevelopersView : ListView<DeveloperState>("Developers info") {
|
||||
var developers = mutableStateListOf<Developer>()
|
||||
var developers: List<Developer>
|
||||
get() = itemsList.map { it.toDeveloper() }
|
||||
set(value) {
|
||||
itemsList.apply {
|
||||
clear()
|
||||
addAll(value.map { it.toDeveloperState() })
|
||||
}
|
||||
}
|
||||
|
||||
override val addItemText: String = "Add developer"
|
||||
override val removeItemText: String = "Remove developer"
|
||||
|
||||
override fun createItem(): DeveloperState = DeveloperState()
|
||||
|
||||
@Composable
|
||||
override fun buildView(item: DeveloperState) {
|
||||
CommonTextField(
|
||||
item.id,
|
||||
"Developer username",
|
||||
) { item.id = it }
|
||||
CommonTextField(
|
||||
item.name,
|
||||
"Developer name",
|
||||
) { item.name = it }
|
||||
CommonTextField(
|
||||
item.eMail,
|
||||
"Developer E-Mail",
|
||||
) { item.eMail = it }
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.inmo.kmppscriptbuilder.core.models.License
|
||||
import dev.inmo.kmppscriptbuilder.core.models.getLicenses
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonTextField
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -38,8 +41,14 @@ class LicensesView: VerticalView("Licenses") {
|
||||
licensesListState.addAll(value.map { it.toLicenseState() })
|
||||
}
|
||||
internal val availableLicensesState = mutableStateListOf<License>()
|
||||
internal val licensesOffersToShow = mutableStateListOf<License>()
|
||||
internal var licenseSearchFilter by mutableStateOf("")
|
||||
internal val searchFieldFocused = mutableStateOf(false)
|
||||
internal val licensesOffersToShow = derivedStateOf {
|
||||
val query = licenseSearchFilter.lowercase()
|
||||
availableLicensesState.filter {
|
||||
it.title.lowercase().contains(query)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
@@ -50,6 +59,16 @@ class LicensesView: VerticalView("Licenses") {
|
||||
}
|
||||
|
||||
override val content: @Composable () -> Unit = {
|
||||
CommonTextField(
|
||||
licenseSearchFilter,
|
||||
"Search filter",
|
||||
onFocusChanged = {
|
||||
searchFieldFocused.value = it
|
||||
}
|
||||
) { filterText ->
|
||||
licenseSearchFilter = filterText
|
||||
}
|
||||
|
||||
with(LicensesDrawer) { draw() }
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ abstract class ListView<T>(title: String) : VerticalView(title) {
|
||||
|
||||
protected val drawer = ListViewDrawer<T>()
|
||||
|
||||
override val content: () -> Unit = {
|
||||
override val content: @Composable () -> Unit = {
|
||||
with(drawer) {
|
||||
draw()
|
||||
}
|
||||
|
||||
@@ -2,9 +2,17 @@ package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import dev.inmo.kmppscriptbuilder.core.models.GpgSigning
|
||||
import dev.inmo.kmppscriptbuilder.core.models.MavenConfig
|
||||
import dev.inmo.kmppscriptbuilder.core.models.SonatypeRepository
|
||||
import dev.inmo.kmppscriptbuilder.core.models.defaultProjectDescription
|
||||
import dev.inmo.kmppscriptbuilder.core.models.defaultProjectName
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.ButtonsPanel
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonTextField
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.SwitchWithLabel
|
||||
|
||||
expect object MavenInfoDrawer : Drawer<MavenInfoView>
|
||||
expect class GpgSigningOptionDrawer : Drawer<GpgSigning>
|
||||
expect fun GpgSigningOptionDrawerWithView(view: MavenInfoView): GpgSigningOptionDrawer
|
||||
|
||||
class MavenInfoView : VerticalView("Project information") {
|
||||
internal var projectNameProperty by mutableStateOf("")
|
||||
@@ -43,10 +51,46 @@ class MavenInfoView : VerticalView("Project information") {
|
||||
publishToMavenCentralProperty = value.repositories.any { it == SonatypeRepository }
|
||||
developersView.developers = value.developers
|
||||
repositoriesView.repositories = value.repositories.filter { it != SonatypeRepository }
|
||||
// developersView.developers = value.developers
|
||||
}
|
||||
|
||||
private val gpgSigningDrawer = GpgSigningOptionDrawerWithView(this)
|
||||
|
||||
override val content: @Composable () -> Unit = {
|
||||
with (MavenInfoDrawer) { draw() }
|
||||
CommonTextField(
|
||||
projectNameProperty,
|
||||
"Public project name",
|
||||
) { projectNameProperty = it }
|
||||
CommonTextField(
|
||||
projectDescriptionProperty,
|
||||
"Public project description",
|
||||
) { projectDescriptionProperty = it }
|
||||
CommonTextField(
|
||||
projectUrlProperty,
|
||||
"Public project URL",
|
||||
) { projectUrlProperty = it }
|
||||
CommonTextField(
|
||||
projectVcsUrlProperty,
|
||||
"Public project VCS URL (with .git)",
|
||||
) { projectVcsUrlProperty = it }
|
||||
|
||||
ButtonsPanel(
|
||||
GpgSigning.Disabled,
|
||||
GpgSigning.Optional,
|
||||
GpgSigning.Enabled
|
||||
) {
|
||||
with(gpgSigningDrawer) {
|
||||
with (it) {
|
||||
draw()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwitchWithLabel(
|
||||
"Include publication to MavenCentral",
|
||||
publishToMavenCentralProperty,
|
||||
placeSwitchAtTheStart = true
|
||||
) { publishToMavenCentralProperty = it }
|
||||
developersView.build()
|
||||
repositoriesView.build()
|
||||
}
|
||||
}
|
||||
@@ -4,16 +4,31 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.inmo.kmppscriptbuilder.core.models.JSProjectType
|
||||
import dev.inmo.kmppscriptbuilder.core.models.JVMProjectType
|
||||
import dev.inmo.kmppscriptbuilder.core.models.MultiplatformProjectType
|
||||
import dev.inmo.kmppscriptbuilder.core.models.ProjectType
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.ButtonsPanel
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
|
||||
expect object ProjectTypeDrawer : Drawer<ProjectTypeView>
|
||||
expect class ProjectTypeDrawer : Drawer<ProjectType>
|
||||
expect fun ProjectTypeDrawerWithView(view: ProjectTypeView): ProjectTypeDrawer
|
||||
|
||||
class ProjectTypeView : VerticalView("Project type") {
|
||||
var projectType by mutableStateOf<ProjectType>(MultiplatformProjectType)
|
||||
private val typeDrawer = ProjectTypeDrawerWithView(this)
|
||||
|
||||
override val content: @Composable () -> Unit = {
|
||||
with(ProjectTypeDrawer) { draw() }
|
||||
ButtonsPanel(
|
||||
MultiplatformProjectType,
|
||||
JVMProjectType,
|
||||
JSProjectType
|
||||
) {
|
||||
with(typeDrawer) {
|
||||
with (it) {
|
||||
draw()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,11 @@ package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonTextField
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
|
||||
class RepositoryState(
|
||||
@@ -19,8 +21,6 @@ class RepositoryState(
|
||||
|
||||
private fun MavenPublishingRepository.toRepositoryState() = RepositoryState(name, url)
|
||||
|
||||
expect object RepositoryStateDrawer : Drawer<RepositoryState>
|
||||
|
||||
class RepositoriesView : ListView<RepositoryState>("Repositories info") {
|
||||
var repositories: List<MavenPublishingRepository>
|
||||
get() = itemsList.map { it.toRepository() }
|
||||
@@ -38,7 +38,14 @@ class RepositoriesView : ListView<RepositoryState>("Repositories info") {
|
||||
|
||||
@Composable
|
||||
override fun buildView(item: RepositoryState) {
|
||||
with(RepositoryStateDrawer) { with(item) { draw() } }
|
||||
CommonTextField(
|
||||
item.name,
|
||||
"Repository name",
|
||||
) { item.name = it }
|
||||
CommonTextField(
|
||||
item.url,
|
||||
"Repository url",
|
||||
) { item.url = it }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package dev.inmo.kmppscriptbuilder.core.ui.utils
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
interface Drawer<T> {
|
||||
fun interface Drawer<T> {
|
||||
@Composable
|
||||
fun T.draw()
|
||||
}
|
||||
@@ -9,7 +9,12 @@ expect fun TitleText(text: String)
|
||||
expect fun CommonText(text: String, onClick: (() -> Unit)? = null)
|
||||
|
||||
@Composable
|
||||
expect fun CommonTextField(presetText: String, hint: String, onChange: (String) -> Unit)
|
||||
expect fun CommonTextField(
|
||||
presetText: String,
|
||||
hint: String,
|
||||
onFocusChanged: (Boolean) -> Unit = {},
|
||||
onChange: (String) -> Unit
|
||||
)
|
||||
|
||||
@Composable
|
||||
expect fun SwitchWithLabel(
|
||||
@@ -19,3 +24,18 @@ expect fun SwitchWithLabel(
|
||||
switchEnabled: Boolean = true,
|
||||
onCheckedChange: (Boolean) -> Unit
|
||||
)
|
||||
|
||||
@Composable
|
||||
expect fun <T> ButtonsPanel(
|
||||
data: Iterable<T>,
|
||||
itemDrawer: @Composable (T) -> Unit
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun <T> ButtonsPanel(
|
||||
vararg data: T,
|
||||
itemDrawer: @Composable (T) -> Unit
|
||||
) = ButtonsPanel(data.toList(), itemDrawer)
|
||||
|
||||
@Composable
|
||||
expect fun DefaultDivider()
|
||||
@@ -5,16 +5,7 @@ import dev.inmo.micro_utils.common.MPPFile
|
||||
|
||||
internal const val appExtension = "kpsb"
|
||||
|
||||
private var lastFile: MPPFile? = null
|
||||
|
||||
fun loadConfigFile(file: MPPFile): Config {
|
||||
lastFile = file
|
||||
return serialFormat.decodeFromString(Config.serializer(), file.text())
|
||||
}
|
||||
|
||||
expect fun MPPFile.text(): String
|
||||
|
||||
expect fun loadConfig(): Config?
|
||||
expect fun openNewConfig(onParsed: (Config) -> Unit)
|
||||
|
||||
expect fun saveConfig(config: Config): Boolean
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path fill="white" d="M14 2H6C4.9 2 4 2.9 4 4V20C4 21.1 4.9 22 6 22H18C19.1 22 20 21.1 20 20V8L14 2M18 20H6V4H13V9H18V20M16 11V18.1L13.9 16L11.1 18.8L8.3 16L11.1 13.2L8.9 11H16Z" /></svg>
|
||||
|
After Width: | Height: | Size: 463 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path fill="white" d="M6.1,10L4,18V8H21A2,2 0 0,0 19,6H12L10,4H4A2,2 0 0,0 2,6V18A2,2 0 0,0 4,20H19C19.9,20 20.7,19.4 20.9,18.5L23.2,10H6.1M19,18H6L7.6,12H20.6L19,18Z" /></svg>
|
||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path fill="white" d="M4 19H10V21H4C2.89 21 2 20.1 2 19V5C2 3.9 2.89 3 4 3H16L20 7V9.12L18 11.12V7.83L15.17 5H4V19M14 10V6H5V10H14M20.42 12.3C20.31 12.19 20.18 12.13 20.04 12.13C19.9 12.13 19.76 12.19 19.65 12.3L18.65 13.3L20.7 15.35L21.7 14.35C21.92 14.14 21.92 13.79 21.7 13.58L20.42 12.3M12 19.94V22H14.06L20.12 15.93L18.07 13.88L12 19.94M14 15C14 13.34 12.66 12 11 12S8 13.34 8 15 9.34 18 11 18C11.04 18 11.08 18 11.13 18L14 15.13C14 15.09 14 15.05 14 15" /></svg>
|
||||
|
After Width: | Height: | Size: 744 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path fill="white" d="M17 3H5C3.89 3 3 3.9 3 5V19C3 20.1 3.89 21 5 21H19C20.1 21 21 20.1 21 19V7L17 3M19 19H5V5H16.17L19 7.83V19M12 12C10.34 12 9 13.34 9 15S10.34 18 12 18 15 16.66 15 15 13.66 12 12 12M6 6H15V10H6V6Z" /></svg>
|
||||
|
After Width: | Height: | Size: 502 B |
@@ -0,0 +1,14 @@
|
||||
package dev.inmo.kmppscriptbuilder.core
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.BuilderView
|
||||
import kotlinx.browser.window
|
||||
import org.jetbrains.compose.web.renderComposableInBody
|
||||
|
||||
fun main() {
|
||||
window.addEventListener("load", {
|
||||
val builder = BuilderView()
|
||||
renderComposableInBody {
|
||||
builder.build()
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.inmo.jsuikit.elements.DefaultButton
|
||||
import dev.inmo.jsuikit.modifiers.UIKitButton
|
||||
import dev.inmo.jsuikit.modifiers.UIKitMargin
|
||||
import dev.inmo.kmppscriptbuilder.core.models.GpgSigning
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
|
||||
actual class GpgSigningOptionDrawer(
|
||||
private val mavenInfoView: MavenInfoView
|
||||
) : Drawer<GpgSigning> {
|
||||
@Composable
|
||||
override fun GpgSigning.draw() {
|
||||
if (mavenInfoView.gpgSignProperty == this) {
|
||||
DefaultButton(name, UIKitButton.Type.Primary)
|
||||
} else {
|
||||
DefaultButton(name, UIKitButton.Type.Default) {
|
||||
mavenInfoView.gpgSignProperty = this
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actual fun GpgSigningOptionDrawerWithView(view: MavenInfoView): GpgSigningOptionDrawer = GpgSigningOptionDrawer(mavenInfoView = view)
|
||||
@@ -0,0 +1,59 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.inmo.jsuikit.elements.DefaultButton
|
||||
import dev.inmo.jsuikit.elements.Divider
|
||||
import dev.inmo.jsuikit.modifiers.UIKitButton
|
||||
import dev.inmo.jsuikit.modifiers.UIKitMargin
|
||||
import dev.inmo.jsuikit.modifiers.builder
|
||||
import dev.inmo.jsuikit.utils.Attrs
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonTextField
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
import org.jetbrains.compose.web.dom.Div
|
||||
|
||||
actual object LicensesDrawer : Drawer<LicensesView> {
|
||||
@Composable
|
||||
override fun LicensesView.draw() {
|
||||
dev.inmo.jsuikit.elements.List(
|
||||
licensesOffersToShow.value,
|
||||
Attrs {
|
||||
if (!searchFieldFocused.value) {
|
||||
hidden()
|
||||
}
|
||||
}
|
||||
) {
|
||||
DefaultButton(
|
||||
it.title,
|
||||
UIKitButton.Type.Text
|
||||
) { _ ->
|
||||
licensesListState.add(it.toLicenseState())
|
||||
licenseSearchFilter = ""
|
||||
}
|
||||
Divider.Common()
|
||||
}
|
||||
|
||||
DefaultButton("Add empty license", UIKitButton.Type.Primary, UIKitMargin.Small) {
|
||||
licensesListState.add(LicenseState())
|
||||
}
|
||||
|
||||
licensesListState.forEach { license ->
|
||||
Div(UIKitMargin.Small.builder()) {
|
||||
CommonTextField(
|
||||
license.id,
|
||||
"License ID",
|
||||
) { license.id = it }
|
||||
CommonTextField(
|
||||
license.title,
|
||||
"License title",
|
||||
) { license.title = it }
|
||||
CommonTextField(
|
||||
license.url ?: "",
|
||||
"License URL",
|
||||
) { license.url = it }
|
||||
DefaultButton("Remove", UIKitButton.Type.Danger, UIKitMargin.Small) {
|
||||
licensesListState.remove(license)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.inmo.jsuikit.elements.DefaultButton
|
||||
import dev.inmo.jsuikit.modifiers.UIKitButton
|
||||
import dev.inmo.jsuikit.modifiers.UIKitMargin
|
||||
import dev.inmo.jsuikit.modifiers.builder
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
import org.jetbrains.compose.web.dom.Div
|
||||
|
||||
actual class ListViewDrawer<T> : Drawer<ListView<T>> {
|
||||
@Composable
|
||||
override fun ListView<T>.draw() {
|
||||
DefaultButton(addItemText, UIKitButton.Type.Primary ) { itemsList.add(createItem()) }
|
||||
itemsList.forEach { item ->
|
||||
Div(UIKitMargin.Small.builder()) {
|
||||
buildView(item)
|
||||
DefaultButton(removeItemText, UIKitButton.Type.Danger, UIKitMargin.Small) {
|
||||
itemsList.remove(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.inmo.jsuikit.elements.DefaultButton
|
||||
import dev.inmo.jsuikit.modifiers.UIKitButton
|
||||
import dev.inmo.jsuikit.modifiers.UIKitMargin
|
||||
import dev.inmo.kmppscriptbuilder.core.models.ProjectType
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
|
||||
actual class ProjectTypeDrawer(
|
||||
private val projectTypeView: ProjectTypeView
|
||||
) : Drawer<ProjectType> {
|
||||
@Composable
|
||||
override fun ProjectType.draw() {
|
||||
if (projectTypeView.projectType == this) {
|
||||
DefaultButton(name, UIKitButton.Type.Primary)
|
||||
} else {
|
||||
DefaultButton(name, UIKitButton.Type.Default) {
|
||||
projectTypeView.projectType = this
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actual fun ProjectTypeDrawerWithView(view: ProjectTypeView): ProjectTypeDrawer = ProjectTypeDrawer(projectTypeView = view)
|
||||
@@ -0,0 +1,82 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.inmo.jsuikit.elements.Icon
|
||||
import dev.inmo.jsuikit.elements.NavItemElement
|
||||
import dev.inmo.jsuikit.elements.Navbar
|
||||
import dev.inmo.jsuikit.elements.NavbarNav
|
||||
import dev.inmo.jsuikit.elements.drawAsLink
|
||||
import dev.inmo.jsuikit.modifiers.UIKitMargin
|
||||
import dev.inmo.jsuikit.modifiers.UIKitPadding
|
||||
import dev.inmo.jsuikit.modifiers.UIKitText
|
||||
import dev.inmo.jsuikit.modifiers.UIKitTooltipModifier
|
||||
import dev.inmo.jsuikit.modifiers.builder
|
||||
import dev.inmo.jsuikit.modifiers.include
|
||||
import dev.inmo.jsuikit.utils.AttrsWithContentBuilder
|
||||
import dev.inmo.kmppscriptbuilder.core.models.Config
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.exportGradle
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.openNewConfig
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.saveConfig
|
||||
import org.jetbrains.compose.web.dom.A
|
||||
import org.jetbrains.compose.web.dom.Div
|
||||
import org.jetbrains.compose.web.dom.Img
|
||||
import org.jetbrains.compose.web.dom.Text
|
||||
|
||||
@Composable
|
||||
actual fun TopAppBar(
|
||||
config: Config,
|
||||
saveAvailable: Boolean,
|
||||
onSaveAvailable: (Boolean) -> Unit,
|
||||
onNewConfig: (Config) -> Unit
|
||||
) {
|
||||
Navbar(
|
||||
leftBuilder = AttrsWithContentBuilder {
|
||||
Div(
|
||||
{
|
||||
onClick {
|
||||
console.log(config)
|
||||
}
|
||||
include(UIKitPadding.Size.Small, UIKitText.Style.Lead)
|
||||
}
|
||||
) {
|
||||
Text("Kotlin publication scripts builder")
|
||||
}
|
||||
Div(UIKitMargin.Small.builder()) {
|
||||
A("https://github.com/InsanusMokrassar/KotlinPublicationScriptsBuilder") {
|
||||
Img("https://img.shields.io/github/stars/InsanusMokrassar/KotlinPublicationScriptsBuilder?label=Github&style=plastic")
|
||||
}
|
||||
}
|
||||
},
|
||||
rightBuilder = AttrsWithContentBuilder {
|
||||
NavbarNav(
|
||||
AttrsWithContentBuilder {
|
||||
NavItemElement(
|
||||
UIKitTooltipModifier("Open file")
|
||||
) {
|
||||
Icon.Storage.Pull.drawAsLink {
|
||||
openNewConfig(onNewConfig)
|
||||
}
|
||||
}
|
||||
},
|
||||
AttrsWithContentBuilder {
|
||||
NavItemElement(
|
||||
UIKitTooltipModifier("Save config")
|
||||
) {
|
||||
Icon.Storage.Push.drawAsLink {
|
||||
saveConfig(config)
|
||||
}
|
||||
}
|
||||
},
|
||||
AttrsWithContentBuilder {
|
||||
NavItemElement(
|
||||
UIKitTooltipModifier("Export gradle script")
|
||||
) {
|
||||
Icon.Storage.Upload.drawAsLink {
|
||||
exportGradle(config)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.inmo.jsuikit.modifiers.UIKitForm
|
||||
import dev.inmo.jsuikit.modifiers.builder
|
||||
import org.jetbrains.compose.web.dom.Legend
|
||||
import org.jetbrains.compose.web.dom.Text
|
||||
|
||||
actual abstract class View {
|
||||
@Composable
|
||||
@@ -9,4 +13,8 @@ actual abstract class View {
|
||||
|
||||
@Composable
|
||||
actual fun View.DrawVertically(title: String, block: @Composable () -> Unit) {
|
||||
Legend(UIKitForm.Legend.builder()) {
|
||||
Text(title)
|
||||
}
|
||||
block()
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui.utils
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.inmo.jsuikit.elements.DefaultButton
|
||||
import dev.inmo.jsuikit.elements.DefaultInput
|
||||
import dev.inmo.jsuikit.elements.Divider
|
||||
import dev.inmo.jsuikit.elements.Flex
|
||||
import dev.inmo.jsuikit.elements.Icon
|
||||
import dev.inmo.jsuikit.elements.Label
|
||||
import dev.inmo.jsuikit.elements.drawAsFormInputPart
|
||||
import dev.inmo.jsuikit.modifiers.UIKitButton
|
||||
import dev.inmo.jsuikit.modifiers.UIKitFlex
|
||||
import dev.inmo.jsuikit.modifiers.UIKitForm
|
||||
import dev.inmo.jsuikit.modifiers.UIKitInverse
|
||||
import dev.inmo.jsuikit.modifiers.UIKitMargin
|
||||
import dev.inmo.jsuikit.modifiers.UIKitText
|
||||
import dev.inmo.jsuikit.modifiers.UIKitUtility
|
||||
import dev.inmo.jsuikit.modifiers.builder
|
||||
import dev.inmo.jsuikit.modifiers.include
|
||||
import dev.inmo.jsuikit.utils.Attrs
|
||||
import org.jetbrains.compose.web.attributes.InputType
|
||||
import org.jetbrains.compose.web.dom.Div
|
||||
import org.jetbrains.compose.web.dom.Legend
|
||||
import org.jetbrains.compose.web.dom.Text
|
||||
|
||||
@Composable
|
||||
actual fun TitleText(text: String) {
|
||||
Legend(UIKitForm.Legend.builder()) {
|
||||
Text(text)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
actual fun CommonText(text: String, onClick: (() -> Unit)?) {
|
||||
Div(
|
||||
{
|
||||
onClick ?.let {
|
||||
this.onClick { _ ->
|
||||
it()
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text(text)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
actual fun CommonTextField(
|
||||
presetText: String,
|
||||
hint: String,
|
||||
onFocusChanged: (Boolean) -> Unit,
|
||||
onChange: (String) -> Unit
|
||||
) {
|
||||
DefaultInput(
|
||||
InputType.Text,
|
||||
presetText,
|
||||
false,
|
||||
placeholder = hint,
|
||||
attributesCustomizer = {
|
||||
onFocusIn { onFocusChanged(true) }
|
||||
onFocusOut { onFocusChanged(false) }
|
||||
},
|
||||
onChange = onChange
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
actual fun SwitchWithLabel(
|
||||
label: String,
|
||||
checked: Boolean,
|
||||
placeSwitchAtTheStart: Boolean,
|
||||
switchEnabled: Boolean,
|
||||
onCheckedChange: (Boolean) -> Unit
|
||||
) {
|
||||
DefaultButton(
|
||||
if (checked) {
|
||||
UIKitButton.Type.Primary
|
||||
} else {
|
||||
UIKitButton.Type.Default
|
||||
},
|
||||
disabled = !switchEnabled,
|
||||
onClick = {
|
||||
onCheckedChange(!checked)
|
||||
},
|
||||
attributesCustomizer = {
|
||||
include(UIKitUtility.Inline)
|
||||
}
|
||||
) {
|
||||
if (checked) {
|
||||
Icon.App.Check.drawAsFormInputPart(UIKitInverse.Light)
|
||||
}
|
||||
Text(label)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
actual fun <T> ButtonsPanel(data: Iterable<T>, itemDrawer: @Composable (T) -> Unit) {
|
||||
Flex(UIKitFlex.Alignment.Vertical.Middle, UIKitMargin.Small) {
|
||||
data.forEach { itemDrawer(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
actual fun DefaultDivider() {
|
||||
Divider.Common()
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.utils
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.models.Config
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.dom.appendElement
|
||||
import org.w3c.dom.HTMLAnchorElement
|
||||
import org.w3c.dom.HTMLInputElement
|
||||
import org.w3c.dom.url.URL
|
||||
import org.w3c.files.Blob
|
||||
import org.w3c.files.BlobPropertyBag
|
||||
import org.w3c.files.FileReader
|
||||
import org.w3c.files.get
|
||||
|
||||
fun saveFile(content: String, filename: String) {
|
||||
val a = document.body!!.appendElement("a") {
|
||||
setAttribute("style", "visibility:hidden; display: none")
|
||||
} as HTMLAnchorElement
|
||||
val blob = Blob(arrayOf(content), BlobPropertyBag(
|
||||
"application/*;charset=utf-8"
|
||||
))
|
||||
val url = URL.createObjectURL(blob)
|
||||
a.href = url
|
||||
a.download = filename
|
||||
a.click()
|
||||
URL.revokeObjectURL(url)
|
||||
a.remove()
|
||||
}
|
||||
|
||||
actual fun openNewConfig(onParsed: (Config) -> Unit) {
|
||||
val targetInput = document.body!!.appendElement("input") {
|
||||
setAttribute("style", "visibility:hidden; display: none")
|
||||
} as HTMLInputElement
|
||||
targetInput.type = "file"
|
||||
targetInput.onchange = {
|
||||
targetInput.files ?.also { files ->
|
||||
for (i in (0 until files.length) ) {
|
||||
files[i] ?.also { file ->
|
||||
val reader = FileReader()
|
||||
|
||||
reader.onload = {
|
||||
val content = it.target.asDynamic().result as String
|
||||
onParsed(serialFormat.decodeFromString(Config.serializer(), content))
|
||||
false
|
||||
}
|
||||
|
||||
reader.readAsText(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetInput.click()
|
||||
targetInput.remove()
|
||||
}
|
||||
|
||||
actual fun saveConfig(config: Config): Boolean {
|
||||
saveFile(
|
||||
serialFormat.encodeToString(Config.serializer(), config),
|
||||
"publish.kpsb"
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
actual fun exportGradle(config: Config): Boolean {
|
||||
val filename = "publish.gradle"
|
||||
|
||||
val content = config.run {
|
||||
type.buildMavenGradleConfig(
|
||||
mavenConfig,
|
||||
licenses
|
||||
)
|
||||
}
|
||||
|
||||
saveFile(content, filename)
|
||||
return true
|
||||
}
|
||||
|
||||
actual fun saveAs(config: Config): Boolean {
|
||||
saveFile(
|
||||
serialFormat.encodeToString(Config.serializer(), config),
|
||||
"publish.kpsb"
|
||||
)
|
||||
return true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.utils
|
||||
|
||||
actual fun openLink(link: String): Boolean {
|
||||
dev.inmo.micro_utils.common.openLink(link)
|
||||
return true
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
/*! UIkit 3.15.12 | https://www.getuikit.com | (c) 2014 - 2022 YOOtheme | MIT License */html{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:16px;font-weight:400;line-height:1.5;-webkit-text-size-adjust:100%;background:#fff;color:#666}body{margin:0}.uk-link,a{color:#1e87f0;text-decoration:none;cursor:pointer}.uk-link-toggle:hover .uk-link,.uk-link:hover,a:hover{color:#0f6ecd;text-decoration:underline}abbr[title]{text-decoration:underline dotted;-webkit-text-decoration-style:dotted}b,strong{font-weight:bolder}:not(pre)>code,:not(pre)>kbd,:not(pre)>samp{font-family:Consolas,monaco,monospace;font-size:.875rem;color:#f0506e;white-space:nowrap;padding:2px 6px;background:#f8f8f8}em{color:#f0506e}ins{background:#ffd;color:#666;text-decoration:none}mark{background:#ffd;color:#666}q{font-style:italic}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}audio,canvas,iframe,img,svg,video{vertical-align:middle}canvas,img,svg,video{max-width:100%;height:auto;box-sizing:border-box}img:not([src]){visibility:hidden;min-width:1px}iframe{border:0}address,dl,fieldset,figure,ol,p,pre,ul{margin:0 0 20px 0}*+address,*+dl,*+fieldset,*+figure,*+ol,*+p,*+pre,*+ul{margin-top:20px}.uk-h1,.uk-h2,.uk-h3,.uk-h4,.uk-h5,.uk-h6,.uk-heading-2xlarge,.uk-heading-large,.uk-heading-medium,.uk-heading-small,.uk-heading-xlarge,h1,h2,h3,h4,h5,h6{margin:0 0 20px 0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-weight:400;color:#333;text-transform:none}*+.uk-h1,*+.uk-h2,*+.uk-h3,*+.uk-h4,*+.uk-h5,*+.uk-h6,*+.uk-heading-2xlarge,*+.uk-heading-large,*+.uk-heading-medium,*+.uk-heading-small,*+.uk-heading-xlarge,*+h1,*+h2,*+h3,*+h4,*+h5,*+h6{margin-top:40px}.uk-h1,h1{font-size:2.23125rem;line-height:1.2}.uk-h2,h2{font-size:1.7rem;line-height:1.3}.uk-h3,h3{font-size:1.5rem;line-height:1.4}.uk-h4,h4{font-size:1.25rem;line-height:1.4}.uk-h5,h5{font-size:16px;line-height:1.4}.uk-h6,h6{font-size:.875rem;line-height:1.4}@media (min-width:960px){.uk-h1,h1{font-size:2.625rem}.uk-h2,h2{font-size:2rem}}ol,ul{padding-left:30px}ol>li>ol,ol>li>ul,ul>li>ol,ul>li>ul{margin:0}dt{font-weight:700}dd{margin-left:0}.uk-hr,hr{overflow:visible;text-align:inherit;margin:0 0 20px 0;border:0;border-top:1px solid #e5e5e5}*+.uk-hr,*+hr{margin-top:20px}address{font-style:normal}blockquote{margin:0 0 20px 0;font-size:1.25rem;line-height:1.5;font-style:italic;color:#333}*+blockquote{margin-top:20px}blockquote p:last-of-type{margin-bottom:0}blockquote footer{margin-top:10px;font-size:.875rem;line-height:1.5;color:#666}blockquote footer::before{content:"— "}pre{font:0.875rem/1.5 Consolas,monaco,monospace;color:#666;-moz-tab-size:4;tab-size:4;overflow:auto;padding:10px;border:1px solid #e5e5e5;border-radius:3px;background:#fff}pre code{font-family:Consolas,monaco,monospace}:focus{outline:0}:focus-visible{outline:2px dotted #333}::selection{background:#39f;color:#fff;text-shadow:none}details,main{display:block}summary{display:list-item}template{display:none}:root{--uk-breakpoint-s:640px;--uk-breakpoint-m:960px;--uk-breakpoint-l:1200px;--uk-breakpoint-xl:1600px}.uk-link-muted a,.uk-link-toggle .uk-link-muted,a.uk-link-muted{color:#999}.uk-link-muted a:hover,.uk-link-toggle:hover .uk-link-muted,a.uk-link-muted:hover{color:#666}.uk-link-text a,.uk-link-toggle .uk-link-text,a.uk-link-text{color:inherit}.uk-link-text a:hover,.uk-link-toggle:hover .uk-link-text,a.uk-link-text:hover{color:#999}.uk-link-heading a,.uk-link-toggle .uk-link-heading,a.uk-link-heading{color:inherit}.uk-link-heading a:hover,.uk-link-toggle:hover .uk-link-heading,a.uk-link-heading:hover{color:#1e87f0;text-decoration:none}.uk-link-reset a,a.uk-link-reset{color:inherit!important;text-decoration:none!important}.uk-link-toggle{color:inherit!important;text-decoration:none!important}.uk-heading-small{font-size:2.6rem;line-height:1.2}.uk-heading-medium{font-size:2.8875rem;line-height:1.1}.uk-heading-large{font-size:3.4rem;line-height:1.1}.uk-heading-xlarge{font-size:4rem;line-height:1}.uk-heading-2xlarge{font-size:6rem;line-height:1}@media (min-width:960px){.uk-heading-small{font-size:3.25rem}.uk-heading-medium{font-size:3.5rem}.uk-heading-large{font-size:4rem}.uk-heading-xlarge{font-size:6rem}.uk-heading-2xlarge{font-size:8rem}}@media (min-width:1200px){.uk-heading-medium{font-size:4rem}.uk-heading-large{font-size:6rem}.uk-heading-xlarge{font-size:8rem}.uk-heading-2xlarge{font-size:11rem}}.uk-heading-divider{padding-bottom:calc(5px + .1em);border-bottom:calc(.2px + .05em) solid #e5e5e5}.uk-heading-bullet{position:relative}.uk-heading-bullet::before{content:"";display:inline-block;position:relative;top:calc(-.1 * 1em);vertical-align:middle;height:calc(4px + .7em);marLine truncated
|
||||
@@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Kotlin Publication Scripts Builder</title>
|
||||
<!-- UIkit CSS -->
|
||||
<link rel="stylesheet" href="./css/uikit.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<!-- <form class="uk-padding-small">-->
|
||||
<!-- <fieldset class="uk-fieldset">-->
|
||||
<!-- <legend class="uk-legend">Project type</legend>-->
|
||||
<!-- <div class="uk-padding-small">-->
|
||||
<!-- <ul class="uk-subnav uk-subnav-pill">-->
|
||||
<!-- <li id="mppProjectType" class="uk-active"><a href="#">Multiplatform</a></li>-->
|
||||
<!-- <li id="jvmProjectType"><a href="#">JVM</a></li>-->
|
||||
<!-- <li id="jsProjectType"><a href="#">JS</a></li>-->
|
||||
<!-- </ul>-->
|
||||
<!-- </div>-->
|
||||
<!-- <legend class="uk-legend">Licenses</legend>-->
|
||||
<!-- <div id="licensesListDiv" class="uk-padding-small"></div>-->
|
||||
|
||||
<!-- <legend class="uk-legend">Project information</legend>-->
|
||||
|
||||
<!-- <div class="uk-padding-small">-->
|
||||
<!-- <div class="uk-margin uk-width-1-1">-->
|
||||
<!-- <label class="uk-form-label" for="projectNameInput">Public project name</label>-->
|
||||
<!-- <input id="projectNameInput" class="uk-input uk-width-expand" type="text" placeholder="${project.name}">-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="uk-margin uk-width-1-1">-->
|
||||
<!-- <label class="uk-form-label" for="projectDescriptionInput">Public project description</label>-->
|
||||
<!-- <input id="projectDescriptionInput" class="uk-input uk-width-expand" type="text" placeholder="${project.name}">-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="uk-margin uk-width-1-1">-->
|
||||
<!-- <label class="uk-form-label" for="projectUrlInput">Public project URL</label>-->
|
||||
<!-- <input id="projectUrlInput" class="uk-input uk-width-expand" type="text" placeholder="Type url to github or other source with readme">-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="uk-margin uk-width-1-1">-->
|
||||
<!-- <label class="uk-form-label" for="projectVCSUrlInput">Public project VCS URL (with .git)</label>-->
|
||||
<!-- <input id="projectVCSUrlInput" class="uk-input uk-width-expand" type="text" placeholder="Type url to github .git file">-->
|
||||
<!-- </div>-->
|
||||
|
||||
<!-- <div class="uk-margin">-->
|
||||
<!-- <label>GPG Signing</label>-->
|
||||
|
||||
<!-- <div class="uk-padding-small">-->
|
||||
<!-- <ul class="uk-subnav uk-subnav-pill">-->
|
||||
<!-- <li id="disableGpgSigning" class="uk-active" uk-tooltip="title: Signing will not be added"><a href="#">Disabled</a></li>-->
|
||||
<!-- <li id="optionalGpgSigning" uk-tooltip="title: Signing will be added, but disabled in case of absence 'signatory.keyId'"><a href="#">Optional</a></li>-->
|
||||
<!-- <li id="enableGpgSigning" uk-tooltip="title: Signing will be always enabled"><a href="#">Enabled</a></li>-->
|
||||
<!-- </ul>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="uk-margin">-->
|
||||
<!-- <label><input id="includeMavenCentralTargetRepoToggle" class="uk-checkbox" type="checkbox"> Include publication to MavenCentral</label>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<!-- <legend class="uk-legend">Developers info</legend>-->
|
||||
<!-- <div id="developersListDiv" class="uk-padding-small"></div>-->
|
||||
|
||||
<!-- <legend class="uk-legend">Repositories info</legend>-->
|
||||
<!-- <div id="repositoriesListDiv" class="uk-padding-small"></div>-->
|
||||
<!-- </fieldset>-->
|
||||
<!-- </form>-->
|
||||
<!-- UIkit JS -->
|
||||
<script src="./js/uikit.min.js"></script>
|
||||
<script src="./js/uikit-icons.min.js"></script>
|
||||
<!-- Internal JS -->
|
||||
<script src="kmppscriptbuilder.core.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
/*! UIkit 3.15.12 | https://www.getuikit.com | (c) 2014 - 2022 YOOtheme | MIT License */(function(t,i){typeof exports=="object"&&typeof module<"u"?module.exports=i():typeof define=="function"&&define.amd?define("uikiticons",i):(t=typeof globalThis<"u"?globalThis:t||self,t.UIkitIcons=i())})(this,function(){"use strict";function t(i){t.installed||i.icon.add({"500px":'<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M9.624,11.866c-0.141,0.132,0.479,0.658,0.662,0.418c0.051-0.046,0.607-0.61,0.662-0.664c0,0,0.738,0.719,0.814,0.719 c0.1,0,0.207-0.055,0.322-0.17c0.27-0.269,0.135-0.416,0.066-0.495l-0.631-0.616l0.658-0.668c0.146-0.156,0.021-0.314-0.1-0.449 c-0.182-0.18-0.359-0.226-0.471-0.125l-0.656,0.654l-0.654-0.654c-0.033-0.034-0.08-0.045-0.124-0.045 c-0.079,0-0.191,0.068-0.307,0.181c-0.202,0.202-0.247,0.351-0.133,0.462l0.665,0.665L9.624,11.866z"/><path d="M11.066,2.884c-1.061,0-2.185,0.248-3.011,0.604c-0.087,0.034-0.141,0.106-0.15,0.205C7.893,3.784,7.919,3.909,7.982,4.066 c0.05,0.136,0.187,0.474,0.452,0.372c0.844-0.326,1.779-0.507,2.633-0.507c0.963,0,1.9,0.191,2.781,0.564 c0.695,0.292,1.357,0.719,2.078,1.34c0.051,0.044,0.105,0.068,0.164,0.068c0.143,0,0.273-0.137,0.389-0.271 c0.191-0.214,0.324-0.395,0.135-0.575c-0.686-0.654-1.436-1.138-2.363-1.533C13.24,3.097,12.168,2.884,11.066,2.884z"/><path d="M16.43,15.747c-0.092-0.028-0.242,0.05-0.309,0.119l0,0c-0.652,0.652-1.42,1.169-2.268,1.521 c-0.877,0.371-1.814,0.551-2.779,0.551c-0.961,0-1.896-0.189-2.775-0.564c-0.848-0.36-1.612-0.879-2.268-1.53 c-0.682-0.688-1.196-1.455-1.529-2.268c-0.325-0.799-0.471-1.643-0.471-1.643c-0.045-0.24-0.258-0.249-0.567-0.203 c-0.128,0.021-0.519,0.079-0.483,0.36v0.01c0.105,0.644,0.289,1.284,0.545,1.895c0.417,0.969,1.002,1.849,1.756,2.604 c0.757,0.754,1.636,1.34,2.604,1.757C8.901,18.785,9.97,19,11.088,19c1.104,0,2.186-0.215,3.188-0.645 c1.838-0.896,2.604-1.757,2.604-1.757c0.182-0.204,0.227-0.317-0.1-0.643C16.779,15.956,16.525,15.774,16.43,15.747z"/><path d="M5.633,13.287c0.293,0.71,0.723,1.341,1.262,1.882c0.54,0.54,1.172,0.971,1.882,1.264c0.731,0.303,1.509,0.461,2.298,0.461 c0.801,0,1.578-0.158,2.297-0.461c0.711-0.293,1.344-0.724,1.883-1.264c0.543-0.541,0.971-1.172,1.264-1.882 c0.314-0.721,0.463-1.5,0.463-2.298c0-0.79-0.148-1.569-0.463-2.289c-0.293-0.699-0.721-1.329-1.264-1.881 c-0.539-0.541-1.172-0.959-1.867-1.263c-0.721-0.303-1.5-0.461-2.299-0.461c-0.802,0-1.613,0.159-2.322,0.461 c-0.577,0.25-1.544,0.867-2.119,1.454v0.012V2.108h8.16C15.1,2.104,15.1,1.69,15.1,1.552C15.1,1.417,15.1,1,14.809,1H5.915 C5.676,1,5.527,1.192,5.527,1.384v6.84c0,0.214,0.273,0.372,0.529,0.428c0.5,0.105,0.614-0.056,0.737-0.224l0,0 c0.18-0.273,0.776-0.884,0.787-0.894c0.901-0.905,2.117-1.408,3.416-1.408c1.285,0,2.5,0.501,3.412,1.408 c0.914,0.914,1.408,2.122,1.408,3.405c0,1.288-0.508,2.496-1.408,3.405c-0.9,0.896-2.152,1.406-3.438,1.406 c-0.877,0-1.711-0.229-2.433-0.671v-4.158c0-0.553,0.237-1.151,0.643-1.614c0.462-0.519,1.094-0.799,1.782-0.799 c0.664,0,1.293,0.253,1.758,0.715c0.459,0.459,0.709,1.071,0.709,1.723c0,1.385-1.094,2.468-2.488,2.468 c-0.273,0-0.769-0.121-0.781-0.125c-0.281-0.087-0.405,0.306-0.438,0.436c-0.159,0.496,0.079,0.585,0.123,0.607 c0.452,0.137,0.743,0.157,1.129,0.157c1.973,0,3.572-1.6,3.572-3.57c0-1.964-1.6-3.552-3.572-3.552c-0.97,0-1.872,0.36-2.546,1.038 c-0.656,0.631-1.027,1.487-1.027,2.322v3.438v-0.011c-0.372-0.42-0.732-1.041-0.981-1.682c-0.102-0.248-0.315-0.202-0.607-0.113 c-0.135,0.035-0.519,0.157-0.44,0.439C5.372,12.799,5.577,13.164,5.633,13.287z"/></svg>',album:'<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><rect x="5" y="2" width="10" height="1"/><rect x="3" y="4" width="14" height="1"/><rect fill="none" stroke="#000" x="1.5" y="6.5" width="17" height="11"/></svg>',"arrow-down":'<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><polygon points="10.5,16.08 5.63,10.66 6.37,10 10.5,14.58 14.63,10 15.37,10.66"/><line fill="none" stroke="#000" x1="10.5" y1="4" x2="10.5" y2="15"/></svg>',"arrow-left":'<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><polyline fill="none" stroke="#000" points="10 14 5 9.5 10 5"/><line fill="none" stroke="#000" x1="16" y1="9.5" x2="5" y2="9.52"/></svg>',"arrow-right":'<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><polyline fill="none" stroke="#000" points="10 5 15 9.5 10 14"/><line fill="none" stroke="#000" x1="4" y1="9.5" x2="15" y2="9.5"/></svg>',"arrow-up":'<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><polygon points="10.5,4 15.37,9.4 14.63,10.08 10.5,5.49 6.37,10.08 5.63,9.4"/><line fill="none" stroke="#000" x1="10.5" y1="16" x2="10.5" y2="5"/></svg>',bag:'<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill="none" stroke="#000" d="M7.5,7.5V4A2.48,2.48,0,0,1,10,1.5,2.54,2.54,0,0,1,12.5,4V7.5"/><polygon fill="none" stroke="#000" points="16.5 7.5 3.5 7.5 2.5 18.Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
/*! UIkit 3.15.12 | https://www.getuikit.com | (c) 2014 - 2022 YOOtheme | MIT License */(function(ue,de){typeof exports=="object"&&typeof module<"u"?module.exports=de():typeof define=="function"&&define.amd?define("uikit",de):(ue=typeof globalThis<"u"?globalThis:ue||self,ue.UIkit=de())})(this,function(){"use strict";const{hasOwnProperty:ue,toString:de}=Object.prototype;function Bt(t,e){return ue.call(t,e)}const uo=/\B([A-Z])/g,Xt=ft(t=>t.replace(uo,"-$1").toLowerCase()),fo=/-(\w)/g,fe=ft(t=>t.replace(fo,us)),St=ft(t=>t.length?us(null,t.charAt(0))+t.slice(1):"");function us(t,e){return e?e.toUpperCase():""}function lt(t,e){return t==null||t.startsWith==null?void 0:t.startsWith(e)}function Gt(t,e){return t==null||t.endsWith==null?void 0:t.endsWith(e)}function p(t,e){return t==null||t.includes==null?void 0:t.includes(e)}function bt(t,e){return t==null||t.findIndex==null?void 0:t.findIndex(e)}const{isArray:Q,from:xi}=Array,{assign:xt}=Object;function mt(t){return typeof t=="function"}function Tt(t){return t!==null&&typeof t=="object"}function yt(t){return de.call(t)==="[object Object]"}function Jt(t){return Tt(t)&&t===t.window}function De(t){return $i(t)===9}function yi(t){return $i(t)>=1}function Kt(t){return $i(t)===1}function $i(t){return!Jt(t)&&Tt(t)&&t.nodeType}function Me(t){return typeof t=="boolean"}function D(t){return typeof t=="string"}function Zt(t){return typeof t=="number"}function Dt(t){return Zt(t)||D(t)&&!isNaN(t-parseFloat(t))}function pe(t){return!(Q(t)?t.length:Tt(t)?Object.keys(t).length:!1)}function R(t){return t===void 0}function ki(t){return Me(t)?t:t==="true"||t==="1"||t===""?!0:t==="false"||t==="0"?!1:t}function Ct(t){const e=Number(t);return isNaN(e)?!1:e}function v(t){return parseFloat(t)||0}function j(t){return y(t)[0]}function y(t){return t&&(yi(t)?[t]:Array.from(t).filter(yi))||[]}function Mt(t){var e;if(Jt(t))return t;t=j(t);const i=De(t)?t:(e=t)==null?void 0:e.ownerDocument;return(i==null?void 0:i.defaultView)||window}function ge(t,e){return t===e||Tt(t)&&Tt(e)&&Object.keys(t).length===Object.keys(e).length&&$t(t,(i,s)=>i===e[s])}function Si(t,e,i){return t.replace(new RegExp(e+"|"+i,"g"),s=>s===e?i:e)}function Qt(t){return t[t.length-1]}function $t(t,e){for(const i in t)if(e(t[i],i)===!1)return!1;return!0}function Ne(t,e){return t.slice().sort((i,s)=>{let{[e]:n=0}=i,{[e]:o=0}=s;return n>o?1:o>n?-1:0})}function ds(t,e){const i=new Set;return t.filter(s=>{let{[e]:n}=s;return i.has(n)?!1:i.add(n)})}function U(t,e,i){return e===void 0&&(e=0),i===void 0&&(i=1),Math.min(Math.max(Ct(t)||0,e),i)}function T(){}function Ti(){for(var t=arguments.length,e=new Array(t),i=0;i<t;i++)e[i]=arguments[i];return[["bottom","top"],["right","left"]].every(s=>{let[n,o]=s;return Math.min(...e.map(r=>{let{[n]:a}=r;return a}))-Math.max(...e.map(r=>{let{[o]:a}=r;return a}))>0})}function ze(t,e){return t.x<=e.right&&t.x>=e.left&&t.y<=e.bottom&&t.y>=e.top}function Ci(t,e,i){const s=e==="width"?"height":"width";return{[s]:t[e]?Math.round(i*t[s]/t[e]):t[s],[e]:i}}function fs(t,e){t={...t};for(const i in t)t=t[i]>e[i]?Ci(t,i,e[i]):t;return t}function po(t,e){t=fs(t,e);for(const i in t)t=t[i]<e[i]?Ci(t,i,e[i]):t;return t}const Fe={ratio:Ci,contain:fs,cover:po};function Ut(t,e,i,s){i===void 0&&(i=0),s===void 0&&(s=!1),e=y(e);const{length:n}=e;return n?(t=Dt(t)?Ct(t):t==="next"?i+1:t==="previous"?i-1:e.indexOf(j(t)),s?U(t,0,n-1):(t%=n,t<0?t+n:t)):-1}function ft(t){const e=Object.create(null);return i=>e[i]||(e[i]=t(i))}class He{constructor(){this.promise=new Promise((e,i)=>{this.reject=i,this.resolve=e})}}function w(t,e,i){if(Tt(e)){for(const n in e)w(t,n,e[n]);return}if(R(i)){var s;return(s=j(t))==null?void 0:s.getAttribute(e)}else for(const n of y(t))mt(i)&&(i=i.call(n,w(n,e))),i===null?me(n,e):n.setAttribute(e,i)}function It(t,e){return y(t).some(i=>i.hasAttribute(e))}function me(t,e){const i=y(t);for(const s of e.split(" "))for(const n of i)n.removeAttribute(s)}function ot(t,e){for(const i of[e,"data-"+e])if(It(t,i))return w(t,i)}const go={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,menuitem:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0};function Ii(t){return y(t).some(e=>go[e.tagName.toLowerCase()])}function q(t){return y(t).some(e=>e.offsetWidth||e.offsetHeight||e.getClientRects().length)}const ve="input,select,textarea,button";function Pi(t){return y(t).some(e=>F(e,ve))}const Le=ve+",a[href],[tabindex]";function We(t){return F(t,Le)}function E(t){var e;return(e=j(t))==null?void 0:e.parentElement}function Re(t,e){return y(t).filter(i=>F(i,e))}function F(t,e){return y(t).some(i=>i.matches(e))}function et(t,e){return Kt(t)?t.closest(lt(e,">")?e.slice(1):e):y(t).map(i=>et(i,e)).filter(Boolean)}function P(t,e){return D(e)?!!et(t,e):j(e).contains(j(t))}function te(t,e){const i=[];for(;t=E(t);)(!e||F(t,e))&&i.push(t);return i}function O(t,e){t=j(t);const i=t?y(t.children):[];return e?Re(i,e):i}function ee(t,e){return e?y(t).indexOf(j(e)):O(E(t)).indexOf(t)}function ht(t,e){returLine truncated
|
||||
@@ -0,0 +1,68 @@
|
||||
package dev.inmo.kmppscriptbuilder.core
|
||||
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.Colors
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.BuilderView
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.loadConfigFile
|
||||
import java.io.File
|
||||
|
||||
//private val uncaughtExceptionsBC = BroadcastChannel<DefaultErrorHandler.ErrorEvent>(Channel.CONFLATED)
|
||||
//val uncaughtExceptionsFlow: Flow<DefaultErrorHandler.ErrorEvent> = uncaughtExceptionsBC.asFlow()
|
||||
|
||||
fun main(args: Array<String>) = application {
|
||||
Window(onCloseRequest = ::exitApplication, title = "Kotlin Multiplatform Publishing Builder") {
|
||||
val builder = BuilderView()
|
||||
MaterialTheme(
|
||||
Colors(
|
||||
primary = Color(0x01, 0x57, 0x9b),
|
||||
primaryVariant = Color(0x00, 0x2f, 0x6c),
|
||||
secondary = Color(0xb2, 0xeb, 0xf2),
|
||||
secondaryVariant = Color(0x81, 0xb9, 0xbf),
|
||||
background = Color(0xe1, 0xe2, 0xe1),
|
||||
surface = Color(0xf5, 0xf5, 0xf6),
|
||||
error = Color(0xb7, 0x1c, 0x1c),
|
||||
onPrimary = Color.White,
|
||||
onSecondary = Color.Black,
|
||||
onBackground = Color.Black,
|
||||
onSurface = Color.Black,
|
||||
onError = Color.White,
|
||||
isLight = MaterialTheme.colors.isLight,
|
||||
)
|
||||
) {
|
||||
Box(
|
||||
Modifier.fillMaxSize()
|
||||
.background(color = Color(245, 245, 245))
|
||||
) {
|
||||
|
||||
val stateVertical = rememberScrollState(0)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(stateVertical)
|
||||
) {
|
||||
Column {
|
||||
builder.build()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VerticalScrollbar(
|
||||
modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
|
||||
adapter = rememberScrollbarAdapter(stateVertical)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (args.isNotEmpty()) {
|
||||
val config = loadConfigFile(File(args.first()))
|
||||
builder.config = config
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -1,65 +0,0 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Divider
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonText
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.exportGradle
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.loadConfig
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.saveAs
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.saveConfig
|
||||
|
||||
actual object BuilderViewDrawer : Drawer<BuilderView> {
|
||||
override fun BuilderView.draw() {
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
Column() {
|
||||
TopAppBar(
|
||||
@Composable {
|
||||
Text("Kotlin publication scripts builder", Modifier.clickable { println(config) })
|
||||
},
|
||||
actions = {
|
||||
createIcon("Open file", "images/open_file.svg") {
|
||||
loadConfig()?.also {
|
||||
config = it
|
||||
}
|
||||
}
|
||||
|
||||
if (saveAvailableState) {
|
||||
createIcon("Save", "images/save_file.svg") {
|
||||
saveConfig(config)
|
||||
}
|
||||
}
|
||||
|
||||
if (saveAvailableState) {
|
||||
createIcon("Export Gradle script", "images/export_gradle.svg") {
|
||||
exportGradle(config)
|
||||
}
|
||||
}
|
||||
|
||||
createIcon("Save as", "images/save_as.svg") {
|
||||
if (saveAs(config)) {
|
||||
saveAvailableState = true
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
Column(Modifier.padding(8.dp)) {
|
||||
projectTypeView.init()
|
||||
Divider()
|
||||
licensesView.init()
|
||||
Divider()
|
||||
mavenInfoView.init()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.OutlinedButton
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.inmo.kmppscriptbuilder.core.models.GpgSigning
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonTextField
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.SwitchWithLabel
|
||||
|
||||
actual class GpgSigningOptionDrawer(
|
||||
private val mavenInfoView: MavenInfoView
|
||||
) : Drawer<GpgSigning> {
|
||||
@Composable
|
||||
override fun GpgSigning.draw() {
|
||||
if (mavenInfoView.gpgSignProperty == this) {
|
||||
Button({}, Modifier.padding(8.dp)) {
|
||||
Text(name)
|
||||
}
|
||||
} else {
|
||||
OutlinedButton(
|
||||
{
|
||||
mavenInfoView.gpgSignProperty = this
|
||||
},
|
||||
Modifier.padding(8.dp)
|
||||
) {
|
||||
Text(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actual fun GpgSigningOptionDrawerWithView(view: MavenInfoView): GpgSigningOptionDrawer = GpgSigningOptionDrawer(mavenInfoView = view)
|
||||
@@ -4,6 +4,9 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.Divider
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonText
|
||||
@@ -11,44 +14,39 @@ import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonTextField
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
|
||||
actual object LicensesDrawer : Drawer<LicensesView> {
|
||||
@Composable
|
||||
override fun LicensesView.draw() {
|
||||
CommonTextField(licenseSearchFilter, "Search filter") { filterText ->
|
||||
licenseSearchFilter = filterText
|
||||
licensesOffersToShow.clear()
|
||||
if (licenseSearchFilter.isNotEmpty()) {
|
||||
licensesOffersToShow.addAll(
|
||||
availableLicensesState.filter { filterText.all { symbol -> symbol.lowercaseChar() in it.title } }
|
||||
)
|
||||
}
|
||||
}
|
||||
Column {
|
||||
licensesOffersToShow.forEach {
|
||||
Column(Modifier.padding(16.dp, 8.dp, 8.dp, 8.dp)) {
|
||||
CommonText(it.title) {
|
||||
licensesListState.add(it.toLicenseState())
|
||||
licenseSearchFilter = ""
|
||||
licensesOffersToShow.clear()
|
||||
if (searchFieldFocused.value) {
|
||||
Column {
|
||||
licensesOffersToShow.value.forEach {
|
||||
Column(Modifier.padding(16.dp, 8.dp, 8.dp, 8.dp)) {
|
||||
CommonText(it.title) {
|
||||
licensesListState.add(it.toLicenseState())
|
||||
licenseSearchFilter = ""
|
||||
}
|
||||
Divider()
|
||||
}
|
||||
Divider()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button({ licensesListState.add(LicenseState()) }, Modifier.padding(8.dp)) {
|
||||
CommonText("Add empty license",)
|
||||
CommonText("Add empty license")
|
||||
}
|
||||
|
||||
licensesListState.forEach { license ->
|
||||
Column(Modifier.padding(8.dp)) {
|
||||
CommonTextField(
|
||||
license.id,
|
||||
"License ID"
|
||||
"License ID",
|
||||
) { license.id = it }
|
||||
CommonTextField(
|
||||
license.title,
|
||||
"License title"
|
||||
"License title",
|
||||
) { license.title = it }
|
||||
CommonTextField(
|
||||
license.url ?: "",
|
||||
"License URL"
|
||||
"License URL",
|
||||
) { license.url = it }
|
||||
Button({ licensesListState.remove(license) }, Modifier.padding(8.dp)) {
|
||||
CommonText("Remove",)
|
||||
|
||||
@@ -3,12 +3,14 @@ package dev.inmo.kmppscriptbuilder.core.ui
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonText
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
|
||||
actual class ListViewDrawer<T> : Drawer<ListView<T>> {
|
||||
@Composable
|
||||
override fun ListView<T>.draw() {
|
||||
Button({ itemsList.add(createItem()) }) {
|
||||
CommonText(addItemText,)
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.OutlinedButton
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.inmo.kmppscriptbuilder.core.models.GpgSigning
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonTextField
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.SwitchWithLabel
|
||||
|
||||
actual object MavenInfoDrawer : Drawer<MavenInfoView> {
|
||||
@Composable
|
||||
private fun MavenInfoView.addGpgSigningButton(gpgSigning: GpgSigning) {
|
||||
if (gpgSignProperty == gpgSigning) {
|
||||
Button({}, Modifier.padding(8.dp)) {
|
||||
Text(gpgSigning.name)
|
||||
}
|
||||
} else {
|
||||
OutlinedButton(
|
||||
{
|
||||
gpgSignProperty = gpgSigning
|
||||
},
|
||||
Modifier.padding(8.dp)
|
||||
) {
|
||||
Text(gpgSigning.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun MavenInfoView.draw() {
|
||||
CommonTextField(
|
||||
projectNameProperty,
|
||||
"Public project name"
|
||||
) { projectNameProperty = it }
|
||||
CommonTextField(
|
||||
projectDescriptionProperty,
|
||||
"Public project description"
|
||||
) { projectDescriptionProperty = it }
|
||||
CommonTextField(
|
||||
projectUrlProperty,
|
||||
"Public project URL"
|
||||
) { projectUrlProperty = it }
|
||||
CommonTextField(
|
||||
projectVcsUrlProperty,
|
||||
"Public project VCS URL (with .git)"
|
||||
) { projectVcsUrlProperty = it }
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text("Gpg Signing: ")
|
||||
addGpgSigningButton(GpgSigning.Disabled)
|
||||
addGpgSigningButton(GpgSigning.Optional)
|
||||
addGpgSigningButton(GpgSigning.Enabled)
|
||||
}
|
||||
|
||||
SwitchWithLabel(
|
||||
"Include publication to MavenCentral",
|
||||
publishToMavenCentralProperty,
|
||||
placeSwitchAtTheStart = true
|
||||
) { publishToMavenCentralProperty = it }
|
||||
developersView.init()
|
||||
repositoriesView.init()
|
||||
}
|
||||
}
|
||||
@@ -15,30 +15,26 @@ import dev.inmo.kmppscriptbuilder.core.models.MultiplatformProjectType
|
||||
import dev.inmo.kmppscriptbuilder.core.models.ProjectType
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
|
||||
actual object ProjectTypeDrawer : Drawer<ProjectTypeView> {
|
||||
actual class ProjectTypeDrawer(
|
||||
private val projectTypeView: ProjectTypeView
|
||||
) : Drawer<ProjectType> {
|
||||
@Composable
|
||||
private fun ProjectTypeView.addProjectTypeButton(newProjectType: ProjectType) {
|
||||
if (projectType == newProjectType) {
|
||||
override fun ProjectType.draw() {
|
||||
if (projectTypeView.projectType == this) {
|
||||
Button({}, Modifier.padding(8.dp)) {
|
||||
Text(newProjectType.name)
|
||||
Text(name)
|
||||
}
|
||||
} else {
|
||||
OutlinedButton(
|
||||
{
|
||||
projectType = newProjectType
|
||||
projectTypeView.projectType = this
|
||||
},
|
||||
Modifier.padding(8.dp)
|
||||
) {
|
||||
Text(newProjectType.name)
|
||||
Text(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun ProjectTypeView.draw() {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
addProjectTypeButton(MultiplatformProjectType)
|
||||
addProjectTypeButton(JVMProjectType)
|
||||
addProjectTypeButton(JSProjectType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actual fun ProjectTypeDrawerWithView(view: ProjectTypeView): ProjectTypeDrawer = ProjectTypeDrawer(projectTypeView = view)
|
||||
@@ -1,18 +0,0 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonTextField
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
|
||||
|
||||
actual object RepositoryStateDrawer : Drawer<RepositoriesView> {
|
||||
override fun RepositoriesView.draw() {
|
||||
CommonTextField(
|
||||
item.name,
|
||||
"Repository name"
|
||||
) { item.name = it }
|
||||
CommonTextField(
|
||||
item.url,
|
||||
"Repository url"
|
||||
) { item.url = it }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.ui
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.TooltipArea
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TopAppBar
|
||||
import androidx.compose.material.primarySurface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.inmo.kmppscriptbuilder.core.models.Config
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.exportGradle
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.openNewConfig
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.saveAs
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.saveConfig
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
private fun createIcon(
|
||||
tooltip: String,
|
||||
resource: String,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
TooltipArea(
|
||||
tooltip = {
|
||||
Surface(
|
||||
modifier = Modifier.shadow(4.dp),
|
||||
color = MaterialTheme.colors.primarySurface,
|
||||
shape = RoundedCornerShape(4.dp)
|
||||
) {
|
||||
Text(tooltip, modifier = Modifier.padding(10.dp), color = MaterialTheme.colors.onPrimary)
|
||||
}
|
||||
}
|
||||
) {
|
||||
IconButton(onClick) {
|
||||
Image(
|
||||
painter = painterResource(resource),
|
||||
contentDescription = tooltip
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
actual fun TopAppBar(
|
||||
config: Config,
|
||||
saveAvailable: Boolean,
|
||||
onSaveAvailable: (Boolean) -> Unit,
|
||||
onNewConfig: (Config) -> Unit
|
||||
) {
|
||||
TopAppBar(
|
||||
@Composable {
|
||||
Text("Kotlin publication scripts builder", Modifier.clickable { println(config) })
|
||||
},
|
||||
actions = {
|
||||
createIcon("Open file", "images/open_file.svg") {
|
||||
openNewConfig(onNewConfig)
|
||||
}
|
||||
|
||||
if (saveAvailable) {
|
||||
createIcon("Save", "images/save_file.svg") {
|
||||
saveConfig(config)
|
||||
}
|
||||
}
|
||||
|
||||
if (saveAvailable) {
|
||||
createIcon("Export Gradle script", "images/export_gradle.svg") {
|
||||
exportGradle(config)
|
||||
}
|
||||
}
|
||||
|
||||
createIcon("Save as", "images/save_as.svg") {
|
||||
if (saveAs(config)) {
|
||||
onSaveAvailable(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
+27
-6
@@ -6,12 +6,14 @@ import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Divider
|
||||
import androidx.compose.material.OutlinedTextField
|
||||
import androidx.compose.material.Switch
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@@ -29,15 +31,15 @@ actual fun SwitchWithLabel(
|
||||
switchEnabled: Boolean,
|
||||
onCheckedChange: (Boolean) -> Unit
|
||||
) {
|
||||
Row(Modifier.padding(0.dp, 8.dp), Arrangement.Start, Alignment.Top) {
|
||||
Row(Modifier.padding(0.dp, 8.dp).clickable { onCheckedChange(!checked) }, Arrangement.Start, Alignment.Top) {
|
||||
val switchCreator = @Composable {
|
||||
Switch(checked, onCheckedChange, Modifier.padding(8.dp, 0.dp), enabled = switchEnabled)
|
||||
Switch(checked, null, Modifier.padding(8.dp, 0.dp), enabled = switchEnabled)
|
||||
}
|
||||
if (placeSwitchAtTheStart) {
|
||||
switchCreator()
|
||||
}
|
||||
Box(Modifier.fillMaxWidth().align(Alignment.CenterVertically).clickable { }) {
|
||||
CommonText(label,)
|
||||
Box(Modifier.fillMaxWidth().align(Alignment.CenterVertically)) {
|
||||
CommonText(label)
|
||||
}
|
||||
if (!placeSwitchAtTheStart) {
|
||||
switchCreator()
|
||||
@@ -46,11 +48,18 @@ actual fun SwitchWithLabel(
|
||||
}
|
||||
|
||||
@Composable
|
||||
actual fun CommonTextField(presetText: String, hint: String, onChange: (String) -> Unit) {
|
||||
actual fun CommonTextField(
|
||||
presetText: String,
|
||||
hint: String,
|
||||
onFocusChanged: (Boolean) -> Unit,
|
||||
onChange: (String) -> Unit
|
||||
) {
|
||||
OutlinedTextField(
|
||||
presetText,
|
||||
onChange,
|
||||
Modifier.fillMaxWidth(),
|
||||
Modifier.fillMaxWidth().onFocusChanged {
|
||||
onFocusChanged(it.isFocused)
|
||||
},
|
||||
singleLine = true,
|
||||
label = {
|
||||
CommonText(hint,)
|
||||
@@ -69,3 +78,15 @@ actual fun TitleText(text: String) {
|
||||
text, Modifier.padding(0.dp, 8.dp), fontSize = 18.sp
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
actual fun <T> ButtonsPanel(data: Iterable<T>, itemDrawer: @Composable (T) -> Unit) {
|
||||
Row {
|
||||
data.forEach { itemDrawer(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
actual fun DefaultDivider() {
|
||||
Divider()
|
||||
}
|
||||
+7
-11
@@ -2,33 +2,29 @@ package dev.inmo.kmppscriptbuilder.core.utils
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.models.Config
|
||||
import dev.inmo.kmppscriptbuilder.core.ui.utils.FileFilter
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.serialFormat
|
||||
import dev.inmo.micro_utils.common.MPPFile
|
||||
import java.io.File
|
||||
import javax.swing.JFileChooser
|
||||
|
||||
private const val appExtension = "kpsb"
|
||||
fun MPPFile.text() = readText()
|
||||
|
||||
private var lastFile: File? = null
|
||||
internal var lastFile: MPPFile? = null
|
||||
|
||||
fun loadConfigFile(file: File): Config {
|
||||
fun loadConfigFile(file: MPPFile): Config {
|
||||
lastFile = file
|
||||
return serialFormat.decodeFromString(Config.serializer(), file.readText())
|
||||
return serialFormat.decodeFromString(Config.serializer(), file.text())
|
||||
}
|
||||
|
||||
actual fun MPPFile.text() = readText()
|
||||
|
||||
actual fun loadConfig(): Config? {
|
||||
actual fun openNewConfig(onParsed: (Config) -> Unit) {
|
||||
val fc = JFileChooser(lastFile ?.parent)
|
||||
fc.addChoosableFileFilter(FileFilter("Kotlin Publication Scripts Builder", Regex(".*\\.$appExtension")))
|
||||
fc.addChoosableFileFilter(FileFilter("JSON", Regex(".*\\.json")))
|
||||
return when (fc.showOpenDialog(null)) {
|
||||
when (fc.showOpenDialog(null)) {
|
||||
JFileChooser.APPROVE_OPTION -> {
|
||||
val file = fc.selectedFile
|
||||
lastFile = file
|
||||
return serialFormat.decodeFromString(Config.serializer(), fc.selectedFile.readText())
|
||||
onParsed(serialFormat.decodeFromString(Config.serializer(), fc.selectedFile.readText()))
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user