From 1164b346cc74998aaf53b95073ef2a4a526f79bc Mon Sep 17 00:00:00 2001 From: Goooler Date: Mon, 22 Jul 2024 11:33:24 +0800 Subject: [PATCH] Fully migrate to nio Path --- .../valkyrie/generator/imagevector/Common.kt | 4 +- .../valkyrie/parser/IconParser.kt | 18 ++++---- .../valkyrie/parser/SvgToXmlParser.kt | 5 +-- .../valkyrie/ui/extension/VirtualFile.kt | 5 ++- .../ui/foundation/dnd/DragAndDropHandler.kt | 26 ++++++----- .../ui/foundation/picker/DirectoryPicker.kt | 13 +++--- .../ui/foundation/picker/FilePicker.kt | 20 ++++----- .../foundation/picker/MultipleFilesPicker.kt | 19 ++++---- .../conversion/IconPackConversionState.kt | 4 +- .../conversion/IconPackConversionViewModel.kt | 43 +++++++++++-------- .../conversion/ui/BatchProcessingState.kt | 6 +-- .../conversion/ui/IconPackPickerState.kt | 26 +++++------ .../iconpack/conversion/util/FileToPainter.kt | 10 +++-- .../destination/IconPackDestinationScreen.kt | 7 ++- .../conversion/SimpleConversionScreen.kt | 34 +++++++-------- .../conversion/SimpleConversionState.kt | 4 +- .../conversion/SimpleConversionViewModel.kt | 16 +++---- stability_config.conf | 2 +- 18 files changed, 140 insertions(+), 122 deletions(-) diff --git a/components/generator/imagevector/src/test/kotlin/io/github/composegears/valkyrie/generator/imagevector/Common.kt b/components/generator/imagevector/src/test/kotlin/io/github/composegears/valkyrie/generator/imagevector/Common.kt index f19680bb..75c69a92 100644 --- a/components/generator/imagevector/src/test/kotlin/io/github/composegears/valkyrie/generator/imagevector/Common.kt +++ b/components/generator/imagevector/src/test/kotlin/io/github/composegears/valkyrie/generator/imagevector/Common.kt @@ -1,6 +1,6 @@ package io.github.composegears.valkyrie.generator.imagevector -import java.io.File +import kotlin.io.path.Path val DEFAULT_CONFIG = ImageVectorGeneratorConfig( packageName = "io.github.composegears.valkyrie.icons", @@ -9,4 +9,4 @@ val DEFAULT_CONFIG = ImageVectorGeneratorConfig( generatePreview = false ) -fun loadIcon(name: String) = File("src/test/resources/${name}") \ No newline at end of file +fun loadIcon(name: String) = Path("src/test/resources/${name}") \ No newline at end of file diff --git a/components/parser/src/main/kotlin/io/github/composegears/valkyrie/parser/IconParser.kt b/components/parser/src/main/kotlin/io/github/composegears/valkyrie/parser/IconParser.kt index 5aca4a0d..411c5fd9 100644 --- a/components/parser/src/main/kotlin/io/github/composegears/valkyrie/parser/IconParser.kt +++ b/components/parser/src/main/kotlin/io/github/composegears/valkyrie/parser/IconParser.kt @@ -5,9 +5,11 @@ import androidx.compose.material.icons.generator.IconParser import androidx.compose.material.icons.generator.vector.Vector import io.github.composegears.valkyrie.parser.IconType.SVG import io.github.composegears.valkyrie.parser.IconType.XML -import java.io.File +import java.nio.file.Path import java.util.* import kotlin.io.path.createTempFile +import kotlin.io.path.extension +import kotlin.io.path.name import kotlin.io.path.readText data class IconParserOutput( @@ -18,18 +20,18 @@ data class IconParserOutput( object IconParser { @Throws(IllegalStateException::class) - fun toVector(file: File): IconParserOutput { - val iconType = IconTypeParser.getIconType(file.extension) ?: error("File not SVG or XML") + fun toVector(path: Path): IconParserOutput { + val iconType = IconTypeParser.getIconType(path.extension) ?: error("File not SVG or XML") - val fileName = getIconName(fileName = file.name) + val fileName = getIconName(fileName = path.name) val icon = when (iconType) { SVG -> { - val tmpFile = createTempFile(suffix = "valkyrie/") - SvgToXmlParser.parse(file, tmpFile) + val tmpPath = createTempFile(suffix = "valkyrie/") + SvgToXmlParser.parse(path, tmpPath) - Icon(fileContent = tmpFile.readText()) + Icon(fileContent = tmpPath.readText()) } - XML -> Icon(fileContent = file.readText()) + XML -> Icon(fileContent = path.readText()) } return IconParserOutput( diff --git a/components/parser/src/main/kotlin/io/github/composegears/valkyrie/parser/SvgToXmlParser.kt b/components/parser/src/main/kotlin/io/github/composegears/valkyrie/parser/SvgToXmlParser.kt index ce3b53c5..956ed348 100644 --- a/components/parser/src/main/kotlin/io/github/composegears/valkyrie/parser/SvgToXmlParser.kt +++ b/components/parser/src/main/kotlin/io/github/composegears/valkyrie/parser/SvgToXmlParser.kt @@ -1,13 +1,12 @@ package io.github.composegears.valkyrie.parser import com.android.ide.common.vectordrawable.Svg2Vector -import java.io.File import java.nio.file.Path import kotlin.io.path.outputStream object SvgToXmlParser { - fun parse(file: File, outPath: Path) { - Svg2Vector.parseSvgToXml(file.toPath(), outPath.outputStream()) + fun parse(input: Path, output: Path) { + Svg2Vector.parseSvgToXml(input, output.outputStream()) } } \ No newline at end of file diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/extension/VirtualFile.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/extension/VirtualFile.kt index b34d5ba5..4924f9e4 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/extension/VirtualFile.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/extension/VirtualFile.kt @@ -1,6 +1,7 @@ package io.github.composegears.valkyrie.ui.extension import com.intellij.openapi.vfs.VirtualFile -import java.io.File +import java.nio.file.Path +import kotlin.io.path.Path -fun VirtualFile.toFile() = File(path) \ No newline at end of file +fun VirtualFile.toPath(): Path = Path(path) \ No newline at end of file diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/dnd/DragAndDropHandler.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/dnd/DragAndDropHandler.kt index 3a770aff..adebc702 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/dnd/DragAndDropHandler.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/dnd/DragAndDropHandler.kt @@ -15,21 +15,22 @@ import java.awt.dnd.DropTargetDragEvent import java.awt.dnd.DropTargetDropEvent import java.awt.dnd.DropTargetEvent import java.awt.dnd.DropTargetListener -import java.io.File +import java.nio.file.Path +import kotlin.io.path.isDirectory @Composable -fun rememberDragAndDropFolderHandler(onDrop: (String) -> Unit): DragAndDropHandlerState { - return rememberFileDragAndDropHandler { file -> +fun rememberDragAndDropFolderHandler(onDrop: (Path) -> Unit): DragAndDropHandlerState { + return rememberFileDragAndDropHandler { path -> val destination = when { - file.isDirectory -> file.path - else -> file.parent + path.isDirectory() -> path + else -> path.parent } onDrop(destination) } } @Composable -fun rememberFileDragAndDropHandler(onDrop: (File) -> Unit): DragAndDropHandlerState { +fun rememberFileDragAndDropHandler(onDrop: (Path) -> Unit): DragAndDropHandlerState { return rememberMultiSelectDragAndDropHandler { fileList -> if (fileList.isNotEmpty()) { onDrop(fileList.first()) @@ -38,7 +39,7 @@ fun rememberFileDragAndDropHandler(onDrop: (File) -> Unit): DragAndDropHandlerSt } @Composable -fun rememberMultiSelectDragAndDropHandler(onDrop: (List) -> Unit): DragAndDropHandlerState { +fun rememberMultiSelectDragAndDropHandler(onDrop: (List) -> Unit): DragAndDropHandlerState { if (LocalInspectionMode.current) { return DragAndDropHandlerState() } else { @@ -73,7 +74,7 @@ data class DragAndDropHandlerState(val isDragging: Boolean = false) { private class SimpleDropTargetListener( val onDragEnter: () -> Unit = {}, val onDragExit: () -> Unit = {}, - val onDrop: (List) -> Unit = {} + val onDrop: (List) -> Unit = {} ) : DropTargetListener { override fun dragEnter(dtde: DropTargetDragEvent?) = onDragEnter() @@ -87,13 +88,16 @@ private class SimpleDropTargetListener( event.acceptDrop(DnDConstants.ACTION_COPY) val transferable = event.transferable - val files = transferable.transferDataFlavors + val paths = transferable.transferDataFlavors + .asSequence() .filter { it.isFlavorJavaFileListType } .mapNotNull { transferable.getTransferData(it) as? List<*> } .flatten() - .filterIsInstance() + .filterIsInstance() + .map { it.toPath() } + .toList() - onDrop(files) + onDrop(paths) event.dropComplete(true) onDragExit() } diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/picker/DirectoryPicker.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/picker/DirectoryPicker.kt index 4ac4e63d..9c75042d 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/picker/DirectoryPicker.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/picker/DirectoryPicker.kt @@ -10,20 +10,21 @@ import com.intellij.openapi.project.Project import io.github.composegears.valkyrie.ui.foundation.theme.LocalProject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import java.nio.file.Path @Composable -fun rememberDirectoryPicker(): Picker { +fun rememberDirectoryPicker(): Picker { if (LocalInspectionMode.current) return StubDirectoryPicker val project = LocalProject.current return remember { DirectoryPicker(project = project) } } -private object StubDirectoryPicker : Picker { - override suspend fun launch(): String? = null +private object StubDirectoryPicker : Picker { + override suspend fun launch(): Path? = null } -private class DirectoryPicker(private val project: Project) : Picker { +private class DirectoryPicker(private val project: Project) : Picker { private val fileChooserDescriptor = FileChooserDescriptor( /* chooseFiles = */ false, @@ -34,7 +35,7 @@ private class DirectoryPicker(private val project: Project) : Picker { /* chooseMultiple = */ false ) - override suspend fun launch(): String? = withContext(Dispatchers.EDT) { - FileChooser.chooseFile(fileChooserDescriptor, project, null)?.path + override suspend fun launch(): Path? = withContext(Dispatchers.EDT) { + FileChooser.chooseFile(fileChooserDescriptor, project, null)?.toNioPath() } } \ No newline at end of file diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/picker/FilePicker.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/picker/FilePicker.kt index c17cf760..e98b2ffa 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/picker/FilePicker.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/picker/FilePicker.kt @@ -11,14 +11,14 @@ import com.intellij.openapi.util.Condition import com.intellij.openapi.vfs.VirtualFile import io.github.composegears.valkyrie.ui.extension.isSvg import io.github.composegears.valkyrie.ui.extension.isXml -import io.github.composegears.valkyrie.ui.extension.toFile +import io.github.composegears.valkyrie.ui.extension.toPath import io.github.composegears.valkyrie.ui.foundation.theme.LocalProject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import java.io.File +import java.nio.file.Path @Composable -fun rememberFilePicker(): Picker { +fun rememberFilePicker(): Picker { if (LocalInspectionMode.current) return StubFilePicker val project = LocalProject.current @@ -26,8 +26,8 @@ fun rememberFilePicker(): Picker { return remember { FilePicker( project = project, - filterCondition = { file -> - val extension = file.extension + filterCondition = { path -> + val extension = path.extension extension != null && (extension.isSvg() || extension.isXml()) } @@ -35,14 +35,14 @@ fun rememberFilePicker(): Picker { } } -private object StubFilePicker : Picker { - override suspend fun launch(): File? = null +private object StubFilePicker : Picker { + override suspend fun launch(): Path? = null } private class FilePicker( private val project: Project, filterCondition: Condition = Condition { true } -) : Picker { +) : Picker { private val fileChooserDescriptor = FileChooserDescriptor( /* chooseFiles = */ true, @@ -53,9 +53,9 @@ private class FilePicker( /* chooseMultiple = */ false ).withFileFilter(filterCondition) - override suspend fun launch() = withContext(Dispatchers.EDT) { + override suspend fun launch(): Path? = withContext(Dispatchers.EDT) { FileChooser .chooseFile(fileChooserDescriptor, project, null) - ?.toFile() + ?.toPath() } } \ No newline at end of file diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/picker/MultipleFilesPicker.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/picker/MultipleFilesPicker.kt index 45890cff..60883864 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/picker/MultipleFilesPicker.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/foundation/picker/MultipleFilesPicker.kt @@ -11,14 +11,13 @@ import com.intellij.openapi.util.Condition import com.intellij.openapi.vfs.VirtualFile import io.github.composegears.valkyrie.ui.extension.isSvg import io.github.composegears.valkyrie.ui.extension.isXml -import io.github.composegears.valkyrie.ui.extension.toFile import io.github.composegears.valkyrie.ui.foundation.theme.LocalProject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import java.io.File +import java.nio.file.Path @Composable -fun rememberMultipleFilesPicker(): Picker> { +fun rememberMultipleFilesPicker(): Picker> { if (LocalInspectionMode.current) return StubMultipleFilesPicker val project = LocalProject.current @@ -26,8 +25,8 @@ fun rememberMultipleFilesPicker(): Picker> { return remember { MultipleFilesPicker( project = project, - filterCondition = { file -> - val extension = file.extension + filterCondition = { path -> + val extension = path.extension extension != null && (extension.isSvg() || extension.isXml()) } @@ -35,14 +34,14 @@ fun rememberMultipleFilesPicker(): Picker> { } } -private object StubMultipleFilesPicker : Picker> { - override suspend fun launch(): List = emptyList() +private object StubMultipleFilesPicker : Picker> { + override suspend fun launch(): List = emptyList() } private class MultipleFilesPicker( private val project: Project, filterCondition: Condition = Condition { true } -) : Picker> { +) : Picker> { private val fileChooserDescriptor = FileChooserDescriptor( /* chooseFiles = */ true, @@ -53,9 +52,9 @@ private class MultipleFilesPicker( /* chooseMultiple = */ true ).withFileFilter(filterCondition) - override suspend fun launch(): List = withContext(Dispatchers.EDT) { + override suspend fun launch(): List = withContext(Dispatchers.EDT) { FileChooser .chooseFiles(fileChooserDescriptor, project, null) - .map(VirtualFile::toFile) + .map(VirtualFile::toNioPath) } } \ No newline at end of file diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/IconPackConversionState.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/IconPackConversionState.kt index b2ece20c..f1b05af3 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/IconPackConversionState.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/IconPackConversionState.kt @@ -1,7 +1,7 @@ package io.github.composegears.valkyrie.ui.screen.mode.iconpack.conversion import androidx.compose.ui.graphics.painter.Painter -import java.io.File +import java.nio.file.Path sealed interface IconPackConversionState { @@ -35,7 +35,7 @@ sealed interface BatchIcon { override val iconName: IconName, override val extension: String, val painter: Painter, - val file: File + val path: Path ) : BatchIcon } diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/IconPackConversionViewModel.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/IconPackConversionViewModel.kt index 6eb1e26a..f0b82883 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/IconPackConversionViewModel.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/IconPackConversionViewModel.kt @@ -18,7 +18,12 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch -import java.io.File +import java.nio.file.Path +import kotlin.io.path.extension +import kotlin.io.path.name +import kotlin.io.path.isRegularFile +import kotlin.io.path.listDirectoryEntries +import kotlin.io.path.nameWithoutExtension class IconPackConversionViewModel( private val inMemorySettings: InMemorySettings @@ -34,8 +39,8 @@ class IconPackConversionViewModel( fun pickerEvent(events: PickerEvent) { when (events) { - is PickerEvent.PickDirectory -> File(events.path).listFiles()?.toList()?.processFiles() - is PickerEvent.PickFiles -> events.files.processFiles() + is PickerEvent.PickDirectory -> events.path.listDirectoryEntries().processFiles() + is PickerEvent.PickFiles -> events.paths.processFiles() } } @@ -85,7 +90,7 @@ class IconPackConversionViewModel( val icon = iconsToProcess.first { it.iconName == iconName } as BatchIcon.Valid val iconResult = runCatching { - val parserOutput = IconParser.toVector(icon.file) + val parserOutput = IconParser.toVector(icon.path) ImageVectorGenerator.convert( vector = parserOutput.vector, @@ -113,7 +118,7 @@ class IconPackConversionViewModel( .forEach { icon -> when (val iconPack = icon.iconPack) { is IconPack.Nested -> { - val parserOutput = IconParser.toVector(icon.file) + val parserOutput = IconParser.toVector(icon.path) val vectorSpecOutput = ImageVectorGenerator.convert( vector = parserOutput.vector, kotlinName = icon.iconName.value, @@ -132,7 +137,7 @@ class IconPackConversionViewModel( ) } is IconPack.Single -> { - val parserOutput = IconParser.toVector(icon.file) + val parserOutput = IconParser.toVector(icon.path) val vectorSpecOutput = ImageVectorGenerator.convert( vector = parserOutput.vector, kotlinName = parserOutput.kotlinName, @@ -186,25 +191,25 @@ class IconPackConversionViewModel( _state.updateState { IconsPickering } } - private fun List.processFiles() { - val files = filter { it.isFile && (it.extension == "xml" || it.extension == "svg") } + private fun List.processFiles() { + val paths = filter { it.isRegularFile() && (it.extension == "xml" || it.extension == "svg") } - if (files.isNotEmpty()) { + if (paths.isNotEmpty()) { _state.updateState { BatchFilesProcessing( - iconsToProcess = files + iconsToProcess = paths .sortedBy { it.name } - .map { file -> - when (val painter = file.toPainterOrNull()) { + .map { path -> + when (val painter = path.toPainterOrNull()) { null -> BatchIcon.Broken( - iconName = IconName(file.nameWithoutExtension), - extension = file.extension + iconName = IconName(path.nameWithoutExtension), + extension = path.extension ) else -> BatchIcon.Valid( - iconName = IconName(IconParser.getIconName(file.name)), - extension = file.extension, + iconName = IconName(IconParser.getIconName(path.name)), + extension = path.extension, iconPack = inMemorySettings.current.buildDefaultIconPack(), - file = file, + path = path, painter = painter ) } @@ -247,6 +252,6 @@ sealed interface ConversionEvent { } sealed interface PickerEvent { - data class PickDirectory(val path: String) : PickerEvent - data class PickFiles(val files: List) : PickerEvent + data class PickDirectory(val path: Path) : PickerEvent + data class PickFiles(val paths: List) : PickerEvent } \ No newline at end of file diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/ui/BatchProcessingState.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/ui/BatchProcessingState.kt index 163b8ea3..f611c0de 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/ui/BatchProcessingState.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/ui/BatchProcessingState.kt @@ -48,7 +48,7 @@ import io.github.composegears.valkyrie.ui.screen.mode.iconpack.conversion.IconPa import io.github.composegears.valkyrie.ui.screen.mode.iconpack.conversion.ui.batch.FileTypeBadge import io.github.composegears.valkyrie.ui.screen.mode.iconpack.conversion.ui.batch.IconNameField import io.github.composegears.valkyrie.ui.screen.mode.iconpack.conversion.ui.batch.IconPreviewBox -import java.io.File +import kotlin.io.path.Path @OptIn(ExperimentalFoundationApi::class) @Composable @@ -308,7 +308,7 @@ private fun BatchProcessingStatePreview() = PreviewTheme { BatchIcon.Valid( iconName = IconName(IconParser.getIconName("ic_all_path_params_1")), extension = "xml", - file = File(""), + path = Path(""), iconPack = IconPack.Single( iconPackage = "package", iconPackName = "ValkyrieIcons" @@ -322,7 +322,7 @@ private fun BatchProcessingStatePreview() = PreviewTheme { BatchIcon.Valid( iconName = IconName(IconParser.getIconName("ic_all_path")), extension = "svg", - file = File(""), + path = Path(""), iconPack = IconPack.Nested( iconPackName = "ValkyrieIcons", iconPackage = "package", diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/ui/IconPackPickerState.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/ui/IconPackPickerState.kt index 16cb6faf..9fd5b3cc 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/ui/IconPackPickerState.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/ui/IconPackPickerState.kt @@ -38,7 +38,9 @@ import io.github.composegears.valkyrie.ui.screen.mode.iconpack.conversion.Picker import io.github.composegears.valkyrie.ui.screen.mode.iconpack.conversion.PickerEvent.PickDirectory import io.github.composegears.valkyrie.ui.screen.mode.iconpack.conversion.PickerEvent.PickFiles import kotlinx.coroutines.launch -import java.io.File +import java.nio.file.Path +import kotlin.io.path.isDirectory +import kotlin.io.path.isRegularFile @Composable fun IconPackPickerState(onPickerEvent: (PickerEvent) -> Unit) { @@ -52,17 +54,17 @@ fun IconPackPickerState(onPickerEvent: (PickerEvent) -> Unit) { contentAlignment = Alignment.Center ) { SelectableState( - onSelectFile = { files -> + onSelectPath = { paths -> when { - files.size == 1 -> { - val file = files.first() + paths.size == 1 -> { + val path = paths.first() when { - file.isDirectory -> onPickerEvent(PickDirectory(path = file.path)) - file.isFile -> onPickerEvent(PickFiles(files = files)) + path.isDirectory() -> onPickerEvent(PickDirectory(path = path)) + path.isRegularFile() -> onPickerEvent(PickFiles(paths = paths)) } } - else -> onPickerEvent(PickFiles(files = files)) + else -> onPickerEvent(PickFiles(paths = paths)) } }, onPickDirectory = { @@ -76,10 +78,10 @@ fun IconPackPickerState(onPickerEvent: (PickerEvent) -> Unit) { }, onPickFiles = { scope.launch { - val files = multipleFilePicker.launch() + val paths = multipleFilePicker.launch() - if (files.isNotEmpty()) { - onPickerEvent(PickFiles(files = files)) + if (paths.isNotEmpty()) { + onPickerEvent(PickFiles(paths = paths)) } } } @@ -92,9 +94,9 @@ fun IconPackPickerState(onPickerEvent: (PickerEvent) -> Unit) { private fun SelectableState( onPickDirectory: () -> Unit, onPickFiles: () -> Unit, - onSelectFile: (List) -> Unit + onSelectPath: (List) -> Unit ) { - val dragAndDropHandler = rememberMultiSelectDragAndDropHandler(onDrop = onSelectFile) + val dragAndDropHandler = rememberMultiSelectDragAndDropHandler(onDrop = onSelectPath) val isDragging by rememberMutableState(dragAndDropHandler.isDragging) { dragAndDropHandler.isDragging } DragAndDropBox(isDragging = isDragging) { diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/util/FileToPainter.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/util/FileToPainter.kt index 00ea012a..ac2c197e 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/util/FileToPainter.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/conversion/util/FileToPainter.kt @@ -4,17 +4,19 @@ import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.toPainter import com.android.ide.common.vectordrawable.VdPreview import io.github.composegears.valkyrie.parser.SvgToXmlParser -import java.io.File +import java.nio.file.Path import kotlin.io.path.createTempFile +import kotlin.io.path.extension +import kotlin.io.path.name import kotlin.io.path.readText -fun File.toPainterOrNull(): Painter? = when (extension) { +fun Path.toPainterOrNull(): Painter? = when (extension) { "svg" -> svgToPainter() "xml" -> xmlToPainter() else -> error("Unsupported file type: $extension") } -private fun File.svgToPainter(): Painter? { +private fun Path.svgToPainter(): Painter? { return runCatching { val outPath = createTempFile(name, extension) SvgToXmlParser.parse(this, outPath) @@ -27,7 +29,7 @@ private fun File.svgToPainter(): Painter? { }.getOrElse { null } } -private fun File.xmlToPainter(): Painter? = runCatching { +private fun Path.xmlToPainter(): Painter? = runCatching { VdPreview.getPreviewFromVectorXml( VdPreview.TargetSize.createFromScale(5.0), this.readText(), diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/destination/IconPackDestinationScreen.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/destination/IconPackDestinationScreen.kt index 67398279..7b1837fe 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/destination/IconPackDestinationScreen.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/iconpack/destination/IconPackDestinationScreen.kt @@ -40,6 +40,7 @@ import io.github.composegears.valkyrie.ui.foundation.picker.rememberDirectoryPic import io.github.composegears.valkyrie.ui.foundation.theme.PreviewTheme import io.github.composegears.valkyrie.ui.screen.mode.iconpack.creation.IconPackCreationScreen import kotlinx.coroutines.launch +import kotlin.io.path.absolutePathString val IconPackDestinationScreen by navDestination { val navController = navController() @@ -47,7 +48,9 @@ val IconPackDestinationScreen by navDestination { val state by viewModel.state.collectAsState() - val dragAndDropHandler = rememberDragAndDropFolderHandler(onDrop = viewModel::updateDestination) + val dragAndDropHandler = rememberDragAndDropFolderHandler { + viewModel.updateDestination(it.absolutePathString()) + } val isDragging by remember(dragAndDropHandler.isDragging) { mutableStateOf(dragAndDropHandler.isDragging) } val scope = rememberCoroutineScope() @@ -61,7 +64,7 @@ val IconPackDestinationScreen by navDestination { val path = directoryPicker.launch() if (path != null) { - viewModel.updateDestination(path) + viewModel.updateDestination(path.absolutePathString()) } } }, diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/simple/conversion/SimpleConversionScreen.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/simple/conversion/SimpleConversionScreen.kt index 0a4969b3..58722764 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/simple/conversion/SimpleConversionScreen.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/simple/conversion/SimpleConversionScreen.kt @@ -38,7 +38,7 @@ import io.github.composegears.valkyrie.ui.foundation.theme.PreviewTheme import io.github.composegears.valkyrie.ui.screen.settings.SettingsScreen import kotlinx.coroutines.launch import java.awt.datatransfer.StringSelection -import java.io.File +import java.nio.file.Path val SimpleConversionScreen by navDestination { val navController = navController() @@ -48,7 +48,7 @@ val SimpleConversionScreen by navDestination { ConversionUi( state = state, - onSelectFile = viewModel::selectFile, + onSelectPath = viewModel::selectPath, openSettings = { navController.navigate( dest = SettingsScreen, @@ -62,7 +62,7 @@ val SimpleConversionScreen by navDestination { @Composable private fun ConversionUi( state: SimpleConversionState, - onSelectFile: (File) -> Unit, + onSelectPath: (Path) -> Unit, openSettings: () -> Unit, resetIconContent: () -> Unit ) { @@ -72,12 +72,12 @@ private fun ConversionUi( PluginUI( content = state.iconContent, - onChooseFile = { + onChoosePath = { scope.launch { - val file = filePicker.launch() + val path = filePicker.launch() - if (file != null) { - onSelectFile(file) + if (path != null) { + onSelectPath(path) } } }, @@ -87,7 +87,7 @@ private fun ConversionUi( CopyPasteManager.getInstance().setContents(StringSelection(text)) notificationManager.show("Copied in clipboard") }, - onSelectFile = onSelectFile, + onSelectPath = onSelectPath, openSettings = openSettings ) } @@ -95,10 +95,10 @@ private fun ConversionUi( @Composable private fun PluginUI( content: String?, - onChooseFile: () -> Unit, + onChoosePath: () -> Unit, onClear: () -> Unit, onCopy: () -> Unit, - onSelectFile: (File) -> Unit, + onSelectPath: (Path) -> Unit, openSettings: () -> Unit ) { Column(modifier = Modifier.fillMaxSize()) { @@ -123,8 +123,8 @@ private fun PluginUI( contentAlignment = Alignment.Center ) { SelectableState( - onSelectFile = onSelectFile, - onChooseFile = onChooseFile + onSelectPath = onSelectPath, + onChoosePath = onChoosePath ) } } @@ -133,15 +133,15 @@ private fun PluginUI( @Composable private fun SelectableState( - onChooseFile: () -> Unit, - onSelectFile: (File) -> Unit + onChoosePath: () -> Unit, + onSelectPath: (Path) -> Unit ) { - val dragAndDropHandler = rememberFileDragAndDropHandler(onDrop = onSelectFile) + val dragAndDropHandler = rememberFileDragAndDropHandler(onDrop = onSelectPath) val isDragging by rememberMutableState(dragAndDropHandler.isDragging) { dragAndDropHandler.isDragging } DragAndDropBox( isDragging = isDragging, - onChoose = onChooseFile + onChoose = onChoosePath ) { Column(horizontalAlignment = Alignment.CenterHorizontally) { Icon( @@ -166,7 +166,7 @@ private fun SelectableState( private fun SimpleConversionScreenPreview() = PreviewTheme { ConversionUi( state = SimpleConversionState(), - onSelectFile = {}, + onSelectPath = {}, openSettings = {}, resetIconContent = {} ) diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/simple/conversion/SimpleConversionState.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/simple/conversion/SimpleConversionState.kt index 9c018931..539623b3 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/simple/conversion/SimpleConversionState.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/simple/conversion/SimpleConversionState.kt @@ -1,8 +1,8 @@ package io.github.composegears.valkyrie.ui.screen.mode.simple.conversion -import java.io.File +import java.nio.file.Path data class SimpleConversionState( - val lastFile: File? = null, + val lastPath: Path? = null, val iconContent: String? = null ) diff --git a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/simple/conversion/SimpleConversionViewModel.kt b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/simple/conversion/SimpleConversionViewModel.kt index c7b57d3c..93bca846 100644 --- a/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/simple/conversion/SimpleConversionViewModel.kt +++ b/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/mode/simple/conversion/SimpleConversionViewModel.kt @@ -11,7 +11,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn -import java.io.File +import java.nio.file.Path class SimpleConversionViewModel(inMemorySettings: InMemorySettings) : TiamatViewModel() { @@ -21,16 +21,16 @@ class SimpleConversionViewModel(inMemorySettings: InMemorySettings) : TiamatView init { _state .combine(inMemorySettings.settings) { state, settings -> - if (state.lastFile != null) { - updateIcon(state.lastFile, settings) + if (state.lastPath != null) { + updateIcon(state.lastPath, settings) } } .launchIn(viewModelScope) } - private fun updateIcon(file: File, valkyriesSettings: ValkyriesSettings) { + private fun updateIcon(path: Path, valkyriesSettings: ValkyriesSettings) { val output = runCatching { - val parserOutput = IconParser.toVector(file) + val parserOutput = IconParser.toVector(path) ImageVectorGenerator.convert( vector = parserOutput.vector, kotlinName = parserOutput.kotlinName, @@ -48,11 +48,11 @@ class SimpleConversionViewModel(inMemorySettings: InMemorySettings) : TiamatView _state.updateState { copy(iconContent = output) } } - fun selectFile(file: File) { - _state.updateState { copy(lastFile = file) } + fun selectPath(path: Path) { + _state.updateState { copy(lastPath = path) } } fun reset() { - _state.updateState { copy(iconContent = null, lastFile = null) } + _state.updateState { copy(iconContent = null, lastPath = null) } } } \ No newline at end of file diff --git a/stability_config.conf b/stability_config.conf index 5d104887..a7a4d303 100644 --- a/stability_config.conf +++ b/stability_config.conf @@ -1,2 +1,2 @@ kotlin.collections.* -java.io.File \ No newline at end of file +java.nio.file.Path \ No newline at end of file