diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/ImportationFilesManager.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/ImportationFilesManager.kt index 4eee7b8a0..45efb128e 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/ImportationFilesManager.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/ImportationFilesManager.kt @@ -39,7 +39,10 @@ import javax.inject.Inject import javax.inject.Singleton @Singleton -class ImportationFilesManager @Inject constructor(@ApplicationContext private val appContext: Context) { +class ImportationFilesManager @Inject constructor( + @ApplicationContext private val appContext: Context, + private val uploadLocalStorage: UploadLocalStorage, +) { private val filesToImport: TransferCountChannel = TransferCountChannel() val filesToImportCount: StateFlow = filesToImport.count @@ -57,9 +60,6 @@ class ImportationFilesManager @Inject constructor(@ApplicationContext private va // the list of already imported files we listen to in the LazyRow. private val alreadyUsedFileNames = AlreadyUsedFileNamesSet() - private val importFolder by lazy { File(appContext.cacheDir, LOCAL_COPY_FOLDER) } - private fun getImportFolderOrCreate() = importFolder.apply { if (!exists()) mkdirs() } - suspend fun addFiles(uris: List) { uris.extractPickedFiles().forEach { filesToImport.send(it) } } @@ -70,14 +70,12 @@ class ImportationFilesManager @Inject constructor(@ApplicationContext private va } } - fun removeLocalCopyFolder() { - if (importFolder.exists()) runCatching { importFolder.deleteRecursively() } - } + fun removeLocalCopyFolder() = uploadLocalStorage.removeLocalCopyFolder() suspend fun restoreAlreadyImportedFiles() { - if (!importFolder.exists()) return + if (!uploadLocalStorage.importFolderExists()) return - val alreadyCopiedFiles = importFolder.listFiles() ?: return + val alreadyCopiedFiles = uploadLocalStorage.listImportFiles() ?: return val restoredFileData = getRestoredFileData(alreadyCopiedFiles) if (alreadyCopiedFiles.size != restoredFileData.size) { @@ -94,7 +92,7 @@ class ImportationFilesManager @Inject constructor(@ApplicationContext private va suspend fun continuouslyCopyPickedFilesToLocalStorage() { filesToImport.consume { fileToImport -> Log.i(TAG, "Importing ${fileToImport.uri}") - val copiedFile = copyFileLocally(fileToImport.uri, fileToImport.fileName) + val copiedFile = uploadLocalStorage.copyFileLocally(fileToImport.uri, fileToImport.fileName) if (copiedFile == null) { reportFailedImportation(fileToImport) @@ -179,27 +177,6 @@ class ImportationFilesManager @Inject constructor(@ApplicationContext private va return getColumnIndex(column).takeIf { it != -1 } } - private fun copyFileLocally(uri: Uri, fileName: String): File? { - val file = File(getImportFolderOrCreate(), fileName).apply { - if (exists()) delete() - runCatching { createNewFile() }.onFailure { return null } - - runCatching { - val inputStream = appContext.contentResolver.openInputStream(uri) ?: return null - - inputStream.use { inputStream -> - outputStream().use { outputStream -> - inputStream.copyTo(outputStream) - } - } - }.onFailure { - return null - } - } - - return file - } - private suspend fun reportFailedImportation(file: PickedFile) { Log.w(TAG, "Failed importation of ${file.uri}"); _failedFiles.emit(file) diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/UploadLocalStorage.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/UploadLocalStorage.kt new file mode 100644 index 000000000..635922b4d --- /dev/null +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/UploadLocalStorage.kt @@ -0,0 +1,67 @@ +/* + * Infomaniak SwissTransfer - Android + * Copyright (C) 2024 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.infomaniak.swisstransfer.ui.screen.newtransfer + +import android.content.Context +import android.net.Uri +import androidx.core.net.toUri +import com.infomaniak.swisstransfer.ui.components.FileUi +import com.infomaniak.swisstransfer.ui.screen.newtransfer.NewTransferViewModel.Companion.LOCAL_COPY_FOLDER +import dagger.hilt.android.qualifiers.ApplicationContext +import io.sentry.Sentry +import java.io.File +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class UploadLocalStorage @Inject constructor(@ApplicationContext private val appContext: Context) { + + private val importFolder by lazy { File(appContext.cacheDir, LOCAL_COPY_FOLDER) } + private fun getImportFolderOrCreate() = importFolder.apply { if (!exists()) mkdirs() } + + fun removeLocalCopyFolder() { + if (importFolder.exists()) runCatching { importFolder.deleteRecursively() } + } + + fun importFolderExists() = importFolder.exists() + + fun listImportFiles(): Array? { + return importFolder.listFiles() + } + + fun copyFileLocally(uri: Uri, fileName: String): File? { + val file = File(getImportFolderOrCreate(), fileName).apply { + if (exists()) delete() + runCatching { createNewFile() }.onFailure { return null } + + runCatching { + val inputStream = appContext.contentResolver.openInputStream(uri) ?: return null + + inputStream.use { inputStream -> + outputStream().use { outputStream -> + inputStream.copyTo(outputStream) + } + } + }.onFailure { + return null + } + } + + return file + } +}