@@ -3,6 +3,7 @@ package com.aqsama.neomarkor.presentation.viewmodel
33import androidx.lifecycle.ViewModel
44import androidx.lifecycle.viewModelScope
55import com.aqsama.neomarkor.domain.model.FolderMetadata
6+ import com.aqsama.neomarkor.domain.model.FOLDER_PRESET_COLORS
67import com.aqsama.neomarkor.domain.repository.FolderRepository
78import com.aqsama.neomarkor.domain.repository.FileRepository
89import com.aqsama.neomarkor.domain.model.FileNode
@@ -88,6 +89,16 @@ class FolderViewModel(
8889 )
8990 }.collect { state -> _uiState .value = state }
9091 }
92+
93+ // Auto-import real filesystem directories as virtual folders
94+ viewModelScope.launch {
95+ combine(
96+ fileRepository.observeFileTree(),
97+ folderRepository.observeFolders(),
98+ ) { tree, folders -> Pair (tree, folders) }.collect { (tree, folders) ->
99+ syncFilesystemDirectories(tree, folders)
100+ }
101+ }
91102 }
92103
93104 fun toggleExpanded (id : String ) {
@@ -117,7 +128,14 @@ class FolderViewModel(
117128
118129 fun createFolder (name : String , colorArgb : Int , parentId : String? = null) {
119130 viewModelScope.launch {
120- folderRepository.createFolder(name, colorArgb, parentId)
131+ // Find the parent folder's filesystem URI so we create the directory in the right place
132+ val parentDirUri = if (parentId != null ) {
133+ _uiState .value.folders.find { it.id == parentId }?.uriString
134+ } else null
135+ // Create the real filesystem directory first
136+ val realUri = fileRepository.createFolder(name, parentDirUri)
137+ // Register as a virtual folder linked to the real directory
138+ folderRepository.createFolder(name, colorArgb, parentId, realUri)
121139 }
122140 }
123141
@@ -185,4 +203,60 @@ class FolderViewModel(
185203
186204 private fun flattenNotes (nodes : List <FileNode >): List <FileNode > =
187205 nodes.flatMap { n -> if (n.isDirectory) flattenNotes(n.children) else listOf (n) }
206+
207+ /* *
208+ * Imports filesystem directories into the virtual folder list so that real folders in the
209+ * chosen root directory appear automatically in the app's folder browser.
210+ * Handles nested directories by processing them in BFS order within a single coroutine.
211+ */
212+ private fun syncFilesystemDirectories (
213+ fileTree : List <FileNode >,
214+ existingFolders : List <FolderMetadata >,
215+ ) {
216+ val existingUris = existingFolders.mapNotNull { it.uriString }.toSet()
217+ // Collect new directories in parent-first order so children can resolve parent IDs
218+ val toCreate = collectDirectoriesToSync(fileTree, existingUris)
219+ if (toCreate.isEmpty()) return
220+
221+ // Build a URI→id map seeded from already-known folders
222+ val knownUriToId = existingFolders
223+ .mapNotNull { f -> f.uriString?.let { it to f.id } }
224+ .toMap()
225+ .toMutableMap()
226+
227+ // Single coroutine to avoid concurrent DataStore reads/writes
228+ viewModelScope.launch {
229+ toCreate.forEach { (dir, parentUri) ->
230+ val parentId = parentUri?.let { knownUriToId[it] }
231+ val newId = folderRepository.createFolder(
232+ name = dir.name,
233+ colorArgb = FOLDER_PRESET_COLORS [0 ],
234+ parentId = parentId,
235+ uriString = dir.uriString,
236+ )
237+ // Track so subsequent children can resolve this folder as their parent
238+ knownUriToId[dir.uriString] = newId
239+ }
240+ }
241+ }
242+
243+ /* *
244+ * Returns a flat list of (directory, parentUri) pairs for all directories not yet tracked,
245+ * preserving parent-before-child ordering so IDs can be resolved incrementally.
246+ */
247+ private fun collectDirectoriesToSync (
248+ nodes : List <FileNode >,
249+ existingUris : Set <String >,
250+ parentUri : String? = null,
251+ ): List <Pair <FileNode , String ?>> {
252+ val result = mutableListOf<Pair <FileNode , String ?>>()
253+ nodes.filter { it.isDirectory }.forEach { dir ->
254+ if (dir.uriString !in existingUris) {
255+ result.add(dir to parentUri)
256+ }
257+ // Always recurse so we find new children under already-tracked parents
258+ result.addAll(collectDirectoriesToSync(dir.children, existingUris, dir.uriString))
259+ }
260+ return result
261+ }
188262}
0 commit comments