Browse Source

:art: Support resetting the learning progress of flashcards https://github.com/siyuan-note/siyuan/issues/9564

Daniel 1 year ago
parent
commit
37b099dfa5
3 changed files with 99 additions and 2 deletions
  1. 23 1
      kernel/api/riff.go
  2. 1 0
      kernel/api/router.go
  3. 75 1
      kernel/model/flashcard.go

+ 23 - 1
kernel/api/riff.go

@@ -27,6 +27,28 @@ import (
 	"github.com/siyuan-note/siyuan/kernel/util"
 )
 
+func resetRiffCards(c *gin.Context) {
+	ret := gulu.Ret.NewResult()
+	defer c.JSON(http.StatusOK, ret)
+
+	arg, ok := util.JsonArg(c, ret)
+	if !ok {
+		return
+	}
+
+	typ := arg["type"].(string)    // notebook, tree, deck
+	id := arg["id"].(string)       // notebook ID, root ID, deck ID
+	blockIDsArg := arg["blockIDs"] // 如果不传入 blockIDs (或者传入实参为空数组),则重置所有卡片
+	var blockIDs []string
+	if nil != blockIDsArg {
+		for _, blockID := range blockIDsArg.([]interface{}) {
+			blockIDs = append(blockIDs, blockID.(string))
+		}
+	}
+
+	model.ResetFlashcards(typ, id, blockIDs)
+}
+
 func getNotebookRiffCards(c *gin.Context) {
 	ret := gulu.Ret.NewResult()
 	defer c.JSON(http.StatusOK, ret)
@@ -76,7 +98,7 @@ func getRiffCards(c *gin.Context) {
 
 	deckID := arg["id"].(string)
 	page := int(arg["page"].(float64))
-	blocks, total, pageCount := model.GetFlashcards(deckID, page)
+	blocks, total, pageCount := model.GetDeckFlashcards(deckID, page)
 	ret.Data = map[string]interface{}{
 		"blocks":    blocks,
 		"total":     total,

+ 1 - 0
kernel/api/router.go

@@ -362,6 +362,7 @@ func ServeAPI(ginServer *gin.Engine) {
 	ginServer.Handle("POST", "/api/riff/getRiffCards", model.CheckAuth, getRiffCards)
 	ginServer.Handle("POST", "/api/riff/getTreeRiffCards", model.CheckAuth, getTreeRiffCards)
 	ginServer.Handle("POST", "/api/riff/getNotebookRiffCards", model.CheckAuth, getNotebookRiffCards)
+	ginServer.Handle("POST", "/api/riff/resetRiffCards", model.CheckAuth, resetRiffCards)
 
 	ginServer.Handle("POST", "/api/notification/pushMsg", model.CheckAuth, pushMsg)
 	ginServer.Handle("POST", "/api/notification/pushErrMsg", model.CheckAuth, pushErrMsg)

+ 75 - 1
kernel/model/flashcard.go

@@ -39,6 +39,80 @@ import (
 	"github.com/siyuan-note/siyuan/kernel/util"
 )
 
+func ResetFlashcards(typ, id string, blockIDs []string) {
+	// Support resetting the learning progress of flashcards https://github.com/siyuan-note/siyuan/issues/9564
+
+	if 0 < len(blockIDs) {
+		resetFlashcards(id, blockIDs)
+		return
+	}
+
+	var blocks []*Block
+	switch typ {
+	case "notebook":
+		for i := 1; ; i++ {
+			pagedBlocks, _, _ := GetNotebookFlashcards(id, i)
+			if 1 > len(blocks) {
+				break
+			}
+			blocks = append(blocks, pagedBlocks...)
+		}
+		for _, block := range blocks {
+			blockIDs = append(blockIDs, block.ID)
+		}
+	case "tree":
+		for i := 1; ; i++ {
+			pagedBlocks, _, _ := GetTreeFlashcards(id, i)
+			if 1 > len(blocks) {
+				break
+			}
+			blocks = append(blocks, pagedBlocks...)
+		}
+		for _, block := range blocks {
+			blockIDs = append(blockIDs, block.ID)
+		}
+	case "deck":
+		for i := 1; ; i++ {
+			pagedBlocks, _, _ := GetDeckFlashcards(id, i)
+			if 1 > len(blocks) {
+				break
+			}
+			blocks = append(blocks, pagedBlocks...)
+		}
+	default:
+		logging.LogErrorf("invalid type [%s]", typ)
+	}
+
+	blockIDs = gulu.Str.RemoveDuplicatedElem(blockIDs)
+	resetFlashcards(id, blockIDs)
+}
+
+func resetFlashcards(deckID string, blockIDs []string) {
+	transactions := []*Transaction{
+		{
+			DoOperations: []*Operation{
+				{
+					Action:   "removeFlashcards",
+					DeckID:   deckID,
+					BlockIDs: blockIDs,
+				},
+			},
+		},
+		{
+			DoOperations: []*Operation{
+				{
+					Action:   "addFlashcards",
+					DeckID:   deckID,
+					BlockIDs: blockIDs,
+				},
+			},
+		},
+	}
+
+	PerformTransactions(&transactions)
+	WaitForWritingFiles()
+}
+
 func GetFlashcardNotebooks() (ret []*Box) {
 	deck := Decks[builtinDeckID]
 	if nil == deck {
@@ -193,7 +267,7 @@ func getTreeFlashcards(rootID string) (ret []riff.Card) {
 	return
 }
 
-func GetFlashcards(deckID string, page int) (blocks []*Block, total, pageCount int) {
+func GetDeckFlashcards(deckID string, page int) (blocks []*Block, total, pageCount int) {
 	blocks = []*Block{}
 	var cards []riff.Card
 	if "" == deckID {