From a200d67acabd93410d03c846145cd4b98d392a5b Mon Sep 17 00:00:00 2001 From: kateliu20 Date: Mon, 23 Sep 2024 11:45:44 -0400 Subject: [PATCH 01/10] Upgrade jewel to 0.23.0 and compose-jb --- gradle/libs.versions.toml | 11 ++++++----- skate-plugin/project-gen/build.gradle.kts | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4d9d90677..656908101 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,8 @@ agpAlpha = "8.6.1" anvil = "2.5.0-beta11" bugsnagGradle = "8.1.0" circuit = "0.23.1" -compose-jb = "1.6.11" +compose-jb = "1.7.0-alpha03" +compose-jb-stable = "1.6.11" coroutines = "1.9.0" dependencyAnalysisPlugin = "1.33.0" detekt = "1.23.7" @@ -13,7 +14,7 @@ errorproneGradle = "3.0.1" intellij-platform = "2.0.1" jdk = "22" jvmTarget = "17" -jewel = "0.15.2.2" +jewel = "0.23.0" jna = "5.15.0" kaml = "0.61.0" kotlin = "2.0.20" @@ -80,7 +81,7 @@ develocity-agent-adapters = "com.gradle:develocity-gradle-plugin-adapters:1.0.4" gradleLints = "androidx.lint:lint-gradle:1.0.0-alpha02" gradlePlugins-anvil = { module = "com.squareup.anvil:gradle-plugin", version.ref = "anvil" } gradlePlugins-bugsnag = { module = "com.bugsnag:bugsnag-android-gradle-plugin", version.ref = "bugsnagGradle" } -gradlePlugins-compose = { module = "org.jetbrains.compose:compose-gradle-plugin", version.ref = "compose-jb" } +gradlePlugins-compose = { module = "org.jetbrains.compose:compose-gradle-plugin", version.ref = "compose-jb-stable" } gradlePlugins-composeCompiler = { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin" } gradlePlugins-dependencyAnalysis = { module = "com.autonomousapps:dependency-analysis-gradle-plugin", version.ref = "dependencyAnalysisPlugin" } gradlePlugins-detekt = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" } @@ -108,8 +109,8 @@ kotlin-poet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinPoet" } kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinx-serialization" } ktfmt = { module = "com.facebook:ktfmt", version.ref = "ktfmt" } -jewel-bridge232 = { module = "org.jetbrains.jewel:jewel-ide-laf-bridge-232", version.ref = "jewel" } -jewel-standalone = { module = "org.jetbrains.jewel:jewel-int-ui-standalone", version = "0.15.2" } +jewel-bridge = { module = "org.jetbrains.jewel:jewel-ide-laf-bridge-241", version.ref = "jewel" } +jewel-standalone = { module = "org.jetbrains.jewel:jewel-int-ui-standalone-241", version.ref = "jewel" } jgrapht = "org.jgrapht:jgrapht-core:1.5.2" jna = { module = "net.java.dev.jna:jna", version.ref = "jna" } jna-platform = { module = "net.java.dev.jna:jna-platform", version.ref = "jna" } diff --git a/skate-plugin/project-gen/build.gradle.kts b/skate-plugin/project-gen/build.gradle.kts index fb6aa6de6..24761dbc3 100644 --- a/skate-plugin/project-gen/build.gradle.kts +++ b/skate-plugin/project-gen/build.gradle.kts @@ -42,7 +42,7 @@ kotlin { implementation(compose.ui) implementation(libs.circuit.foundation) implementation(libs.compose.markdown) - implementation(libs.jewel.bridge232) + implementation(libs.jewel.bridge) implementation(libs.kotlin.poet) implementation(libs.markdown) } From f27b0ddcd050adb8812ae59010a9ad994470c891 Mon Sep 17 00:00:00 2001 From: kateliu20 Date: Mon, 23 Sep 2024 12:30:33 -0400 Subject: [PATCH 02/10] Fix transformation and adjust to new jewel --- .../compose/playground/MarkdownPlayground.kt | 2 +- .../playground/ProjectGenPlayground.kt | 2 +- .../kotlin/slack/tooling/aibot/ChatColors.kt | 11 ++----- .../tooling/markdown/ui/MarkdownPanel.kt | 2 +- .../projectgen/PrefixTransformation.kt | 33 ++++--------------- .../tooling/projectgen/ProjectGenPresenter.kt | 5 +-- .../slack/tooling/projectgen/ProjectGenUi.kt | 21 +++++------- .../slack/tooling/projectgen/UiElement.kt | 7 ++-- .../kotlin/slack/tooling/projectgen/models.kt | 2 +- 9 files changed, 27 insertions(+), 58 deletions(-) diff --git a/skate-plugin/compose-playground/src/jvmMain/kotlin/slack/tooling/compose/playground/MarkdownPlayground.kt b/skate-plugin/compose-playground/src/jvmMain/kotlin/slack/tooling/compose/playground/MarkdownPlayground.kt index 76dbd9f68..1da865b53 100644 --- a/skate-plugin/compose-playground/src/jvmMain/kotlin/slack/tooling/compose/playground/MarkdownPlayground.kt +++ b/skate-plugin/compose-playground/src/jvmMain/kotlin/slack/tooling/compose/playground/MarkdownPlayground.kt @@ -34,7 +34,7 @@ import slack.tooling.markdown.ui.MarkdownContent fun main() = singleWindowApplication { var isDark by remember { mutableStateOf(false) } IntUiTheme(isDark) { - Column(Modifier.background(JewelTheme.globalColors.paneBackground)) { + Column(Modifier.background(JewelTheme.globalColors.panelBackground)) { DefaultButton(modifier = Modifier.padding(16.dp), onClick = { isDark = !isDark }) { Text("Toggle dark mode") } diff --git a/skate-plugin/compose-playground/src/jvmMain/kotlin/slack/tooling/compose/playground/ProjectGenPlayground.kt b/skate-plugin/compose-playground/src/jvmMain/kotlin/slack/tooling/compose/playground/ProjectGenPlayground.kt index e8cdbeb44..2ebc4ecc2 100644 --- a/skate-plugin/compose-playground/src/jvmMain/kotlin/slack/tooling/compose/playground/ProjectGenPlayground.kt +++ b/skate-plugin/compose-playground/src/jvmMain/kotlin/slack/tooling/compose/playground/ProjectGenPlayground.kt @@ -35,7 +35,7 @@ import slack.tooling.projectgen.ProjectGenUi.ProjectGenApp fun main() = singleWindowApplication { var isDark by remember { mutableStateOf(false) } IntUiTheme(isDark) { - Column(Modifier.background(JewelTheme.globalColors.paneBackground)) { + Column(Modifier.background(JewelTheme.globalColors.panelBackground)) { DefaultButton(modifier = Modifier.padding(16.dp), onClick = { isDark = !isDark }) { Text("Toggle dark mode") } diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatColors.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatColors.kt index e7e085bfe..1fb44bb82 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatColors.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatColors.kt @@ -15,21 +15,14 @@ */ package slack.tooling.aibot -import androidx.compose.runtime.Composable -import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.ui.graphics.Color -import org.jetbrains.jewel.foundation.theme.JewelTheme object ChatColors { val promptBackground = Color(0xFF45494A) - // Color(0xFF2d2f30) responseBackground - val responseBackground: Color - @Composable @ReadOnlyComposable get() = JewelTheme.globalColors.infoContent + val responseBackground = Color(0xFF2d2f30) - // Color(0xFFEAEEF7) userTextColor - val userTextColor: Color - @Composable @ReadOnlyComposable get() = JewelTheme.globalColors.infoContent + val userTextColor = Color(0xFFEAEEF7) val responseTextColor = Color(0xFFE0EEF7) } diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/markdown/ui/MarkdownPanel.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/markdown/ui/MarkdownPanel.kt index 7ee19663b..1dc7fbf9e 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/markdown/ui/MarkdownPanel.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/markdown/ui/MarkdownPanel.kt @@ -131,7 +131,7 @@ private fun jewelMarkdownColor( dividerColor: Color = JewelTheme.globalColors.borders.normal, ): MarkdownColors { val (codeText, codeBackground, inlineCodeText, inlineCodeBackground) = - rememberCodeBackground(JewelTheme.globalColors.paneBackground, text) + rememberCodeBackground(JewelTheme.globalColors.panelBackground, text) return DefaultMarkdownColors( text = text, codeText = codeText, diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/PrefixTransformation.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/PrefixTransformation.kt index 38c6cebc5..304f17ea8 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/PrefixTransformation.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/PrefixTransformation.kt @@ -15,33 +15,12 @@ */ package slack.tooling.projectgen -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.input.OffsetMapping -import androidx.compose.ui.text.input.TransformedText -import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.foundation.text.input.OutputTransformation +import androidx.compose.foundation.text.input.TextFieldBuffer +import androidx.compose.foundation.text.input.insert -class PrefixTransformation(val prefix: String) : VisualTransformation { - override fun filter(text: AnnotatedString): TransformedText { - return prefixFilter(text, prefix) +class PrefixTransformation(private val prefix: String) : OutputTransformation { + override fun TextFieldBuffer.transformOutput() { + insert(0, prefix) } } - -private fun prefixFilter(number: AnnotatedString, prefix: String): TransformedText { - - val out = prefix + number.text - val prefixOffset = prefix.length - - val numberOffsetTranslator = - object : OffsetMapping { - override fun originalToTransformed(offset: Int): Int { - return offset + prefixOffset - } - - override fun transformedToOriginal(offset: Int): Int { - if (offset <= prefixOffset - 1) return prefixOffset - return offset - prefixOffset - } - } - - return TransformedText(AnnotatedString(out), numberOffsetTranslator) -} diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/ProjectGenPresenter.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/ProjectGenPresenter.kt index ac75936fe..0256976fb 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/ProjectGenPresenter.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/ProjectGenPresenter.kt @@ -187,7 +187,8 @@ internal class ProjectGenPresenter( add("view-binding") } }, - androidResourcePrefix = androidResourcePrefix.value.takeIf { androidResources.isChecked }, + androidResourcePrefix = + androidResourcePrefix.value.text.takeIf { androidResources.isChecked }, dagger = dagger.isChecked, daggerFeatures = buildSet { @@ -209,7 +210,7 @@ internal class ProjectGenPresenter( packageName: String, android: Boolean, androidFeatures: Set, - androidResourcePrefix: String?, + androidResourcePrefix: CharSequence?, dagger: Boolean, daggerFeatures: Set, robolectric: Boolean, diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/ProjectGenUi.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/ProjectGenUi.kt index 2da855d26..a777b2e23 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/ProjectGenUi.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/ProjectGenUi.kt @@ -42,7 +42,6 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.awt.ComposePanel -import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Popup @@ -118,7 +117,7 @@ internal fun ProjectGen(state: ProjectGenScreen.State, modifier: Modifier = Modi ) } - Box(modifier.fillMaxSize().background(JewelTheme.globalColors.paneBackground)) { + Box(modifier.fillMaxSize().background(JewelTheme.globalColors.panelBackground)) { val listState = rememberLazyListState() Column(Modifier.padding(16.dp)) { LazyColumn( @@ -133,7 +132,7 @@ internal fun ProjectGen(state: ProjectGenScreen.State, modifier: Modifier = Modi Divider(Orientation.Horizontal) } is SectionElement -> { - Column(Modifier.animateItemPlacement()) { + Column(Modifier.animateItem()) { Text(element.title, style = Typography.h1TextStyle()) Text(element.description) } @@ -143,27 +142,23 @@ internal fun ProjectGen(state: ProjectGenScreen.State, modifier: Modifier = Modi element.name, element.hint, element.isChecked, - modifier = Modifier.animateItemPlacement(), + modifier = Modifier.animateItem(), indent = (element.indentLevel * INDENT_SIZE).dp, onEnabledChange = { element.isChecked = it }, ) } is TextElement -> { Column( - Modifier.padding(start = (element.indentLevel * INDENT_SIZE).dp) - .animateItemPlacement() + Modifier.padding(start = (element.indentLevel * INDENT_SIZE).dp).animateItem() ) { Text(text = element.label, style = Typography.h4TextStyle()) Spacer(Modifier.height(4.dp)) TextField( - value = element.value, - onValueChange = { newValue -> element.value = newValue }, + state = element.value, modifier = Modifier.fillMaxWidth(), readOnly = element.readOnly, enabled = element.enabled, - visualTransformation = - element.prefixTransformation?.let(::PrefixTransformation) - ?: VisualTransformation.None, + outputTransformation = element.prefixTransformation?.let(::PrefixTransformation), outline = if (element.isValid) Outline.None else Outline.Error, ) element.description?.let { @@ -177,7 +172,7 @@ internal fun ProjectGen(state: ProjectGenScreen.State, modifier: Modifier = Modi } Divider(Orientation.Horizontal) Box( - Modifier.background(JewelTheme.globalColors.paneBackground) + Modifier.background(JewelTheme.globalColors.panelBackground) .fillMaxWidth() .padding(top = 16.dp, start = 16.dp, end = 16.dp), contentAlignment = Alignment.CenterEnd, @@ -239,7 +234,7 @@ private fun StatusDialog( Box( Modifier.width(600.dp) .height(100.dp) - .background(JewelTheme.globalColors.paneBackground) + .background(JewelTheme.globalColors.panelBackground) .border(1.5.dp, JewelTheme.globalColors.borders.disabled, RoundedCornerShape(8.dp)) ) { Column( diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/UiElement.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/UiElement.kt index e225ad434..e3b556348 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/UiElement.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/UiElement.kt @@ -15,6 +15,7 @@ */ package slack.tooling.projectgen +import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable import androidx.compose.runtime.derivedStateOf @@ -68,17 +69,17 @@ internal class TextElement( private val dependentElements: List = emptyList(), val validationRegex: Regex? = null, ) : UiElement { - var value by mutableStateOf(initialValue) + val value = TextFieldState(initialValue) val enabled by derivedStateOf { !readOnly && dependentElements.all { it.isChecked } } val isValid by derivedStateOf { - validationRegex?.let { value.isNotBlank() && value.matches(it) } != false + validationRegex?.let { value.text.isNotBlank() && value.text.matches(it) } != false } override fun reset() { - value = initialValue isVisible = initialVisibility + value.edit { replace(0, length, initialValue) } } override var isVisible: Boolean by mutableStateOf(initialVisibility) diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/models.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/models.kt index 0a66a5c83..779e84e3a 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/models.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/projectgen/models.kt @@ -186,7 +186,7 @@ internal interface DependenciesVisitor { } internal data class AndroidLibraryFeature( - val resourcesPrefix: String?, + val resourcesPrefix: CharSequence?, val viewBindingEnabled: Boolean, val androidTest: Boolean, val packageName: String, From 9414b1363c7bbc0d754e15c1fd9e534abe1f8e6a Mon Sep 17 00:00:00 2001 From: kateliu20 Date: Mon, 23 Sep 2024 14:00:58 -0400 Subject: [PATCH 03/10] Change text area to have state --- .../slack/tooling/aibot/ChatWindowUi.kt | 62 +++++++++---------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt index e72aec314..11fda3db6 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt @@ -28,11 +28,15 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.runtime.Composable +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -45,12 +49,14 @@ import androidx.compose.ui.input.key.Key import androidx.compose.ui.input.key.KeyEventType import androidx.compose.ui.input.key.isShiftPressed import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.onKeyEvent import androidx.compose.ui.input.key.onPreviewKeyEvent import androidx.compose.ui.input.key.type +import androidx.compose.ui.modifier.modifierLocalMapOf import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import org.jetbrains.jewel.foundation.theme.JewelTheme import org.jetbrains.jewel.ui.component.Icon @@ -60,7 +66,7 @@ import org.jetbrains.jewel.ui.component.TextArea @Composable fun ChatWindowUi(state: ChatScreen.State, modifier: Modifier = Modifier) { - Column(modifier = modifier.fillMaxSize().background(JewelTheme.globalColors.paneBackground)) { + Column(modifier = modifier.fillMaxSize().background(JewelTheme.globalColors.panelBackground)) { LazyColumn(modifier = Modifier.weight(1f), reverseLayout = true) { items(state.messages.reversed()) { message -> Row( @@ -80,50 +86,38 @@ fun ChatWindowUi(state: ChatScreen.State, modifier: Modifier = Modifier) { @Composable private fun ConversationField(modifier: Modifier = Modifier, onSendMessage: (String) -> Unit) { - var textValue by remember { mutableStateOf(TextFieldValue()) } - val isTextNotEmpty = textValue.text.isNotBlank() + val textState by remember { mutableStateOf(TextFieldState()) } + val isTextNotEmpty = textState.text.isNotBlank() fun sendMessage() { if (isTextNotEmpty) { - onSendMessage(textValue.text) - textValue = TextFieldValue("") + onSendMessage(textState.text.toString()) + textState.clearText() } } - Row( - modifier.padding(4.dp).height(IntrinsicSize.Min), + modifier.padding(4.dp).height(56.dp), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.Bottom, ) { - // user text input. enter sends the message and clears text - // shift + enter adds a new line and expands the text field TextArea( - value = textValue, - onValueChange = { newText -> textValue = newText }, - modifier = - Modifier.weight(1f).heightIn(min = 56.dp).padding(4.dp).onPreviewKeyEvent { event -> + state = textState, + modifier = Modifier.weight(1f).heightIn(min = 56.dp).onKeyEvent { event -> + if(event.type == KeyEventType.KeyDown){ when { - (event.key == Key.Enter || event.key == Key.NumPadEnter) && - event.type == KeyEventType.KeyDown -> { - if (event.isShiftPressed) { - val newText = - textValue.text.replaceRange( - textValue.selection.start, - textValue.selection.end, - "\n", - ) - val newSelection = TextRange(textValue.selection.start + 1) - textValue = TextFieldValue(newText, newSelection) - true - } else { - sendMessage() - true - } + event.key == Key.Enter && event.isShiftPressed -> { + sendMessage() + true } else -> false } - }, - placeholder = { Text("Start your conversation") }, + } else { + false + } + }, + decorationBoxModifier = Modifier.padding(4.dp), + placeholder = { Text("Start your conversation...", modifier= Modifier.padding(4.dp))}, + textStyle = JewelTheme.defaultTextStyle, ) Column(Modifier.fillMaxHeight(), verticalArrangement = Arrangement.Center) { // button will be disabled if there is no text @@ -169,3 +163,7 @@ private fun ChatBubble(message: Message, modifier: Modifier = Modifier) { private fun Modifier.enabled(enabled: Boolean): Modifier { return this.then(if (enabled) Modifier.alpha(1.0f) else Modifier.alpha(0.38f)) } + +private fun TextFieldState.clearText() { + edit { replace(0, length, "") } +} From 63eaa21b50b04050002757ad625a2006888dc0d7 Mon Sep 17 00:00:00 2001 From: kateliu20 Date: Mon, 23 Sep 2024 14:15:12 -0400 Subject: [PATCH 04/10] Additional UI changes to text area --- .../src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt index 11fda3db6..89406da6c 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt @@ -34,6 +34,7 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.text.input.TextFieldLineLimits import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.runtime.Composable import androidx.compose.runtime.derivedStateOf @@ -96,7 +97,7 @@ private fun ConversationField(modifier: Modifier = Modifier, onSendMessage: (Str } } Row( - modifier.padding(4.dp).height(56.dp), + modifier.padding(4.dp).height(100.dp), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.Bottom, ) { @@ -115,9 +116,10 @@ private fun ConversationField(modifier: Modifier = Modifier, onSendMessage: (Str false } }, + placeholder = { Text("Start your conversation...", modifier.padding(4.dp))}, decorationBoxModifier = Modifier.padding(4.dp), - placeholder = { Text("Start your conversation...", modifier= Modifier.padding(4.dp))}, textStyle = JewelTheme.defaultTextStyle, + lineLimits = TextFieldLineLimits.MultiLine(Int.MAX_VALUE) ) Column(Modifier.fillMaxHeight(), verticalArrangement = Arrangement.Center) { // button will be disabled if there is no text From 3a0f62d0eeb82703f6af35a55b9c3a418e766981 Mon Sep 17 00:00:00 2001 From: kateliu20 Date: Mon, 23 Sep 2024 14:18:10 -0400 Subject: [PATCH 05/10] Run spotless and check --- .../slack/tooling/aibot/ChatWindowUi.kt | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt index 89406da6c..0e63f7c08 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt @@ -19,7 +19,6 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize @@ -28,16 +27,13 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.input.TextFieldLineLimits import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.runtime.Composable -import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -51,13 +47,9 @@ import androidx.compose.ui.input.key.KeyEventType import androidx.compose.ui.input.key.isShiftPressed import androidx.compose.ui.input.key.key import androidx.compose.ui.input.key.onKeyEvent -import androidx.compose.ui.input.key.onPreviewKeyEvent import androidx.compose.ui.input.key.type -import androidx.compose.ui.modifier.modifierLocalMapOf import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import org.jetbrains.jewel.foundation.theme.JewelTheme import org.jetbrains.jewel.ui.component.Icon @@ -97,29 +89,30 @@ private fun ConversationField(modifier: Modifier = Modifier, onSendMessage: (Str } } Row( - modifier.padding(4.dp).height(100.dp), + modifier = Modifier.padding(4.dp).height(100.dp), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.Bottom, ) { TextArea( state = textState, - modifier = Modifier.weight(1f).heightIn(min = 56.dp).onKeyEvent { event -> - if(event.type == KeyEventType.KeyDown){ - when { - event.key == Key.Enter && event.isShiftPressed -> { - sendMessage() - true + modifier = + Modifier.weight(1f).heightIn(min = 56.dp).onKeyEvent { event -> + if (event.type == KeyEventType.KeyDown) { + when { + event.key == Key.Enter && event.isShiftPressed -> { + sendMessage() + true + } + else -> false } - else -> false + } else { + false } - } else { - false - } - }, - placeholder = { Text("Start your conversation...", modifier.padding(4.dp))}, + }, + placeholder = { Text("Start your conversation...", modifier.padding(4.dp)) }, decorationBoxModifier = Modifier.padding(4.dp), textStyle = JewelTheme.defaultTextStyle, - lineLimits = TextFieldLineLimits.MultiLine(Int.MAX_VALUE) + lineLimits = TextFieldLineLimits.MultiLine(Int.MAX_VALUE), ) Column(Modifier.fillMaxHeight(), verticalArrangement = Arrangement.Center) { // button will be disabled if there is no text From aa32432f1ca9f371e9c8ebfe96d96a369f54c217 Mon Sep 17 00:00:00 2001 From: kateliu20 Date: Mon, 23 Sep 2024 14:33:16 -0400 Subject: [PATCH 06/10] Upgrade compose-jb to latest beta --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 656908101..0f98437d6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ agpAlpha = "8.6.1" anvil = "2.5.0-beta11" bugsnagGradle = "8.1.0" circuit = "0.23.1" -compose-jb = "1.7.0-alpha03" +compose-jb = "1.7.0-beta02" compose-jb-stable = "1.6.11" coroutines = "1.9.0" dependencyAnalysisPlugin = "1.33.0" From eae65724045d598a94a4c65b6fa00ea99ef68d22 Mon Sep 17 00:00:00 2001 From: kateliu20 Date: Mon, 23 Sep 2024 14:46:13 -0400 Subject: [PATCH 07/10] Upgrade to latest jewel --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0f98437d6..f183ab5ba 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ errorproneGradle = "3.0.1" intellij-platform = "2.0.1" jdk = "22" jvmTarget = "17" -jewel = "0.23.0" +jewel = "0.24.2" jna = "5.15.0" kaml = "0.61.0" kotlin = "2.0.20" From c4a9cb58c865d8c7c47310bab780f68ee1075b58 Mon Sep 17 00:00:00 2001 From: kateliu20 Date: Mon, 23 Sep 2024 16:48:14 -0400 Subject: [PATCH 08/10] Resolve deprecated painterResource error --- skate-plugin/project-gen/build.gradle.kts | 1 + .../slack/tooling/aibot/ChatWindowUi.kt | 4 +- .../slack/tooling/aibot/PainterResource.kt | 66 +++++++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt diff --git a/skate-plugin/project-gen/build.gradle.kts b/skate-plugin/project-gen/build.gradle.kts index 24761dbc3..93fb5b8c1 100644 --- a/skate-plugin/project-gen/build.gradle.kts +++ b/skate-plugin/project-gen/build.gradle.kts @@ -30,6 +30,7 @@ kotlin { jvmMain { dependencies { implementation(compose.animation) + implementation(compose.components.resources) implementation(compose.desktop.common) implementation(compose.desktop.linux_arm64) implementation(compose.desktop.linux_x64) diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt index 0e63f7c08..e5970e0e9 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt @@ -37,7 +37,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -48,7 +47,6 @@ import androidx.compose.ui.input.key.isShiftPressed import androidx.compose.ui.input.key.key import androidx.compose.ui.input.key.onKeyEvent import androidx.compose.ui.input.key.type -import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import org.jetbrains.jewel.foundation.theme.JewelTheme @@ -126,7 +124,7 @@ private fun ConversationField(modifier: Modifier = Modifier, onSendMessage: (Str enabled = isTextNotEmpty, ) { Icon( - painter = painterResource("/drawable/send.svg"), + painter = PainterResource().painterResource("drawable/send.svg"), contentDescription = "Send", modifier = Modifier.size(20.dp), ) diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt new file mode 100644 index 000000000..372d22e02 --- /dev/null +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2024 Slack Technologies, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package slack.tooling.aibot + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.graphics.painter.BitmapPainter +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.rememberVectorPainter +import androidx.compose.ui.platform.LocalDensity +import org.jetbrains.compose.resources.ExperimentalResourceApi +import org.jetbrains.compose.resources.decodeToImageBitmap +import org.jetbrains.compose.resources.decodeToImageVector +import org.jetbrains.compose.resources.decodeToSvgPainter + +// Migration snippet copied from https://github.com/JetBrains/compose-multiplatform-core/pull/1457 +// To resolve deprecated painterResource function from upgrading compose-jb +class PainterResource { + @Composable + fun painterResource(resourcePath: String): Painter = + when (resourcePath.substringAfterLast(".")) { + "svg" -> rememberSvgResource(resourcePath) + "xml" -> rememberVectorXmlResource(resourcePath) + else -> rememberBitmapResource(resourcePath) + } + + @OptIn(ExperimentalResourceApi::class) + @Composable + internal fun rememberBitmapResource(path: String): Painter { + return remember(path) { BitmapPainter(readResourceBytes(path).decodeToImageBitmap()) } + } + + @OptIn(ExperimentalResourceApi::class) + @Composable + internal fun rememberVectorXmlResource(path: String): Painter { + val density = LocalDensity.current + val imageVector = + remember(density, path) { readResourceBytes(path).decodeToImageVector(density) } + return rememberVectorPainter(imageVector) + } + + @OptIn(ExperimentalResourceApi::class) + @Composable + internal fun rememberSvgResource(path: String): Painter { + val density = LocalDensity.current + return remember(density, path) { readResourceBytes(path).decodeToSvgPainter(density) } + } + + private object ResourceLoader + + private fun readResourceBytes(resourcePath: String) = + ResourceLoader.javaClass.classLoader.getResourceAsStream(resourcePath).readAllBytes() +} From 35b22fcc01010d9856c5c824f73034297330f157 Mon Sep 17 00:00:00 2001 From: kateliu20 Date: Mon, 23 Sep 2024 17:01:07 -0400 Subject: [PATCH 09/10] Change PainterResource to an object --- .../src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt | 2 +- .../src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt index e5970e0e9..208b62d53 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt @@ -124,7 +124,7 @@ private fun ConversationField(modifier: Modifier = Modifier, onSendMessage: (Str enabled = isTextNotEmpty, ) { Icon( - painter = PainterResource().painterResource("drawable/send.svg"), + painter = PainterResource.painterResource("drawable/send.svg"), contentDescription = "Send", modifier = Modifier.size(20.dp), ) diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt index 372d22e02..02e9630e4 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt @@ -28,7 +28,7 @@ import org.jetbrains.compose.resources.decodeToSvgPainter // Migration snippet copied from https://github.com/JetBrains/compose-multiplatform-core/pull/1457 // To resolve deprecated painterResource function from upgrading compose-jb -class PainterResource { +object PainterResource { @Composable fun painterResource(resourcePath: String): Painter = when (resourcePath.substringAfterLast(".")) { From d432093d8eb493b111c741a093ee93b0bdd59d71 Mon Sep 17 00:00:00 2001 From: kateliu20 Date: Mon, 23 Sep 2024 17:17:31 -0400 Subject: [PATCH 10/10] remove object --- .../slack/tooling/aibot/ChatWindowUi.kt | 2 +- .../slack/tooling/aibot/PainterResource.kt | 59 +++++++++---------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt index 208b62d53..00415fd5d 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/ChatWindowUi.kt @@ -124,7 +124,7 @@ private fun ConversationField(modifier: Modifier = Modifier, onSendMessage: (Str enabled = isTextNotEmpty, ) { Icon( - painter = PainterResource.painterResource("drawable/send.svg"), + painter = painterResource("drawable/send.svg"), contentDescription = "Send", modifier = Modifier.size(20.dp), ) diff --git a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt index 02e9630e4..aa5806656 100644 --- a/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt +++ b/skate-plugin/project-gen/src/jvmMain/kotlin/slack/tooling/aibot/PainterResource.kt @@ -28,39 +28,36 @@ import org.jetbrains.compose.resources.decodeToSvgPainter // Migration snippet copied from https://github.com/JetBrains/compose-multiplatform-core/pull/1457 // To resolve deprecated painterResource function from upgrading compose-jb -object PainterResource { - @Composable - fun painterResource(resourcePath: String): Painter = - when (resourcePath.substringAfterLast(".")) { - "svg" -> rememberSvgResource(resourcePath) - "xml" -> rememberVectorXmlResource(resourcePath) - else -> rememberBitmapResource(resourcePath) - } - - @OptIn(ExperimentalResourceApi::class) - @Composable - internal fun rememberBitmapResource(path: String): Painter { - return remember(path) { BitmapPainter(readResourceBytes(path).decodeToImageBitmap()) } - } - - @OptIn(ExperimentalResourceApi::class) - @Composable - internal fun rememberVectorXmlResource(path: String): Painter { - val density = LocalDensity.current - val imageVector = - remember(density, path) { readResourceBytes(path).decodeToImageVector(density) } - return rememberVectorPainter(imageVector) +@Composable +fun painterResource(resourcePath: String): Painter = + when (resourcePath.substringAfterLast(".")) { + "svg" -> rememberSvgResource(resourcePath) + "xml" -> rememberVectorXmlResource(resourcePath) + else -> rememberBitmapResource(resourcePath) } - @OptIn(ExperimentalResourceApi::class) - @Composable - internal fun rememberSvgResource(path: String): Painter { - val density = LocalDensity.current - return remember(density, path) { readResourceBytes(path).decodeToSvgPainter(density) } - } +@OptIn(ExperimentalResourceApi::class) +@Composable +internal fun rememberBitmapResource(path: String): Painter { + return remember(path) { BitmapPainter(readResourceBytes(path).decodeToImageBitmap()) } +} - private object ResourceLoader +@OptIn(ExperimentalResourceApi::class) +@Composable +internal fun rememberVectorXmlResource(path: String): Painter { + val density = LocalDensity.current + val imageVector = remember(density, path) { readResourceBytes(path).decodeToImageVector(density) } + return rememberVectorPainter(imageVector) +} - private fun readResourceBytes(resourcePath: String) = - ResourceLoader.javaClass.classLoader.getResourceAsStream(resourcePath).readAllBytes() +@OptIn(ExperimentalResourceApi::class) +@Composable +internal fun rememberSvgResource(path: String): Painter { + val density = LocalDensity.current + return remember(density, path) { readResourceBytes(path).decodeToSvgPainter(density) } } + +private object ResourceLoader + +private fun readResourceBytes(resourcePath: String) = + ResourceLoader.javaClass.classLoader.getResourceAsStream(resourcePath).readAllBytes()