diff --git a/composeApp/src/androidMain/kotlin/mg/dot/feufaro/AndroidFileRepository.kt b/composeApp/src/androidMain/kotlin/mg/dot/feufaro/AndroidFileRepository.kt index ff27666..3cce5e8 100644 --- a/composeApp/src/androidMain/kotlin/mg/dot/feufaro/AndroidFileRepository.kt +++ b/composeApp/src/androidMain/kotlin/mg/dot/feufaro/AndroidFileRepository.kt @@ -85,22 +85,39 @@ class AndroidFileRepository(private val context: Context) : FileRepository { file.readBytes() }*/ override suspend fun saveLocalFile(filePath: String, data: ByteArray) = withContext(Dispatchers.IO) { - val file = if (filePath.contains("/") ) { - File(filePath) - } else { - File(getPAppPublicFolder(), filePath) - } - try { - file.parentFile?.mkdirs() - file.writeBytes(data) - println("Fichier sauvegardé dans : ${file.absolutePath}") + if (filePath.startsWith("content://") || filePath.startsWith("file://")) { + val uri = Uri.parse(filePath) + context.contentResolver.openOutputStream(uri)?.use { outputStream -> + outputStream.write(data) + outputStream.flush() + } ?: throw Exception("Impossible d'ouvrir l'Uri pour écriture") + } else { + val file = if (filePath.contains("/")) { + File(filePath) + } else { + File(getPAppPublicFolder(), filePath) + } + file.parentFile?.mkdirs() + file.writeBytes(data) + } - if (file.extension.lowercase() == "pdf") { - openPdfFile(context = context, filePath = file.absolutePath) + withContext(Dispatchers.Main) { + if (filePath.endsWith(".pdf", ignoreCase = true)) { + openPdfFile(context = context, filePath = filePath) + } else { + Toast.makeText( + context.applicationContext, + "Sauvegarde réussie", + Toast.LENGTH_LONG + ).show() + } } } catch (e: Exception) { e.printStackTrace() + withContext(Dispatchers.Main) { + Toast.makeText(context, "Erreur de sauvegarde : ${e.message}", Toast.LENGTH_SHORT).show() + } throw e } } @@ -121,8 +138,9 @@ class AndroidFileRepository(private val context: Context) : FileRepository { return appDir } - override fun pickSavePath(defaultName: String): String? { - return File(getPAppPublicFolder(), defaultName).absolutePath + override fun pickSavePath(defaultName: String, title: String): String? { + val file = File(context.filesDir, defaultName) + return file?.absolutePath } suspend fun openPdfFile(context: Context, filePath: String) { val file = File(filePath) diff --git a/composeApp/src/androidMain/kotlin/mg/dot/feufaro/ui/FileSaveLauncher.kt b/composeApp/src/androidMain/kotlin/mg/dot/feufaro/ui/FileSaveLauncher.kt new file mode 100644 index 0000000..1d501a7 --- /dev/null +++ b/composeApp/src/androidMain/kotlin/mg/dot/feufaro/ui/FileSaveLauncher.kt @@ -0,0 +1,25 @@ +package mg.dot.feufaro.ui + +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember + +@Composable +actual fun rememberFileSaveLauncher( + onResult: (String?) -> Unit +): FileSaveLauncher { + val launcher = rememberLauncherForActivityResult( + contract = ActivityResultContracts.CreateDocument("text/plain") + ) { uri -> + onResult(uri?.toString()) + } + + return remember { + object : FileSaveLauncher { + override fun launch(defaultName: String) { + launcher.launch(defaultName) + } + } + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/FileRepository.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/FileRepository.kt index 34a4350..2e1a4db 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/FileRepository.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/FileRepository.kt @@ -20,7 +20,7 @@ interface FileRepository { suspend fun getAppPublicFolder() : File fun getFileName(shortName: String) : String // suspend fun readFileBytes(filePath: String): ByteArray - fun pickSavePath(defaultName: String): String? + fun pickSavePath(defaultName: String, title: String): String? } // This is just a regular class that implements the common 'FileRepository' interface. diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ui/FileSaveLauncher.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ui/FileSaveLauncher.kt new file mode 100644 index 0000000..28ebf28 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ui/FileSaveLauncher.kt @@ -0,0 +1,12 @@ +package mg.dot.feufaro.ui + +import androidx.compose.runtime.Composable + +interface FileSaveLauncher { + fun launch(defaultName: String) +} + +@Composable +expect fun rememberFileSaveLauncher( + onResult: (String?) -> Unit +): FileSaveLauncher \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/di/DesktopFileRepository.kt b/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/di/DesktopFileRepository.kt index e7c38b5..7a7229d 100644 --- a/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/di/DesktopFileRepository.kt +++ b/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/di/DesktopFileRepository.kt @@ -72,8 +72,8 @@ class DesktopFileRepository : FileRepository { // IMPORTS AND IMPLEMENTS THE com return "$userHome/$shortName" } - override fun pickSavePath(defaultName: String): String? { - val dialog = FileDialog(null as Frame?, "Exporter en PDF", FileDialog.SAVE) + override fun pickSavePath(defaultName: String, title: String): String? { + val dialog = FileDialog(null as Frame?, title, FileDialog.SAVE) dialog.directory = System.getProperty("user.home") dialog.file = defaultName dialog.isVisible = true diff --git a/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/ui/FileSaveLauncher.kt b/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/ui/FileSaveLauncher.kt new file mode 100644 index 0000000..242ddb4 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/ui/FileSaveLauncher.kt @@ -0,0 +1,39 @@ +package mg.dot.feufaro.ui + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.awt.FileDialog +import java.awt.Frame +import java.io.File + +@Composable +actual fun rememberFileSaveLauncher( + onResult: (String?) -> Unit +): FileSaveLauncher { + return remember { + object : FileSaveLauncher { + override fun launch(defaultName: String) { + CoroutineScope(Dispatchers.IO).launch { + val dialog = FileDialog(null as Frame?, "Sauvegarder la source", FileDialog.SAVE) + dialog.directory = System.getProperty("user.home") + dialog.file = defaultName + dialog.isVisible = true + + val path = if (dialog.directory != null && dialog.file != null) { + File(dialog.directory, dialog.file).absolutePath + } else { + null + } + + withContext(Dispatchers.Main) { + onResult(path) + } + } + } + } + } +} \ No newline at end of file