Contribution Manager UI Test

This commit is contained in:
Stef Tervelde
2024-11-17 09:39:08 +01:00
parent 28ab38a11c
commit a82ac33f83
6 changed files with 218 additions and 12 deletions
+7 -3
View File
@@ -2,8 +2,11 @@ import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins{
id("java")
kotlin("jvm") version "1.9.23"
id("org.jetbrains.compose") version "1.7.1"
kotlin("jvm") version libs.versions.kotlin
alias(libs.plugins.compose.compiler)
alias(libs.plugins.jetbrainsCompose)
alias(libs.plugins.serialization)
}
group = rootProject.group
@@ -28,7 +31,6 @@ sourceSets{
}
}
compose.desktop {
application {
mainClass = "processing.app.ui.Splash"
@@ -79,6 +81,8 @@ dependencies {
implementation(compose.desktop.currentOs)
implementation("io.github.alexzhirkevich:compottie:${compottieVersion}")
implementation("com.charleskorn.kaml:kaml:0.65.0")
}
tasks.register<Copy>("addCore"){
@@ -0,0 +1,188 @@
package processing.app.contrib.ui
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.PointerIcon
import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.LineHeightStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import com.charleskorn.kaml.Yaml
import com.charleskorn.kaml.YamlConfiguration
import kotlinx.serialization.Serializable
import java.net.URL
fun main() = application {
Window(onCloseRequest = ::exitApplication) {
ContributionsManager()
}
}
enum class Status {
VALID,
BROKEN,
DEPRECATED
}
enum class Type {
library,
mode,
tool,
examples,
}
@Serializable
data class Author(
val name: String,
val url: String? = null,
)
@Serializable
data class Contribution(
val id: Int,
val status: Status,
val source: String,
val type: Type,
val name: String? = null,
val categories: List<String>? = emptyList(),
val authors: String? = null,
val authorList: List<Author>? = emptyList(),
val url: String? = null,
val sentence: String? = null,
val paragraph: String? = null,
val version: String? = null,
val prettyVersion: String? = null,
val minRevision: Int? = null,
val maxRevision: Int? = null,
val download: String? = null,
)
@Serializable
data class Contributions(
val contributions: List<Contribution>
)
@Composable
fun ContributionsManager(){
val contributions = remember { mutableStateOf(arrayOf<Contribution>()) }
val error = remember { mutableStateOf<Exception?>(null) }
LaunchedEffect(Unit){
try {
val url = URL("https://github.com/mingness/processing-contributions-new/raw/refs/heads/main/contributions.yaml")
val connection = url.openConnection()
val inputStream = connection.getInputStream()
val yaml = inputStream.readAllBytes().decodeToString()
// TODO cache in processing folder
val parser = Yaml(
configuration = YamlConfiguration(
strictMode = false
)
)
val result = parser.decodeFromString(Contributions.serializer(), yaml)
contributions.value = result.contributions
.filter { it.status == Status.VALID }
.map {
// TODO Parse better
val authorList = it.authors?.split(",")?.map { author ->
val parts = author.split("](")
val name = parts[0].removePrefix("[")
val url = parts.getOrNull(1)?.removeSuffix(")")
Author(name, url)
} ?: emptyList()
it.copy(authorList = authorList)
}
.toTypedArray()
} catch (e: Exception){
error.value = e
}
}
if(error.value != null){
Text("Error loading contributions: ${error.value}")
return
}
if(contributions.value.isEmpty()){
Text("Loading contributions...")
return
}
val contributionsByType = contributions.value.groupBy { it.type }
val types = Type.entries
val selectedType = remember { mutableStateOf(types.first()) }
val contributionsForType = (contributionsByType[selectedType.value] ?: emptyList())
.sortedBy { it.name }
val selectedContribution = remember { mutableStateOf<Contribution?>(null) }
Box{
Column {
Row{
for(type in types){
Text(type.name, modifier = Modifier
.background(if(selectedType.value == type) Color.Gray else Color.Transparent)
.clickable {
selectedType.value = type
selectedContribution.value = null
}
.padding(8.dp)
)
}
Spacer(modifier = Modifier.weight(1f))
Text("Updates")
}
Box{
val state = rememberLazyListState()
LazyColumn(state = state) {
item{
// Table Header
}
items(contributionsForType){ contribution ->
Row(modifier = Modifier
.pointerHoverIcon(PointerIcon.Hand)
.clickable { selectedContribution.value = contribution }
.padding(8.dp)
) {
Row(modifier = Modifier.weight(1f)){
Text("status")
}
Row(horizontalArrangement = Arrangement.spacedBy(4.dp), modifier = Modifier.weight(8f)){
Text(contribution.name ?: "Unnamed", fontWeight = FontWeight.Bold)
Text(contribution.sentence ?: "No description", maxLines = 1, overflow = TextOverflow.Ellipsis)
}
Row(modifier = Modifier.weight(4f)){
Text(contribution.authorList?.joinToString { it.name } ?: "Unknown")
}
}
}
}
VerticalScrollbar(
modifier = Modifier
.align(Alignment.CenterEnd)
.background(Color.LightGray)
.fillMaxHeight(),
adapter = rememberScrollbarAdapter(
scrollState = state
)
)
}
}
}
}
+2 -2
View File
@@ -64,11 +64,11 @@ fun main() = application {
fun JDKManager(){
val home = Platform.getJavaHome()
val valid = File(home, "bin/java").exists()
// if(valid) return
if(valid) return
val color = Theme.getColor("status.notice.bgcolor")
val colorText = Theme.getColor("status.notice.fgcolor")
val buttonColor = Theme.getColor("toolbar.button.enabled.field")
val buttonColor = Theme.getColor("toolbar.button.enabled.field")
val buttonTextColor = Theme.getColor("toolbar.button.enabled.glyph")
val fontFamily = FontFamily(
+10 -1
View File
@@ -1,2 +1,11 @@
group = "org.processing"
version = "4.4.0"
version = "4.4.0"
plugins {
kotlin("jvm") version libs.versions.kotlin apply false
alias(libs.plugins.kotlinMultiplatform) apply false
alias(libs.plugins.compose.compiler) apply false
alias(libs.plugins.jetbrainsCompose) apply false
}
+11
View File
@@ -0,0 +1,11 @@
[versions]
kotlin = "2.0.20"
compose-plugin = "1.7.1"
[libraries]
[plugins]
jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
-6
View File
@@ -6,12 +6,6 @@ include(
"java"
)
pluginManagement {
plugins {
kotlin("jvm") version "1.9.23"
}
}
buildscript {
repositories {
mavenCentral()