Anki note api functions (#802)
* Assign duplicateScope to a variable * Add api.addAnkiNote * Add api.getAnkiNoteInfo, update returned data format
This commit is contained in:
parent
3dd4822ab3
commit
892f7ed3b8
@ -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 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);
|
||||
}
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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}) {
|
||||
|
@ -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});
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user