mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-05-22 03:50:55 +08:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
c6b3083a24
@ -548,7 +548,7 @@
|
|||||||
"kernelFault1": "Please check if the network connection and kernel process is normal",
|
"kernelFault1": "Please check if the network connection and kernel process is normal",
|
||||||
"kernelFault2": "If the problem still occurs after restarting, please report it via <a href=\"https://github.com/siyuan-note/siyuan/issues\" target=\"_blank\">GitHub Issues</a>",
|
"kernelFault2": "If the problem still occurs after restarting, please report it via <a href=\"https://github.com/siyuan-note/siyuan/issues\" target=\"_blank\">GitHub Issues</a>",
|
||||||
"fontSize": "Font Size",
|
"fontSize": "Font Size",
|
||||||
"fontSizeTip": "The default font size is 16px, this setting only affects the font size display in the editor",
|
"fontSizeTip": "The default font size is 16px, this setting affects the editor and exported PDF/HTML font size display",
|
||||||
"font1": "This setting only affects the font family display in the editor, choose <code class='fn__code'>Default</code> to use the theme's font family",
|
"font1": "This setting only affects the font family display in the editor, choose <code class='fn__code'>Default</code> to use the theme's font family",
|
||||||
"newNameFile": "The name of the new subdocument is",
|
"newNameFile": "The name of the new subdocument is",
|
||||||
"newNameSettingFile": "The name of the new document is",
|
"newNameSettingFile": "The name of the new document is",
|
||||||
|
@ -548,7 +548,7 @@
|
|||||||
"kernelFault1": "Verifique si la conexión de red y los procesos del kernel son normales",
|
"kernelFault1": "Verifique si la conexión de red y los procesos del kernel son normales",
|
||||||
"kernelFault2": "Si el problema sigue produciéndose después de reiniciar, comuníquelo a través de <a href=\"https://github.com/siyuan-note/siyuan/issues\" target=\"_blank\">Problemas en GitHub</a>",
|
"kernelFault2": "Si el problema sigue produciéndose después de reiniciar, comuníquelo a través de <a href=\"https://github.com/siyuan-note/siyuan/issues\" target=\"_blank\">Problemas en GitHub</a>",
|
||||||
"fontSize": "Tamaño de la fuente",
|
"fontSize": "Tamaño de la fuente",
|
||||||
"fontSizeTip": "El tamaño de la fuente por defecto es de 16px, este ajuste sólo afecta a la visualización del tamaño de la fuente en el editor",
|
"fontSizeTip": "El tamaño de fuente predeterminado es 16px, esta configuración afecta el editor y la visualización del tamaño de fuente PDF/HTML exportado",
|
||||||
"font1": "Este ajuste sólo afecta a la visualización de la familia de fuentes en el editor, elija <code class='fn__code'>Por defecto</code> para utilizar la familia de fuentes del tema",
|
"font1": "Este ajuste sólo afecta a la visualización de la familia de fuentes en el editor, elija <code class='fn__code'>Por defecto</code> para utilizar la familia de fuentes del tema",
|
||||||
"newNameFile": "El nombre del nuevo subdocumento es",
|
"newNameFile": "El nombre del nuevo subdocumento es",
|
||||||
"newNameSettingFile": "El nombre del nuevo documento es",
|
"newNameSettingFile": "El nombre del nuevo documento es",
|
||||||
|
@ -548,7 +548,7 @@
|
|||||||
"kernelFault1": "Veuillez vérifier si la connexion réseau et les processus du noyau sont normaux",
|
"kernelFault1": "Veuillez vérifier si la connexion réseau et les processus du noyau sont normaux",
|
||||||
"kernelFault2": "Si le problème persiste après le redémarrage, veuillez le signaler via <a href=\"https://github.com/siyuan-note/siyuan/issues\" target=\"_blank\">GitHub Issues</a>",
|
"kernelFault2": "Si le problème persiste après le redémarrage, veuillez le signaler via <a href=\"https://github.com/siyuan-note/siyuan/issues\" target=\"_blank\">GitHub Issues</a>",
|
||||||
"fontSize": "Taille de la police",
|
"fontSize": "Taille de la police",
|
||||||
"fontSizeTip": "La taille de la police par défaut est de 16px, ce paramètre n'affecte que la taille de la police affichée dans l'éditeur.",
|
"fontSizeTip": "La taille de police par défaut est de 16px, ce paramètre affecte l'éditeur et l'affichage de la taille de police PDF/HTML exportée",
|
||||||
"font1": "Ce paramètre n'affecte que l'affichage de la famille de polices dans l'éditeur, choisissez <code class='fn__code'>Default</code> pour utiliser la famille de polices du thème.",
|
"font1": "Ce paramètre n'affecte que l'affichage de la famille de polices dans l'éditeur, choisissez <code class='fn__code'>Default</code> pour utiliser la famille de polices du thème.",
|
||||||
"newNameFile": "Le nom du nouveau sous-document est",
|
"newNameFile": "Le nom du nouveau sous-document est",
|
||||||
"newNameSettingFile": "Le nom du nouveau document est",
|
"newNameSettingFile": "Le nom du nouveau document est",
|
||||||
|
@ -548,7 +548,7 @@
|
|||||||
"kernelFault1": "請檢查網絡連接和內核進程是否正常",
|
"kernelFault1": "請檢查網絡連接和內核進程是否正常",
|
||||||
"kernelFault2": "如果重啟後仍然出現該問題,請通過<a href=\"https://ld246.com/article/1649901726096\" target=\"_blank\">這裡回饋</a>",
|
"kernelFault2": "如果重啟後仍然出現該問題,請通過<a href=\"https://ld246.com/article/1649901726096\" target=\"_blank\">這裡回饋</a>",
|
||||||
"fontSize": "字型大小",
|
"fontSize": "字型大小",
|
||||||
"fontSizeTip": "字型大小預設為 16px,該設置僅影響編輯器內字體大小顯示",
|
"fontSizeTip": "字號默認為 16px,該設置影響編輯器和導出 PDF/HTML 字體大小顯示",
|
||||||
"font1": "該設置僅影響編輯器內字體顯示,選擇 <code class='fn__code'>預設</code> 則使用主題自帶字體",
|
"font1": "該設置僅影響編輯器內字體顯示,選擇 <code class='fn__code'>預設</code> 則使用主題自帶字體",
|
||||||
"newNameFile": "新建子文檔名為",
|
"newNameFile": "新建子文檔名為",
|
||||||
"newNameSettingFile": "新建文檔名為",
|
"newNameSettingFile": "新建文檔名為",
|
||||||
|
@ -548,7 +548,7 @@
|
|||||||
"kernelFault1": "请检查网络连接和内核进程是否正常",
|
"kernelFault1": "请检查网络连接和内核进程是否正常",
|
||||||
"kernelFault2": "如果重启后仍然出现该问题,请通过<a href=\"https://ld246.com/article/1649901726096\" target=\"_blank\">这里反馈</a>",
|
"kernelFault2": "如果重启后仍然出现该问题,请通过<a href=\"https://ld246.com/article/1649901726096\" target=\"_blank\">这里反馈</a>",
|
||||||
"fontSize": "字号",
|
"fontSize": "字号",
|
||||||
"fontSizeTip": "字号默认为 16px,该设置仅影响编辑器内字体大小显示",
|
"fontSizeTip": "字号默认为 16px,该设置影响编辑器和导出 PDF/HTML 字体大小显示",
|
||||||
"font1": "该设置仅影响编辑器内字体显示,选择 <code class='fn__code'>默认</code> 则使用主题自带字体",
|
"font1": "该设置仅影响编辑器内字体显示,选择 <code class='fn__code'>默认</code> 则使用主题自带字体",
|
||||||
"newNameFile": "新建子文档名为",
|
"newNameFile": "新建子文档名为",
|
||||||
"newNameSettingFile": "新建文档名为",
|
"newNameSettingFile": "新建文档名为",
|
||||||
|
@ -18,6 +18,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -95,7 +96,7 @@ func heading2Doc(c *gin.Context) {
|
|||||||
|
|
||||||
name := path.Base(targetPath)
|
name := path.Base(targetPath)
|
||||||
box := model.Conf.Box(targetNotebook)
|
box := model.Conf.Box(targetNotebook)
|
||||||
files, _, _ := model.ListDocTree(targetNotebook, path.Dir(targetPath), model.Conf.FileTree.Sort)
|
files, _, _ := model.ListDocTree(targetNotebook, path.Dir(targetPath), model.Conf.FileTree.Sort, false, model.Conf.FileTree.MaxListCount)
|
||||||
evt := util.NewCmdResult("heading2doc", 0, util.PushModeBroadcast)
|
evt := util.NewCmdResult("heading2doc", 0, util.PushModeBroadcast)
|
||||||
evt.Data = map[string]interface{}{
|
evt.Data = map[string]interface{}{
|
||||||
"box": box,
|
"box": box,
|
||||||
@ -140,7 +141,7 @@ func li2Doc(c *gin.Context) {
|
|||||||
|
|
||||||
name := path.Base(targetPath)
|
name := path.Base(targetPath)
|
||||||
box := model.Conf.Box(targetNotebook)
|
box := model.Conf.Box(targetNotebook)
|
||||||
files, _, _ := model.ListDocTree(targetNotebook, path.Dir(targetPath), model.Conf.FileTree.Sort)
|
files, _, _ := model.ListDocTree(targetNotebook, path.Dir(targetPath), model.Conf.FileTree.Sort, false, model.Conf.FileTree.MaxListCount)
|
||||||
evt := util.NewCmdResult("li2doc", 0, util.PushModeBroadcast)
|
evt := util.NewCmdResult("li2doc", 0, util.PushModeBroadcast)
|
||||||
evt.Data = map[string]interface{}{
|
evt.Data = map[string]interface{}{
|
||||||
"box": box,
|
"box": box,
|
||||||
@ -448,7 +449,7 @@ func createDailyNote(c *gin.Context) {
|
|||||||
evt.AppId = app
|
evt.AppId = app
|
||||||
|
|
||||||
name := path.Base(p)
|
name := path.Base(p)
|
||||||
files, _, _ := model.ListDocTree(box.ID, path.Dir(p), model.Conf.FileTree.Sort)
|
files, _, _ := model.ListDocTree(box.ID, path.Dir(p), model.Conf.FileTree.Sort, false, model.Conf.FileTree.MaxListCount)
|
||||||
evt.Data = map[string]interface{}{
|
evt.Data = map[string]interface{}{
|
||||||
"box": box,
|
"box": box,
|
||||||
"path": p,
|
"path": p,
|
||||||
@ -590,8 +591,13 @@ func searchDocs(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flashcard := false
|
||||||
|
if arg["flashcard"] != nil {
|
||||||
|
flashcard = arg["flashcard"].(bool)
|
||||||
|
}
|
||||||
|
|
||||||
k := arg["k"].(string)
|
k := arg["k"].(string)
|
||||||
ret.Data = model.SearchDocsByKeyword(k)
|
ret.Data = model.SearchDocsByKeyword(k, flashcard)
|
||||||
}
|
}
|
||||||
|
|
||||||
func listDocsByPath(c *gin.Context) {
|
func listDocsByPath(c *gin.Context) {
|
||||||
@ -610,13 +616,26 @@ func listDocsByPath(c *gin.Context) {
|
|||||||
if nil != sortParam {
|
if nil != sortParam {
|
||||||
sortMode = int(sortParam.(float64))
|
sortMode = int(sortParam.(float64))
|
||||||
}
|
}
|
||||||
files, totals, err := model.ListDocTree(notebook, p, sortMode)
|
flashcard := false
|
||||||
|
if arg["flashcard"] != nil {
|
||||||
|
flashcard = arg["flashcard"].(bool)
|
||||||
|
}
|
||||||
|
maxListCount := model.Conf.FileTree.MaxListCount
|
||||||
|
if arg["maxListCount"] != nil {
|
||||||
|
// API `listDocsByPath` add an optional parameter `maxListCount` https://github.com/siyuan-note/siyuan/issues/7993
|
||||||
|
maxListCount = int(arg["maxListCount"].(float64))
|
||||||
|
if 0 >= maxListCount {
|
||||||
|
maxListCount = math.MaxInt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
files, totals, err := model.ListDocTree(notebook, p, sortMode, flashcard, maxListCount)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
ret.Code = -1
|
ret.Code = -1
|
||||||
ret.Msg = err.Error()
|
ret.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if model.Conf.FileTree.MaxListCount < totals {
|
if maxListCount < totals {
|
||||||
util.PushMsg(fmt.Sprintf(model.Conf.Language(48), len(files)), 7000)
|
util.PushMsg(fmt.Sprintf(model.Conf.Language(48), len(files)), 7000)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,7 +727,7 @@ func getDoc(c *gin.Context) {
|
|||||||
func pushCreate(box *model.Box, p, treeID string, arg map[string]interface{}) {
|
func pushCreate(box *model.Box, p, treeID string, arg map[string]interface{}) {
|
||||||
evt := util.NewCmdResult("create", 0, util.PushModeBroadcast)
|
evt := util.NewCmdResult("create", 0, util.PushModeBroadcast)
|
||||||
name := path.Base(p)
|
name := path.Base(p)
|
||||||
files, _, _ := model.ListDocTree(box.ID, path.Dir(p), model.Conf.FileTree.Sort)
|
files, _, _ := model.ListDocTree(box.ID, path.Dir(p), model.Conf.FileTree.Sort, false, model.Conf.FileTree.MaxListCount)
|
||||||
evt.Data = map[string]interface{}{
|
evt.Data = map[string]interface{}{
|
||||||
"box": box,
|
"box": box,
|
||||||
"path": p,
|
"path": p,
|
||||||
|
@ -308,10 +308,26 @@ func lsNotebooks(c *gin.Context) {
|
|||||||
ret := gulu.Ret.NewResult()
|
ret := gulu.Ret.NewResult()
|
||||||
defer c.JSON(http.StatusOK, ret)
|
defer c.JSON(http.StatusOK, ret)
|
||||||
|
|
||||||
notebooks, err := model.ListNotebooks()
|
arg, ok := util.JsonArg(c, ret)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
flashcard := false
|
||||||
|
if arg["flashcard"] != nil {
|
||||||
|
flashcard = arg["flashcard"].(bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
var notebooks []*model.Box
|
||||||
|
if flashcard {
|
||||||
|
notebooks = model.GetFlashcardNotebooks()
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
notebooks, err = model.ListNotebooks()
|
||||||
if nil != err {
|
if nil != err {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"notebooks": notebooks,
|
"notebooks": notebooks,
|
||||||
|
@ -107,6 +107,8 @@ func NetImg2LocalAssets(rootID, originalURL string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
name := filepath.Base(u)
|
name := filepath.Base(u)
|
||||||
|
name = util.FilterFileName(name)
|
||||||
|
name = util.TruncateLenFileName(name)
|
||||||
name = "net-img-" + name
|
name = "net-img-" + name
|
||||||
name = util.AssetName(name)
|
name = util.AssetName(name)
|
||||||
writePath := filepath.Join(assetsDirPath, name)
|
writePath := filepath.Join(assetsDirPath, name)
|
||||||
|
@ -110,7 +110,7 @@ func loadTreeNodes(box string, p string, level int) (ret []*ast.Node, err error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func buildBlockChildren(block *Block) (err error) {
|
func buildBlockChildren(block *Block) (err error) {
|
||||||
files, _, err := ListDocTree(block.Box, block.Path, Conf.FileTree.Sort)
|
files, _, err := ListDocTree(block.Box, block.Path, Conf.FileTree.Sort, false, Conf.FileTree.MaxListCount)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -141,9 +141,18 @@ func (box *Box) moveCorruptedData(filePath string) {
|
|||||||
logging.LogWarnf("moved corrupted data file [%s] to [%s]", filePath, to)
|
logging.LogWarnf("moved corrupted data file [%s] to [%s]", filePath, to)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SearchDocsByKeyword(keyword string) (ret []map[string]string) {
|
func SearchDocsByKeyword(keyword string, flashcard bool) (ret []map[string]string) {
|
||||||
ret = []map[string]string{}
|
ret = []map[string]string{}
|
||||||
|
|
||||||
|
var deckBlockIDs []string
|
||||||
|
if flashcard {
|
||||||
|
deck := Decks[builtinDeckID]
|
||||||
|
if nil != deck {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
deckBlockIDs = deck.GetBlockIDs()
|
||||||
|
}
|
||||||
|
|
||||||
openedBoxes := Conf.GetOpenedBoxes()
|
openedBoxes := Conf.GetOpenedBoxes()
|
||||||
boxes := map[string]*Box{}
|
boxes := map[string]*Box{}
|
||||||
for _, box := range openedBoxes {
|
for _, box := range openedBoxes {
|
||||||
@ -154,8 +163,14 @@ func SearchDocsByKeyword(keyword string) (ret []map[string]string) {
|
|||||||
if "" != keyword {
|
if "" != keyword {
|
||||||
for _, box := range boxes {
|
for _, box := range boxes {
|
||||||
if strings.Contains(box.Name, keyword) {
|
if strings.Contains(box.Name, keyword) {
|
||||||
|
if flashcard {
|
||||||
|
if isBoxContainFlashcard(box.ID, deckBlockIDs) {
|
||||||
ret = append(ret, map[string]string{"path": "/", "hPath": box.Name + "/", "box": box.ID, "boxIcon": box.Icon})
|
ret = append(ret, map[string]string{"path": "/", "hPath": box.Name + "/", "box": box.ID, "boxIcon": box.Icon})
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ret = append(ret, map[string]string{"path": "/", "hPath": box.Name + "/", "box": box.ID, "boxIcon": box.Icon})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
condition := "hpath LIKE '%" + keyword + "%'"
|
condition := "hpath LIKE '%" + keyword + "%'"
|
||||||
@ -168,17 +183,29 @@ func SearchDocsByKeyword(keyword string) (ret []map[string]string) {
|
|||||||
rootBlocks = sql.QueryRootBlockByCondition(condition)
|
rootBlocks = sql.QueryRootBlockByCondition(condition)
|
||||||
} else {
|
} else {
|
||||||
for _, box := range boxes {
|
for _, box := range boxes {
|
||||||
|
if flashcard {
|
||||||
|
if isBoxContainFlashcard(box.ID, deckBlockIDs) {
|
||||||
|
ret = append(ret, map[string]string{"path": "/", "hPath": box.Name + "/", "box": box.ID, "boxIcon": box.Icon})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
ret = append(ret, map[string]string{"path": "/", "hPath": box.Name + "/", "box": box.ID, "boxIcon": box.Icon})
|
ret = append(ret, map[string]string{"path": "/", "hPath": box.Name + "/", "box": box.ID, "boxIcon": box.Icon})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, block := range rootBlocks {
|
for _, rootBlock := range rootBlocks {
|
||||||
b := boxes[block.Box]
|
b := boxes[rootBlock.Box]
|
||||||
if nil == b {
|
if nil == b {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
hPath := b.Name + block.HPath
|
hPath := b.Name + rootBlock.HPath
|
||||||
ret = append(ret, map[string]string{"path": block.Path, "hPath": hPath, "box": block.Box, "boxIcon": b.Icon})
|
if flashcard {
|
||||||
|
if isTreeContainFlashcard(rootBlock.ID, deckBlockIDs) {
|
||||||
|
ret = append(ret, map[string]string{"path": rootBlock.Path, "hPath": hPath, "box": rootBlock.Box, "boxIcon": b.Icon})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = append(ret, map[string]string{"path": rootBlock.Path, "hPath": hPath, "box": rootBlock.Box, "boxIcon": b.Icon})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(ret, func(i, j int) bool {
|
sort.Slice(ret, func(i, j int) bool {
|
||||||
@ -194,7 +221,7 @@ type FileInfo struct {
|
|||||||
isdir bool
|
isdir bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListDocTree(boxID, path string, sortMode int) (ret []*File, totals int, err error) {
|
func ListDocTree(boxID, path string, sortMode int, flashcard bool, maxListCount int) (ret []*File, totals int, err error) {
|
||||||
//os.MkdirAll("pprof", 0755)
|
//os.MkdirAll("pprof", 0755)
|
||||||
//cpuProfile, _ := os.Create("pprof/cpu_profile_list_doc_tree")
|
//cpuProfile, _ := os.Create("pprof/cpu_profile_list_doc_tree")
|
||||||
//pprof.StartCPUProfile(cpuProfile)
|
//pprof.StartCPUProfile(cpuProfile)
|
||||||
@ -202,6 +229,15 @@ func ListDocTree(boxID, path string, sortMode int) (ret []*File, totals int, err
|
|||||||
|
|
||||||
ret = []*File{}
|
ret = []*File{}
|
||||||
|
|
||||||
|
var deckBlockIDs []string
|
||||||
|
if flashcard {
|
||||||
|
deck := Decks[builtinDeckID]
|
||||||
|
if nil != deck {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
deckBlockIDs = deck.GetBlockIDs()
|
||||||
|
}
|
||||||
|
|
||||||
box := Conf.Box(boxID)
|
box := Conf.Box(boxID)
|
||||||
if nil == box {
|
if nil == box {
|
||||||
return nil, 0, errors.New(Conf.Language(0))
|
return nil, 0, errors.New(Conf.Language(0))
|
||||||
@ -247,8 +283,16 @@ func ListDocTree(boxID, path string, sortMode int) (ret []*File, totals int, err
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if flashcard {
|
||||||
|
rootID := strings.TrimSuffix(filepath.Base(parentDocPath), ".sy")
|
||||||
|
if isTreeContainFlashcard(rootID, deckBlockIDs) {
|
||||||
docs = append(docs, doc)
|
docs = append(docs, doc)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
docs = append(docs, doc)
|
||||||
|
}
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,8 +303,15 @@ func ListDocTree(boxID, path string, sortMode int) (ret []*File, totals int, err
|
|||||||
|
|
||||||
if ial := box.docIAL(file.path); nil != ial {
|
if ial := box.docIAL(file.path); nil != ial {
|
||||||
doc := box.docFromFileInfo(file, ial)
|
doc := box.docFromFileInfo(file, ial)
|
||||||
|
|
||||||
|
if flashcard {
|
||||||
|
rootID := strings.TrimSuffix(filepath.Base(file.path), ".sy")
|
||||||
|
if isTreeContainFlashcard(rootID, deckBlockIDs) {
|
||||||
docs = append(docs, doc)
|
docs = append(docs, doc)
|
||||||
continue
|
}
|
||||||
|
} else {
|
||||||
|
docs = append(docs, doc)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elapsed = time.Now().Sub(start).Milliseconds()
|
elapsed = time.Now().Sub(start).Milliseconds()
|
||||||
@ -312,8 +363,8 @@ func ListDocTree(boxID, path string, sortMode int) (ret []*File, totals int, err
|
|||||||
return fileTreeFiles[i].Sort < fileTreeFiles[j].Sort
|
return fileTreeFiles[i].Sort < fileTreeFiles[j].Sort
|
||||||
})
|
})
|
||||||
ret = append(ret, fileTreeFiles...)
|
ret = append(ret, fileTreeFiles...)
|
||||||
if Conf.FileTree.MaxListCount < len(ret) {
|
if maxListCount < len(ret) {
|
||||||
ret = ret[:Conf.FileTree.MaxListCount]
|
ret = ret[:maxListCount]
|
||||||
}
|
}
|
||||||
ret = ret[:]
|
ret = ret[:]
|
||||||
return
|
return
|
||||||
@ -339,8 +390,8 @@ func ListDocTree(boxID, path string, sortMode int) (ret []*File, totals int, err
|
|||||||
ret = append(ret, docs...)
|
ret = append(ret, docs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Conf.FileTree.MaxListCount < len(ret) {
|
if maxListCount < len(ret) {
|
||||||
ret = ret[:Conf.FileTree.MaxListCount]
|
ret = ret[:maxListCount]
|
||||||
}
|
}
|
||||||
ret = ret[:]
|
ret = ret[:]
|
||||||
|
|
||||||
|
@ -38,8 +38,60 @@ import (
|
|||||||
"github.com/siyuan-note/siyuan/kernel/util"
|
"github.com/siyuan-note/siyuan/kernel/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Decks = map[string]*riff.Deck{}
|
func GetFlashcardNotebooks() (ret []*Box) {
|
||||||
var deckLock = sync.Mutex{}
|
deck := Decks[builtinDeckID]
|
||||||
|
if nil == deck {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
deckBlockIDs := deck.GetBlockIDs()
|
||||||
|
|
||||||
|
boxes := Conf.GetOpenedBoxes()
|
||||||
|
for _, box := range boxes {
|
||||||
|
if isBoxContainFlashcard(box.ID, deckBlockIDs) {
|
||||||
|
ret = append(ret, box)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func isTreeContainFlashcard(rootID string, deckBlockIDs []string) (ret bool) {
|
||||||
|
blockIDs := getTreeSubTreeChildBlocks(rootID)
|
||||||
|
for _, blockID := range deckBlockIDs {
|
||||||
|
if gulu.Str.Contains(blockID, blockIDs) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func isBoxContainFlashcard(boxID string, deckBlockIDs []string) (ret bool) {
|
||||||
|
entries, err := os.ReadDir(filepath.Join(util.DataDir, boxID))
|
||||||
|
if nil != err {
|
||||||
|
logging.LogErrorf("read dir failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entry := range entries {
|
||||||
|
if entry.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.HasSuffix(entry.Name(), ".sy") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
rootID := strings.TrimSuffix(entry.Name(), ".sy")
|
||||||
|
if isTreeContainFlashcard(rootID, deckBlockIDs) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
Decks = map[string]*riff.Deck{}
|
||||||
|
deckLock = sync.Mutex{}
|
||||||
|
)
|
||||||
|
|
||||||
func GetNotebookFlashcards(boxID string, page int) (blocks []*Block, total, pageCount int) {
|
func GetNotebookFlashcards(boxID string, page int) (blocks []*Block, total, pageCount int) {
|
||||||
blocks = []*Block{}
|
blocks = []*Block{}
|
||||||
@ -66,9 +118,7 @@ func GetNotebookFlashcards(boxID string, page int) (blocks []*Block, total, page
|
|||||||
var treeBlockIDs []string
|
var treeBlockIDs []string
|
||||||
for _, rootID := range rootIDs {
|
for _, rootID := range rootIDs {
|
||||||
blockIDs := getTreeSubTreeChildBlocks(rootID)
|
blockIDs := getTreeSubTreeChildBlocks(rootID)
|
||||||
for _, blockID := range blockIDs {
|
treeBlockIDs = append(treeBlockIDs, blockIDs...)
|
||||||
treeBlockIDs = append(treeBlockIDs, blockID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
treeBlockIDs = gulu.Str.RemoveDuplicatedElem(treeBlockIDs)
|
treeBlockIDs = gulu.Str.RemoveDuplicatedElem(treeBlockIDs)
|
||||||
|
|
||||||
@ -307,9 +357,7 @@ func GetNotebookDueFlashcards(boxID string, reviewedCardIDs []string) (ret []*Fl
|
|||||||
var treeBlockIDs []string
|
var treeBlockIDs []string
|
||||||
for _, rootID := range rootIDs {
|
for _, rootID := range rootIDs {
|
||||||
blockIDs := getTreeSubTreeChildBlocks(rootID)
|
blockIDs := getTreeSubTreeChildBlocks(rootID)
|
||||||
for _, blockID := range blockIDs {
|
treeBlockIDs = append(treeBlockIDs, blockIDs...)
|
||||||
treeBlockIDs = append(treeBlockIDs, blockID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
treeBlockIDs = gulu.Str.RemoveDuplicatedElem(treeBlockIDs)
|
treeBlockIDs = gulu.Str.RemoveDuplicatedElem(treeBlockIDs)
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ func Mount(boxID string) (alreadyMount bool, err error) {
|
|||||||
|
|
||||||
box.Index()
|
box.Index()
|
||||||
// 缓存根一级的文档树展开
|
// 缓存根一级的文档树展开
|
||||||
ListDocTree(box.ID, "/", Conf.FileTree.Sort)
|
ListDocTree(box.ID, "/", Conf.FileTree.Sort, false, Conf.FileTree.MaxListCount)
|
||||||
treenode.SaveBlockTree(false)
|
treenode.SaveBlockTree(false)
|
||||||
util.ClearPushProgress(100)
|
util.ClearPushProgress(100)
|
||||||
|
|
||||||
|
@ -50,8 +50,8 @@ func MoveFoldHeading(updateNode, oldNode *ast.Node) {
|
|||||||
})
|
})
|
||||||
for _, h := range updateFoldHeadings {
|
for _, h := range updateFoldHeadings {
|
||||||
children := foldHeadings[h.ID]
|
children := foldHeadings[h.ID]
|
||||||
for _, c := range children {
|
for i := len(children) - 1; 0 <= i; i-- {
|
||||||
h.Next.InsertAfter(c) // Next 是 Block IAL
|
h.Next.InsertAfter(children[i]) // Next 是 Block IAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user