mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-16 22:50:13 +01:00
🎨 Supports local shorthands on Android https://github.com/siyuan-note/siyuan/issues/14414
This commit is contained in:
parent
f43699b2c4
commit
1cb8520700
4 changed files with 151 additions and 87 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue