Closed Yashobanta-Kumar-Behera closed 3 months ago
Please don't spam and directly ping project members with "how do I" questions in the issue tracker. This isn't stack overflow; the issue tracker is to track issues with jewel and not general Compose/CS questions.
But I am using lazy tree of jewel but i can't find any way to generate nodes asynchronously and if coroutine scopes are used then the nodes are not getting updated. What can i do? There are no documentation regarding this in jewel. can you help me that?
If you're generating the tree in exactly the same way as we do in our sample code, saving it to a state, and the tree doesn't update, please file a bug for that bug with repro steps, expected behaviour, and if possible sample code that reproduces the issue, then we can look into it
The sample code provided in the standalone app it uses static way to build the tree. There are no sample for async.
fun Note.asTree(isDirectory: (Note) -> Unit = {}): Tree<Note> =
buildTree {
addNode(this@asTree) {
dirExpander(isDirectory)
}
}
val coroutineScope = CoroutineScope(Dispatchers.Default)
fun ChildrenGeneratorScope<Note>.dirExpander(isDirectory: (Note) -> Unit ) {
var notes: List<Note>? = null
coroutineScope.launch {
noteService.getNotesFromStorage(parent.data).collectLatest {
notes = it.notes
}
notes?.forEach { newNote ->
if (newNote.isDirectory) {
addNode(newNote) {
dirExpander(isDirectory)
}
} else addLeaf(newNote)
}
}
}
val tree by remember { mutableStateOf(rootNote.asTree()) }
val lazyListState = rememberLazyListState()
val treeState = remember { TreeState(SelectableLazyListState(lazyListState)) }
Box(modifier.fillMaxSize().border(1.dp, borderColor, RoundedCornerShape(2.dp))) {
LazyTree(
tree = tree,
treeState = treeState,
onElementClick = {},
onElementDoubleClick = { element ->
val selectedNote = element.data
if (selectedNote.isDirectory) {
return@LazyTree
}
MainViewModel.noteTabs = MainViewModel.noteTabs.toMutableMap().apply {
putIfAbsent(
selectedNote.path, NoteEditorState(CodeEditor(EditorSettings()), selectedNote)
) }
MainViewModel.selectedTabKey = selectedNote.path
},
) { element ->
Row(Modifier.fillMaxWidth().padding(vertical = 2.dp), verticalAlignment = Alignment.CenterVertically) {
val selectedNote = element.data
Icon(
resource = if (selectedNote.isDirectory) FileIconProvider.getFolderIconPath() else FileIconProvider.getIconPath(FileUtil.getFileExtension(selectedNote.name)),
contentDescription = null,
iconClass = IconHolder::class.java,
modifier = Modifier.size(20.dp).padding(end = 5.dp),
)
Text(element.data.name, fontSize = 14.sp)
}
}
VerticalScrollbar(
rememberScrollbarAdapter(noteBrowserState.lazyListState),
modifier = Modifier.align(Alignment.CenterEnd),
)
}
Here is the code sample which i have used
Modifying trees works fine, I just updated the standalone sample. https://github.com/JetBrains/jewel/commit/ee994e20978e19d079cbfd0bd6c509a2bf154286
The issue is somewhere in your code — check that you're actually setting the new tree value. If you find bugs in Jewel please open a new issue.
I need to load the child nodes after network call completed till then need to show loader in the node which is expanded. Is there any way?