diff --git a/kernel/api/av.go b/kernel/api/av.go index 08fcc4415..2cb0cc452 100644 --- a/kernel/api/av.go +++ b/kernel/api/av.go @@ -135,7 +135,7 @@ func addAttributeViewValues(c *gin.Context) { return } - pushRefreshAttrView(avID) + util.PushReloadAttrView(avID) } func removeAttributeViewValues(c *gin.Context) { @@ -160,7 +160,7 @@ func removeAttributeViewValues(c *gin.Context) { return } - pushRefreshAttrView(avID) + util.PushReloadAttrView(avID) } func addAttributeViewKey(c *gin.Context) { @@ -186,7 +186,7 @@ func addAttributeViewKey(c *gin.Context) { return } - pushRefreshAttrView(avID) + util.PushReloadAttrView(avID) } func removeAttributeViewKey(c *gin.Context) { @@ -208,7 +208,7 @@ func removeAttributeViewKey(c *gin.Context) { return } - pushRefreshAttrView(avID) + util.PushReloadAttrView(avID) } func sortAttributeViewKey(c *gin.Context) { @@ -235,7 +235,7 @@ func sortAttributeViewKey(c *gin.Context) { return } - pushRefreshAttrView(avID) + util.PushReloadAttrView(avID) } func getAttributeViewFilterSort(c *gin.Context) { @@ -509,9 +509,5 @@ func setAttributeViewBlockAttr(c *gin.Context) { blockAttributeViewKeys := model.UpdateAttributeViewCell(nil, avID, keyID, rowID, cellID, value) ret.Data = blockAttributeViewKeys - pushRefreshAttrView(avID) -} - -func pushRefreshAttrView(avID string) { - util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": avID}) + util.PushReloadAttrView(avID) } diff --git a/kernel/av/mirror.go b/kernel/av/mirror.go index 8814d8f56..bd9db29e0 100644 --- a/kernel/av/mirror.go +++ b/kernel/av/mirror.go @@ -66,7 +66,7 @@ func IsMirror(avID string) bool { return nil != blockIDs && 1 < len(blockIDs) } -func RemoveBlockRel(avID, blockID string) { +func RemoveBlockRel(avID, blockID string, existBlockTree func(string) bool) (ret bool) { AttributeViewBlocksLock.Lock() defer AttributeViewBlocksLock.Unlock() @@ -95,10 +95,13 @@ func RemoveBlockRel(avID, blockID string) { var newBlockIDs []string for _, v := range blockIDs { if v != blockID { - newBlockIDs = append(newBlockIDs, v) + if existBlockTree(v) { + newBlockIDs = append(newBlockIDs, v) + } } } avBlocks[avID] = newBlockIDs + ret = len(newBlockIDs) != len(blockIDs) data, err = msgpack.Marshal(avBlocks) if nil != err { @@ -109,6 +112,7 @@ func RemoveBlockRel(avID, blockID string) { logging.LogErrorf("write attribute view blocks failed: %s", err) return } + return } func BatchUpsertBlockRel(nodes []*ast.Node) { @@ -161,7 +165,7 @@ func BatchUpsertBlockRel(nodes []*ast.Node) { } } -func UpsertBlockRel(avID, blockID string) { +func UpsertBlockRel(avID, blockID string) (ret bool) { AttributeViewBlocksLock.Lock() defer AttributeViewBlocksLock.Unlock() @@ -186,9 +190,11 @@ func UpsertBlockRel(avID, blockID string) { } blockIDs := avBlocks[avID] + oldLen := len(blockIDs) blockIDs = append(blockIDs, blockID) blockIDs = gulu.Str.RemoveDuplicatedElem(blockIDs) avBlocks[avID] = blockIDs + ret = oldLen != len(blockIDs) data, err := msgpack.Marshal(avBlocks) if nil != err { @@ -199,4 +205,5 @@ func UpsertBlockRel(avID, blockID string) { logging.LogErrorf("write attribute view blocks failed: %s", err) return } + return } diff --git a/kernel/bazaar/package.go b/kernel/bazaar/package.go index dafd7b889..aa9f63841 100644 --- a/kernel/bazaar/package.go +++ b/kernel/bazaar/package.go @@ -554,7 +554,7 @@ func downloadPackage(repoURLHash string, pushProgress bool, systemID string) (da repoURLHash = strings.TrimPrefix(repoURLHash, "https://github.com/") u := util.BazaarOSSServer + "/package/" + repoURLHash buf := &bytes.Buffer{} - resp, err := httpclient.NewBrowserRequest().SetOutput(buf).SetDownloadCallback(func(info req.DownloadInfo) { + resp, err := httpclient.NewCloudFileRequest2m().SetOutput(buf).SetDownloadCallback(func(info req.DownloadInfo) { if pushProgress { progress := float32(info.DownloadedSize) / float32(info.Response.ContentLength) //logging.LogDebugf("downloading bazaar package [%f]", progress) diff --git a/kernel/filesys/json_parser.go b/kernel/filesys/json_parser.go index 45f8c4bc0..bb536ae26 100644 --- a/kernel/filesys/json_parser.go +++ b/kernel/filesys/json_parser.go @@ -144,6 +144,21 @@ func genTreeByJSON(node *ast.Node, tree *parse.Tree, idMap *map[string]bool, nee *needFix = true return // 忽略空查询嵌入块 } + case ast.NodeCodeBlock: + if 4 > len(node.Children) { + // https://ld246.com/article/1713689223067 + existCode := false + for _, child := range node.Children { + if ast.NodeCodeBlockCode.String() == child.TypeStr { + existCode = true + break + } + } + if !existCode { + *needFix = true + return // 忽略空代码块 + } + } } fixLegacyData(tree.Context.Tip, node, idMap, needFix, needMigrate2Spec1) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index ad8d3d96d..c0446d980 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1339,6 +1339,7 @@ func unbindAttributeViewBlock(operation *Operation, tx *Transaction) (err error) unbindBlockAv(tx, operation.AvID, value.BlockID) } value.BlockID = operation.NextID + value.IsDetached = true if nil != value.Block { value.Block.ID = operation.NextID } @@ -1602,7 +1603,7 @@ func updateAttributeViewColRelation(operation *Operation) (err error) { } if !isSameAv { err = av.SaveAttributeView(destAv) - util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": destAv.ID}) + util.PushReloadAttrView(destAv.ID) } av.UpsertAvBackRel(srcAv.ID, destAv.ID) @@ -2419,7 +2420,7 @@ func removeAttributeViewBlock(srcIDs []string, avID string, tx *Transaction) (er relatedAvIDs := av.GetSrcAvIDs(avID) for _, relatedAvID := range relatedAvIDs { - util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": relatedAvID}) + util.PushReloadAttrView(relatedAvID) } err = av.SaveAttributeView(attrView) @@ -2648,23 +2649,23 @@ func sortAttributeViewRow(operation *Operation) (err error) { } var rowID string - var index, previousIndex int + var idx, previousIndex int for i, r := range view.Table.RowIDs { if r == operation.ID { rowID = r - index = i + idx = i break } } if "" == rowID { rowID = operation.ID view.Table.RowIDs = append(view.Table.RowIDs, rowID) - index = len(view.Table.RowIDs) - 1 + idx = len(view.Table.RowIDs) - 1 } switch view.LayoutType { case av.LayoutTypeTable: - view.Table.RowIDs = append(view.Table.RowIDs[:index], view.Table.RowIDs[index+1:]...) + view.Table.RowIDs = append(view.Table.RowIDs[:idx], view.Table.RowIDs[idx+1:]...) for i, r := range view.Table.RowIDs { if r == operation.PreviousID { previousIndex = i + 1 @@ -2934,7 +2935,7 @@ func RemoveAttributeViewKey(avID, keyID string) (err error) { } av.SaveAttributeView(destAv) - util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": destAv.ID}) + util.PushReloadAttrView(destAv.ID) if !destAvRelSrcAv { av.RemoveAvRel(destAv.ID, attrView.ID) @@ -3250,7 +3251,7 @@ func UpdateAttributeViewCell(tx *Transaction, avID, keyID, rowID, cellID string, relatedAvIDs := av.GetSrcAvIDs(avID) for _, relatedAvID := range relatedAvIDs { - util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": relatedAvID}) + util.PushReloadAttrView(relatedAvID) } if err = av.SaveAttributeView(attrView); nil != err { diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index 3f3e1ff1d..6747c7c62 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -799,6 +799,7 @@ func (tx *Transaction) doDelete(operation *Operation) (ret *TxErr) { } func removeAvBlockRel(node *ast.Node) { + var avIDs []string ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus { if !entering { return ast.WalkContinue @@ -806,10 +807,16 @@ func removeAvBlockRel(node *ast.Node) { if ast.NodeAttributeView == n.Type { avID := n.AttributeViewID - av.RemoveBlockRel(avID, n.ID) + if changed := av.RemoveBlockRel(avID, n.ID, treenode.ExistBlockTree); changed { + avIDs = append(avIDs, avID) + } } return ast.WalkContinue }) + avIDs = gulu.Str.RemoveDuplicatedElem(avIDs) + for _, avID := range avIDs { + util.PushReloadAttrView(avID) + } } func syncDelete2AttributeView(node *ast.Node) { @@ -854,7 +861,7 @@ func syncDelete2AttributeView(node *ast.Node) { }) for _, avID := range changedAvIDs.Values() { - util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": avID}) + util.PushReloadAttrView(avID.(string)) } } @@ -1127,6 +1134,7 @@ func refreshHeadingChildrenUpdated(heading *ast.Node, updated string) { } func upsertAvBlockRel(node *ast.Node) { + var avIDs []string ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus { if !entering { return ast.WalkContinue @@ -1134,10 +1142,16 @@ func upsertAvBlockRel(node *ast.Node) { if ast.NodeAttributeView == n.Type { avID := n.AttributeViewID - av.UpsertBlockRel(avID, n.ID) + if changed := av.UpsertBlockRel(avID, n.ID); changed { + avIDs = append(avIDs, avID) + } } return ast.WalkContinue }) + avIDs = gulu.Str.RemoveDuplicatedElem(avIDs) + for _, avID := range avIDs { + util.PushReloadAttrView(avID) + } } func (tx *Transaction) doUpdateUpdated(operation *Operation) (ret *TxErr) { @@ -1471,7 +1485,7 @@ func refreshDynamicRefTexts(updatedDefNodes map[string]*ast.Node, updatedTrees m } if changedAv { av.SaveAttributeView(attrView) - util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": avID}) + util.PushReloadAttrView(avID) } } } diff --git a/kernel/treenode/blocktree.go b/kernel/treenode/blocktree.go index 823036acc..03c3ddafd 100644 --- a/kernel/treenode/blocktree.go +++ b/kernel/treenode/blocktree.go @@ -194,6 +194,19 @@ func GetBlockTreeRootByHPathPreferredParentID(boxID, hPath, preferredParentID st return } +func ExistBlockTree(id string) bool { + hash := btHash(id) + val, ok := blockTrees.Load(hash) + if !ok { + return false + } + slice := val.(*btSlice) + slice.m.Lock() + _, ok = slice.data[id] + slice.m.Unlock() + return ok +} + func GetBlockTree(id string) (ret *BlockTree) { if "" == id { return diff --git a/kernel/util/websocket.go b/kernel/util/websocket.go index 868315739..2c8bcbf10 100644 --- a/kernel/util/websocket.go +++ b/kernel/util/websocket.go @@ -216,6 +216,10 @@ func PushClearProgress() { BroadcastByType("main", "cprogress", 0, "", nil) } +func PushReloadAttrView(avID string) { + BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": avID}) +} + func PushReloadDoc(rootID string) { BroadcastByType("main", "reloaddoc", 0, "", rootID) }