diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index 42e04e2b5..14bb008f2 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -1,5 +1,5 @@ { - "backlinkTurnTo": "Reference Transfer", + "transferBlockRef": "Transfer Reference", "sortByFiletree": "Use doc tree sorting rule", "tabToWindow": "Move to New Window", "openByNewWindow": "Open with New Window", diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index f5c305501..3f326363e 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -1,5 +1,5 @@ { - "backlinkTurnTo": "Transferencia de referencia", + "transferBlockRef": "Transferencia de referencia", "sortByFiletree": "Usar reglas de clasificación del árbol de documentos", "tabToWindow": "Mover a una Nueva Ventana", "openByNewWindow": "Abrir con Nueva Ventana", diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index 34606e95c..a63c5f659 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -1,5 +1,5 @@ { - "backlinkTurnTo": "Transfert de référence", + "transferBlockRef": "Référence de transfert", "sortByFiletree": "Utiliser les règles de tri de l'arborescence des documents", "tabToWindow": "Passer à une nouvelle fenêtre", "openByNewWindow": "Ouvrir avec une nouvelle fenêtre", diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index 57b921256..0e91d2119 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -1,5 +1,5 @@ { - "backlinkTurnTo": "引用轉移", + "transferBlockRef": "轉移引用", "sortByFiletree": "使用文檔樹排序規則", "tabToWindow": "移動到新窗口", "openByNewWindow": "使用新窗口打開", diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index 5bb1af0ca..f6d2ab9e8 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -1,5 +1,5 @@ { - "backlinkTurnTo": "引用转移", + "transferBlockRef": "转移引用", "sortByFiletree": "使用文档树排序规则", "tabToWindow": "移动到新窗口", "openByNewWindow": "使用新窗口打开", diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts index 9638ca6d3..0d3fd861c 100644 --- a/app/src/protyle/gutter/index.ts +++ b/app/src/protyle/gutter/index.ts @@ -1,9 +1,4 @@ -import { - hasClosestBlock, - hasClosestByAttribute, - hasClosestByMatchTag, - hasClosestByTag -} from "../util/hasClosest"; +import {hasClosestBlock, hasClosestByAttribute, hasClosestByMatchTag, hasClosestByTag} from "../util/hasClosest"; import {getIconByType} from "../../editor/getIcon"; import {iframeMenu, setFold, tableMenu, videoMenu, zoomOut} from "../../menus/protyle"; import {MenuItem} from "../../menus/Menu"; @@ -11,7 +6,8 @@ import {copySubMenu, openAttr, openWechatNotify} from "../../menus/commonMenuIte import {copyPlainText, updateHotkeyTip, writeText} from "../util/compatibility"; import { transaction, - turnsIntoOneTransaction, turnsIntoTransaction, + turnsIntoOneTransaction, + turnsIntoTransaction, updateBatchTransaction, updateTransaction } from "../wysiwyg/transaction"; @@ -1379,13 +1375,13 @@ export class Gutter { const countElement = nodeElement.lastElementChild.querySelector(".protyle-attr--refcount") if (countElement && countElement.textContent) { window.siyuan.menus.menu.append(new MenuItem({ - label: window.siyuan.languages.backlinkTurnTo, + label: window.siyuan.languages.transferBlockRef, click() { const renameDialog = new Dialog({ - title: window.siyuan.languages.backlinkTurnTo, + title: window.siyuan.languages.transferBlockRef, content: `
-
${window.siyuan.languages.backlinkTurnTo}
+
${window.siyuan.languages.transferBlockRef}
diff --git a/kernel/api/block.go b/kernel/api/block.go index 36ff236d1..3e5ac4a37 100644 --- a/kernel/api/block.go +++ b/kernel/api/block.go @@ -30,6 +30,26 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) +func transferBlockRef(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { + return + } + + fromID := arg["fromID"].(string) + toID := arg["toID"].(string) + err := model.TransferBlockRef(fromID, toID) + if nil != err { + ret.Code = -1 + ret.Msg = err.Error() + ret.Data = map[string]interface{}{"closeTimeout": 7000} + return + } +} + func swapBlockRef(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) diff --git a/kernel/api/router.go b/kernel/api/router.go index 0961fe81e..0a2d07fec 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -170,6 +170,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/block/getHeadingChildrenIDs", model.CheckAuth, getHeadingChildrenIDs) ginServer.Handle("POST", "/api/block/getHeadingChildrenDOM", model.CheckAuth, getHeadingChildrenDOM) ginServer.Handle("POST", "/api/block/swapBlockRef", model.CheckAuth, swapBlockRef) + ginServer.Handle("POST", "/api/block/transferBlockRef", model.CheckAuth, transferBlockRef) ginServer.Handle("POST", "/api/file/getFile", model.CheckAuth, getFile) ginServer.Handle("POST", "/api/file/putFile", model.CheckAuth, putFile) diff --git a/kernel/model/block.go b/kernel/model/block.go index c48e11dcb..7add88011 100644 --- a/kernel/model/block.go +++ b/kernel/model/block.go @@ -115,6 +115,45 @@ func RecentUpdatedBlocks() (ret []*Block) { return } +func TransferBlockRef(fromID, toID string) (err error) { + toTree, _ := loadTreeByBlockID(toID) + if nil == toTree { + err = ErrBlockNotFound + return + } + toNode := treenode.GetNodeInTree(toTree, toID) + if nil == toNode { + err = ErrBlockNotFound + return + } + toRefText := getNodeRefText(toNode) + + refIDs, _ := sql.QueryRefIDsByDefID(fromID, false) + for _, refID := range refIDs { + tree, _ := loadTreeByBlockID(refID) + if nil == tree { + continue + } + node := treenode.GetNodeInTree(tree, refID) + textMarks := node.ChildrenByType(ast.NodeTextMark) + for _, textMark := range textMarks { + if textMark.IsTextMarkType("block-ref") && textMark.TextMarkBlockRefID == fromID { + textMark.TextMarkBlockRefID = toID + if "d" == textMark.TextMarkBlockRefSubtype { + textMark.TextMarkTextContent = toRefText + } + } + } + + if err = indexWriteJSONQueue(tree); nil != err { + return + } + } + + util.ReloadUI() + return +} + func SwapBlockRef(refID, defID string, includeChildren bool) (err error) { refTree, err := loadTreeByBlockID(refID) if nil != err {