mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-17 15:10:12 +01:00
♻️ Adjust addRiffCards/removeRiffCards implementation to be asynchronous transaction https://github.com/siyuan-note/siyuan/issues/7936
This commit is contained in:
parent
e5143a8474
commit
3e14b4f29c
3 changed files with 58 additions and 104 deletions
|
|
@ -216,13 +216,22 @@ func removeRiffCards(c *gin.Context) {
|
|||
for _, blockID := range blockIDsArg {
|
||||
blockIDs = append(blockIDs, blockID.(string))
|
||||
}
|
||||
err := model.RemoveFlashcardsByBlockIDs(deckID, blockIDs)
|
||||
if nil != err {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
|
||||
transactions := []*model.Transaction{
|
||||
{
|
||||
DoOperations: []*model.Operation{
|
||||
{
|
||||
Action: "removeFlashcards",
|
||||
DeckID: deckID,
|
||||
BlockIDs: blockIDs,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
model.PerformTransactions(&transactions)
|
||||
model.WaitForWritingFiles()
|
||||
|
||||
if "" != deckID {
|
||||
deck := model.Decks[deckID]
|
||||
ret.Data = deckData(deck)
|
||||
|
|
@ -245,13 +254,22 @@ func addRiffCards(c *gin.Context) {
|
|||
for _, blockID := range blockIDsArg {
|
||||
blockIDs = append(blockIDs, blockID.(string))
|
||||
}
|
||||
err := model.AddFlashcards(deckID, blockIDs)
|
||||
if nil != err {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
|
||||
transactions := []*model.Transaction{
|
||||
{
|
||||
DoOperations: []*model.Operation{
|
||||
{
|
||||
Action: "addFlashcards",
|
||||
DeckID: deckID,
|
||||
BlockIDs: blockIDs,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
model.PerformTransactions(&transactions)
|
||||
model.WaitForWritingFiles()
|
||||
|
||||
deck := model.Decks[deckID]
|
||||
ret.Data = deckData(deck)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -456,95 +456,20 @@ func getAllDueFlashcards(reviewedCardIDs []string) (ret []*Flashcard) {
|
|||
return
|
||||
}
|
||||
|
||||
func RemoveFlashcardsByCardIDs(deckID string, cardIDs []string) (err error) {
|
||||
func (tx *Transaction) doRemoveFlashcards(operation *Operation) (ret *TxErr) {
|
||||
deckLock.Lock()
|
||||
defer deckLock.Unlock()
|
||||
|
||||
if syncingStorages {
|
||||
err = errors.New(Conf.Language(81))
|
||||
ret = &TxErr{code: TxErrCodeDataIsSyncing}
|
||||
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
|
||||
}
|
||||
deckID := operation.DeckID
|
||||
blockIDs := operation.BlockIDs
|
||||
|
||||
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()
|
||||
|
||||
if syncingStorages {
|
||||
err = errors.New(Conf.Language(81))
|
||||
return
|
||||
}
|
||||
|
||||
if err = removeBlocksDeckAttr(blockIDs, deckID); nil != err {
|
||||
return
|
||||
if err := tx.removeBlocksDeckAttr(blockIDs, deckID); nil != err {
|
||||
return &TxErr{code: TxErrCodeWriteTree, msg: err.Error(), id: deckID}
|
||||
}
|
||||
|
||||
if "" == deckID { // 支持在 All 卡包中移除闪卡 https://github.com/siyuan-note/siyuan/issues/7425
|
||||
|
|
@ -557,7 +482,7 @@ func RemoveFlashcardsByBlockIDs(deckID string, blockIDs []string) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func removeBlocksDeckAttr(blockIDs []string, deckID string) (err error) {
|
||||
func (tx *Transaction) removeBlocksDeckAttr(blockIDs []string, deckID string) (err error) {
|
||||
var rootIDs []string
|
||||
blockRoots := map[string]string{}
|
||||
for _, blockID := range blockIDs {
|
||||
|
|
@ -577,7 +502,7 @@ func removeBlocksDeckAttr(blockIDs []string, deckID string) (err error) {
|
|||
|
||||
tree := trees[rootID]
|
||||
if nil == tree {
|
||||
tree, _ = loadTreeByBlockID(blockID)
|
||||
tree, _ = tx.loadTree(blockID)
|
||||
}
|
||||
if nil == tree {
|
||||
continue
|
||||
|
|
@ -612,7 +537,7 @@ func removeBlocksDeckAttr(blockIDs []string, deckID string) (err error) {
|
|||
node.SetIALAttr("custom-riff-decks", val)
|
||||
}
|
||||
|
||||
if err = indexWriteJSONQueue(tree); nil != err {
|
||||
if err = tx.writeTree(tree); nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -643,15 +568,18 @@ func removeFlashcardsByBlockIDs(blockIDs []string, deck *riff.Deck) {
|
|||
}
|
||||
}
|
||||
|
||||
func AddFlashcards(deckID string, blockIDs []string) (err error) {
|
||||
func (tx *Transaction) doAddFlashcards(operation *Operation) (ret *TxErr) {
|
||||
deckLock.Lock()
|
||||
defer deckLock.Unlock()
|
||||
|
||||
if syncingStorages {
|
||||
err = errors.New(Conf.Language(81))
|
||||
ret = &TxErr{code: TxErrCodeDataIsSyncing}
|
||||
return
|
||||
}
|
||||
|
||||
deckID := operation.DeckID
|
||||
blockIDs := operation.BlockIDs
|
||||
|
||||
blockRoots := map[string]string{}
|
||||
for _, blockID := range blockIDs {
|
||||
bt := treenode.GetBlockTree(blockID)
|
||||
|
|
@ -668,7 +596,7 @@ func AddFlashcards(deckID string, blockIDs []string) (err error) {
|
|||
|
||||
tree := trees[rootID]
|
||||
if nil == tree {
|
||||
tree, _ = loadTreeByBlockID(blockID)
|
||||
tree, _ = tx.loadTree(blockID)
|
||||
}
|
||||
if nil == tree {
|
||||
continue
|
||||
|
|
@ -691,8 +619,8 @@ func AddFlashcards(deckID string, blockIDs []string) (err error) {
|
|||
val = strings.TrimSuffix(val, ",")
|
||||
node.SetIALAttr("custom-riff-decks", val)
|
||||
|
||||
if err = indexWriteJSONQueue(tree); nil != err {
|
||||
return
|
||||
if err := tx.writeTree(tree); nil != err {
|
||||
return &TxErr{code: TxErrCodeWriteTree, msg: err.Error(), id: deckID}
|
||||
}
|
||||
|
||||
cache.PutBlockIAL(blockID, parse.IAL2Map(node.KramdownIAL))
|
||||
|
|
@ -715,8 +643,8 @@ func AddFlashcards(deckID string, blockIDs []string) (err error) {
|
|||
cardID := ast.NewNodeID()
|
||||
deck.AddCard(cardID, blockID)
|
||||
}
|
||||
err = deck.Save()
|
||||
if nil != err {
|
||||
|
||||
if err := deck.Save(); nil != err {
|
||||
logging.LogErrorf("save deck [%s] failed: %s", deckID, err)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@ func PerformTransactions(transactions *[]*Transaction) {
|
|||
|
||||
const (
|
||||
TxErrCodeBlockNotFound = 0
|
||||
TxErrCodeDataIsSyncing = 1
|
||||
TxErrCodeWriteTree = 2
|
||||
TxErrWriteAttributeView = 3
|
||||
)
|
||||
|
|
@ -208,7 +209,11 @@ func performTx(tx *Transaction) (ret *TxErr) {
|
|||
case "unfoldHeading":
|
||||
ret = tx.doUnfoldHeading(op)
|
||||
case "setAttrs":
|
||||
ret = tx.setAttrs(op)
|
||||
ret = tx.doSetAttrs(op)
|
||||
case "addFlashcards":
|
||||
ret = tx.doAddFlashcards(op)
|
||||
case "removeFlashcards":
|
||||
ret = tx.doRemoveFlashcards(op)
|
||||
case "insertAttrViewBlock":
|
||||
ret = tx.doInsertAttrViewBlock(op)
|
||||
case "removeAttrViewBlock":
|
||||
|
|
@ -927,7 +932,7 @@ func (tx *Transaction) doCreate(operation *Operation) (ret *TxErr) {
|
|||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) setAttrs(operation *Operation) (ret *TxErr) {
|
||||
func (tx *Transaction) doSetAttrs(operation *Operation) (ret *TxErr) {
|
||||
id := operation.ID
|
||||
tree, err := tx.loadTree(id)
|
||||
if nil != err {
|
||||
|
|
@ -968,7 +973,7 @@ func (tx *Transaction) setAttrs(operation *Operation) (ret *TxErr) {
|
|||
}
|
||||
}
|
||||
|
||||
if err = indexWriteJSONQueue(tree); nil != err {
|
||||
if err = tx.writeTree(tree); nil != err {
|
||||
return
|
||||
}
|
||||
cache.PutBlockIAL(id, parse.IAL2Map(node.KramdownIAL))
|
||||
|
|
@ -1007,6 +1012,9 @@ type Operation struct {
|
|||
PreviousID string `json:"previousID"`
|
||||
NextID string `json:"nextID"`
|
||||
RetData interface{} `json:"retData"`
|
||||
BlockIDs []string `json:"blockIDs"`
|
||||
|
||||
DeckID string `json:"deckID"` // 用于添加/删除闪卡
|
||||
|
||||
SrcIDs []string `json:"srcIDs"` // 用于将块拖拽到属性视图中
|
||||
Name string `json:"name"` // 用于属性视图列名
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue