diff --git a/kernel/api/riff.go b/kernel/api/riff.go index 0cc51928b..df706cd54 100644 --- a/kernel/api/riff.go +++ b/kernel/api/riff.go @@ -254,7 +254,7 @@ func deckData(deck *riff.Deck) map[string]interface{} { return map[string]interface{}{ "id": deck.ID, "name": deck.Name, - "size": len(deck.BlockCard), + "size": deck.CountCards(), "created": time.UnixMilli(deck.Created).Format("2006-01-02 15:04:05"), "updated": time.UnixMilli(deck.Updated).Format("2006-01-02 15:04:05"), } diff --git a/kernel/go.mod b/kernel/go.mod index e7dcccc10..98e132251 100644 --- a/kernel/go.mod +++ b/kernel/go.mod @@ -47,7 +47,7 @@ require ( github.com/siyuan-note/filelock v0.0.0-20230223100551-200cbe1cf84e github.com/siyuan-note/httpclient v0.0.0-20230224113038-40f0e2672f0f github.com/siyuan-note/logging v0.0.0-20230223101545-ec2cbf198ffb - github.com/siyuan-note/riff v0.0.0-20230224074237-c16f59420520 + github.com/siyuan-note/riff v0.0.0-20230224144841-cfbe0748ddb7 github.com/steambap/captcha v1.4.1 github.com/studio-b12/gowebdav v0.0.0-20230203202212-3282f94193f2 github.com/vmihailenco/msgpack/v5 v5.3.5 diff --git a/kernel/go.sum b/kernel/go.sum index fc9f462f9..787f7c3b9 100644 --- a/kernel/go.sum +++ b/kernel/go.sum @@ -288,6 +288,18 @@ github.com/siyuan-note/logging v0.0.0-20230223101545-ec2cbf198ffb h1:qzz7ZQw7/tH github.com/siyuan-note/logging v0.0.0-20230223101545-ec2cbf198ffb/go.mod h1:6mRFtAAvYPn3cDzqvyv+t8BVPGqpONDMMb5ywOhY1D4= github.com/siyuan-note/riff v0.0.0-20230224074237-c16f59420520 h1:14vDSmi+YYBCnPb41ESSaq8kzgx6Sj4fE1mNJQwVObw= github.com/siyuan-note/riff v0.0.0-20230224074237-c16f59420520/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8= +github.com/siyuan-note/riff v0.0.0-20230224124310-d7b524f12a93 h1:sr98gF9C+JansB+A1PbIPMoYMzipaYLo/l7tuzfiVsE= +github.com/siyuan-note/riff v0.0.0-20230224124310-d7b524f12a93/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8= +github.com/siyuan-note/riff v0.0.0-20230224135851-50a5d05ebc1f h1:WmTcCgdOf+PxsFOBkbxsPLsEtjFoN8G/Iy/XRjfpsKw= +github.com/siyuan-note/riff v0.0.0-20230224135851-50a5d05ebc1f/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8= +github.com/siyuan-note/riff v0.0.0-20230224140523-e14e716c1b0b h1:mvyYjIIwOK/BqBbwZClldcMB/XUEC7/Mudee1S81WVA= +github.com/siyuan-note/riff v0.0.0-20230224140523-e14e716c1b0b/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8= +github.com/siyuan-note/riff v0.0.0-20230224141518-b70f9beb2db0 h1:3RGcJ0UOkwm5bQR6yBua3SgZYSxyblrFItjbbbWPIzE= +github.com/siyuan-note/riff v0.0.0-20230224141518-b70f9beb2db0/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8= +github.com/siyuan-note/riff v0.0.0-20230224143400-ff2c16506fcd h1:KBaZACXvXKcFVX0jWdIRrklxUu/ZHkW7NygoduNuRQs= +github.com/siyuan-note/riff v0.0.0-20230224143400-ff2c16506fcd/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8= +github.com/siyuan-note/riff v0.0.0-20230224144841-cfbe0748ddb7 h1:Kr8hhMhr6v+U24TMDCP5WdP4dWrXm5maar+TycTZs9I= +github.com/siyuan-note/riff v0.0.0-20230224144841-cfbe0748ddb7/go.mod h1:XJtLlKCr8cZE+lzykM4edHHih92M9M50UNw/nDLYRN8= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.7 h1:I6tZjLXD2Q1kjvNbIzB1wvQBsXmKXiVrhpRE8ZjP5jY= diff --git a/kernel/model/flashcard.go b/kernel/model/flashcard.go index e254b69dc..11be65d0b 100644 --- a/kernel/model/flashcard.go +++ b/kernel/model/flashcard.go @@ -44,22 +44,20 @@ var deckLock = sync.Mutex{} func GetTreeFlashcards(rootID string, page int) (blocks []*Block, total, pageCount int) { blocks = []*Block{} - treeBlockIDs := getTreeSubTreeChildBlocks(rootID) - var allBlockIDs []string const pageSize = 20 deck := Decks[builtinDeckID] if nil == deck { return } - for bID, _ := range deck.BlockCard { - if _, ok := treeBlockIDs[bID]; !ok { - continue + var allBlockIDs []string + deckBlockIDs := deck.GetBlockIDs() + treeBlockIDs := getTreeSubTreeChildBlocks(rootID) + for _, blockID := range deckBlockIDs { + if treeBlockIDs[blockID] { + allBlockIDs = append(allBlockIDs, blockID) } - - allBlockIDs = append(allBlockIDs, bID) } - allBlockIDs = gulu.Str.RemoveDuplicatedElem(allBlockIDs) sort.Strings(allBlockIDs) @@ -103,9 +101,7 @@ func GetFlashcards(deckID string, page int) (blocks []*Block, total, pageCount i const pageSize = 20 if "" == deckID { for _, deck := range Decks { - for bID, _ := range deck.BlockCard { - allBlockIDs = append(allBlockIDs, bID) - } + allBlockIDs = append(allBlockIDs, deck.GetBlockIDs()...) } } else { deck := Decks[deckID] @@ -113,9 +109,7 @@ func GetFlashcards(deckID string, page int) (blocks []*Block, total, pageCount i return } - for bID, _ := range deck.BlockCard { - allBlockIDs = append(allBlockIDs, bID) - } + allBlockIDs = append(allBlockIDs, deck.GetBlockIDs()...) } allBlockIDs = gulu.Str.RemoveDuplicatedElem(allBlockIDs) @@ -372,6 +366,84 @@ func getAllDueFlashcards() (ret []*Flashcard) { return } +func RemoveFlashcardsByCardIDs(deckID string, cardIDs []string) (err error) { + deckLock.Lock() + defer deckLock.Unlock() + + if syncingStorages { + err = errors.New(Conf.Language(81)) + return + } + + var needRemoveDeckAttrBlockIDs []string + if "" == deckID { + // 在 All 卡包中移除 + var affectedBlockIDs []string + for _, deck := range Decks { + changed := false + for _, cardID := range cardIDs { + card := deck.GetCard(cardID) + if nil == card { + continue + } + + affectedBlockIDs = append(affectedBlockIDs, card.BlockID()) + deck.RemoveCard(cardID) + changed = true + } + + if changed { + if err = deck.Save(); nil != err { + return + } + } + + // 检查刚刚移除的卡片关联的块是否还存在更多关联的卡片 + affectedBlockIDs = gulu.Str.RemoveDuplicatedElem(affectedBlockIDs) + for _, blockID := range affectedBlockIDs { + moreRelatedCards := deck.GetCardsByBlockID(blockID) + if 1 > len(moreRelatedCards) { + needRemoveDeckAttrBlockIDs = append(needRemoveDeckAttrBlockIDs, blockID) + } + } + } + } else { + // 在指定卡包中移除 + deck := Decks[deckID] + if nil == deck { + return + } + + var affectedBlockIDs []string + for _, cardID := range cardIDs { + card := deck.GetCard(cardID) + if nil == card { + continue + } + + affectedBlockIDs = append(affectedBlockIDs, card.BlockID()) + deck.RemoveCard(cardID) + if err = deck.Save(); nil != err { + return + } + } + + // 检查刚刚移除的卡片关联的块是否还存在更多关联的卡片 + affectedBlockIDs = gulu.Str.RemoveDuplicatedElem(affectedBlockIDs) + for _, blockID := range affectedBlockIDs { + moreRelatedCards := deck.GetCardsByBlockID(blockID) + if 1 > len(moreRelatedCards) { + needRemoveDeckAttrBlockIDs = append(needRemoveDeckAttrBlockIDs, blockID) + } + } + } + + if err = removeBlocksDeckAttr(needRemoveDeckAttrBlockIDs, deckID); nil != err { + return + } + return +} + func RemoveFlashcardsByBlockIDs(deckID string, blockIDs []string) (err error) { deckLock.Lock() defer deckLock.Unlock() @@ -381,6 +453,21 @@ func RemoveFlashcardsByBlockIDs(deckID string, blockIDs []string) (err error) { return } + if err = removeBlocksDeckAttr(blockIDs, deckID); nil != err { + return + } + + if "" == deckID { // 支持在 All 卡包中移除闪卡 https://github.com/siyuan-note/siyuan/issues/7425 + for _, deck := range Decks { + removeFlashcardsByBlockIDs(blockIDs, deck) + } + } else { + removeFlashcardsByBlockIDs(blockIDs, Decks[deckID]) + } + return +} + +func removeBlocksDeckAttr(blockIDs []string, deckID string) (err error) { var rootIDs []string blockRoots := map[string]string{} for _, blockID := range blockIDs { @@ -394,7 +481,6 @@ func RemoveFlashcardsByBlockIDs(deckID string, blockIDs []string) (err error) { } rootIDs = gulu.Str.RemoveDuplicatedElem(rootIDs) - availableDeckIDs := getDeckIDs() trees := map[string]*parse.Tree{} for _, blockID := range blockIDs { rootID := blockRoots[blockID] @@ -418,6 +504,7 @@ func RemoveFlashcardsByBlockIDs(deckID string, blockIDs []string) (err error) { deckAttrs := node.IALAttr("custom-riff-decks") var deckIDs []string if "" != deckID { + availableDeckIDs := getDeckIDs() for _, dID := range strings.Split(deckAttrs, ",") { if dID != deckID && gulu.Str.Contains(dID, availableDeckIDs) { deckIDs = append(deckIDs, dID) @@ -450,31 +537,19 @@ func RemoveFlashcardsByBlockIDs(deckID string, blockIDs []string) (err error) { pushBroadcastAttrTransactions(trans) } - if "" == deckID { // 支持在 All 卡包中移除闪卡 https://github.com/siyuan-note/siyuan/issues/7425 - for _, deck := range Decks { - removeFlashcard(blockIDs, deck) - } - } else { - removeFlashcard(blockIDs, Decks[deckID]) - } return } -func removeFlashcard(blockIDs []string, deck *riff.Deck) { +func removeFlashcardsByBlockIDs(blockIDs []string, deck *riff.Deck) { if nil == deck { logging.LogErrorf("deck is nil") return } - for _, blockID := range blockIDs { - // TODO 这里的代码需要重构,要支持一个块对应多张卡 - cardID := deck.BlockCard[blockID] - if "" == cardID { - continue - } - deck.RemoveCard(cardID) + cards := deck.GetCardsByBlockIDs(blockIDs) + for _, card := range cards { + deck.RemoveCard(card.ID()) } - err := deck.Save() if nil != err { logging.LogErrorf("save deck [%s] failed: %s", deck.ID, err)