diff options
author | Eloy Robillard <eloy.robillard@gmail.com> | 2024-03-18 12:19:27 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-18 11:19:27 +0000 |
commit | 7ee76d708934adeef06479f7757beb22c6c01d14 (patch) | |
tree | c03ad4227e8a71939bb5efddffe57fa21a75b043 /ext/js/background | |
parent | 4fe881d68d4c1182bee2e78a559c2064aaf48b0d (diff) |
Add an option to allow both viewing and adding duplicates (#693)
* Detect duplicates when checking if can add note
* Display the stacked add buttons
Diffstat (limited to 'ext/js/background')
-rw-r--r-- | ext/js/background/backend.js | 87 |
1 files changed, 77 insertions, 10 deletions
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js index 182f11aa..cd44a07f 100644 --- a/ext/js/background/backend.js +++ b/ext/js/background/backend.js @@ -544,22 +544,89 @@ export class Backend { return await this._anki.addNote(note); } + /** + * @param {import('anki').Note[]} notes + * @returns {Promise<({ canAdd: true; } | { canAdd: false; error: string; })[]>} + */ + async detectDuplicateNotes(notes) { + // `allowDuplicate` is on for all notes by default, so we temporarily set it to false + // to check which notes are duplicates. + const notesNoDuplicatesAllowed = notes.map((note) => ({...note, options: {...note.options, allowDuplicate: false}})); + + return await this._anki.canAddNotesWithErrorDetail(notesNoDuplicatesAllowed); + } + + /** + * Partitions notes between those that can / cannot be added. + * It further sets the `isDuplicate` strings for notes that have a duplicate. + * @param {import('anki').Note[]} notes + * @returns {Promise<import('backend').CanAddResults>} + */ + async partitionAddibleNotes(notes) { + const canAddResults = await this.detectDuplicateNotes(notes); + + /** @type {{ note: import('anki').Note, isDuplicate: boolean }[]} */ + const canAddArray = []; + + /** @type {import('anki').Note[]} */ + const cannotAddArray = []; + + for (let i = 0; i < canAddResults.length; i++) { + const result = canAddResults[i]; + + // If the note is a duplicate, the error is "cannot create note because it is a duplicate". + if (result.canAdd) { + canAddArray.push({note: notes[i], isDuplicate: false}); + } else if (result.error.endsWith('duplicate')) { + canAddArray.push({note: notes[i], isDuplicate: true}); + } else { + cannotAddArray.push(notes[i]); + } + } + + return {canAddArray, cannotAddArray}; + } + /** @type {import('api').ApiHandler<'getAnkiNoteInfo'>} */ async _onApiGetAnkiNoteInfo({notes, fetchAdditionalInfo}) { - /** @type {import('anki').NoteInfoWrapper[]} */ - const results = []; + const {canAddArray, cannotAddArray} = await this.partitionAddibleNotes(notes); + /** @type {{note: import('anki').Note, info: import('anki').NoteInfoWrapper}[]} */ - const cannotAdd = []; - const canAddArray = await this._anki.canAddNotes(notes); + const cannotAdd = cannotAddArray.filter((note) => isNoteDataValid(note)).map((note) => ({note, info: {canAdd: false, valid: false, noteIds: null}})); + + /** @type {import('anki').NoteInfoWrapper[]} */ + const results = cannotAdd.map(({info}) => info); + + /** @type {import('anki').Note[]} */ + const duplicateNotes = []; + + /** @type {number[]} */ + const originalIndices = []; + + for (let i = 0; i < canAddArray.length; i++) { + if (canAddArray[i].isDuplicate) { + duplicateNotes.push(canAddArray[i].note); + // Keep original indices to locate duplicate inside `duplicateNoteIds` + originalIndices.push(i); + } + } + + const duplicateNoteIds = await this._anki.findNoteIds(duplicateNotes); + + for (let i = 0; i < canAddArray.length; ++i) { + const {note, isDuplicate} = canAddArray[i]; - for (let i = 0; i < notes.length; ++i) { - const note = notes[i]; - let canAdd = canAddArray[i]; const valid = isNoteDataValid(note); - if (!valid) { canAdd = false; } - const info = {canAdd, valid, noteIds: null}; + + const info = { + canAdd: valid, + valid, + noteIds: isDuplicate ? duplicateNoteIds[originalIndices.indexOf(i)] : null + }; + results.push(info); - if (!canAdd && valid) { + + if (!valid) { cannotAdd.push({note, info}); } } |