diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index ab0e66e77..b1362c1d6 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -1,5 +1,7 @@ { - "confirmDeleteTip": "Are you sure to delete ${x}?
After deletion, it can be restored in [Data History], retained ${y} days according to [Settings - Editor - History Retention Days]", + "andSubFile": "Are you sure you want to delete ${x} and its ${y} subdocs?", + "confirmDeleteTip": "Are you sure to delete ${x}?", + "rollbackTip": "After deletion, it can be restored in [Data History], retained ${x} days according to [Settings - Editor - History Retention Days]", "newView": "Add View", "newCol": "Add column", "newRow": "Add entry", @@ -686,7 +688,6 @@ "customEmoji": "Add custom emoji", "customEmojiTip": "Open Emoji folder, put the picture in and click the refresh button", "recentEmoji": "Common Emoticons", - "andSubFile": "and its x subdocs", "changeIcon": "Change icon", "addIcon": "Add icon", "includeSubFile": "\nInclude x subdocs", diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index e3372cd27..ee2938cdf 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -1,5 +1,7 @@ { - "confirmDeleteTip": "¿Está seguro de eliminar ${x}?
Después de la eliminación, se puede restaurar en [Historial de datos] y se conserva ${y } días según [Configuración - Editor - Días de retención del historial]", + "andSubFile": "¿Está seguro de que desea eliminar ${x} y sus subdocumentos ${y}?", + "confirmDeleteTip": "¿Está seguro de eliminar ${x}?", + "rollbackTip": "Después de la eliminación, se puede restaurar en [Historial de datos] y se conserva ${x} días según [Configuración - Editor - Días de retención del historial]", "newView": "Agregar vista", "newCol": "Agregar columna", "newRow": "Agregar entrada", @@ -235,7 +237,7 @@ "hideAll": "Ocultar todo", "showAll": "Mostrar todo", "showCol": "Mostrar columna", - "número": "Número", + "number": "Número", "fecha": "Fecha", "seleccionar": "Seleccionar", "multiSelect": "Selección múltiple", @@ -686,7 +688,6 @@ "customEmoji": "Añadir un emoji personalizado", "customEmojiTip": "Abrir carpeta de emojis, poner la imagen y hacer clic en el botón de actualización", "recentEmoji": "Emoticonos comunes", - "andSubFile": "y sus x documentos secundarios", "changeIcon": "Cambiar el icono", "addIcon": "Agregar icono", "includeSubFile": "\nIncluir x documentos secundarios", diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index 4564610c2..4cd8a8577 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -1,5 +1,7 @@ { - "confirmDeleteTip": "Êtes-vous sûr de supprimer ${x} ?
Après la suppression, il peut être restauré dans [Historique des données], conservé ${y } jours selon [Paramètres - Éditeur - Jours de rétention de l'historique]", + "andSubFile": "Êtes-vous sûr de vouloir supprimer ${x} et ses sous-documents ${y} ?", + "confirmDeleteTip": "Êtes-vous sûr de supprimer ${x} ?", + "rollbackTip": "Après la suppression, il peut être restauré dans [Historique des données], conservé ${x} jours selon [Paramètres - Éditeur - Jours de rétention de l'historique]", "newView": "Ajouter une vue", "newCol": "Ajouter une colonne", "newRow": "Ajouter une entrée", @@ -235,7 +237,7 @@ "hideAll": "Masquer tout", "showAll": "Afficher tout", "showCol": "Afficher la colonne", - "numéro": "Numéro", + "number": "Numéro", "date": "Date", "select": "Sélectionner", "multiSelect": "Multi-sélection", @@ -686,7 +688,6 @@ "customEmoji": "Ajouter un emoji personnalisé", "customEmojiTip": "Ouvrir Emoji folder, insérez l'image et cliquez sur le bouton d'actualisation", "recentEmoji": "Emoticônes courantes", - "andSubFile": "et son x sous-documents", "changeIcon": "Changer l'icône", "addIcon": "Ajouter une icône", "includeSubFile": "\nInclure x sous-documents", diff --git a/app/appearance/langs/ja_JP.json b/app/appearance/langs/ja_JP.json index 0015ddb34..56b0d1f7d 100644 --- a/app/appearance/langs/ja_JP.json +++ b/app/appearance/langs/ja_JP.json @@ -1,5 +1,7 @@ { - "confirmDeleteTip": "${x} を削除してもよろしいですか?
削除後は [データ履歴] で復元でき、${y} は保持されます。 [設定 - エディター - 履歴の保存日数] による日数", + "andSubFile": "${x} とそのサブドキュメント ${y} を削除してもよろしいですか?", + "confirmDeleteTip": "${x} を削除してもよろしいですか?", + "rollbackTip": "削除後は [データ履歴] で復元でき、${x} は保持されます。 [設定 - エディター - 履歴の保存日数] による日数", "newView": "ビューを追加", "newCol": "列を追加", "newRow": "エントリを追加", @@ -686,7 +688,6 @@ "customEmoji": "絵文字を追加", "customEmojiTip": "絵文字フォルダに画像を入れて更新ボタンをクリックしてください", "recentEmoji": "よく使う絵文字", - "andSubFile": "およびその x サブドキュメント", "changeIcon": "アイコンを変更", "addIcon": "アイコンを追加", "includeSubFile": "\nx 個のサブドキュメントを含む", diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index c3cf96ba3..baf565af4 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -1,5 +1,7 @@ { - "confirmDeleteTip": "確定刪除${x} 嗎?
刪除後可在 [資料歷史] 中恢復,按 [設定- 編輯器- 歷史保留天數] 保留${y} 天", + "andSubFile": "決定刪除 ${x} 及其 ${y} 個子文件嗎?", + "confirmDeleteTip": "確定刪除${x} 嗎?", + "rollbackTip": "刪除後可在 [資料歷史] 中恢復,按 [設定 - 編輯器 - 歷史保留天數] 保留 ${x} 天", "newView": "新增視圖", "newCol": "新增列", "newRow": "新增項目", @@ -686,7 +688,6 @@ "customEmoji": "新增自訂表情", "customEmojiTip": "打開 Emoji 資料夾 放入圖片後並點擊重新整理按鈕", "recentEmoji": "常用表情", - "andSubFile": "及其 x 個子文檔", "changeIcon": "修改圖示", "addIcon": "新增圖示", "includeSubFile": "\n包含 x 個子文檔", diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index ec93e965c..3e3c5460a 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -1,5 +1,5 @@ { - "andSubFile": "确定删除 ${x} 及其 ${y} 个子文档吗?", + "andSubFile": "确定删除 ${x} 及其 ${y} 个子文档吗?", "confirmDeleteTip": "确定删除 ${x} 吗?", "rollbackTip": "删除后可在 [数据历史] 中恢复,按 [设置 - 编辑器 - 历史保留天数] 保留 ${x} 天", "newView": "添加视图", diff --git a/kernel/api/av.go b/kernel/api/av.go index ca9d3858e..88953e6b3 100644 --- a/kernel/api/av.go +++ b/kernel/api/av.go @@ -27,7 +27,7 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) -func getAttributeViewSelectOptions(c *gin.Context) { +func getAttributeViewKeysByAvID(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) @@ -36,8 +36,7 @@ func getAttributeViewSelectOptions(c *gin.Context) { return } avID := arg["avID"].(string) - keyID := arg["keyID"].(string) - ret.Data = model.GetAttributeViewSelectOptions(avID, keyID) + ret.Data = model.GetAttributeViewKeysByAvID(avID) } func getMirrorDatabaseBlocks(c *gin.Context) { diff --git a/kernel/api/block_op.go b/kernel/api/block_op.go index 65d9a96a2..24bb48fdb 100644 --- a/kernel/api/block_op.go +++ b/kernel/api/block_op.go @@ -133,6 +133,59 @@ func appendDailyNoteBlock(c *gin.Context) { broadcastTransactions(transactions) } +func prependDailyNoteBlock(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { + return + } + + data := arg["data"].(string) + dataType := arg["dataType"].(string) + boxID := arg["notebook"].(string) + if util.InvalidIDPattern(boxID, ret) { + return + } + if "markdown" == dataType { + luteEngine := util.NewLute() + var err error + data, err = dataBlockDOM(data, luteEngine) + if nil != err { + ret.Code = -1 + ret.Msg = "data block DOM failed: " + err.Error() + return + } + } + + p, _, err := model.CreateDailyNote(boxID) + if nil != err { + ret.Code = -1 + ret.Msg = "create daily note failed: " + err.Error() + return + } + + parentID := strings.TrimSuffix(path.Base(p), ".sy") + transactions := []*model.Transaction{ + { + DoOperations: []*model.Operation{ + { + Action: "prependInsert", + Data: data, + ParentID: parentID, + }, + }, + }, + } + + model.PerformTransactions(&transactions) + model.WaitForWritingFiles() + + ret.Data = transactions + broadcastTransactions(transactions) +} + func unfoldBlock(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) diff --git a/kernel/api/router.go b/kernel/api/router.go index 6de7dd863..d4e622fa5 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -185,6 +185,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/block/prependBlock", model.CheckAuth, model.CheckReadonly, prependBlock) ginServer.Handle("POST", "/api/block/appendBlock", model.CheckAuth, model.CheckReadonly, appendBlock) ginServer.Handle("POST", "/api/block/appendDailyNoteBlock", model.CheckAuth, model.CheckReadonly, appendDailyNoteBlock) + ginServer.Handle("POST", "/api/block/prependDailyNoteBlock", model.CheckAuth, model.CheckReadonly, prependDailyNoteBlock) ginServer.Handle("POST", "/api/block/updateBlock", model.CheckAuth, model.CheckReadonly, updateBlock) ginServer.Handle("POST", "/api/block/deleteBlock", model.CheckAuth, model.CheckReadonly, deleteBlock) ginServer.Handle("POST", "/api/block/moveBlock", model.CheckAuth, model.CheckReadonly, moveBlock) @@ -423,7 +424,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/av/getAttributeViewPrimaryKeyValues", model.CheckAuth, model.CheckReadonly, getAttributeViewPrimaryKeyValues) ginServer.Handle("POST", "/api/av/setDatabaseBlockView", model.CheckAuth, model.CheckReadonly, setDatabaseBlockView) ginServer.Handle("POST", "/api/av/getMirrorDatabaseBlocks", model.CheckAuth, model.CheckReadonly, getMirrorDatabaseBlocks) - ginServer.Handle("POST", "/api/av/getAttributeViewSelectOptions", model.CheckAuth, model.CheckReadonly, getAttributeViewSelectOptions) + ginServer.Handle("POST", "/api/av/getAttributeViewKeysByAvID", model.CheckAuth, model.CheckReadonly, getAttributeViewKeysByAvID) ginServer.Handle("POST", "/api/ai/chatGPT", model.CheckAuth, chatGPT) ginServer.Handle("POST", "/api/ai/chatGPTWithAction", model.CheckAuth, chatGPTWithAction) diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index edfcee6f0..c5eb0e05d 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -41,8 +41,8 @@ import ( "github.com/xrash/smetrics" ) -func GetAttributeViewSelectOptions(avID string, keyID string) (ret []*av.SelectOption) { - ret = []*av.SelectOption{} +func GetAttributeViewKeysByAvID(avID string) (ret []*av.Key) { + ret = []*av.Key{} attrView, err := av.ParseAttributeView(avID) if nil != err { @@ -50,17 +50,9 @@ func GetAttributeViewSelectOptions(avID string, keyID string) (ret []*av.SelectO return } - key, _ := attrView.GetKey(keyID) - if nil == key { - return - } - - if av.KeyTypeSelect != key.Type && av.KeyTypeMSelect != key.Type { - return - } - - if 0 < len(key.Options) { - ret = key.Options + for _, keyValues := range attrView.KeyValues { + key := keyValues.Key + ret = append(ret, key) } return ret } diff --git a/kernel/model/search.go b/kernel/model/search.go index aaf19de66..ff260314a 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -35,6 +35,7 @@ import ( "github.com/88250/gulu" "github.com/88250/lute" "github.com/88250/lute/ast" + "github.com/88250/lute/html" "github.com/88250/lute/lex" "github.com/88250/lute/parse" "github.com/88250/vitess-sqlparser/sqlparser" @@ -1538,8 +1539,8 @@ func stringQuery(query string) string { // markReplaceSpan 用于处理搜索高亮。 func markReplaceSpan(n *ast.Node, unlinks *[]*ast.Node, keywords []string, markSpanDataType string, luteEngine *lute.Lute) bool { - text := n.Content() if ast.NodeText == n.Type { + text := n.Content() escapedText := util.EscapeHTML(text) escapedKeywords := make([]string, len(keywords)) for i, keyword := range keywords { @@ -1569,6 +1570,17 @@ func markReplaceSpan(n *ast.Node, unlinks *[]*ast.Node, keywords []string, markS return false } + var text string + if n.IsTextMarkType("code") { + // code 在前面的 n. + for i, k := range keywords { + keywords[i] = html.EscapeString(k) + } + text = n.TextMarkTextContent + } else { + text = n.Content() + } + startTag := search.GetMarkSpanStart(markSpanDataType) text = search.EncloseHighlighting(text, keywords, startTag, search.GetMarkSpanEnd(), Conf.Search.CaseSensitive, false) if strings.Contains(text, search.MarkDataType) {