jasonwilliams / anki

Anki VSCode Plugin
MIT License
282 stars 31 forks source link

Duplicate IDs with reversable cards #135

Open StefanoDeVuono opened 2 months ago

StefanoDeVuono commented 2 months ago

I have a series of reversable cards in my deck. I've been getting errors from VS Code itself like

Element with id 1672700247222 is already registered

I put in some debuggers and poked around the code. It appears that I have two cards per note. For example when I query my deck for cards and map {id: cardId, model: modelName, note}, I get the following:

[
  {
    id: 1672700247224,
    model: 'Basic (and reversed card)',
    note: 1672700247222
  },
  {
    id: 1672700247225,
    model: 'Basic (and reversed card)',
    note: 1672700247222
  },
  {
    id: 1672700349071,
    model: 'Basic (and reversed card)',
    note: 1672700349071
  },
  {
    id: 1672700349072,
    model: 'Basic (and reversed card)',
    note: 1672700349071
  },
//...
  {
    id: 1679991935941,
    model: 'Basic (and reversed card)',
    note: 1679991935938
  },
  {
    id: 1679991935942,
    model: 'Basic (and reversed card)',
    note: 1679991935938
  }
]

Although all card IDs are unique, the anki plugin uses note IDs, causing collisions.

In particular, the return from the AnkiCardProvider#getChildren() method causes collisions. VS Code calls this method on a TreeDataProvider and consumes the result. So, VS Code itself is throwing the error.

If for example, I change the method to the following:

+let existingNoteIds: { [key: string]: boolean } = {};
      const mappedCards = cards?.map((v, i) => {
        const deckID = getAnkiState().getDeckIDFromName(v.deckName || "");
        const cardUri = `anki:/decks/${deckID}/${v.noteId?.toString()}.json`;
        this.ankiFS.writeFile(Uri.parse(cardUri), Buffer.from(v.toString()), {
          create: true,
          overwrite: true,
        });
        return new Dependency(
          v.question,
          v.noteId?.toString() ?? i.toString(),
          TreeItemCollapsibleState.None,
          cardUri,
          ItemType.Card
        );
+      }).filter(card => {
+        if (existingNoteIds[card.id] ) {
+          return false;
+        } else {
+          existingNoteIds[card.id] = true;
+          return true;
+        }
+      });

VS Code doesn't error.

Any thoughts or suggestions?

StefanoDeVuono commented 1 month ago

@jasonwilliams I also notice this when creating a brand new BasicWithHightlightVSCodeRev note.

image