🎨 改进闪卡存储数据结构,支持一个块对应多张闪卡 https://github.com/siyuan-note/siyuan/issues/7417

This commit is contained in:
Liang Ding 2023-02-24 22:53:14 +08:00
parent fe9abe4b4b
commit 7bceb8e641
No known key found for this signature in database
GPG key ID: 136F30F901A2231D
4 changed files with 120 additions and 33 deletions

View file

@ -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"),
}

View file

@ -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

View file

@ -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=

View file

@ -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
cards := deck.GetCardsByBlockIDs(blockIDs)
for _, card := range cards {
deck.RemoveCard(card.ID())
}
deck.RemoveCard(cardID)
}
err := deck.Save()
if nil != err {
logging.LogErrorf("save deck [%s] failed: %s", deck.ID, err)