Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
afe993a15c
7 changed files with 169 additions and 21 deletions
|
@ -472,6 +472,7 @@ export class Gutter {
|
|||
}
|
||||
|
||||
private turnsIntoOne(options: {
|
||||
menuId?: string,
|
||||
accelerator?: string,
|
||||
icon?: string,
|
||||
label: string,
|
||||
|
@ -479,7 +480,6 @@ export class Gutter {
|
|||
selectsElement: Element[],
|
||||
type: TTurnIntoOne,
|
||||
level?: TTurnIntoOneSub,
|
||||
menuId?: string,
|
||||
}) {
|
||||
return {
|
||||
id: options.menuId,
|
||||
|
@ -493,6 +493,7 @@ export class Gutter {
|
|||
}
|
||||
|
||||
private turnsInto(options: {
|
||||
menuId?: string,
|
||||
icon?: string,
|
||||
label: string,
|
||||
protyle: IProtyle,
|
||||
|
@ -501,7 +502,6 @@ export class Gutter {
|
|||
level?: number,
|
||||
isContinue?: boolean,
|
||||
accelerator?: string,
|
||||
menuId?: string,
|
||||
}) {
|
||||
return {
|
||||
id: options.menuId,
|
||||
|
@ -551,6 +551,7 @@ export class Gutter {
|
|||
const turnIntoSubmenu: IMenu[] = [];
|
||||
if (isContinue) {
|
||||
turnIntoSubmenu.push(this.turnsIntoOne({
|
||||
menuId: "list",
|
||||
icon: "iconList",
|
||||
label: window.siyuan.languages.list,
|
||||
protyle,
|
||||
|
@ -559,6 +560,7 @@ export class Gutter {
|
|||
type: "Blocks2ULs"
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsIntoOne({
|
||||
menuId: "orderedList",
|
||||
icon: "iconOrderedList",
|
||||
label: window.siyuan.languages["ordered-list"],
|
||||
accelerator: window.siyuan.config.keymap.editor.insert["ordered-list"].custom,
|
||||
|
@ -567,6 +569,7 @@ export class Gutter {
|
|||
type: "Blocks2OLs"
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsIntoOne({
|
||||
menuId: "check",
|
||||
icon: "iconCheck",
|
||||
label: window.siyuan.languages.check,
|
||||
accelerator: window.siyuan.config.keymap.editor.insert.check.custom,
|
||||
|
@ -575,6 +578,7 @@ export class Gutter {
|
|||
type: "Blocks2TLs"
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsIntoOne({
|
||||
menuId: "quote",
|
||||
icon: "iconQuote",
|
||||
label: window.siyuan.languages.quote,
|
||||
accelerator: window.siyuan.config.keymap.editor.insert.quote.custom,
|
||||
|
@ -586,6 +590,7 @@ export class Gutter {
|
|||
// 多选引用转换为块的时候 id 不一致
|
||||
if (!hasEmbedBlock) {
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "paragraph",
|
||||
icon: "iconParagraph",
|
||||
label: window.siyuan.languages.paragraph,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.paragraph.custom,
|
||||
|
@ -596,6 +601,7 @@ export class Gutter {
|
|||
}));
|
||||
}
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading1",
|
||||
icon: "iconH1",
|
||||
label: window.siyuan.languages.heading1,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading1.custom,
|
||||
|
@ -606,6 +612,7 @@ export class Gutter {
|
|||
isContinue
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading2",
|
||||
icon: "iconH2",
|
||||
label: window.siyuan.languages.heading2,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading2.custom,
|
||||
|
@ -616,6 +623,7 @@ export class Gutter {
|
|||
isContinue
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading3",
|
||||
icon: "iconH3",
|
||||
label: window.siyuan.languages.heading3,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading3.custom,
|
||||
|
@ -626,6 +634,7 @@ export class Gutter {
|
|||
isContinue
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading4",
|
||||
icon: "iconH4",
|
||||
label: window.siyuan.languages.heading4,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading4.custom,
|
||||
|
@ -636,6 +645,7 @@ export class Gutter {
|
|||
isContinue
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading5",
|
||||
icon: "iconH5",
|
||||
label: window.siyuan.languages.heading5,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading5.custom,
|
||||
|
@ -646,6 +656,7 @@ export class Gutter {
|
|||
isContinue
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading6",
|
||||
icon: "iconH6",
|
||||
label: window.siyuan.languages.heading6,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading6.custom,
|
||||
|
@ -669,6 +680,7 @@ export class Gutter {
|
|||
label: window.siyuan.languages.merge + " " + window.siyuan.languages.superBlock,
|
||||
type: "submenu",
|
||||
submenu: [this.turnsIntoOne({
|
||||
menuId: "hLayout",
|
||||
label: window.siyuan.languages.hLayout,
|
||||
accelerator: window.siyuan.config.keymap.editor.general.hLayout.custom,
|
||||
icon: "iconSplitLR",
|
||||
|
@ -677,6 +689,7 @@ export class Gutter {
|
|||
type: "BlocksMergeSuperBlock",
|
||||
level: "col"
|
||||
}), this.turnsIntoOne({
|
||||
menuId: "vLayout",
|
||||
label: window.siyuan.languages.vLayout,
|
||||
accelerator: window.siyuan.config.keymap.editor.general.vLayout.custom,
|
||||
icon: "iconSplitTB",
|
||||
|
@ -911,6 +924,7 @@ export class Gutter {
|
|||
// "heading1-6", "list", "ordered-list", "check", "quote", "code", "table", "line", "math", "paragraph"
|
||||
if (type === "NodeParagraph" && !protyle.disabled) {
|
||||
turnIntoSubmenu.push(this.turnsIntoOne({
|
||||
menuId: "list",
|
||||
icon: "iconList",
|
||||
label: window.siyuan.languages.list,
|
||||
accelerator: window.siyuan.config.keymap.editor.insert.list.custom,
|
||||
|
@ -919,6 +933,7 @@ export class Gutter {
|
|||
type: "Blocks2ULs"
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsIntoOne({
|
||||
menuId: "orderedList",
|
||||
icon: "iconOrderedList",
|
||||
label: window.siyuan.languages["ordered-list"],
|
||||
accelerator: window.siyuan.config.keymap.editor.insert["ordered-list"].custom,
|
||||
|
@ -927,6 +942,7 @@ export class Gutter {
|
|||
type: "Blocks2OLs"
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsIntoOne({
|
||||
menuId: "check",
|
||||
icon: "iconCheck",
|
||||
label: window.siyuan.languages.check,
|
||||
accelerator: window.siyuan.config.keymap.editor.insert.check.custom,
|
||||
|
@ -935,6 +951,7 @@ export class Gutter {
|
|||
type: "Blocks2TLs"
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsIntoOne({
|
||||
menuId: "quote",
|
||||
icon: "iconQuote",
|
||||
label: window.siyuan.languages.quote,
|
||||
accelerator: window.siyuan.config.keymap.editor.insert.quote.custom,
|
||||
|
@ -943,6 +960,7 @@ export class Gutter {
|
|||
type: "Blocks2Blockquote"
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading1",
|
||||
icon: "iconH1",
|
||||
label: window.siyuan.languages.heading1,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading1.custom,
|
||||
|
@ -952,6 +970,7 @@ export class Gutter {
|
|||
type: "Blocks2Hs",
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading2",
|
||||
icon: "iconH2",
|
||||
label: window.siyuan.languages.heading2,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading2.custom,
|
||||
|
@ -961,6 +980,7 @@ export class Gutter {
|
|||
type: "Blocks2Hs",
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading3",
|
||||
icon: "iconH3",
|
||||
label: window.siyuan.languages.heading3,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading3.custom,
|
||||
|
@ -970,6 +990,7 @@ export class Gutter {
|
|||
type: "Blocks2Hs",
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading4",
|
||||
icon: "iconH4",
|
||||
label: window.siyuan.languages.heading4,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading4.custom,
|
||||
|
@ -979,6 +1000,7 @@ export class Gutter {
|
|||
type: "Blocks2Hs",
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading5",
|
||||
icon: "iconH5",
|
||||
label: window.siyuan.languages.heading5,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading5.custom,
|
||||
|
@ -988,6 +1010,7 @@ export class Gutter {
|
|||
type: "Blocks2Hs",
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading6",
|
||||
icon: "iconH6",
|
||||
label: window.siyuan.languages.heading6,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading6.custom,
|
||||
|
@ -998,6 +1021,7 @@ export class Gutter {
|
|||
}));
|
||||
} else if (type === "NodeHeading" && !protyle.disabled) {
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "paragraph",
|
||||
icon: "iconParagraph",
|
||||
label: window.siyuan.languages.paragraph,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.paragraph.custom,
|
||||
|
@ -1006,6 +1030,7 @@ export class Gutter {
|
|||
type: "Blocks2Ps",
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsIntoOne({
|
||||
menuId: "quote",
|
||||
icon: "iconQuote",
|
||||
label: window.siyuan.languages.quote,
|
||||
accelerator: window.siyuan.config.keymap.editor.insert.quote.custom,
|
||||
|
@ -1015,6 +1040,7 @@ export class Gutter {
|
|||
}));
|
||||
if (subType !== "h1") {
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading1",
|
||||
icon: "iconH1",
|
||||
label: window.siyuan.languages.heading1,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading1.custom,
|
||||
|
@ -1026,6 +1052,7 @@ export class Gutter {
|
|||
}
|
||||
if (subType !== "h2") {
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading2",
|
||||
icon: "iconH2",
|
||||
label: window.siyuan.languages.heading2,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading2.custom,
|
||||
|
@ -1037,6 +1064,7 @@ export class Gutter {
|
|||
}
|
||||
if (subType !== "h3") {
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading3",
|
||||
icon: "iconH3",
|
||||
label: window.siyuan.languages.heading3,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading3.custom,
|
||||
|
@ -1048,6 +1076,7 @@ export class Gutter {
|
|||
}
|
||||
if (subType !== "h4") {
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading4",
|
||||
icon: "iconH4",
|
||||
label: window.siyuan.languages.heading4,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading4.custom,
|
||||
|
@ -1059,6 +1088,7 @@ export class Gutter {
|
|||
}
|
||||
if (subType !== "h5") {
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading5",
|
||||
icon: "iconH5",
|
||||
label: window.siyuan.languages.heading5,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading5.custom,
|
||||
|
@ -1070,6 +1100,7 @@ export class Gutter {
|
|||
}
|
||||
if (subType !== "h6") {
|
||||
turnIntoSubmenu.push(this.turnsInto({
|
||||
menuId: "heading6",
|
||||
icon: "iconH6",
|
||||
label: window.siyuan.languages.heading6,
|
||||
accelerator: window.siyuan.config.keymap.editor.heading.heading6.custom,
|
||||
|
@ -1081,6 +1112,7 @@ export class Gutter {
|
|||
}
|
||||
} else if (type === "NodeList" && !protyle.disabled) {
|
||||
turnIntoSubmenu.push(this.turnsOneInto({
|
||||
menuId: "paragraph",
|
||||
id,
|
||||
icon: "iconParagraph",
|
||||
label: window.siyuan.languages.paragraph,
|
||||
|
@ -1090,6 +1122,7 @@ export class Gutter {
|
|||
type: "CancelList"
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsIntoOne({
|
||||
menuId: "quote",
|
||||
icon: "iconQuote",
|
||||
label: window.siyuan.languages.quote,
|
||||
accelerator: window.siyuan.config.keymap.editor.insert.quote.custom,
|
||||
|
@ -1099,6 +1132,7 @@ export class Gutter {
|
|||
}));
|
||||
if (nodeElement.getAttribute("data-subtype") === "o") {
|
||||
turnIntoSubmenu.push(this.turnsOneInto({
|
||||
menuId: "list",
|
||||
id,
|
||||
icon: "iconList",
|
||||
label: window.siyuan.languages.list,
|
||||
|
@ -1108,6 +1142,7 @@ export class Gutter {
|
|||
type: "OL2UL"
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsOneInto({
|
||||
menuId: "check",
|
||||
id,
|
||||
icon: "iconCheck",
|
||||
label: window.siyuan.languages.check,
|
||||
|
@ -1118,6 +1153,7 @@ export class Gutter {
|
|||
}));
|
||||
} else if (nodeElement.getAttribute("data-subtype") === "t") {
|
||||
turnIntoSubmenu.push(this.turnsOneInto({
|
||||
menuId: "list",
|
||||
id,
|
||||
icon: "iconList",
|
||||
label: window.siyuan.languages.list,
|
||||
|
@ -1127,6 +1163,7 @@ export class Gutter {
|
|||
type: "TL2UL"
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsOneInto({
|
||||
menuId: "orderedList",
|
||||
id,
|
||||
icon: "iconOrderedList",
|
||||
label: window.siyuan.languages["ordered-list"],
|
||||
|
@ -1137,6 +1174,7 @@ export class Gutter {
|
|||
}));
|
||||
} else {
|
||||
turnIntoSubmenu.push(this.turnsOneInto({
|
||||
menuId: "orderedList",
|
||||
id,
|
||||
icon: "iconOrderedList",
|
||||
label: window.siyuan.languages["ordered-list"],
|
||||
|
@ -1146,6 +1184,7 @@ export class Gutter {
|
|||
type: "UL2OL"
|
||||
}));
|
||||
turnIntoSubmenu.push(this.turnsOneInto({
|
||||
menuId: "check",
|
||||
id,
|
||||
icon: "iconCheck",
|
||||
label: window.siyuan.languages.check,
|
||||
|
@ -1157,6 +1196,7 @@ export class Gutter {
|
|||
}
|
||||
} else if (type === "NodeBlockquote" && !protyle.disabled) {
|
||||
turnIntoSubmenu.push(this.turnsOneInto({
|
||||
menuId: "paragraph",
|
||||
id,
|
||||
icon: "iconParagraph",
|
||||
label: window.siyuan.languages.paragraph,
|
||||
|
|
|
@ -63,6 +63,7 @@ func ServeAPI(ginServer *gin.Engine) {
|
|||
ginServer.Handle("POST", "/api/system/getChangelog", model.CheckAuth, getChangelog)
|
||||
ginServer.Handle("POST", "/api/system/getNetwork", model.CheckAuth, model.CheckAdminRole, getNetwork)
|
||||
ginServer.Handle("POST", "/api/system/exportConf", model.CheckAuth, model.CheckAdminRole, exportConf)
|
||||
ginServer.Handle("POST", "/api/system/importConf", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importConf)
|
||||
|
||||
ginServer.Handle("POST", "/api/storage/setLocalStorage", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setLocalStorage)
|
||||
ginServer.Handle("POST", "/api/storage/getLocalStorage", model.CheckAuth, getLocalStorage)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/copier"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
@ -25,10 +25,10 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/88250/lute"
|
||||
|
||||
"github.com/88250/gulu"
|
||||
"github.com/88250/lute"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/siyuan-note/logging"
|
||||
"github.com/siyuan-note/siyuan/kernel/conf"
|
||||
"github.com/siyuan-note/siyuan/kernel/model"
|
||||
|
@ -211,17 +211,19 @@ func exportConf(c *gin.Context) {
|
|||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
||||
logging.LogInfof("exporting conf...")
|
||||
|
||||
name := "siyuan-conf-" + time.Now().Format("20060102150405") + ".json"
|
||||
tmpDir := filepath.Join(util.TempDir, "export")
|
||||
if err := os.MkdirAll(tmpDir, 0755); err != nil {
|
||||
logging.LogErrorf("export WebDAV provider failed: %s", err)
|
||||
logging.LogErrorf("export conf failed: %s", err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
clonedConf := &model.AppConf{}
|
||||
if err := copier.Copy(clonedConf, model.Conf); err != nil {
|
||||
if err := copier.CopyWithOption(clonedConf, model.Conf, copier.Option{IgnoreEmpty: false, DeepCopy: true}); err != nil {
|
||||
logging.LogErrorf("export conf failed: %s", err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
|
@ -291,6 +293,8 @@ func exportConf(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
logging.LogInfof("exported conf")
|
||||
|
||||
zipPath := "/export/" + name + ".zip"
|
||||
ret.Data = map[string]interface{}{
|
||||
"name": name,
|
||||
|
@ -298,6 +302,96 @@ func exportConf(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func importConf(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(200, ret)
|
||||
|
||||
logging.LogInfof("importing conf...")
|
||||
|
||||
form, err := c.MultipartForm()
|
||||
if err != nil {
|
||||
logging.LogErrorf("read upload file failed: %s", err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
files := form.File["file"]
|
||||
if 1 != len(files) {
|
||||
ret.Code = -1
|
||||
ret.Msg = "invalid upload file"
|
||||
return
|
||||
}
|
||||
|
||||
f := files[0]
|
||||
fh, err := f.Open()
|
||||
if err != nil {
|
||||
logging.LogErrorf("read upload file failed: %s", err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(fh)
|
||||
fh.Close()
|
||||
if err != nil {
|
||||
logging.LogErrorf("read upload file failed: %s", err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
tmpDir := filepath.Join(util.TempDir, "import")
|
||||
if err = os.MkdirAll(tmpDir, 0755); err != nil {
|
||||
logging.LogErrorf("import conf failed: %s", err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
tmp := filepath.Join(tmpDir, f.Filename)
|
||||
if err = os.WriteFile(tmp, data, 0644); err != nil {
|
||||
logging.LogErrorf("import conf failed: %s", err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
if err = gulu.Zip.Unzip(tmp, tmpDir); err != nil {
|
||||
logging.LogErrorf("import conf failed: %s", err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
tmp = filepath.Join(tmpDir, f.Filename[:len(f.Filename)-4])
|
||||
data, err = os.ReadFile(tmp)
|
||||
if err != nil {
|
||||
logging.LogErrorf("import conf failed: %s", err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
importedConf := model.NewAppConf()
|
||||
if err = gulu.JSON.UnmarshalJSON(data, importedConf); err != nil {
|
||||
logging.LogErrorf("import conf failed: %s", err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
if err = copier.CopyWithOption(model.Conf, importedConf, copier.Option{IgnoreEmpty: true, DeepCopy: true}); err != nil {
|
||||
logging.LogErrorf("import conf failed: %s", err)
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
logging.LogInfof("imported conf")
|
||||
model.Close(false, true, 1)
|
||||
}
|
||||
|
||||
func getConf(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
|
|
@ -1675,7 +1675,7 @@ func (tx *Transaction) doSetAttrViewViewIcon(operation *Operation) (ret *TxErr)
|
|||
}
|
||||
|
||||
func (tx *Transaction) doSetAttrViewName(operation *Operation) (ret *TxErr) {
|
||||
err := setAttributeViewName(operation)
|
||||
err := tx.setAttributeViewName(operation)
|
||||
if err != nil {
|
||||
return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()}
|
||||
}
|
||||
|
@ -1684,7 +1684,7 @@ func (tx *Transaction) doSetAttrViewName(operation *Operation) (ret *TxErr) {
|
|||
|
||||
const attrAvNameTpl = `<span data-av-id="${avID}" data-popover-url="/api/av/getMirrorDatabaseBlocks" class="popover__block">${avName}</span>`
|
||||
|
||||
func setAttributeViewName(operation *Operation) (err error) {
|
||||
func (tx *Transaction) setAttributeViewName(operation *Operation) (err error) {
|
||||
avID := operation.ID
|
||||
attrView, err := av.ParseAttributeView(avID)
|
||||
if err != nil {
|
||||
|
@ -1694,7 +1694,7 @@ func setAttributeViewName(operation *Operation) (err error) {
|
|||
attrView.Name = strings.TrimSpace(operation.Data.(string))
|
||||
err = av.SaveAttributeView(attrView)
|
||||
|
||||
_, nodes := getAttrViewBoundNodes(attrView)
|
||||
_, nodes := tx.getAttrViewBoundNodes(attrView)
|
||||
for _, node := range nodes {
|
||||
avNames := getAvNames(node.IALAttr(av.NodeAttrNameAvs))
|
||||
oldAttrs := parse.IAL2Map(node.KramdownIAL)
|
||||
|
@ -1731,7 +1731,7 @@ func getAvNames(avIDs string) (ret string) {
|
|||
return
|
||||
}
|
||||
|
||||
func getAttrViewBoundNodes(attrView *av.AttributeView) (trees []*parse.Tree, nodes []*ast.Node) {
|
||||
func (tx *Transaction) getAttrViewBoundNodes(attrView *av.AttributeView) (trees []*parse.Tree, nodes []*ast.Node) {
|
||||
blockKeyValues := attrView.GetBlockKeyValues()
|
||||
treeCache := map[string]*parse.Tree{}
|
||||
for _, blockKeyValue := range blockKeyValues.Values {
|
||||
|
@ -1742,7 +1742,11 @@ func getAttrViewBoundNodes(attrView *av.AttributeView) (trees []*parse.Tree, nod
|
|||
var tree *parse.Tree
|
||||
tree = treeCache[blockKeyValue.BlockID]
|
||||
if nil == tree {
|
||||
tree, _ = LoadTreeByBlockID(blockKeyValue.BlockID)
|
||||
if nil == tx {
|
||||
tree, _ = LoadTreeByBlockID(blockKeyValue.BlockID)
|
||||
} else {
|
||||
tree, _ = tx.loadTree(blockKeyValue.BlockID)
|
||||
}
|
||||
}
|
||||
if nil == tree {
|
||||
continue
|
||||
|
|
|
@ -51,7 +51,7 @@ var Conf *AppConf
|
|||
|
||||
// AppConf 维护应用元数据,保存在 ~/.siyuan/conf.json。
|
||||
type AppConf struct {
|
||||
LogLevel string `json:"logLevel"` // 日志级别:Off, Trace, Debug, Info, Warn, Error, Fatal
|
||||
LogLevel string `json:"logLevel"` // 日志级别:off, trace, debug, info, warn, error, fatal
|
||||
Appearance *conf.Appearance `json:"appearance"` // 外观
|
||||
Langs []*conf.Lang `json:"langs"` // 界面语言列表
|
||||
Lang string `json:"lang"` // 选择的界面语言,同 Appearance.Lang
|
||||
|
@ -87,6 +87,10 @@ type AppConf struct {
|
|||
m *sync.Mutex
|
||||
}
|
||||
|
||||
func NewAppConf() *AppConf {
|
||||
return &AppConf{LogLevel: "debug", m: &sync.Mutex{}}
|
||||
}
|
||||
|
||||
func (conf *AppConf) GetUILayout() *conf.UILayout {
|
||||
conf.m.Lock()
|
||||
defer conf.m.Unlock()
|
||||
|
@ -114,7 +118,7 @@ func (conf *AppConf) SetUser(user *conf.User) {
|
|||
func InitConf() {
|
||||
initLang()
|
||||
|
||||
Conf = &AppConf{LogLevel: "debug", m: &sync.Mutex{}}
|
||||
Conf = NewAppConf()
|
||||
confPath := filepath.Join(util.ConfDir, "conf.json")
|
||||
if gulu.File.IsExist(confPath) {
|
||||
if data, err := os.ReadFile(confPath); err != nil {
|
||||
|
|
|
@ -1704,7 +1704,7 @@ func removeDoc(box *Box, p string, luteEngine *lute.Lute) {
|
|||
continue
|
||||
}
|
||||
|
||||
syncDelete2AvBlock(removeTree.Root)
|
||||
syncDelete2AvBlock(removeTree.Root, removeTree, nil)
|
||||
}
|
||||
|
||||
if existChildren {
|
||||
|
|
|
@ -819,14 +819,14 @@ func (tx *Transaction) doDelete(operation *Operation) (ret *TxErr) {
|
|||
}
|
||||
|
||||
if needSyncDel2AvBlock {
|
||||
syncDelete2AvBlock(node)
|
||||
syncDelete2AvBlock(node, tree, tx)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func syncDelete2AvBlock(node *ast.Node) {
|
||||
func syncDelete2AvBlock(node *ast.Node, nodeTree *parse.Tree, tx *Transaction) {
|
||||
changedAvIDs := syncDelete2AttributeView(node)
|
||||
avIDs := syncDelete2Block(node)
|
||||
avIDs := tx.syncDelete2Block(node, nodeTree)
|
||||
changedAvIDs = append(changedAvIDs, avIDs...)
|
||||
changedAvIDs = gulu.Str.RemoveDuplicatedElem(changedAvIDs)
|
||||
|
||||
|
@ -835,7 +835,7 @@ func syncDelete2AvBlock(node *ast.Node) {
|
|||
}
|
||||
}
|
||||
|
||||
func syncDelete2Block(node *ast.Node) (changedAvIDs []string) {
|
||||
func (tx *Transaction) syncDelete2Block(node *ast.Node, nodeTree *parse.Tree) (changedAvIDs []string) {
|
||||
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||
if !entering || ast.NodeAttributeView != n.Type {
|
||||
return ast.WalkContinue
|
||||
|
@ -857,7 +857,7 @@ func syncDelete2Block(node *ast.Node) (changedAvIDs []string) {
|
|||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
trees, nodes := getAttrViewBoundNodes(attrView)
|
||||
trees, nodes := tx.getAttrViewBoundNodes(attrView)
|
||||
for _, toChangNode := range nodes {
|
||||
avs := toChangNode.IALAttr(av.NodeAttrNameAvs)
|
||||
if "" != avs {
|
||||
|
@ -874,8 +874,13 @@ func syncDelete2Block(node *ast.Node) (changedAvIDs []string) {
|
|||
toChangNode.SetIALAttr(av.NodeAttrViewNames, avNames)
|
||||
pushBroadcastAttrTransactions(oldAttrs, toChangNode)
|
||||
}
|
||||
|
||||
nodeTreeID := nodeTree.ID
|
||||
for _, tree := range trees {
|
||||
indexWriteTreeUpsertQueue(tree)
|
||||
self := nodeTreeID == tree.ID
|
||||
if !self {
|
||||
indexWriteTreeUpsertQueue(tree)
|
||||
}
|
||||
}
|
||||
return ast.WalkContinue
|
||||
})
|
||||
|
|
Loading…
Add table
Reference in a new issue