From e5df997e19e655110f51a418111c6574c21a1bad Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Fri, 6 Sep 2024 09:49:46 +0800 Subject: [PATCH] :art: Improve dynamic anchor text auto-refresh stability https://github.com/siyuan-note/siyuan/issues/8234 --- kernel/model/transaction.go | 28 +++++++++++++++++++++++----- kernel/util/websocket.go | 4 ++-- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index 6f978786d..dbb2bf422 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -1439,8 +1439,9 @@ func refreshDynamicRefText(updatedDefNode *ast.Node, updatedTree *parse.Tree) { func refreshDynamicRefTexts(updatedDefNodes map[string]*ast.Node, updatedTrees map[string]*parse.Tree) { // 1. 更新引用的动态锚文本 treeRefNodeIDs := map[string]*hashset.Set{} + var changedParentNodes []*ast.Node for _, updateNode := range updatedDefNodes { - refs := getRefsCacheByDefNode(updateNode) + refs, parentNodes := getRefsCacheByDefNode(updateNode) for _, ref := range refs { if refIDs, ok := treeRefNodeIDs[ref.RootID]; !ok { refIDs = hashset.New() @@ -1450,6 +1451,14 @@ func refreshDynamicRefTexts(updatedDefNodes map[string]*ast.Node, updatedTrees m refIDs.Add(ref.BlockID) } } + if 0 < len(parentNodes) { + changedParentNodes = append(changedParentNodes, parentNodes...) + } + } + if 0 < len(changedParentNodes) { + for _, parent := range changedParentNodes { + updatedDefNodes[parent.ID] = parent + } } changedRefTree := map[string]*parse.Tree{} @@ -1471,13 +1480,15 @@ func refreshDynamicRefTexts(updatedDefNodes map[string]*ast.Node, updatedTrees m } if n.IsBlock() && refNodeIDs.Contains(n.ID) { - changed := updateRefText(n, updatedDefNodes) + changed, changedDefNodes := updateRefText(n, updatedDefNodes) if !refTreeChanged && changed { refTreeChanged = true } // 推送动态锚文本节点刷新 - task.AppendAsyncTaskWithDelay(task.ReloadProtyleBlock, 200*time.Millisecond, util.PushReloadBlock, refTreeID, n.ID) + for _, defNode := range changedDefNodes { + task.AppendAsyncTaskWithDelay(task.ReloadProtyleBlock, 200*time.Millisecond, util.PushReloadBlock, refTreeID, n.ID, defNode.id, defNode.refText) + } return ast.WalkContinue } return ast.WalkContinue @@ -1532,7 +1543,7 @@ func refreshDynamicRefTexts(updatedDefNodes map[string]*ast.Node, updatedTrees m } } -func getRefsCacheByDefNode(updateNode *ast.Node) (ret []*sql.Ref) { +func getRefsCacheByDefNode(updateNode *ast.Node) (ret []*sql.Ref, changedParentNodes []*ast.Node) { ret = sql.GetRefsCacheByDefID(updateNode.ID) if nil != updateNode.Parent && ast.NodeDocument != updateNode.Parent.Type && updateNode.Parent.IsContainerBlock() && updateNode == treenode.FirstLeafBlock(updateNode.Parent) { // 容器块下第一个叶子块 @@ -1545,6 +1556,7 @@ func getRefsCacheByDefNode(updateNode *ast.Node) (ret []*sql.Ref) { parentRefs := sql.GetRefsCacheByDefID(parent.ID) if 0 < len(parentRefs) { ret = append(ret, parentRefs...) + changedParentNodes = append(changedParentNodes, parent) } } } @@ -1575,7 +1587,12 @@ func flushUpdateRefTextRenameDoc() { updateRefTextRenameDocs = map[string]*parse.Tree{} } -func updateRefText(refNode *ast.Node, changedDefNodes map[string]*ast.Node) (changed bool) { +type changedDefNode struct { + id string + refText string +} + +func updateRefText(refNode *ast.Node, changedDefNodes map[string]*ast.Node) (changed bool, defNodes []*changedDefNode) { ast.Walk(refNode, func(n *ast.Node, entering bool) ast.WalkStatus { if !entering { return ast.WalkContinue @@ -1597,6 +1614,7 @@ func updateRefText(refNode *ast.Node, changedDefNodes map[string]*ast.Node) (cha refText := getNodeRefText(defNode) treenode.SetDynamicBlockRefText(n, refText) changed = true + defNodes = append(defNodes, &changedDefNode{id: defID, refText: refText}) return ast.WalkContinue }) return diff --git a/kernel/util/websocket.go b/kernel/util/websocket.go index 21efe6a39..5d52116aa 100644 --- a/kernel/util/websocket.go +++ b/kernel/util/websocket.go @@ -258,8 +258,8 @@ func PushProtyleReload(rootID string) { BroadcastByType("protyle", "reload", 0, "", rootID) } -func PushReloadBlock(rootID, blockID string) { - BroadcastByType("main", "reloadBlock", 0, "", map[string]interface{}{"rootID": rootID, "blockID": blockID}) +func PushReloadBlock(rootID, blockID, defBlockID, refText string) { + BroadcastByType("protyle", "reloadBlock", 0, "", map[string]interface{}{"rootID": rootID, "blockID": blockID, "defBlockID": defBlockID, "refText": refText}) } func PushProtyleLoading(rootID, msg string) {