From b6cd6930c71adfa79faa5b188c30d9793b6abfd8 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Fri, 22 Nov 2024 22:36:19 +0800 Subject: [PATCH] :art: Improve dragging of headings or list items to the doc tree https://github.com/siyuan-note/siyuan/issues/13170 --- kernel/api/filetree.go | 22 +++++++++++++++++---- kernel/model/file.go | 42 ++++++++++++++++++++++++++++++++++++++++ kernel/model/heading.go | 38 ++++++++++++++++++++++++++++-------- kernel/model/listitem.go | 38 +++++++++++++++++++++++++++++------- 4 files changed, 121 insertions(+), 19 deletions(-) diff --git a/kernel/api/filetree.go b/kernel/api/filetree.go index 24a2c381f..80674df89 100644 --- a/kernel/api/filetree.go +++ b/kernel/api/filetree.go @@ -214,8 +214,15 @@ func heading2Doc(c *gin.Context) { srcHeadingID := arg["srcHeadingID"].(string) targetNotebook := arg["targetNoteBook"].(string) - targetPath := arg["targetPath"].(string) - srcRootBlockID, targetPath, err := model.Heading2Doc(srcHeadingID, targetNotebook, targetPath) + var targetPath string + if arg["targetPath"] != nil { + targetPath = arg["targetPath"].(string) + } + var previousPath string + if arg["previousPath"] != nil { + previousPath = arg["previousPath"].(string) + } + srcRootBlockID, targetPath, err := model.Heading2Doc(srcHeadingID, targetNotebook, targetPath, previousPath) if err != nil { ret.Code = -1 ret.Msg = err.Error() @@ -259,8 +266,15 @@ func li2Doc(c *gin.Context) { srcListItemID := arg["srcListItemID"].(string) targetNotebook := arg["targetNoteBook"].(string) - targetPath := arg["targetPath"].(string) - srcRootBlockID, targetPath, err := model.ListItem2Doc(srcListItemID, targetNotebook, targetPath) + var targetPath string + if arg["targetPath"] != nil { + targetPath = arg["targetPath"].(string) + } + var previousPath string + if arg["previousPath"] != nil { + previousPath = arg["previousPath"].(string) + } + srcRootBlockID, targetPath, err := model.ListItem2Doc(srcListItemID, targetNotebook, targetPath, previousPath) if err != nil { ret.Code = -1 ret.Msg = err.Error() diff --git a/kernel/model/file.go b/kernel/model/file.go index 39d3587d0..8f6936edc 100644 --- a/kernel/model/file.go +++ b/kernel/model/file.go @@ -2163,3 +2163,45 @@ func (box *Box) addMinSort(parentPath, id string) { return } } + +func (box *Box) addSort(previousID, id string) { + confDir := filepath.Join(util.DataDir, box.ID, ".siyuan") + if err := os.MkdirAll(confDir, 0755); err != nil { + logging.LogErrorf("create conf dir failed: %s", err) + return + } + confPath := filepath.Join(confDir, "sort.json") + fullSortIDs := map[string]int{} + var data []byte + if filelock.IsExist(confPath) { + data, err := filelock.ReadFile(confPath) + if err != nil { + logging.LogErrorf("read sort conf failed: %s", err) + return + } + + if err = gulu.JSON.UnmarshalJSON(data, &fullSortIDs); err != nil { + logging.LogErrorf("unmarshal sort conf failed: %s", err) + } + } + + sortVal := 0 + previousSortVal, ok := fullSortIDs[previousID] + if !ok { + sortVal++ + } else { + sortVal = previousSortVal + 1 + } + + fullSortIDs[id] = sortVal + + data, err := gulu.JSON.MarshalJSON(fullSortIDs) + if err != nil { + logging.LogErrorf("marshal sort conf failed: %s", err) + return + } + if err = filelock.WriteFile(confPath, data); err != nil { + logging.LogErrorf("write sort conf failed: %s", err) + return + } +} diff --git a/kernel/model/heading.go b/kernel/model/heading.go index c5e8d90eb..e256adb0b 100644 --- a/kernel/model/heading.go +++ b/kernel/model/heading.go @@ -273,7 +273,7 @@ func Doc2Heading(srcID, targetID string, after bool) (srcTreeBox, srcTreePath st return } -func Heading2Doc(srcHeadingID, targetBoxID, targetPath string) (srcRootBlockID, newTargetPath string, err error) { +func Heading2Doc(srcHeadingID, targetBoxID, targetPath, previousPath string) (srcRootBlockID, newTargetPath string, err error) { srcTree, _ := LoadTreeByBlockID(srcHeadingID) if nil == srcTree { err = ErrBlockNotFound @@ -305,15 +305,33 @@ func Heading2Doc(srcHeadingID, targetBoxID, targetPath string) (srcRootBlockID, moveToRoot := "/" == targetPath toHP := path.Join("/", headingText) toFolder := "/" - - if !moveToRoot { - toBlock := treenode.GetBlockTreeRootByPath(targetBoxID, targetPath) - if nil == toBlock { + if "" != previousPath { + previousDoc := treenode.GetBlockTreeRootByPath(targetBoxID, previousPath) + if nil == previousDoc { err = ErrBlockNotFound return } - toHP = path.Join(toBlock.HPath, headingText) - toFolder = path.Join(path.Dir(targetPath), toBlock.ID) + parentPath := path.Dir(previousPath) + if "/" != parentPath { + parentPath = strings.TrimSuffix(parentPath, "/") + ".sy" + parentDoc := treenode.GetBlockTreeRootByPath(targetBoxID, parentPath) + if nil == parentDoc { + err = ErrBlockNotFound + return + } + toHP = path.Join(parentDoc.HPath, headingText) + toFolder = path.Join(path.Dir(parentPath), parentDoc.ID) + } + } else { + if !moveToRoot { + parentDoc := treenode.GetBlockTreeRootByPath(targetBoxID, targetPath) + if nil == parentDoc { + err = ErrBlockNotFound + return + } + toHP = path.Join(parentDoc.HPath, headingText) + toFolder = path.Join(path.Dir(targetPath), parentDoc.ID) + } } newTargetPath = path.Join(toFolder, srcHeadingID+".sy") @@ -375,7 +393,11 @@ func Heading2Doc(srcHeadingID, targetBoxID, targetPath string) (srcRootBlockID, newTree.Box, newTree.Path = targetBoxID, newTargetPath newTree.Root.SetIALAttr("updated", util.CurrentTimeSecondsStr()) newTree.Root.Spec = "1" - box.addMinSort(path.Dir(newTargetPath), newTree.ID) + if "" != previousPath { + box.addSort(strings.TrimSuffix(path.Base(previousPath), ".sy"), newTree.ID) + } else { + box.addMinSort(path.Dir(newTargetPath), newTree.ID) + } if err = indexWriteTreeUpsertQueue(newTree); err != nil { return "", "", err } diff --git a/kernel/model/listitem.go b/kernel/model/listitem.go index b3d26c007..ebf54cbc7 100644 --- a/kernel/model/listitem.go +++ b/kernel/model/listitem.go @@ -18,6 +18,7 @@ package model import ( "path" + "strings" "github.com/88250/lute/ast" "github.com/88250/lute/parse" @@ -26,7 +27,7 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) -func ListItem2Doc(srcListItemID, targetBoxID, targetPath string) (srcRootBlockID, newTargetPath string, err error) { +func ListItem2Doc(srcListItemID, targetBoxID, targetPath, previousPath string) (srcRootBlockID, newTargetPath string, err error) { srcTree, _ := LoadTreeByBlockID(srcListItemID) if nil == srcTree { err = ErrBlockNotFound @@ -48,14 +49,33 @@ func ListItem2Doc(srcListItemID, targetBoxID, targetPath string) (srcRootBlockID toHP := path.Join("/", listItemText) toFolder := "/" - if !moveToRoot { - toBlock := treenode.GetBlockTreeRootByPath(targetBoxID, targetPath) - if nil == toBlock { + if "" != previousPath { + previousDoc := treenode.GetBlockTreeRootByPath(targetBoxID, previousPath) + if nil == previousDoc { err = ErrBlockNotFound return } - toHP = path.Join(toBlock.HPath, listItemText) - toFolder = path.Join(path.Dir(targetPath), toBlock.ID) + parentPath := path.Dir(previousPath) + if "/" != parentPath { + parentPath = strings.TrimSuffix(parentPath, "/") + ".sy" + parentDoc := treenode.GetBlockTreeRootByPath(targetBoxID, parentPath) + if nil == parentDoc { + err = ErrBlockNotFound + return + } + toHP = path.Join(parentDoc.HPath, listItemText) + toFolder = path.Join(path.Dir(parentPath), parentDoc.ID) + } + } else { + if !moveToRoot { + parentDoc := treenode.GetBlockTreeRootByPath(targetBoxID, targetPath) + if nil == parentDoc { + err = ErrBlockNotFound + return + } + toHP = path.Join(parentDoc.HPath, listItemText) + toFolder = path.Join(path.Dir(targetPath), parentDoc.ID) + } } newTargetPath = path.Join(toFolder, srcListItemID+".sy") @@ -107,7 +127,11 @@ func ListItem2Doc(srcListItemID, targetBoxID, targetPath string) (srcRootBlockID newTree.Box, newTree.Path = targetBoxID, newTargetPath newTree.Root.SetIALAttr("updated", util.CurrentTimeSecondsStr()) newTree.Root.Spec = "1" - box.addMinSort(path.Dir(newTargetPath), newTree.ID) + if "" != previousPath { + box.addSort(strings.TrimSuffix(path.Base(previousPath), ".sy"), newTree.ID) + } else { + box.addMinSort(path.Dir(newTargetPath), newTree.ID) + } if err = indexWriteTreeUpsertQueue(newTree); err != nil { return "", "", err }