diff --git a/gradle-client/build.gradle.kts b/gradle-client/build.gradle.kts index 135717b..89e3406 100644 --- a/gradle-client/build.gradle.kts +++ b/gradle-client/build.gradle.kts @@ -63,6 +63,7 @@ kotlin { implementation(libs.material3WindowSizeClassMultiplatform) implementation(libs.materialKolor) + implementation(libs.filekit.compose) implementation(libs.slf4j.api) implementation(libs.logback.classic) diff --git a/gradle-client/proguard-desktop.pro b/gradle-client/proguard-desktop.pro index 31491a9..ad81f4b 100644 --- a/gradle-client/proguard-desktop.pro +++ b/gradle-client/proguard-desktop.pro @@ -31,7 +31,6 @@ -dontwarn org.openjsse.** # Kotlin embedded compiler dependencies --dontwarn com.sun.jna.** -dontwarn kotlin.annotations.jvm.** -dontwarn org.jetbrains.kotlin.com.google.common.** -dontwarn org.jetbrains.kotlin.com.google.gson.** @@ -86,3 +85,9 @@ # Kotlin embedded compiler -keep class org.jetbrains.kotlin.** { *; } + +# JNA classes +-keep class com.sun.jna.** { *; } +-keepclassmembers class * extends com.sun.jna.** { public *; } +-keep class * implements com.sun.jna.** { *; } +-dontnote com.sun.** diff --git a/gradle-client/src/jvmMain/kotlin/org/gradle/client/ui/build/BuildContent.kt b/gradle-client/src/jvmMain/kotlin/org/gradle/client/ui/build/BuildContent.kt index 9658548..0081407 100644 --- a/gradle-client/src/jvmMain/kotlin/org/gradle/client/ui/build/BuildContent.kt +++ b/gradle-client/src/jvmMain/kotlin/org/gradle/client/ui/build/BuildContent.kt @@ -13,6 +13,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import com.arkivanov.decompose.extensions.compose.subscribeAsState +import io.github.vinceglb.filekit.compose.rememberDirectoryPickerLauncher import kotlinx.coroutines.launch import org.gradle.client.core.database.Build import org.gradle.client.core.gradle.GradleConnectionParameters @@ -136,7 +137,6 @@ private fun BuildMainContent(component: BuildComponent, build: Build, snackbarSt state = javaHome, defaultState = System.getenv("JAVA_HOME")?.takeIf { it.isNotBlank() }, isError = !isJavaHomeValid, - showHiddenFiles = true, showSnackbar = { message -> scope.launch { snackbarState.showSnackbar(message) } } ) DirectoryField( @@ -144,7 +144,6 @@ private fun BuildMainContent(component: BuildComponent, build: Build, snackbarSt state = gradleUserHome, defaultState = System.getProperty("user.home") + "/.gradle", isError = !isGradleUserHomeValid, - showHiddenFiles = true, showSnackbar = { message -> scope.launch { snackbarState.showSnackbar(message) } }, ) GradleDistributionField(state = gradleDistSource) @@ -268,7 +267,6 @@ private fun DirectoryField( defaultState: String? = null, readOnly: Boolean = false, isError: Boolean = false, - showHiddenFiles: Boolean = false, showSnackbar: (message: String) -> Unit, ) { BuildTextField( @@ -287,20 +285,12 @@ private fun DirectoryField( }, trailingIcon = { val helpText = "Select a $description" - var isDirChooserOpen by remember { mutableStateOf(false) } - if (isDirChooserOpen) { - DirChooserDialog( - helpText = helpText, - showHiddenFiles = showHiddenFiles, - onDirChosen = { dir -> - isDirChooserOpen = false - if (dir == null) { - showSnackbar("No $description selected") - } else { - state.value = dir.absolutePath - } - } - ) + val dirPickerLauncher = rememberDirectoryPickerLauncher(helpText) { dir -> + if (dir == null) { + showSnackbar("No $description selected") + } else { + state.value = dir.file.absolutePath + } } Row { IconButton( @@ -309,7 +299,7 @@ private fun DirectoryField( content = { Icon(Icons.Default.Clear, "Clear") } ) PlainTextTooltip(helpText) { - IconButton(onClick = { isDirChooserOpen = true }) { + IconButton(onClick = { dirPickerLauncher.launch() }) { Icon(Icons.Default.Folder, helpText) } } diff --git a/gradle-client/src/jvmMain/kotlin/org/gradle/client/ui/buildlist/BuildListContent.kt b/gradle-client/src/jvmMain/kotlin/org/gradle/client/ui/buildlist/BuildListContent.kt index 7ce6bc7..b9a6f3c 100644 --- a/gradle-client/src/jvmMain/kotlin/org/gradle/client/ui/buildlist/BuildListContent.kt +++ b/gradle-client/src/jvmMain/kotlin/org/gradle/client/ui/buildlist/BuildListContent.kt @@ -15,6 +15,8 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.arkivanov.decompose.extensions.compose.subscribeAsState +import io.github.vinceglb.filekit.compose.rememberDirectoryPickerLauncher +import io.github.vinceglb.filekit.core.FileKitPlatformSettings import kotlinx.coroutines.launch import org.gradle.client.core.Constants.APPLICATION_DISPLAY_NAME import org.gradle.client.core.database.Build @@ -79,32 +81,25 @@ private fun BuildListDeleteButon(component: BuildListComponent, build: Build) { @Composable private fun AddBuildButton(component: BuildListComponent, snackbarState: SnackbarHostState) { val scope = rememberCoroutineScope() - var isDirChooserOpen by remember { mutableStateOf(false) } - if (isDirChooserOpen) { - DirChooserDialog( - helpText = ADD_BUILD_HELP_TEXT, - onDirChosen = { rootDir -> - isDirChooserOpen = false - if (rootDir == null) { - scope.launch { snackbarState.showSnackbar("No build selected") } - } else { - val valid = rootDir.listFiles { file -> - file.name.startsWith("settings.gradle") - }?.isNotEmpty() ?: false - if (!valid) { - scope.launch { snackbarState.showSnackbar("Directory is not a Gradle build!") } - } else { - component.onNewBuildRootDirChosen(rootDir) - } - } + val dirPickerLauncher = rememberDirectoryPickerLauncher(ADD_BUILD_HELP_TEXT) { rootDir -> + if (rootDir == null) { + scope.launch { snackbarState.showSnackbar("No build selected") } + } else { + val valid = rootDir.file.listFiles { file -> + file.name.startsWith("settings.gradle") + }?.isNotEmpty() ?: false + if (!valid) { + scope.launch { snackbarState.showSnackbar("Directory is not a Gradle build!") } + } else { + component.onNewBuildRootDirChosen(rootDir.file) } - ) + } } PlainTextTooltip(ADD_BUILD_HELP_TEXT) { ExtendedFloatingActionButton( icon = { Icon(Icons.Default.Add, "") }, text = { Text(text = "Add build", Modifier.testTag("add_build")) }, - onClick = { isDirChooserOpen = true }, + onClick = { dirPickerLauncher.launch() }, ) } } diff --git a/gradle-client/src/jvmMain/kotlin/org/gradle/client/ui/composables/DirChooserDialog.kt b/gradle-client/src/jvmMain/kotlin/org/gradle/client/ui/composables/DirChooserDialog.kt deleted file mode 100644 index ed52e9d..0000000 --- a/gradle-client/src/jvmMain/kotlin/org/gradle/client/ui/composables/DirChooserDialog.kt +++ /dev/null @@ -1,27 +0,0 @@ -package org.gradle.client.ui.composables - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import java.io.File -import javax.swing.JFileChooser - -@Composable -fun DirChooserDialog( - helpText: String, - showHiddenFiles: Boolean = false, - onDirChosen: (dir: File?) -> Unit, -) { - LaunchedEffect(Unit) { - val chooser = JFileChooser() - chooser.dialogTitle = helpText - chooser.fileSelectionMode = JFileChooser.DIRECTORIES_ONLY - chooser.isAcceptAllFileFilterUsed = false - chooser.isMultiSelectionEnabled = false - chooser.isFileHidingEnabled = !showHiddenFiles - if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { - onDirChosen(chooser.selectedFile) - } else { - onDirChosen(null) - } - } -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index df217a4..fc32949 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -30,6 +30,7 @@ gradle-declarative-dsl-evaluator = { module = "org.gradle:gradle-declarative-dsl gradle-declarative-dsl-tooling-models = { module = "org.gradle:gradle-declarative-dsl-tooling-models", version.ref = "declarative-dsl" } material3WindowSizeClassMultiplatform = { module = "dev.chrisbanes.material3:material3-window-size-class-multiplatform", version = "0.3.1" } materialKolor = { module = "com.materialkolor:material-kolor", version = "1.4.4" } +filekit-compose = { module = "io.github.vinceglb:filekit-compose", version = "0.7.0" } slf4j-api = { module = "org.slf4j:slf4j-api", version = "2.0.12" } logback-classic = { module = "ch.qos.logback:logback-classic", version = "1.5.3" } junit-junit = { module = "junit:junit", version = "4.13.2" }