🎨 Add a kernel API /api/block/getBlockTreeInfos https://github.com/siyuan-note/siyuan/issues/11311

This commit is contained in:
Daniel 2024-05-09 23:20:28 +08:00
parent 5d47fe4e86
commit 7d73482cfa
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
4 changed files with 120 additions and 22 deletions

View file

@ -29,6 +29,24 @@ import (
"github.com/siyuan-note/siyuan/kernel/util"
)
func getBlockTreeInfos(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
arg, ok := util.JsonArg(c, ret)
if !ok {
return
}
var ids []string
idsArg := arg["ids"].([]interface{})
for _, id := range idsArg {
ids = append(ids, id.(string))
}
ret.Data = model.GetBlockTreeInfos(ids)
}
func getBlockSiblingID(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)

View file

@ -199,6 +199,7 @@ func ServeAPI(ginServer *gin.Engine) {
ginServer.Handle("POST", "/api/block/swapBlockRef", model.CheckAuth, model.CheckReadonly, swapBlockRef)
ginServer.Handle("POST", "/api/block/transferBlockRef", model.CheckAuth, model.CheckReadonly, transferBlockRef)
ginServer.Handle("POST", "/api/block/getBlockSiblingID", model.CheckAuth, getBlockSiblingID)
ginServer.Handle("POST", "/api/block/getBlockTreeInfos", model.CheckAuth, getBlockTreeInfos)
ginServer.Handle("POST", "/api/file/getFile", model.CheckAuth, getFile)
ginServer.Handle("POST", "/api/file/putFile", model.CheckAuth, model.CheckReadonly, putFile)

View file

@ -26,6 +26,7 @@ import (
"github.com/88250/lute/ast"
"github.com/88250/lute/parse"
"github.com/open-spaced-repetition/go-fsrs"
"github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
@ -114,6 +115,66 @@ type Path struct {
Created string `json:"created"` // 创建时间
}
type BlockTreeInfo struct {
ID string `json:"id"`
Type string `json:"type"`
ParentID string `json:"parentID"`
ParentType string `json:"parentType"`
PreviousID string `json:"previousID"`
PreviousType string `json:"previousType"`
NextID string `json:"nextID"`
NextType string `json:"nextType"`
}
func GetBlockTreeInfos(ids []string) (ret map[string]*BlockTreeInfo) {
ret = map[string]*BlockTreeInfo{}
luteEngine := util.NewLute()
treeCache := map[string]*parse.Tree{}
for _, id := range ids {
bt := treenode.GetBlockTree(id)
if nil == bt {
ret[id] = &BlockTreeInfo{ID: id}
continue
}
tree := treeCache[bt.RootID]
if nil == tree {
tree, _ = filesys.LoadTree(bt.BoxID, bt.Path, luteEngine)
if nil == tree {
ret[id] = &BlockTreeInfo{ID: id}
continue
}
treeCache[bt.RootID] = tree
}
node := treenode.GetNodeInTree(tree, id)
if nil == node {
ret[id] = &BlockTreeInfo{ID: id}
continue
}
bti := &BlockTreeInfo{ID: id, Type: node.Type.String()}
ret[id] = bti
parent := treenode.ParentBlock(node)
if nil != parent {
bti.ParentID = parent.ID
bti.ParentType = parent.Type.String()
}
previous := treenode.PreviousBlock(node)
if nil != previous {
bti.PreviousID = previous.ID
bti.PreviousType = previous.Type.String()
}
next := treenode.NextBlock(node)
if nil != next {
bti.NextID = next.ID
bti.NextType = next.Type.String()
}
}
return
}
func GetBlockSiblingID(id string) (parent, previous, next string) {
tree, err := LoadTreeByBlockID(id)
if nil != err {
@ -147,14 +208,14 @@ func GetBlockSiblingID(id string) (parent, previous, next string) {
if parentListItem.Previous != nil {
previous = parentListItem.Previous.ID
if flb := firstChild(parentListItem.Previous); nil != flb {
if flb := treenode.FirstChildBlock(parentListItem.Previous); nil != flb {
previous = flb.ID
}
}
if parentListItem.Next != nil {
next = parentListItem.Next.ID
if flb := firstChild(parentListItem.Next); nil != flb {
if flb := treenode.FirstChildBlock(parentListItem.Next); nil != flb {
next = flb.ID
}
}
@ -167,7 +228,7 @@ func GetBlockSiblingID(id string) (parent, previous, next string) {
if nil != current.Parent && current.Parent.IsBlock() {
parent = current.Parent.ID
if flb := firstChild(current.Parent); nil != flb {
if flb := treenode.FirstChildBlock(current.Parent); nil != flb {
parent = flb.ID
}
@ -176,28 +237,28 @@ func GetBlockSiblingID(id string) (parent, previous, next string) {
if nil != current.Previous && current.Previous.IsBlock() {
previous = current.Previous.ID
if flb := firstChild(current.Previous); nil != flb {
if flb := treenode.FirstChildBlock(current.Previous); nil != flb {
previous = flb.ID
}
}
if nil != current.Next && current.Next.IsBlock() {
next = current.Next.ID
if flb := firstChild(current.Next); nil != flb {
if flb := treenode.FirstChildBlock(current.Next); nil != flb {
next = flb.ID
}
}
} else {
if nil != current.Parent.Previous && current.Parent.Previous.IsBlock() {
previous = current.Parent.Previous.ID
if flb := firstChild(current.Parent.Previous); nil != flb {
if flb := treenode.FirstChildBlock(current.Parent.Previous); nil != flb {
previous = flb.ID
}
}
if nil != current.Parent.Next && current.Parent.Next.IsBlock() {
next = current.Parent.Next.ID
if flb := firstChild(current.Parent.Next); nil != flb {
if flb := treenode.FirstChildBlock(current.Parent.Next); nil != flb {
next = flb.ID
}
}
@ -207,21 +268,6 @@ func GetBlockSiblingID(id string) (parent, previous, next string) {
return
}
func firstChild(node *ast.Node) (ret *ast.Node) {
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {
return ast.WalkContinue
}
if n.IsBlock() {
ret = n
return ast.WalkStop
}
return ast.WalkContinue
})
return
}
func IsBlockFolded(id string) bool {
for i := 0; i < 32; i++ {
b, _ := getBlock(id, nil)

View file

@ -401,6 +401,39 @@ func ParentBlock(node *ast.Node) *ast.Node {
return nil
}
func PreviousBlock(node *ast.Node) *ast.Node {
for n := node.Previous; nil != n; n = n.Previous {
if "" != n.ID && n.IsBlock() {
return n
}
}
return nil
}
func NextBlock(node *ast.Node) *ast.Node {
for n := node.Next; nil != n; n = n.Next {
if "" != n.ID && n.IsBlock() {
return n
}
}
return nil
}
func FirstChildBlock(node *ast.Node) (ret *ast.Node) {
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {
return ast.WalkContinue
}
if n.IsBlock() {
ret = n
return ast.WalkStop
}
return ast.WalkContinue
})
return
}
func GetNodeInTree(tree *parse.Tree, id string) (ret *ast.Node) {
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {