Skip to content

Commit

Permalink
Merge pull request #109 from MohamedRejeb/0.5.x
Browse files Browse the repository at this point in the history
Add FileSaverLauncher to desktop
  • Loading branch information
MohamedRejeb committed Jul 9, 2024
2 parents de4e950 + 8c652f2 commit 4981c35
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.mohamedrejeb.calf.picker

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.rememberUpdatedState
import com.mohamedrejeb.calf.io.KmpFile
import com.mohamedrejeb.calf.picker.platform.awt.AwtFileSaver
import kotlinx.coroutines.launch

@Composable
fun rememberFileSaverLauncher(
bytes: ByteArray?,
baseName: String,
extension: String,
initialDirectory: String?,
onResult: (KmpFile?) -> Unit,
): FileSaverLauncher {
val scope = rememberCoroutineScope()

val currentBytes by rememberUpdatedState(bytes)
val currentBaseName by rememberUpdatedState(baseName)
val currentExtension by rememberUpdatedState(extension)
val currentInitialDirectory by rememberUpdatedState(initialDirectory)
val currentOnResult by rememberUpdatedState(onResult)

return FileSaverLauncher(
onLaunch = {
scope.launch {
val file = AwtFileSaver.saveFile(
bytes = currentBytes,
baseName = currentBaseName,
extension = currentExtension,
initialDirectory = currentInitialDirectory,
parentWindow = null,
)

currentOnResult(file)
}
}
)
}

class FileSaverLauncher(
private val onLaunch: () -> Unit,
) {
fun launch() {
onLaunch()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.mohamedrejeb.calf.picker.platform.awt

import com.mohamedrejeb.calf.io.KmpFile
import kotlinx.coroutines.suspendCancellableCoroutine
import java.awt.Dialog
import java.awt.FileDialog
import java.awt.Frame
import java.awt.Window
import java.io.File
import kotlin.coroutines.resume

internal object AwtFileSaver {
suspend fun saveFile(
bytes: ByteArray?,
baseName: String,
extension: String,
initialDirectory: String?,
parentWindow: Window?,
): KmpFile? = suspendCancellableCoroutine { continuation ->
fun handleResult(value: Boolean, files: Array<File>?) {
if (value) {
val file = files?.firstOrNull()?.let { file ->
// Write bytes to file, or create a new file
bytes?.let { file.writeBytes(bytes) } ?: file.createNewFile()
KmpFile(file)
}
continuation.resume(file)
}
}

// Handle parentWindow: Dialog, Frame, or null
val dialog = when (parentWindow) {
is Dialog -> object : FileDialog(parentWindow, "Save dialog", SAVE) {
override fun setVisible(value: Boolean) {
super.setVisible(value)
handleResult(value, files)
}
}

else -> object : FileDialog(parentWindow as? Frame, "Save dialog", SAVE) {
override fun setVisible(value: Boolean) {
super.setVisible(value)
handleResult(value, files)
}
}
}

// Set initial directory
dialog.directory = initialDirectory

// Set file name
dialog.file = "$baseName.$extension"

// Show the dialog
dialog.isVisible = true

// Dispose the dialog when the continuation is cancelled
continuation.invokeOnCancellation { dialog.dispose() }
}
}

0 comments on commit 4981c35

Please sign in to comment.