diff --git a/app/src/main/java/com/itsaky/androidide/fragments/sidebar/FileTreeSelectionFragment.kt b/app/src/main/java/com/itsaky/androidide/fragments/sidebar/FileTreeSelectionFragment.kt index 8be80cb480..c86a087361 100644 --- a/app/src/main/java/com/itsaky/androidide/fragments/sidebar/FileTreeSelectionFragment.kt +++ b/app/src/main/java/com/itsaky/androidide/fragments/sidebar/FileTreeSelectionFragment.kt @@ -1,5 +1,6 @@ package com.itsaky.androidide.fragments.sidebar +import android.content.Context import android.os.Bundle import android.view.View import androidx.core.view.isVisible @@ -14,6 +15,8 @@ import com.itsaky.androidide.projects.IProjectManager import com.unnamed.b.atv.model.TreeNode import com.unnamed.b.atv.view.AndroidTreeView import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.currentCoroutineContext +import kotlinx.coroutines.ensureActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File @@ -35,6 +38,7 @@ class FileTreeSelectionFragment : Fragment(R.layout.fragment_file_tree_selection private fun loadTreeData() { binding.loadingIndicator.isVisible = true + val safeContext = requireContext() viewLifecycleOwner.lifecycleScope.launch { val projectRootFile = IProjectManager.getInstance().projectDir if (!projectRootFile.exists()) { @@ -44,10 +48,12 @@ class FileTreeSelectionFragment : Fragment(R.layout.fragment_file_tree_selection val rootNode = withContext(Dispatchers.IO) { val node = TreeNode.root() - buildTreeNodes(node, projectRootFile) + buildTreeNodes(node, projectRootFile, safeContext) node } - setupTreeView(rootNode) + if (isAdded) { + setupTreeView(rootNode) + } } } @@ -58,15 +64,18 @@ class FileTreeSelectionFragment : Fragment(R.layout.fragment_file_tree_selection rootNode.children?.forEach { treeView?.expandNode(it) } } - private fun buildTreeNodes(parentNode: TreeNode, dir: File) { - dir.listFiles()?.sortedWith(compareBy({ !it.isDirectory }, { it.name }))?.forEach { file -> - val node = TreeNode(file).apply { - viewHolder = MultiSelectFileTreeViewHolder(requireContext(), selectedFiles) - } - parentNode.addChild(node) - if (file.isDirectory) { - buildTreeNodes(node, file) - } + private suspend fun buildTreeNodes(parentNode: TreeNode, dir: File, context: Context) { + dir.listFiles() + ?.sortedWith(compareBy({ !it.isDirectory }, { it.name })) + ?.forEach { file -> + currentCoroutineContext().ensureActive() + val node = TreeNode(file).apply { + viewHolder = MultiSelectFileTreeViewHolder(context, selectedFiles) + } + parentNode.addChild(node) + if (file.isDirectory) { + buildTreeNodes(node, file, context) + } } } @@ -79,21 +88,21 @@ class FileTreeSelectionFragment : Fragment(R.layout.fragment_file_tree_selection val baseDir = IProjectManager.getInstance().projectDir - selectedFiles.forEach { - val itemText = it.relativeTo(baseDir).path - // Create a File object by joining the project root with the relative path (itemText) - val file = File(baseDir, itemText) + selectedFiles.forEach { selectedPath -> + val relativePath = selectedPath.relativeTo(baseDir).path + // Create a File object by joining the project root with the relative path + val target = File(baseDir, relativePath) - if (file.exists() && file.isDirectory) { + if (target.exists() && target.isDirectory) { // It's a valid directory, so walk through it and add all readable files - file.walkTopDown() - .filter { it.isFile && it.canRead() } - .forEach { - finalContextList.add(it.relativeTo(baseDir).path) + target.walkTopDown() + .filter { walkedFile -> walkedFile.isFile && walkedFile.canRead() } + .forEach { walkedFile -> + finalContextList.add(walkedFile.relativeTo(baseDir).path) } - } else if (file.exists() && file.isFile && file.canRead()) { + } else if (target.exists() && target.isFile && target.canRead()) { // It's a single, readable file - finalContextList.add(itemText) + finalContextList.add(relativePath) } }