Browse Source

Merge remote-tracking branch 'origin/dev' into dev

Vanessa 8 months ago
parent
commit
b9e62d2b7a
3 changed files with 44 additions and 28 deletions
  1. 20 14
      app/src/layout/dock/Graph.ts
  2. 1 1
      app/src/protyle/util/paste.ts
  3. 23 13
      kernel/model/search.go

+ 20 - 14
app/src/layout/dock/Graph.ts

@@ -632,37 +632,43 @@ export class Graph extends Model {
                         iterations: 256,
                         updateInterval: 64,
                         onlyDynamicEdges: false,
-                        fit: true
+                        fit: false
                     },
                     timestep: 0.5,
                     adaptiveTimestep: true,
                     wind: {x: 0, y: 0}
                 },
             };
-            let j = Math.max(Math.ceil(this.graphData.nodes.length * 0.1), 128);
-            const nodes = new vis.DataSet(this.graphData.nodes.slice(0, j));
+            let i = Math.max(Math.ceil(this.graphData.nodes.length * 0.1), 128);
+            const nodes = new vis.DataSet(this.graphData.nodes.slice(0, i));
             const edges = new vis.DataSet();
             const network = new vis.Network(this.graphElement, {nodes, edges}, options);
             const time = 256;
+            let intervalNodeTime = Math.max(Math.ceil(time / 8), 32);
             let batch = this.graphData.nodes.length / time / 2;
-            if (batch < 64) {
-                batch = 64;
+            if (batch < 32) {
+                batch = 32;
             }
-            if (batch > 256) {
-                batch = 256;
+            if (batch > 128) {
+                batch = 128;
             }
-            let i = 0;
+            let count = 0;
             const intervalNode = setInterval(() => {
-                const nodes = this.graphData.nodes.slice(j, j + batch);
+                const nodes = this.graphData.nodes.slice(i, i + batch);
                 if (nodes.length === 0) {
                     clearInterval(intervalNode);
                     return;
                 }
                 network.body.data.nodes.add(nodes);
-                j += batch;
-            }, time / 8);
+                i += batch;
+                count++;
+                if (0 === count % (batch / 8)) {
+                    network.fit({animation: false});
+                }
+            }, intervalNodeTime);
+            let j = 0;
             const intervalId = setInterval(() => {
-                const edges = this.graphData.links.slice(i, i + batch);
+                const edges = this.graphData.links.slice(j, j + batch);
                 if (edges.length === 0) {
                     clearInterval(intervalId);
                     network.fit({
@@ -671,7 +677,7 @@ export class Graph extends Model {
                     return;
                 }
                 network.body.data.edges.add(edges);
-                i += batch;
+                j += batch;
             }, time);
             this.network = network;
             network.on("stabilizationIterationsDone", () => {
@@ -683,7 +689,7 @@ export class Graph extends Model {
             network.on("dragEnd", () => {
                 setTimeout(() => {
                     network.physics.stopSimulation();
-                }, 5000);
+                }, 3000);
             });
             network.on("click", (params: any) => {
                 if (params.nodes.length !== 1) {

+ 1 - 1
app/src/protyle/util/paste.ts

@@ -182,7 +182,7 @@ export const pasteAsPlainText = async (protyle: IProtyle) => {
             textPlain = textPlain.replace(/__@sub@__/g, "<sub>").replace(/__@\/sub@__/g, "</sub>");
             textPlain = textPlain.replace(/__@sup@__/g, "<sup>").replace(/__@\/sup@__/g, "</sup>");
             textPlain = textPlain.replace(/__@kbd@__/g, "<kbd>").replace(/__@\/kbd@__/g, "</kbd>");
-            textPlain = textPlain.replace(/__@u@__/g, "<u>").replace(/__@\/u@__/g, "</u");
+            textPlain = textPlain.replace(/__@u@__/g, "<u>").replace(/__@\/u@__/g, "</u>");
 
             const content = protyle.lute.BlockDOM2EscapeMarkerContent(protyle.lute.Md2BlockDOM(textPlain));
             // insertHTML 会进行内部反转义

+ 23 - 13
kernel/model/search.go

@@ -830,17 +830,19 @@ func replaceTextNode(text *ast.Node, method int, keyword string, replacement str
 				newContent = bytes.ReplaceAll(text.Tokens, []byte(keyword), []byte(replacement))
 			}
 		} else {
-			// 当搜索结果中的文本元素包含大小写混合时替换失败
-			// Replace fails when search results contain mixed case in text elements https://github.com/siyuan-note/siyuan/issues/9171
-			keywords := strings.Split(keyword, " ")
-			// keyword 可能是 "foo Foo" 使用空格分隔的大小写命中情况,这里统一转换小写后去重
-			if 0 < len(keywords) {
-				var lowerKeywords []string
-				for _, k := range keywords {
-					lowerKeywords = append(lowerKeywords, strings.ToLower(k))
+			if "" != strings.TrimSpace(keyword) {
+				// 当搜索结果中的文本元素包含大小写混合时替换失败
+				// Replace fails when search results contain mixed case in text elements https://github.com/siyuan-note/siyuan/issues/9171
+				keywords := strings.Split(keyword, " ")
+				// keyword 可能是 "foo Foo" 使用空格分隔的大小写命中情况,这里统一转换小写后去重
+				if 0 < len(keywords) {
+					var lowerKeywords []string
+					for _, k := range keywords {
+						lowerKeywords = append(lowerKeywords, strings.ToLower(k))
+					}
+					lowerKeywords = gulu.Str.RemoveDuplicatedElem(lowerKeywords)
+					keyword = strings.Join(lowerKeywords, " ")
 				}
-				lowerKeywords = gulu.Str.RemoveDuplicatedElem(lowerKeywords)
-				keyword = strings.Join(lowerKeywords, " ")
 			}
 
 			if bytes.Contains(bytes.ToLower(text.Tokens), []byte(keyword)) {
@@ -945,7 +947,7 @@ func FullTextSearchBlock(query string, boxes, paths []string, types map[string]b
 		typeFilter := buildTypeFilter(types)
 		boxFilter := buildBoxesFilter(boxes)
 		pathFilter := buildPathsFilter(paths)
-		if 2 > len(strings.Split(query, " ")) {
+		if 2 > len(strings.Split(strings.TrimSpace(query), " ")) {
 			blocks, matchedBlockCount, matchedRootCount = fullTextSearchByQuerySyntax(query, boxFilter, pathFilter, typeFilter, ignoreFilter, orderByClause, beforeLen, page, pageSize)
 		} else {
 			docMode = true // 文档全文搜索模式 https://github.com/siyuan-note/siyuan/issues/10584
@@ -1304,7 +1306,12 @@ func fullTextSearchByRegexp(exp, boxFilter, pathFilter, typeFilter, ignoreFilter
 	fieldFilter := fieldRegexp(exp)
 	stmt := "SELECT * FROM `blocks` WHERE " + fieldFilter + " AND type IN " + typeFilter
 	stmt += boxFilter + pathFilter + ignoreFilter + " " + orderBy
-	regex := regexp.MustCompile(exp)
+	regex, err := regexp.Compile(exp)
+	if nil != err {
+		util.PushErrMsg(err.Error(), 5000)
+		return
+	}
+
 	blocks := sql.SelectBlocksRegex(stmt, regex, Conf.Search.Name, Conf.Search.Alias, Conf.Search.Memo, Conf.Search.IAL, page, pageSize)
 	ret = fromSQLBlocks(&blocks, "", beforeLen)
 	if 1 > len(ret) {
@@ -1458,7 +1465,10 @@ func highlightByRegexp(query, typeFilter, id string) (ret []string) {
 	fieldFilter := fieldRegexp(query)
 	stmt := "SELECT * FROM `blocks` WHERE " + fieldFilter + " AND type IN " + typeFilter
 	stmt += " AND root_id = '" + id + "'"
-	regex := regexp.MustCompile(query)
+	regex, _ := regexp.Compile(query)
+	if nil == regex {
+		return
+	}
 	sqlBlocks := sql.SelectBlocksRegex(stmt, regex, Conf.Search.Name, Conf.Search.Alias, Conf.Search.Memo, Conf.Search.IAL, 1, 256)
 	for _, block := range sqlBlocks {
 		keyword := gulu.Str.SubstringsBetween(block.Content, search.SearchMarkLeft, search.SearchMarkRight)