This commit is contained in:
Liang Ding 2023-03-18 17:10:14 +08:00
parent e984082d42
commit 29577de910
No known key found for this signature in database
GPG key ID: 136F30F901A2231D
3 changed files with 69 additions and 7 deletions

View file

@ -104,6 +104,25 @@ func reviewRiffCard(c *gin.Context) {
} }
} }
func skipReviewRiffCard(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
arg, ok := util.JsonArg(c, ret)
if !ok {
return
}
deckID := arg["deckID"].(string)
cardID := arg["cardID"].(string)
err := model.SkipReviewFlashcard(deckID, cardID)
if nil != err {
ret.Code = -1
ret.Msg = err.Error()
return
}
}
func getNotebookRiffDueCards(c *gin.Context) { func getNotebookRiffDueCards(c *gin.Context) {
ret := gulu.Ret.NewResult() ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret) defer c.JSON(http.StatusOK, ret)

View file

@ -314,6 +314,7 @@ func ServeAPI(ginServer *gin.Engine) {
ginServer.Handle("POST", "/api/riff/getTreeRiffDueCards", model.CheckAuth, getTreeRiffDueCards) ginServer.Handle("POST", "/api/riff/getTreeRiffDueCards", model.CheckAuth, getTreeRiffDueCards)
ginServer.Handle("POST", "/api/riff/getNotebookRiffDueCards", model.CheckAuth, getNotebookRiffDueCards) ginServer.Handle("POST", "/api/riff/getNotebookRiffDueCards", model.CheckAuth, getNotebookRiffDueCards)
ginServer.Handle("POST", "/api/riff/reviewRiffCard", model.CheckAuth, model.CheckReadonly, reviewRiffCard) ginServer.Handle("POST", "/api/riff/reviewRiffCard", model.CheckAuth, model.CheckReadonly, reviewRiffCard)
ginServer.Handle("POST", "/api/riff/skipReviewRiffCard", model.CheckAuth, model.CheckReadonly, skipReviewRiffCard)
ginServer.Handle("POST", "/api/riff/getRiffCards", model.CheckAuth, getRiffCards) ginServer.Handle("POST", "/api/riff/getRiffCards", model.CheckAuth, getRiffCards)
ginServer.Handle("POST", "/api/riff/getTreeRiffCards", model.CheckAuth, getTreeRiffCards) ginServer.Handle("POST", "/api/riff/getTreeRiffCards", model.CheckAuth, getTreeRiffCards)
ginServer.Handle("POST", "/api/riff/getNotebookRiffCards", model.CheckAuth, getNotebookRiffCards) ginServer.Handle("POST", "/api/riff/getNotebookRiffCards", model.CheckAuth, getNotebookRiffCards)

View file

@ -181,8 +181,13 @@ func getCardsBlocks(cards []riff.Card, page int) (blocks []*Block, total, pageCo
return return
} }
var (
// reviewCardCache <cardID, card> 用于复习时缓存卡片,以便支持撤销。 // reviewCardCache <cardID, card> 用于复习时缓存卡片,以便支持撤销。
var reviewCardCache = map[string]riff.Card{} reviewCardCache = map[string]riff.Card{}
// skipCardCache <cardID, card> 用于复习时缓存跳过的卡片,以便支持跳过过滤。
skipCardCache = map[string]riff.Card{}
)
func ReviewFlashcard(deckID, cardID string, rating riff.Rating) (err error) { func ReviewFlashcard(deckID, cardID string, rating riff.Rating) (err error) {
deckLock.Lock() deckLock.Lock()
@ -203,6 +208,9 @@ func ReviewFlashcard(deckID, cardID string, rating riff.Rating) (err error) {
// 命中缓存说明这张卡片已经复习过了,这次调用复习是撤销后再次复习 // 命中缓存说明这张卡片已经复习过了,这次调用复习是撤销后再次复习
// 将缓存的卡片重新覆盖回卡包中,以恢复最开始复习前的状态 // 将缓存的卡片重新覆盖回卡包中,以恢复最开始复习前的状态
deck.SetCard(cachedCard) deck.SetCard(cachedCard)
// 从跳过缓存中移除(如果上一次点的是跳过的话),如果不在跳过缓存中,说明上一次点的是复习,这里移除一下也没有副作用
delete(skipCardCache, cardID)
} else { } else {
// 首次复习该卡片,将卡片缓存以便后续支持撤销后再次复习 // 首次复习该卡片,将卡片缓存以便后续支持撤销后再次复习
reviewCardCache[cardID] = card reviewCardCache[cardID] = card
@ -217,12 +225,32 @@ func ReviewFlashcard(deckID, cardID string, rating riff.Rating) (err error) {
dueCards := getDueFlashcards(deckID) dueCards := getDueFlashcards(deckID)
if 1 > len(dueCards) { if 1 > len(dueCards) {
// 该卡包中没有待复习的卡片了,说明最后一张卡片已经复习完了,清空撤销缓存 // 该卡包中没有待复习的卡片了,说明最后一张卡片已经复习完了,清空撤销缓存和跳过缓存
reviewCardCache = map[string]riff.Card{} reviewCardCache = map[string]riff.Card{}
skipCardCache = map[string]riff.Card{}
} }
return return
} }
func SkipReviewFlashcard(deckID, cardID string) (err error) {
deckLock.Lock()
defer deckLock.Unlock()
if syncingStorages {
err = errors.New(Conf.Language(81))
return
}
deck := Decks[deckID]
card := deck.GetCard(cardID)
if nil == card {
return
}
skipCardCache[cardID] = card
return
}
type Flashcard struct { type Flashcard struct {
DeckID string `json:"deckID"` DeckID string `json:"deckID"`
CardID string `json:"cardID"` CardID string `json:"cardID"`
@ -286,7 +314,7 @@ func GetNotebookDueFlashcards(boxID string) (ret []*Flashcard, err error) {
return return
} }
cards := deck.Dues() cards := getDeckDueCards(deck)
now := time.Now() now := time.Now()
for _, card := range cards { for _, card := range cards {
blockID := card.BlockID() blockID := card.BlockID()
@ -317,7 +345,7 @@ func GetTreeDueFlashcards(rootID string) (ret []*Flashcard, err error) {
} }
treeBlockIDs := getTreeSubTreeChildBlocks(rootID) treeBlockIDs := getTreeSubTreeChildBlocks(rootID)
cards := deck.Dues() cards := getDeckDueCards(deck)
now := time.Now() now := time.Now()
for _, card := range cards { for _, card := range cards {
blockID := card.BlockID() blockID := card.BlockID()
@ -396,7 +424,7 @@ func getDueFlashcards(deckID string) (ret []*Flashcard) {
return return
} }
cards := deck.Dues() cards := getDeckDueCards(deck)
now := time.Now() now := time.Now()
for _, card := range cards { for _, card := range cards {
blockID := card.BlockID() blockID := card.BlockID()
@ -416,7 +444,7 @@ func getDueFlashcards(deckID string) (ret []*Flashcard) {
func getAllDueFlashcards() (ret []*Flashcard) { func getAllDueFlashcards() (ret []*Flashcard) {
now := time.Now() now := time.Now()
for _, deck := range Decks { for _, deck := range Decks {
cards := deck.Dues() cards := getDeckDueCards(deck)
for _, card := range cards { for _, card := range cards {
blockID := card.BlockID() blockID := card.BlockID()
if nil == treenode.GetBlockTree(blockID) { if nil == treenode.GetBlockTree(blockID) {
@ -867,3 +895,17 @@ func getDeckIDs() (deckIDs []string) {
} }
return return
} }
func getDeckDueCards(deck *riff.Deck) (ret []riff.Card) {
ret = []riff.Card{}
dues := deck.Dues()
for _, c := range dues {
if nil != skipCardCache[c.ID()] {
continue
}
ret = append(ret, c)
}
return
}