🎨 Spaced repetition interface supports review by document selection https://github.com/siyuan-note/siyuan/issues/7954
This commit is contained in:
parent
0ebdd49f8a
commit
66bd5e91a5
7 changed files with 112 additions and 38 deletions
|
@ -95,7 +95,7 @@ func heading2Doc(c *gin.Context) {
|
|||
|
||||
name := path.Base(targetPath)
|
||||
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)
|
||||
evt := util.NewCmdResult("heading2doc", 0, util.PushModeBroadcast)
|
||||
evt.Data = map[string]interface{}{
|
||||
"box": box,
|
||||
|
@ -140,7 +140,7 @@ func li2Doc(c *gin.Context) {
|
|||
|
||||
name := path.Base(targetPath)
|
||||
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)
|
||||
evt := util.NewCmdResult("li2doc", 0, util.PushModeBroadcast)
|
||||
evt.Data = map[string]interface{}{
|
||||
"box": box,
|
||||
|
@ -448,7 +448,7 @@ func createDailyNote(c *gin.Context) {
|
|||
evt.AppId = app
|
||||
|
||||
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)
|
||||
evt.Data = map[string]interface{}{
|
||||
"box": box,
|
||||
"path": p,
|
||||
|
@ -590,8 +590,13 @@ func searchDocs(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
flashcard := false
|
||||
if arg["flashcard"] != nil {
|
||||
flashcard = arg["flashcard"].(bool)
|
||||
}
|
||||
|
||||
k := arg["k"].(string)
|
||||
ret.Data = model.SearchDocsByKeyword(k)
|
||||
ret.Data = model.SearchDocsByKeyword(k, flashcard)
|
||||
}
|
||||
|
||||
func listDocsByPath(c *gin.Context) {
|
||||
|
@ -610,7 +615,12 @@ func listDocsByPath(c *gin.Context) {
|
|||
if nil != sortParam {
|
||||
sortMode = int(sortParam.(float64))
|
||||
}
|
||||
files, totals, err := model.ListDocTree(notebook, p, sortMode)
|
||||
flashcard := false
|
||||
if arg["flashcard"] != nil {
|
||||
flashcard = arg["flashcard"].(bool)
|
||||
}
|
||||
|
||||
files, totals, err := model.ListDocTree(notebook, p, sortMode, flashcard)
|
||||
if nil != err {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
|
@ -708,7 +718,7 @@ func getDoc(c *gin.Context) {
|
|||
func pushCreate(box *model.Box, p, treeID string, arg map[string]interface{}) {
|
||||
evt := util.NewCmdResult("create", 0, util.PushModeBroadcast)
|
||||
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)
|
||||
evt.Data = map[string]interface{}{
|
||||
"box": box,
|
||||
"path": p,
|
||||
|
|
|
@ -308,11 +308,27 @@ func lsNotebooks(c *gin.Context) {
|
|||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
||||
notebooks, err := model.ListNotebooks()
|
||||
if nil != err {
|
||||
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 {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ret.Data = map[string]interface{}{
|
||||
"notebooks": notebooks,
|
||||
}
|
||||
|
|
|
@ -27,16 +27,6 @@ import (
|
|||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
func getRiffCardNotebooks(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
||||
notebooks := model.GetFlashcardNotebooks()
|
||||
ret.Data = map[string]interface{}{
|
||||
"notebooks": notebooks,
|
||||
}
|
||||
}
|
||||
|
||||
func getNotebookRiffCards(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
|
|
@ -110,7 +110,7 @@ func loadTreeNodes(box string, p string, level int) (ret []*ast.Node, 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)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -141,9 +141,18 @@ func (box *Box) moveCorruptedData(filePath string) {
|
|||
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{}
|
||||
|
||||
var deckBlockIDs []string
|
||||
if flashcard {
|
||||
deck := Decks[builtinDeckID]
|
||||
if nil != deck {
|
||||
return
|
||||
}
|
||||
deckBlockIDs = deck.GetBlockIDs()
|
||||
}
|
||||
|
||||
openedBoxes := Conf.GetOpenedBoxes()
|
||||
boxes := map[string]*Box{}
|
||||
for _, box := range openedBoxes {
|
||||
|
@ -154,7 +163,13 @@ func SearchDocsByKeyword(keyword string) (ret []map[string]string) {
|
|||
if "" != keyword {
|
||||
for _, box := range boxes {
|
||||
if strings.Contains(box.Name, keyword) {
|
||||
ret = append(ret, map[string]string{"path": "/", "hPath": box.Name + "/", "box": box.ID, "boxIcon": box.Icon})
|
||||
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})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,17 +183,29 @@ func SearchDocsByKeyword(keyword string) (ret []map[string]string) {
|
|||
rootBlocks = sql.QueryRootBlockByCondition(condition)
|
||||
} else {
|
||||
for _, box := range boxes {
|
||||
ret = append(ret, map[string]string{"path": "/", "hPath": box.Name + "/", "box": box.ID, "boxIcon": box.Icon})
|
||||
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})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, block := range rootBlocks {
|
||||
b := boxes[block.Box]
|
||||
for _, rootBlock := range rootBlocks {
|
||||
b := boxes[rootBlock.Box]
|
||||
if nil == b {
|
||||
continue
|
||||
}
|
||||
hPath := b.Name + block.HPath
|
||||
ret = append(ret, map[string]string{"path": block.Path, "hPath": hPath, "box": block.Box, "boxIcon": b.Icon})
|
||||
hPath := b.Name + rootBlock.HPath
|
||||
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 {
|
||||
|
@ -194,7 +221,7 @@ type FileInfo struct {
|
|||
isdir bool
|
||||
}
|
||||
|
||||
func ListDocTree(boxID, path string, sortMode int) (ret []*File, totals int, err error) {
|
||||
func ListDocTree(boxID, path string, sortMode int, flashcard bool) (ret []*File, totals int, err error) {
|
||||
//os.MkdirAll("pprof", 0755)
|
||||
//cpuProfile, _ := os.Create("pprof/cpu_profile_list_doc_tree")
|
||||
//pprof.StartCPUProfile(cpuProfile)
|
||||
|
@ -202,6 +229,15 @@ func ListDocTree(boxID, path string, sortMode int) (ret []*File, totals int, err
|
|||
|
||||
ret = []*File{}
|
||||
|
||||
var deckBlockIDs []string
|
||||
if flashcard {
|
||||
deck := Decks[builtinDeckID]
|
||||
if nil != deck {
|
||||
return
|
||||
}
|
||||
deckBlockIDs = deck.GetBlockIDs()
|
||||
}
|
||||
|
||||
box := Conf.Box(boxID)
|
||||
if nil == box {
|
||||
return nil, 0, errors.New(Conf.Language(0))
|
||||
|
@ -247,7 +283,15 @@ func ListDocTree(boxID, path string, sortMode int) (ret []*File, totals int, err
|
|||
}
|
||||
}
|
||||
}
|
||||
docs = append(docs, doc)
|
||||
|
||||
if flashcard {
|
||||
rootID := strings.TrimSuffix(filepath.Base(parentDocPath), ".sy")
|
||||
if isTreeContainFlashcard(rootID, deckBlockIDs) {
|
||||
docs = append(docs, doc)
|
||||
}
|
||||
} else {
|
||||
docs = append(docs, doc)
|
||||
}
|
||||
}
|
||||
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 {
|
||||
doc := box.docFromFileInfo(file, ial)
|
||||
docs = append(docs, doc)
|
||||
continue
|
||||
|
||||
if flashcard {
|
||||
rootID := strings.TrimSuffix(filepath.Base(file.path), ".sy")
|
||||
if isTreeContainFlashcard(rootID, deckBlockIDs) {
|
||||
docs = append(docs, doc)
|
||||
}
|
||||
} else {
|
||||
docs = append(docs, doc)
|
||||
}
|
||||
}
|
||||
}
|
||||
elapsed = time.Now().Sub(start).Milliseconds()
|
||||
|
|
|
@ -47,14 +47,24 @@ func GetFlashcardNotebooks() (ret []*Box) {
|
|||
|
||||
boxes := Conf.GetOpenedBoxes()
|
||||
for _, box := range boxes {
|
||||
if isNotebookContainFlashcard(box.ID, deckBlockIDs) {
|
||||
if isBoxContainFlashcard(box.ID, deckBlockIDs) {
|
||||
ret = append(ret, box)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func isNotebookContainFlashcard(boxID string, deckBlockIDs []string) (ret bool) {
|
||||
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)
|
||||
|
@ -71,11 +81,8 @@ func isNotebookContainFlashcard(boxID string, deckBlockIDs []string) (ret bool)
|
|||
}
|
||||
|
||||
rootID := strings.TrimSuffix(entry.Name(), ".sy")
|
||||
blockIDs := getTreeSubTreeChildBlocks(rootID)
|
||||
for _, blockID := range deckBlockIDs {
|
||||
if gulu.Str.Contains(blockID, blockIDs) {
|
||||
return true
|
||||
}
|
||||
if isTreeContainFlashcard(rootID, deckBlockIDs) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
|
@ -194,7 +194,7 @@ func Mount(boxID string) (alreadyMount bool, err error) {
|
|||
|
||||
box.Index()
|
||||
// 缓存根一级的文档树展开
|
||||
ListDocTree(box.ID, "/", Conf.FileTree.Sort)
|
||||
ListDocTree(box.ID, "/", Conf.FileTree.Sort, false)
|
||||
treenode.SaveBlockTree(false)
|
||||
util.ClearPushProgress(100)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue