This commit is contained in:
Daniel 2025-03-28 21:32:09 +08:00
parent f43699b2c4
commit 1cb8520700
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
4 changed files with 151 additions and 87 deletions

View file

@ -26,7 +26,6 @@ import {isTouchDevice} from "../../util/functions";
import {App} from "../../index";
import {refreshFileTree} from "../../dialog/processSystem";
import {hideTooltip, showTooltip} from "../../dialog/tooltip";
import * as dayjs from "dayjs";
export class Files extends Model {
public element: HTMLElement;
@ -325,8 +324,7 @@ export class Files extends Model {
});
} else if (type === "addLocal") {
fetchPost("/api/filetree/moveLocalShorthands", {
"notebook": notebookId,
"path": dayjs().format("YYYY-MM-DD HH:mm:ss")
"notebook": notebookId
});
this.element.querySelectorAll('[data-type="addLocal"]').forEach(item => {
item.remove();

View file

@ -1,8 +1,4 @@
import {
hasClosestByClassName,
hasClosestByTag,
hasTopClosestByTag
} from "../../protyle/util/hasClosest";
import {hasClosestByClassName, hasClosestByTag, hasTopClosestByTag} from "../../protyle/util/hasClosest";
import {escapeHtml} from "../../util/escape";
import {Model} from "../../layout/Model";
import {Constants} from "../../constants";
@ -20,7 +16,6 @@ import {MenuItem} from "../../menus/Menu";
import {App} from "../../index";
import {refreshFileTree} from "../../dialog/processSystem";
import {setStorageVal} from "../../protyle/util/compatibility";
import * as dayjs from "dayjs";
export class MobileFiles extends Model {
public element: HTMLElement;
@ -220,8 +215,7 @@ export class MobileFiles extends Model {
window.siyuan.menus.menu.fullscreen("bottom");
} else if (type === "addLocal") {
fetchPost("/api/filetree/moveLocalShorthands", {
"notebook": notebookId,
"path": dayjs().format("YYYY-MM-DD HH:mm:ss")
"notebook": notebookId
});
this.element.querySelectorAll('[data-type="addLocal"]').forEach(item => {
item.remove();

View file

@ -55,43 +55,33 @@ func moveLocalShorthands(c *gin.Context) {
parentID = parentIDArg.(string)
}
id := ast.NewNodeID()
idArg := arg["id"]
if nil != idArg {
id = idArg.(string)
var hPath string
hPathArg := arg["path"]
if nil != hPathArg {
hPath = arg["path"].(string)
baseName := path.Base(hPath)
dir := path.Dir(hPath)
r, _ := regexp.Compile("\r\n|\r|\n|\u2028|\u2029|\t|/")
baseName = r.ReplaceAllString(baseName, "")
if 512 < utf8.RuneCountInString(baseName) {
baseName = gulu.Str.SubStr(baseName, 512)
}
hPath = path.Join(dir, baseName)
}
hPath := arg["path"].(string)
baseName := path.Base(hPath)
dir := path.Dir(hPath)
r, _ := regexp.Compile("\r\n|\r|\n|\u2028|\u2029|\t|/")
baseName = r.ReplaceAllString(baseName, "")
if 512 < utf8.RuneCountInString(baseName) {
baseName = gulu.Str.SubStr(baseName, 512)
}
hPath = path.Join(dir, baseName)
if !strings.HasPrefix(hPath, "/") {
hPath = "/" + hPath
}
id, err := model.MoveLocalShorthands(notebook, hPath, parentID, id)
ids, err := model.MoveLocalShorthands(notebook, hPath, parentID)
if err != nil {
ret.Code = -1
ret.Msg = err.Error()
return
}
if "" == id {
ret.Code = 1
ret.Msg = "No local shorthand need to move"
return
}
ret.Data = id
model.FlushTxQueue()
box := model.Conf.Box(notebook)
b, _ := model.GetBlock(id, nil)
pushCreate(box, b.Path, arg)
for _, id := range ids {
b, _ := model.GetBlock(id, nil)
pushCreate(box, b.Path, arg)
}
}
func listDocTree(c *gin.Context) {

View file

@ -20,14 +20,20 @@ import (
"bytes"
"os"
"path/filepath"
"slices"
"strconv"
"strings"
"time"
"github.com/88250/gulu"
"github.com/88250/lute/ast"
"github.com/88250/lute/parse"
"github.com/siyuan-note/logging"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
)
func MoveLocalShorthands(boxID, hPath, parentID, id string) (retID string, err error) {
func MoveLocalShorthands(boxID, hPath, parentID string) (retIDs []string, err error) {
shorthandsDir := filepath.Join(util.ShortcutsPath, "shorthands")
if !gulu.File.IsDir(shorthandsDir) {
return
@ -39,69 +45,145 @@ func MoveLocalShorthands(boxID, hPath, parentID, id string) (retID string, err e
return
}
buff := bytes.Buffer{}
var toRemoves []string
assetsDir := filepath.Join(util.DataDir, "assets")
for _, entry := range entries {
if entry.IsDir() {
if "assets" == entry.Name() {
assetsEntries, readErr := os.ReadDir(filepath.Join(shorthandsDir, entry.Name()))
if nil != readErr {
logging.LogErrorf("read dir [%s] failed: %s", shorthandsDir, readErr)
if entry.IsDir() && "assets" == entry.Name() {
assetsEntries, readErr := os.ReadDir(filepath.Join(shorthandsDir, entry.Name()))
if nil != readErr {
logging.LogErrorf("read dir [%s] failed: %s", shorthandsDir, readErr)
continue
}
for _, assetEntry := range assetsEntries {
if assetEntry.IsDir() {
continue
}
for _, assetEntry := range assetsEntries {
if assetEntry.IsDir() {
continue
}
p := filepath.Join(shorthandsDir, entry.Name(), assetEntry.Name())
assetWritePath := filepath.Join(assetsDir, assetEntry.Name())
if renameErr := os.Rename(p, assetWritePath); nil != renameErr {
logging.LogErrorf("rename file [%s] to [%s] failed: %s", p, assetWritePath, renameErr)
continue
}
p := filepath.Join(shorthandsDir, entry.Name(), assetEntry.Name())
assetWritePath := filepath.Join(assetsDir, assetEntry.Name())
if renameErr := os.Rename(p, assetWritePath); nil != renameErr {
logging.LogErrorf("rename file [%s] to [%s] failed: %s", p, assetWritePath, renameErr)
continue
}
}
}
if filepath.Ext(entry.Name()) != ".md" {
continue
}
p := filepath.Join(shorthandsDir, entry.Name())
data, readErr := os.ReadFile(p)
if nil != readErr {
logging.LogErrorf("read file [%s] failed: %s", p, readErr)
continue
}
buff.Write(bytes.TrimSpace(data))
buff.WriteString("\n\n")
toRemoves = append(toRemoves, p)
}
clearShorthand := func(toRemoves []string) {
for _, p := range toRemoves {
if removeErr := os.Remove(p); nil != removeErr {
logging.LogErrorf("remove file [%s] failed: %s", p, removeErr)
var toRemoves []string
box := Conf.Box(boxID)
if "" == hPath { // hPath 为空的话每一个速记对应创建一个文档记录
for _, entry := range entries {
if filepath.Ext(entry.Name()) != ".md" {
continue
}
p := filepath.Join(shorthandsDir, entry.Name())
data, readErr := os.ReadFile(p)
if nil != readErr {
logging.LogErrorf("read file [%s] failed: %s", p, readErr)
continue
}
content := string(bytes.TrimSpace(data))
if "" == content {
toRemoves = append(toRemoves, p)
continue
}
t := strings.TrimSuffix(entry.Name(), ".md")
i, parseErr := strconv.ParseInt(t, 10, 64)
if nil != parseErr {
logging.LogErrorf("parse [%s] to int failed: %s", t, parseErr)
continue
}
hPath = "/" + time.UnixMilli(i).Format("2006-01-02 15:04:05")
var retID string
retID, err = CreateWithMarkdown("", boxID, hPath, content, parentID, "", false, "")
if nil != err {
logging.LogErrorf("create doc failed: %s", err)
return
}
retIDs = append(retIDs, retID)
toRemoves = append(toRemoves, p)
box.addMinSort("/", retID)
}
} else { // 不为空的话将所有速记合并到指定路径的文档中
if !strings.HasPrefix(hPath, "/") {
hPath = "/" + hPath
}
buff := bytes.Buffer{}
for _, entry := range entries {
if filepath.Ext(entry.Name()) != ".md" {
continue
}
p := filepath.Join(shorthandsDir, entry.Name())
data, readErr := os.ReadFile(p)
if nil != readErr {
logging.LogErrorf("read file [%s] failed: %s", p, readErr)
continue
}
content := string(bytes.TrimSpace(data))
if "" == content {
toRemoves = append(toRemoves, p)
continue
}
buff.WriteString(content)
buff.WriteString("\n\n")
toRemoves = append(toRemoves, p)
}
if 0 < buff.Len() {
bt := treenode.GetBlockTreeRootByHPath(boxID, hPath)
if nil == bt {
var retID string
retID, err = CreateWithMarkdown("", boxID, hPath, buff.String(), parentID, "", false, "")
if nil != err {
logging.LogErrorf("create doc failed: %s", err)
return
}
retIDs = append(retIDs, retID)
} else {
var tree *parse.Tree
tree, err = loadTreeByBlockTree(bt)
if nil != err {
logging.LogErrorf("load tree by block tree failed: %s", err)
return
}
var last *ast.Node
for c := tree.Root.FirstChild; nil != c; c = c.Next {
last = c
}
luteEngine := util.NewStdLute()
inputTree := parse.Parse("", buff.Bytes(), luteEngine.ParseOptions)
if nil != inputTree {
var nodes []*ast.Node
for c := inputTree.Root.FirstChild; nil != c; c = c.Next {
nodes = append(nodes, c)
}
slices.Reverse(nodes)
for _, node := range nodes {
last.InsertAfter(node)
}
}
indexWriteTreeIndexQueue(tree)
}
}
}
content := strings.TrimSpace(buff.String())
if 1 > len(content) {
clearShorthand(toRemoves)
return
for _, p := range toRemoves {
if removeErr := os.Remove(p); nil != removeErr {
logging.LogErrorf("remove file [%s] failed: %s", p, removeErr)
}
}
retID, err = CreateWithMarkdown("", boxID, hPath, content, parentID, id, false, "")
if nil != err {
logging.LogErrorf("create doc failed: %s", err)
return
}
clearShorthand(toRemoves)
return
}