aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-09-10 16:05:17 -0400
committerGitHub <noreply@github.com>2020-09-10 16:05:17 -0400
commit892f7ed3b8d4a97dd7fd8086a404c5e8ea1355fb (patch)
treeccc4551b2dbef20193c85a946e61d8774873cad2
parent3dd4822ab3e1312336065f70cf31b87dac39473b (diff)
Anki note api functions (#802)
* Assign duplicateScope to a variable * Add api.addAnkiNote * Add api.getAnkiNoteInfo, update returned data format
-rw-r--r--ext/bg/js/backend.js90
-rw-r--r--ext/mixed/js/api.js8
-rw-r--r--ext/mixed/js/display.js24
3 files changed, 74 insertions, 48 deletions
diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js
index 47295a27..e3ef1e88 100644
--- a/ext/bg/js/backend.js
+++ b/ext/bg/js/backend.js
@@ -91,6 +91,8 @@ class Backend {
['kanjiFind', {async: true, contentScript: true, handler: this._onApiKanjiFind.bind(this)}],
['termsFind', {async: true, contentScript: true, handler: this._onApiTermsFind.bind(this)}],
['textParse', {async: true, contentScript: true, handler: this._onApiTextParse.bind(this)}],
+ ['addAnkiNote', {async: true, contentScript: true, handler: this._onApiAddAnkiNote.bind(this)}],
+ ['getAnkiNoteInfo', {async: true, contentScript: true, handler: this._onApiGetAnkiNoteInfo.bind(this)}],
['definitionAdd', {async: true, contentScript: true, handler: this._onApiDefinitionAdd.bind(this)}],
['definitionsAddable', {async: true, contentScript: true, handler: this._onApiDefinitionsAddable.bind(this)}],
['noteView', {async: true, contentScript: true, handler: this._onApiNoteView.bind(this)}],
@@ -437,60 +439,68 @@ class Backend {
return results;
}
+ async _onApiAddAnkiNote({note}) {
+ return await this._anki.addNote(note);
+ }
+
+ async _onApiGetAnkiNoteInfo({notes, duplicateScope}) {
+ const results = [];
+ const cannotAdd = [];
+ const canAddArray = await this._anki.canAddNotes(notes);
+
+ for (let i = 0; i < notes.length; ++i) {
+ const note = notes[i];
+ const canAdd = canAddArray[i];
+ const info = {canAdd, noteIds: null};
+ results.push(info);
+ if (!canAdd) {
+ cannotAdd.push({note, info});
+ }
+ }
+
+ if (cannotAdd.length > 0) {
+ const cannotAddNotes = cannotAdd.map(({note}) => note);
+ const noteIdsArray = await this._anki.findNoteIds(cannotAddNotes, duplicateScope);
+ for (let i = 0, ii = Math.min(cannotAdd.length, noteIdsArray.length); i < ii; ++i) {
+ const noteIds = noteIdsArray[i];
+ if (noteIds.length > 0) {
+ cannotAdd[i].info.noteIds = noteIds;
+ }
+ }
+ }
+
+ return results;
+ }
+
async _onApiDefinitionAdd({definition, mode, context, ownerFrameId, optionsContext}, sender) {
const options = this.getOptions(optionsContext);
const templates = this._getTemplates(options);
const {id: tabId, windowId} = (sender && sender.tab ? sender.tab : {});
const note = await this._createNote(definition, mode, context, options, templates, true, {windowId, tabId, ownerFrameId});
- return this._anki.addNote(note);
+ return await this._onApiAddAnkiNote({note});
}
async _onApiDefinitionsAddable({definitions, modes, context, optionsContext}) {
const options = this.getOptions(optionsContext);
const templates = this._getTemplates(options);
- const states = [];
-
- try {
- const notePromises = [];
- for (const definition of definitions) {
- for (const mode of modes) {
- const notePromise = this._createNote(definition, mode, context, options, templates, false, null);
- notePromises.push(notePromise);
- }
- }
- const notes = await Promise.all(notePromises);
-
- const cannotAdd = [];
- const results = await this._anki.canAddNotes(notes);
- for (let resultBase = 0; resultBase < results.length; resultBase += modes.length) {
- const state = {};
- for (let modeOffset = 0; modeOffset < modes.length; ++modeOffset) {
- const index = resultBase + modeOffset;
- const result = results[index];
- const info = {canAdd: result};
- state[modes[modeOffset]] = info;
- if (!result) {
- cannotAdd.push([notes[index], info]);
- }
- }
-
- states.push(state);
- }
- if (cannotAdd.length > 0) {
- const noteIdsArray = await this._anki.findNoteIds(cannotAdd.map((e) => e[0]), options.anki.duplicateScope);
- for (let i = 0, ii = Math.min(cannotAdd.length, noteIdsArray.length); i < ii; ++i) {
- const noteIds = noteIdsArray[i];
- if (noteIds.length > 0) {
- cannotAdd[i][1].noteId = noteIds[0];
- }
- }
+ const modeCount = modes.length;
+ const {duplicateScope} = options.anki;
+ const notePromises = [];
+ for (const definition of definitions) {
+ for (const mode of modes) {
+ const notePromise = this._createNote(definition, mode, context, options, templates, false, null);
+ notePromises.push(notePromise);
}
- } catch (e) {
- // NOP
}
+ const notes = await Promise.all(notePromises);
- return states;
+ const infos = await this._onApiGetAnkiNoteInfo({notes, duplicateScope});
+ const results = [];
+ for (let i = 0, ii = infos.length; i < ii; i += modeCount) {
+ results.push(infos.slice(i, i + modeCount));
+ }
+ return results;
}
async _onApiNoteView({noteId}) {
diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js
index 7dc77fb6..d9569187 100644
--- a/ext/mixed/js/api.js
+++ b/ext/mixed/js/api.js
@@ -77,6 +77,14 @@ const api = (() => {
return this._invoke('kanjiFind', {text, optionsContext});
}
+ addAnkiNote(note) {
+ return this._invoke('addAnkiNote', {note});
+ }
+
+ getAnkiNoteInfo(notes, duplicateScope) {
+ return this._invoke('getAnkiNoteInfo', {notes, duplicateScope});
+ }
+
definitionAdd(definition, mode, context, ownerFrameId, optionsContext) {
return this._invoke('definitionAdd', {definition, mode, context, ownerFrameId, optionsContext});
}
diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js
index 6fdab46b..7dd5920a 100644
--- a/ext/mixed/js/display.js
+++ b/ext/mixed/js/display.js
@@ -889,10 +889,15 @@ class Display extends EventDispatcher {
async _setContentTermsOrKanjiUpdateAdderButtons(token, isTerms, definitions) {
const modes = isTerms ? ['term-kanji', 'term-kana'] : ['kanji'];
- const states = await this._getDefinitionsAddable(definitions, modes);
+ let states;
+ try {
+ states = await this._getDefinitionsAddable(definitions, modes);
+ } catch (e) {
+ return;
+ }
if (this._setContentToken !== token) { return; }
- this._updateAdderButtons(states);
+ this._updateAdderButtons(states, modes);
}
_setContentExtensionUnloaded() {
@@ -953,19 +958,22 @@ class Display extends EventDispatcher {
this._navigationHeader.dataset.hasNext = `${!!next}`;
}
- _updateAdderButtons(states) {
- for (let i = 0; i < states.length; ++i) {
+ _updateAdderButtons(states, modes) {
+ for (let i = 0, ii = states.length; i < ii; ++i) {
+ const infos = states[i];
let noteId = null;
- for (const [mode, info] of Object.entries(states[i])) {
+ for (let j = 0, jj = infos.length; j < jj; ++j) {
+ const {canAdd, noteIds} = infos[j];
+ const mode = modes[j];
const button = this._adderButtonFind(i, mode);
if (button === null) {
continue;
}
- if (!info.canAdd && noteId === null && info.noteId) {
- noteId = info.noteId;
+ if (Array.isArray(noteIds) && noteIds.length > 0) {
+ noteId = noteIds[0];
}
- button.classList.toggle('disabled', !info.canAdd);
+ button.classList.toggle('disabled', !canAdd);
button.classList.remove('pending');
}
if (noteId !== null) {