diff --git a/arkfilepicker/src/main/java/space/taran/arkfilepicker/LogTags.kt b/arkfilepicker/src/main/java/space/taran/arkfilepicker/LogTags.kt new file mode 100644 index 0000000..86db937 --- /dev/null +++ b/arkfilepicker/src/main/java/space/taran/arkfilepicker/LogTags.kt @@ -0,0 +1,5 @@ +package space.taran.arkfilepicker + +object LogTags { + const val FILES: String = "files" +} \ No newline at end of file diff --git a/arkfilepicker/src/main/java/space/taran/arkfilepicker/folders/RootsScan.kt b/arkfilepicker/src/main/java/space/taran/arkfilepicker/folders/RootsScan.kt new file mode 100644 index 0000000..2c7e248 --- /dev/null +++ b/arkfilepicker/src/main/java/space/taran/arkfilepicker/folders/RootsScan.kt @@ -0,0 +1,41 @@ +package space.taran.arkfilepicker.folders + +import android.util.Log +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ensureActive +import kotlinx.coroutines.withContext +import space.taran.arkfilepicker.FileUtils +import space.taran.arkfilepicker.LogTags +import space.taran.arkfilepicker.arkFolder +import java.nio.file.Path +import java.util.LinkedList +import java.util.Queue +import kotlin.io.path.exists +import kotlin.io.path.isDirectory +import kotlin.io.path.listDirectoryEntries + +class ArkRootsScan { + + private val roots = mutableListOf() + private val queue: Queue = LinkedList() + + fun getRoots() = roots + + suspend fun scan(devices: List) = withContext(Dispatchers.IO) { + queue.addAll(devices) + + while (queue.isNotEmpty()) { + ensureActive() + scanFolder(queue.poll()!!) + } + } + + private fun scanFolder(folder: Path) = try { + if (folder.arkFolder().exists()) { + roots.add(folder) + } else + queue.addAll(folder.listDirectoryEntries().filter(Path::isDirectory)) + } catch (e: Exception) { + Log.w(LogTags.FILES, "Can't scan $folder due to $e") + } +} \ No newline at end of file diff --git a/arkfilepicker/src/main/java/space/taran/arkfilepicker/presentation/filepicker/ArkFilePickerFragment.kt b/arkfilepicker/src/main/java/space/taran/arkfilepicker/presentation/filepicker/ArkFilePickerFragment.kt index 4b37958..2c46815 100644 --- a/arkfilepicker/src/main/java/space/taran/arkfilepicker/presentation/filepicker/ArkFilePickerFragment.kt +++ b/arkfilepicker/src/main/java/space/taran/arkfilepicker/presentation/filepicker/ArkFilePickerFragment.kt @@ -3,6 +3,7 @@ package space.taran.arkfilepicker.presentation.filepicker import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle +import android.util.Log import android.util.TypedValue import android.view.KeyEvent import android.view.LayoutInflater @@ -28,6 +29,7 @@ import com.mikepenz.fastadapter.GenericItem import com.mikepenz.fastadapter.adapters.ItemAdapter import com.mikepenz.fastadapter.binding.AbstractBindingItem import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import org.orbitmvi.orbit.viewmodel.observe import space.taran.arkfilepicker.ArkFilePickerConfig import space.taran.arkfilepicker.presentation.DevicesPopup @@ -206,7 +208,6 @@ open class ArkFilePickerFragment : } } - private fun displayPath(state: FilePickerState) = binding.apply { layoutPath.removeViews(1, layoutPath.childCount - 1) val pathWithoutDevice = @@ -310,7 +311,11 @@ open class ArkFilePickerFragment : fun newInstance(config: ArkFilePickerConfig) = ArkFilePickerFragment().apply { - setConfig(config) + runBlocking { + val roots = FoldersRepo.instance.provideFolders() + setConfig(config) + showRoots = config.showRoots && roots.isNotEmpty() + } } private const val DIALOG_WIDTH = 300f diff --git a/arkfilepicker/src/main/java/space/taran/arkfilepicker/presentation/filepicker/ArkFilePickerViewModel.kt b/arkfilepicker/src/main/java/space/taran/arkfilepicker/presentation/filepicker/ArkFilePickerViewModel.kt index 3b86f7f..140b7f2 100644 --- a/arkfilepicker/src/main/java/space/taran/arkfilepicker/presentation/filepicker/ArkFilePickerViewModel.kt +++ b/arkfilepicker/src/main/java/space/taran/arkfilepicker/presentation/filepicker/ArkFilePickerViewModel.kt @@ -12,6 +12,7 @@ import org.orbitmvi.orbit.syntax.simple.postSideEffect import org.orbitmvi.orbit.syntax.simple.reduce import org.orbitmvi.orbit.viewmodel.container import space.taran.arkfilepicker.FileUtils +import space.taran.arkfilepicker.folders.ArkRootsScan import space.taran.arkfilepicker.listChildren import space.taran.arkfilepicker.folders.FoldersRepo import java.nio.file.Path @@ -29,6 +30,7 @@ internal data class FilePickerState( val rootsWithFavs: Map> ) { val currentDevice get() = devices[selectedDevicePos] + val arkRootsAvailable get() = rootsWithFavs.isNotEmpty() } internal sealed class FilePickerSideEffect { @@ -45,6 +47,8 @@ internal class ArkFilePickerViewModel( private val foldersRepo = FoldersRepo.instance + private val arkRootsScanner = ArkRootsScan() + override val container: Container = container(initialState()) @@ -107,6 +111,12 @@ internal class ArkFilePickerViewModel( } } + private fun onScanArkRoots() { + viewModelScope.launch { + + } + } + private fun onPathPicked(path: Path) = intent { postSideEffect(FilePickerSideEffect.NotifyPathPicked(path)) postSideEffect(FilePickerSideEffect.DismissDialog)