Skip to content

Commit

Permalink
Use native file pickers from FileKit on Mac and Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] committed Aug 7, 2024
1 parent 30fa1c6 commit 465630c
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 40 deletions.
1 change: 1 addition & 0 deletions gradle-client/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ kotlin {

implementation(libs.material3WindowSizeClassMultiplatform)
implementation(libs.materialKolor)
implementation(libs.filekit.compose)

implementation(libs.slf4j.api)
implementation(libs.logback.classic)
Expand Down
7 changes: 6 additions & 1 deletion gradle-client/proguard-desktop.pro
Original file line number Diff line number Diff line change
Expand Up @@ -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.**
Expand Down Expand Up @@ -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.**
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ enum class DesktopOS(val id: String) {
Linux("linux"),
Mac("macos"),
Windows("windows");

val isLinux: Boolean get() = this == Linux
}

val currentDesktopOS: DesktopOS by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -21,6 +22,7 @@ import org.gradle.client.core.gradle.GradleConnectionParameters.Companion.isVali
import org.gradle.client.core.gradle.GradleConnectionParameters.Companion.isValidGradleVersion
import org.gradle.client.core.gradle.GradleConnectionParameters.Companion.isValidJavaHome
import org.gradle.client.core.gradle.GradleDistribution
import org.gradle.client.core.util.currentDesktopOS
import org.gradle.client.ui.composables.*
import org.gradle.client.ui.theme.plusPaneSpacing
import org.gradle.client.ui.theme.spacing
Expand Down Expand Up @@ -287,37 +289,82 @@ 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
}
}
)
}
Row {
IconButton(
enabled = state.value.isNotBlank(),
onClick = { state.value = "" },
content = { Icon(Icons.Default.Clear, "Clear") }
)
PlainTextTooltip(helpText) {
IconButton(onClick = { isDirChooserOpen = true }) {
Icon(Icons.Default.Folder, helpText)
}
}
if (currentDesktopOS.isLinux) {
LinuxDirectoryFieldPicker(description, helpText, state, showHiddenFiles, showSnackbar)
} else {
NonLinuxDirectoryFieldPicker(description, helpText, state, showSnackbar)
}
},
)
}

@Composable
private fun LinuxDirectoryFieldPicker(
description: String,
helpText: String,
state: MutableState<String>,
showHiddenFiles: Boolean = false,
showSnackbar: (message: String) -> Unit,
) {
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
}
}
)
}
DirectoryFilePickerIcon(helpText, state) {
isDirChooserOpen = true
}
}

@Composable
private fun NonLinuxDirectoryFieldPicker(
description: String,
helpText: String,
state: MutableState<String>,
showSnackbar: (message: String) -> Unit,
) {
val dirPickerLauncher = rememberDirectoryPickerLauncher(helpText) { dir ->
if (dir == null) {
showSnackbar("No $description selected")
} else {
state.value = dir.file.absolutePath
}
}
DirectoryFilePickerIcon(helpText, state) {
dirPickerLauncher.launch()
}
}

@Composable
private fun DirectoryFilePickerIcon(
helpText: String,
state: MutableState<String>,
onClick: () -> Unit
) {
Row {
IconButton(
enabled = state.value.isNotBlank(),
onClick = { state.value = "" },
content = { Icon(Icons.Default.Clear, "Clear") }
)
PlainTextTooltip(helpText) {
IconButton(onClick = onClick) {
Icon(Icons.Default.Folder, helpText)
}
}
}
}

@Composable
@Suppress("LongParameterList")
fun BuildTextField(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@ 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.CoroutineScope
import kotlinx.coroutines.launch
import org.gradle.client.core.Constants.APPLICATION_DISPLAY_NAME
import org.gradle.client.core.database.Build
import org.gradle.client.core.util.currentDesktopOS
import org.gradle.client.ui.composables.*
import org.gradle.client.ui.theme.plusPaneSpacing
import java.io.File

@Composable
fun BuildListContent(component: BuildListComponent) {
Expand Down Expand Up @@ -78,33 +83,65 @@ private fun BuildListDeleteButon(component: BuildListComponent, build: Build) {

@Composable
private fun AddBuildButton(component: BuildListComponent, snackbarState: SnackbarHostState) {
if (currentDesktopOS.isLinux) {
LinuxAddBuildButton(component, snackbarState)
} else {
NonLinuxAddBuildButton(component, snackbarState)
}
}

@Composable
private fun NonLinuxAddBuildButton(component: BuildListComponent, snackbarState: SnackbarHostState) {
val scope = rememberCoroutineScope()
val dirPickerLauncher = rememberDirectoryPickerLauncher(ADD_BUILD_HELP_TEXT) { rootDir ->
onBuildDirSelected(scope, component, snackbarState, rootDir?.file)
}
AddBuildDirFAB { dirPickerLauncher.launch() }
}

@Composable
private fun LinuxAddBuildButton(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)
}
}
onBuildDirSelected(scope, component, snackbarState, rootDir)
}
)
}
AddBuildDirFAB { isDirChooserOpen = true }
}

private fun onBuildDirSelected(
scope: CoroutineScope,
component: BuildListComponent,
snackbarState: SnackbarHostState,
rootDir: File?
) {
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)
}
}
}

@Composable
private fun AddBuildDirFAB(onClick: () -> Unit) {
PlainTextTooltip(ADD_BUILD_HELP_TEXT) {
ExtendedFloatingActionButton(
icon = { Icon(Icons.Default.Add, "") },
text = { Text(text = "Add build", Modifier.testTag("add_build")) },
onClick = { isDirChooserOpen = true },
onClick = onClick,
)
}
}
Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down

0 comments on commit 465630c

Please sign in to comment.