mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-17 07:00:12 +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 {App} from "../../index";
|
||||||
import {refreshFileTree} from "../../dialog/processSystem";
|
import {refreshFileTree} from "../../dialog/processSystem";
|
||||||
import {hideTooltip, showTooltip} from "../../dialog/tooltip";
|
import {hideTooltip, showTooltip} from "../../dialog/tooltip";
|
||||||
import * as dayjs from "dayjs";
|
|
||||||
|
|
||||||
export class Files extends Model {
|
export class Files extends Model {
|
||||||
public element: HTMLElement;
|
public element: HTMLElement;
|
||||||
|
|
@ -325,8 +324,7 @@ export class Files extends Model {
|
||||||
});
|
});
|
||||||
} else if (type === "addLocal") {
|
} else if (type === "addLocal") {
|
||||||
fetchPost("/api/filetree/moveLocalShorthands", {
|
fetchPost("/api/filetree/moveLocalShorthands", {
|
||||||
"notebook": notebookId,
|
"notebook": notebookId
|
||||||
"path": dayjs().format("YYYY-MM-DD HH:mm:ss")
|
|
||||||
});
|
});
|
||||||
this.element.querySelectorAll('[data-type="addLocal"]').forEach(item => {
|
this.element.querySelectorAll('[data-type="addLocal"]').forEach(item => {
|
||||||
item.remove();
|
item.remove();
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
import {
|
import {hasClosestByClassName, hasClosestByTag, hasTopClosestByTag} from "../../protyle/util/hasClosest";
|
||||||
hasClosestByClassName,
|
|
||||||
hasClosestByTag,
|
|
||||||
hasTopClosestByTag
|
|
||||||
} from "../../protyle/util/hasClosest";
|
|
||||||
import {escapeHtml} from "../../util/escape";
|
import {escapeHtml} from "../../util/escape";
|
||||||
import {Model} from "../../layout/Model";
|
import {Model} from "../../layout/Model";
|
||||||
import {Constants} from "../../constants";
|
import {Constants} from "../../constants";
|
||||||
|
|
@ -20,7 +16,6 @@ import {MenuItem} from "../../menus/Menu";
|
||||||
import {App} from "../../index";
|
import {App} from "../../index";
|
||||||
import {refreshFileTree} from "../../dialog/processSystem";
|
import {refreshFileTree} from "../../dialog/processSystem";
|
||||||
import {setStorageVal} from "../../protyle/util/compatibility";
|
import {setStorageVal} from "../../protyle/util/compatibility";
|
||||||
import * as dayjs from "dayjs";
|
|
||||||
|
|
||||||
export class MobileFiles extends Model {
|
export class MobileFiles extends Model {
|
||||||
public element: HTMLElement;
|
public element: HTMLElement;
|
||||||
|
|
@ -220,8 +215,7 @@ export class MobileFiles extends Model {
|
||||||
window.siyuan.menus.menu.fullscreen("bottom");
|
window.siyuan.menus.menu.fullscreen("bottom");
|
||||||
} else if (type === "addLocal") {
|
} else if (type === "addLocal") {
|
||||||
fetchPost("/api/filetree/moveLocalShorthands", {
|
fetchPost("/api/filetree/moveLocalShorthands", {
|
||||||
"notebook": notebookId,
|
"notebook": notebookId
|
||||||
"path": dayjs().format("YYYY-MM-DD HH:mm:ss")
|
|
||||||
});
|
});
|
||||||
this.element.querySelectorAll('[data-type="addLocal"]').forEach(item => {
|
this.element.querySelectorAll('[data-type="addLocal"]').forEach(item => {
|
||||||
item.remove();
|
item.remove();
|
||||||
|
|
|
||||||
|
|
@ -55,13 +55,10 @@ func moveLocalShorthands(c *gin.Context) {
|
||||||
parentID = parentIDArg.(string)
|
parentID = parentIDArg.(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
id := ast.NewNodeID()
|
var hPath string
|
||||||
idArg := arg["id"]
|
hPathArg := arg["path"]
|
||||||
if nil != idArg {
|
if nil != hPathArg {
|
||||||
id = idArg.(string)
|
hPath = arg["path"].(string)
|
||||||
}
|
|
||||||
|
|
||||||
hPath := arg["path"].(string)
|
|
||||||
baseName := path.Base(hPath)
|
baseName := path.Base(hPath)
|
||||||
dir := path.Dir(hPath)
|
dir := path.Dir(hPath)
|
||||||
r, _ := regexp.Compile("\r\n|\r|\n|\u2028|\u2029|\t|/")
|
r, _ := regexp.Compile("\r\n|\r|\n|\u2028|\u2029|\t|/")
|
||||||
|
|
@ -70,28 +67,21 @@ func moveLocalShorthands(c *gin.Context) {
|
||||||
baseName = gulu.Str.SubStr(baseName, 512)
|
baseName = gulu.Str.SubStr(baseName, 512)
|
||||||
}
|
}
|
||||||
hPath = path.Join(dir, baseName)
|
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 {
|
if err != nil {
|
||||||
ret.Code = -1
|
ret.Code = -1
|
||||||
ret.Msg = err.Error()
|
ret.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if "" == id {
|
|
||||||
ret.Code = 1
|
|
||||||
ret.Msg = "No local shorthand need to move"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.Data = id
|
|
||||||
|
|
||||||
model.FlushTxQueue()
|
model.FlushTxQueue()
|
||||||
box := model.Conf.Box(notebook)
|
box := model.Conf.Box(notebook)
|
||||||
|
for _, id := range ids {
|
||||||
b, _ := model.GetBlock(id, nil)
|
b, _ := model.GetBlock(id, nil)
|
||||||
pushCreate(box, b.Path, arg)
|
pushCreate(box, b.Path, arg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func listDocTree(c *gin.Context) {
|
func listDocTree(c *gin.Context) {
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,20 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/88250/gulu"
|
"github.com/88250/gulu"
|
||||||
|
"github.com/88250/lute/ast"
|
||||||
|
"github.com/88250/lute/parse"
|
||||||
"github.com/siyuan-note/logging"
|
"github.com/siyuan-note/logging"
|
||||||
|
"github.com/siyuan-note/siyuan/kernel/treenode"
|
||||||
"github.com/siyuan-note/siyuan/kernel/util"
|
"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")
|
shorthandsDir := filepath.Join(util.ShortcutsPath, "shorthands")
|
||||||
if !gulu.File.IsDir(shorthandsDir) {
|
if !gulu.File.IsDir(shorthandsDir) {
|
||||||
return
|
return
|
||||||
|
|
@ -39,12 +45,9 @@ func MoveLocalShorthands(boxID, hPath, parentID, id string) (retID string, err e
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
buff := bytes.Buffer{}
|
|
||||||
var toRemoves []string
|
|
||||||
assetsDir := filepath.Join(util.DataDir, "assets")
|
assetsDir := filepath.Join(util.DataDir, "assets")
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
if entry.IsDir() {
|
if entry.IsDir() && "assets" == entry.Name() {
|
||||||
if "assets" == entry.Name() {
|
|
||||||
assetsEntries, readErr := os.ReadDir(filepath.Join(shorthandsDir, entry.Name()))
|
assetsEntries, readErr := os.ReadDir(filepath.Join(shorthandsDir, entry.Name()))
|
||||||
if nil != readErr {
|
if nil != readErr {
|
||||||
logging.LogErrorf("read dir [%s] failed: %s", shorthandsDir, readErr)
|
logging.LogErrorf("read dir [%s] failed: %s", shorthandsDir, readErr)
|
||||||
|
|
@ -65,6 +68,11 @@ func MoveLocalShorthands(boxID, hPath, parentID, id string) (retID string, err e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var toRemoves []string
|
||||||
|
box := Conf.Box(boxID)
|
||||||
|
|
||||||
|
if "" == hPath { // hPath 为空的话每一个速记对应创建一个文档记录
|
||||||
|
for _, entry := range entries {
|
||||||
if filepath.Ext(entry.Name()) != ".md" {
|
if filepath.Ext(entry.Name()) != ".md" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -76,32 +84,106 @@ func MoveLocalShorthands(boxID, hPath, parentID, id string) (retID string, err e
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
buff.Write(bytes.TrimSpace(data))
|
content := string(bytes.TrimSpace(data))
|
||||||
buff.WriteString("\n\n")
|
if "" == content {
|
||||||
toRemoves = append(toRemoves, p)
|
toRemoves = append(toRemoves, p)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
clearShorthand := func(toRemoves []string) {
|
t := strings.TrimSuffix(entry.Name(), ".md")
|
||||||
for _, p := range toRemoves {
|
i, parseErr := strconv.ParseInt(t, 10, 64)
|
||||||
if removeErr := os.Remove(p); nil != removeErr {
|
if nil != parseErr {
|
||||||
logging.LogErrorf("remove file [%s] failed: %s", p, removeErr)
|
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, "")
|
||||||
content := strings.TrimSpace(buff.String())
|
|
||||||
if 1 > len(content) {
|
|
||||||
clearShorthand(toRemoves)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
retID, err = CreateWithMarkdown("", boxID, hPath, content, parentID, id, false, "")
|
|
||||||
if nil != err {
|
if nil != err {
|
||||||
logging.LogErrorf("create doc failed: %s", err)
|
logging.LogErrorf("create doc failed: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
clearShorthand(toRemoves)
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range toRemoves {
|
||||||
|
if removeErr := os.Remove(p); nil != removeErr {
|
||||||
|
logging.LogErrorf("remove file [%s] failed: %s", p, removeErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue