From 7ee76d708934adeef06479f7757beb22c6c01d14 Mon Sep 17 00:00:00 2001 From: Eloy Robillard Date: Mon, 18 Mar 2024 12:19:27 +0100 Subject: Add an option to allow both viewing and adding duplicates (#693) * Detect duplicates when checking if can add note * Display the stacked add buttons --- ext/js/comm/anki-connect.js | 57 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'ext/js/comm') diff --git a/ext/js/comm/anki-connect.js b/ext/js/comm/anki-connect.js index 0bf38bda..a763f394 100644 --- a/ext/js/comm/anki-connect.js +++ b/ext/js/comm/anki-connect.js @@ -139,6 +139,17 @@ export class AnkiConnect { return this._normalizeArray(result, notes.length, 'boolean'); } + /** + * @param {import('anki').Note[]} notes + * @returns {Promise<({ canAdd: true } | { canAdd: false, error: string })[]>} + */ + async canAddNotesWithErrorDetail(notes) { + if (!this._enabled) { return []; } + await this._checkVersion(); + const result = await this._invoke('canAddNotesWithErrorDetail', {notes}); + return this._normalizeCanAddNotesWithErrorDetailArray(result, notes.length); + } + /** * @param {import('anki').NoteId[]} noteIds * @returns {Promise<(?import('anki').NoteInfo)[]>} @@ -579,6 +590,52 @@ export class AnkiConnect { return /** @type {T[]} */ (result); } + /** + * @param {unknown} result + * @param {number} expectedCount + * @returns {import('anki-connect.js').CanAddResult[]} + * @throws {Error} + */ + _normalizeCanAddNotesWithErrorDetailArray(result, expectedCount) { + if (!Array.isArray(result)) { + throw this._createUnexpectedResultError('array', result, ''); + } + if (expectedCount !== result.length) { + throw this._createError(`Unexpected result array size: expected ${expectedCount}, received ${result.length}`, result); + } + /** @type {import('anki-connect.js').CanAddResult[]} */ + const result2 = []; + for (let i = 0; i < expectedCount; ++i) { + const item = /** @type {unknown} */ (result[i]); + if (item === null || typeof item !== 'object') { + throw this._createError(`Unexpected result type at index ${i}: expected object, received ${this._getTypeName(item)}`, result); + } + + const {canAdd, error} = /** @type {{[key: string]: unknown}} */ (item); + if (typeof canAdd !== 'boolean') { + throw this._createError(`Unexpected result type at index ${i}, field canAdd: expected boolean, received ${this._getTypeName(canAdd)}`, result); + } + + if (canAdd && typeof error !== 'undefined') { + throw this._createError(`Unexpected result type at index ${i}, field error: expected undefined, received ${this._getTypeName(error)}`, result); + } + if (!canAdd && typeof error !== 'string') { + throw this._createError(`Unexpected result type at index ${i}, field error: expected string, received ${this._getTypeName(error)}`, result); + } + + if (canAdd) { + result2.push({canAdd}); + } else if (typeof error === 'string') { + const item2 = { + canAdd, + error + }; + result2.push(item2); + } + } + return result2; + } + /** * @param {unknown} result * @returns {(?import('anki').NoteInfo)[]} -- cgit v1.2.3