Refactor display anki functions (#1224)
* Refactor note adding/viewing functions * Move _addDefinition * Update where anki field templates are assigned * Update _createNote to not include options/templates arguments * Simplify getAnkiNoteInfo to not require duplicateScope
This commit is contained in:
parent
4ed9493645
commit
5e87a490f7
@ -103,12 +103,12 @@ class AnkiConnect {
|
|||||||
return await this._invoke('storeMediaFile', {filename: fileName, data: dataBase64});
|
return await this._invoke('storeMediaFile', {filename: fileName, data: dataBase64});
|
||||||
}
|
}
|
||||||
|
|
||||||
async findNoteIds(notes, duplicateScope) {
|
async findNoteIds(notes) {
|
||||||
if (!this._enabled) { return []; }
|
if (!this._enabled) { return []; }
|
||||||
await this._checkVersion();
|
await this._checkVersion();
|
||||||
const actions = notes.map((note) => {
|
const actions = notes.map((note) => {
|
||||||
let query = '';
|
let query = '';
|
||||||
switch (duplicateScope) {
|
switch (this._getDuplicateScopeFromNote(note)) {
|
||||||
case 'deck':
|
case 'deck':
|
||||||
query = `"deck:${this._escapeQuery(note.deckName)}" `;
|
query = `"deck:${this._escapeQuery(note.deckName)}" `;
|
||||||
break;
|
break;
|
||||||
@ -178,4 +178,15 @@ class AnkiConnect {
|
|||||||
const key = fieldNames[0];
|
const key = fieldNames[0];
|
||||||
return `"${key.toLowerCase()}:${this._escapeQuery(fields[key])}"`;
|
return `"${key.toLowerCase()}:${this._escapeQuery(fields[key])}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_getDuplicateScopeFromNote(note) {
|
||||||
|
const {options} = note;
|
||||||
|
if (typeof options === 'object' && options !== null) {
|
||||||
|
const {duplicateScope} = options;
|
||||||
|
if (typeof duplicateScope !== 'undefined') {
|
||||||
|
return duplicateScope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -447,7 +447,7 @@ class Backend {
|
|||||||
return await this._anki.addNote(note);
|
return await this._anki.addNote(note);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onApiGetAnkiNoteInfo({notes, duplicateScope}) {
|
async _onApiGetAnkiNoteInfo({notes}) {
|
||||||
const results = [];
|
const results = [];
|
||||||
const cannotAdd = [];
|
const cannotAdd = [];
|
||||||
const canAddArray = await this._anki.canAddNotes(notes);
|
const canAddArray = await this._anki.canAddNotes(notes);
|
||||||
@ -464,7 +464,7 @@ class Backend {
|
|||||||
|
|
||||||
if (cannotAdd.length > 0) {
|
if (cannotAdd.length > 0) {
|
||||||
const cannotAddNotes = cannotAdd.map(({note}) => note);
|
const cannotAddNotes = cannotAdd.map(({note}) => note);
|
||||||
const noteIdsArray = await this._anki.findNoteIds(cannotAddNotes, duplicateScope);
|
const noteIdsArray = await this._anki.findNoteIds(cannotAddNotes);
|
||||||
for (let i = 0, ii = Math.min(cannotAdd.length, noteIdsArray.length); i < ii; ++i) {
|
for (let i = 0, ii = Math.min(cannotAdd.length, noteIdsArray.length); i < ii; ++i) {
|
||||||
const noteIds = noteIdsArray[i];
|
const noteIds = noteIdsArray[i];
|
||||||
if (noteIds.length > 0) {
|
if (noteIds.length > 0) {
|
||||||
|
@ -81,8 +81,8 @@ const api = (() => {
|
|||||||
return this._invoke('addAnkiNote', {note});
|
return this._invoke('addAnkiNote', {note});
|
||||||
}
|
}
|
||||||
|
|
||||||
getAnkiNoteInfo(notes, duplicateScope) {
|
getAnkiNoteInfo(notes) {
|
||||||
return this._invoke('getAnkiNoteInfo', {notes, duplicateScope});
|
return this._invoke('getAnkiNoteInfo', {notes});
|
||||||
}
|
}
|
||||||
|
|
||||||
injectAnkiNoteMedia(timestamp, definitionDetails, audioDetails, screenshotDetails, clipboardDetails) {
|
injectAnkiNoteMedia(timestamp, definitionDetails, audioDetails, screenshotDetails, clipboardDetails) {
|
||||||
|
@ -86,8 +86,8 @@ class Display extends EventDispatcher {
|
|||||||
documentUtil: this._documentUtil
|
documentUtil: this._documentUtil
|
||||||
});
|
});
|
||||||
this._mode = null;
|
this._mode = null;
|
||||||
this._defaultAnkiFieldTemplates = null;
|
this._ankiFieldTemplates = null;
|
||||||
this._defaultAnkiFieldTemplatesPromise = null;
|
this._ankiFieldTemplatesDefault = null;
|
||||||
this._ankiNoteBuilder = new AnkiNoteBuilder(true);
|
this._ankiNoteBuilder = new AnkiNoteBuilder(true);
|
||||||
this._updateAdderButtonsPromise = Promise.resolve();
|
this._updateAdderButtonsPromise = Promise.resolve();
|
||||||
this._contentScrollElement = document.querySelector('#content-scroll');
|
this._contentScrollElement = document.querySelector('#content-scroll');
|
||||||
@ -125,10 +125,10 @@ class Display extends EventDispatcher {
|
|||||||
['firstEntry', () => { this._focusEntry(0, true); }],
|
['firstEntry', () => { this._focusEntry(0, true); }],
|
||||||
['historyBackward', () => { this._sourceTermView(); }],
|
['historyBackward', () => { this._sourceTermView(); }],
|
||||||
['historyForward', () => { this._nextTermView(); }],
|
['historyForward', () => { this._nextTermView(); }],
|
||||||
['addNoteKanji', () => { this._noteTryAdd('kanji'); }],
|
['addNoteKanji', () => { this._tryAddAnkiNoteForSelectedDefinition('kanji'); }],
|
||||||
['addNoteTermKanji', () => { this._noteTryAdd('term-kanji'); }],
|
['addNoteTermKanji', () => { this._tryAddAnkiNoteForSelectedDefinition('term-kanji'); }],
|
||||||
['addNoteTermKana', () => { this._noteTryAdd('term-kana'); }],
|
['addNoteTermKana', () => { this._tryAddAnkiNoteForSelectedDefinition('term-kana'); }],
|
||||||
['viewNote', () => { this._noteTryView(); }],
|
['viewNote', () => { this._tryViewAnkiNoteForSelectedDefinition(); }],
|
||||||
['playAudio', () => { this._playAudioCurrent(); }],
|
['playAudio', () => { this._playAudioCurrent(); }],
|
||||||
['copyHostSelection', () => this._copyHostSelection()]
|
['copyHostSelection', () => this._copyHostSelection()]
|
||||||
]);
|
]);
|
||||||
@ -304,8 +304,10 @@ class Display extends EventDispatcher {
|
|||||||
|
|
||||||
async updateOptions() {
|
async updateOptions() {
|
||||||
const options = await api.optionsGet(this.getOptionsContext());
|
const options = await api.optionsGet(this.getOptionsContext());
|
||||||
|
const templates = await this._getAnkiFieldTemplates(options);
|
||||||
const {scanning: scanningOptions, sentenceParsing: sentenceParsingOptions} = options;
|
const {scanning: scanningOptions, sentenceParsing: sentenceParsingOptions} = options;
|
||||||
this._options = options;
|
this._options = options;
|
||||||
|
this._ankiFieldTemplates = templates;
|
||||||
|
|
||||||
this._updateDocumentOptions(options);
|
this._updateDocumentOptions(options);
|
||||||
this._updateTheme(options.general.popupTheme);
|
this._updateTheme(options.general.popupTheme);
|
||||||
@ -747,9 +749,7 @@ class Display extends EventDispatcher {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const link = e.currentTarget;
|
const link = e.currentTarget;
|
||||||
const index = this._getClosestDefinitionIndex(link);
|
const index = this._getClosestDefinitionIndex(link);
|
||||||
if (index < 0 || index >= this._definitions.length) { return; }
|
this._addAnkiNote(index, link.dataset.mode);
|
||||||
|
|
||||||
this._noteAdd(this._definitions[index], link.dataset.mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onNoteView(e) {
|
_onNoteView(e) {
|
||||||
@ -1188,43 +1188,42 @@ class Display extends EventDispatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_noteTryAdd(mode) {
|
_tryAddAnkiNoteForSelectedDefinition(mode) {
|
||||||
const index = this._index;
|
this._addAnkiNote(this._index, mode);
|
||||||
if (index < 0 || index >= this._definitions.length) { return; }
|
|
||||||
|
|
||||||
const button = this._adderButtonFind(index, mode);
|
|
||||||
if (button !== null && !button.disabled) {
|
|
||||||
this._noteAdd(this._definitions[index], mode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_noteTryView() {
|
_tryViewAnkiNoteForSelectedDefinition() {
|
||||||
const button = this._viewerButtonFind(this._index);
|
const button = this._viewerButtonFind(this._index);
|
||||||
if (button !== null && !button.disabled) {
|
if (button !== null && !button.disabled) {
|
||||||
api.noteView(button.dataset.noteId);
|
api.noteView(button.dataset.noteId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _noteAdd(definition, mode) {
|
async _addAnkiNote(definitionIndex, mode) {
|
||||||
|
if (definitionIndex < 0 || definitionIndex >= this._definitions.length) { return false; }
|
||||||
|
const definition = this._definitions[definitionIndex];
|
||||||
|
|
||||||
|
const button = this._adderButtonFind(definitionIndex, mode);
|
||||||
|
if (button === null || button.disabled) { return false; }
|
||||||
|
|
||||||
const overrideToken = this._progressIndicatorVisible.setOverride(true);
|
const overrideToken = this._progressIndicatorVisible.setOverride(true);
|
||||||
try {
|
try {
|
||||||
const noteContext = await this._getNoteContext();
|
const noteContext = await this._getNoteContext();
|
||||||
const noteId = await this._addDefinition(definition, mode, noteContext);
|
const note = await this._createNote(definition, mode, noteContext, true);
|
||||||
|
const noteId = await api.addAnkiNote(note);
|
||||||
if (noteId) {
|
if (noteId) {
|
||||||
const index = this._definitions.indexOf(definition);
|
button.disabled = true;
|
||||||
const adderButton = this._adderButtonFind(index, mode);
|
this._viewerButtonShow(definitionIndex, noteId);
|
||||||
if (adderButton !== null) {
|
|
||||||
adderButton.disabled = true;
|
|
||||||
}
|
|
||||||
this._viewerButtonShow(index, noteId);
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Note could not be added');
|
throw new Error('Note could not be added');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.onError(e);
|
this.onError(e);
|
||||||
|
return false;
|
||||||
} finally {
|
} finally {
|
||||||
this._progressIndicatorVisible.clearOverride(overrideToken);
|
this._progressIndicatorVisible.clearOverride(overrideToken);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _playAudio(definitionIndex, expressionIndex) {
|
async _playAudio(definitionIndex, expressionIndex) {
|
||||||
@ -1462,56 +1461,30 @@ class Display extends EventDispatcher {
|
|||||||
this.trigger('modeChange', {mode});
|
this.trigger('modeChange', {mode});
|
||||||
}
|
}
|
||||||
|
|
||||||
async _getTemplates(options) {
|
async _getAnkiFieldTemplates(options) {
|
||||||
let templates = options.anki.fieldTemplates;
|
let templates = options.anki.fieldTemplates;
|
||||||
if (typeof templates === 'string') { return templates; }
|
if (typeof templates === 'string') { return templates; }
|
||||||
|
|
||||||
templates = this._defaultAnkiFieldTemplates;
|
templates = this._ankiFieldTemplatesDefault;
|
||||||
if (typeof templates === 'string') { return templates; }
|
if (typeof templates === 'string') { return templates; }
|
||||||
|
|
||||||
return await this._getDefaultTemplatesPromise();
|
templates = await api.getDefaultAnkiFieldTemplates();
|
||||||
}
|
this._ankiFieldTemplatesDefault = templates;
|
||||||
|
return templates;
|
||||||
_getDefaultTemplatesPromise() {
|
|
||||||
if (this._defaultAnkiFieldTemplatesPromise === null) {
|
|
||||||
this._defaultAnkiFieldTemplatesPromise = this._getDefaultTemplates();
|
|
||||||
this._defaultAnkiFieldTemplatesPromise.then(
|
|
||||||
() => { this._defaultAnkiFieldTemplatesPromise = null; },
|
|
||||||
() => {} // NOP
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return this._defaultAnkiFieldTemplatesPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
async _getDefaultTemplates() {
|
|
||||||
const value = await api.getDefaultAnkiFieldTemplates();
|
|
||||||
this._defaultAnkiFieldTemplates = value;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
async _addDefinition(definition, mode, context) {
|
|
||||||
const options = this._options;
|
|
||||||
const templates = await this._getTemplates(options);
|
|
||||||
const note = await this._createNote(definition, mode, context, options, templates, true);
|
|
||||||
return await api.addAnkiNote(note);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _areDefinitionsAddable(definitions, modes, context) {
|
async _areDefinitionsAddable(definitions, modes, context) {
|
||||||
const options = this._options;
|
|
||||||
const templates = await this._getTemplates(options);
|
|
||||||
|
|
||||||
const modeCount = modes.length;
|
const modeCount = modes.length;
|
||||||
const {duplicateScope} = options.anki;
|
|
||||||
const notePromises = [];
|
const notePromises = [];
|
||||||
for (const definition of definitions) {
|
for (const definition of definitions) {
|
||||||
for (const mode of modes) {
|
for (const mode of modes) {
|
||||||
const notePromise = this._createNote(definition, mode, context, options, templates, false);
|
const notePromise = this._createNote(definition, mode, context, false);
|
||||||
notePromises.push(notePromise);
|
notePromises.push(notePromise);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const notes = await Promise.all(notePromises);
|
const notes = await Promise.all(notePromises);
|
||||||
|
|
||||||
const infos = await api.getAnkiNoteInfo(notes, duplicateScope);
|
const infos = await api.getAnkiNoteInfo(notes);
|
||||||
const results = [];
|
const results = [];
|
||||||
for (let i = 0, ii = infos.length; i < ii; i += modeCount) {
|
for (let i = 0, ii = infos.length; i < ii; i += modeCount) {
|
||||||
results.push(infos.slice(i, i + modeCount));
|
results.push(infos.slice(i, i + modeCount));
|
||||||
@ -1533,7 +1506,9 @@ class Display extends EventDispatcher {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _createNote(definition, mode, context, options, templates, injectMedia) {
|
async _createNote(definition, mode, context, injectMedia) {
|
||||||
|
const options = this._options;
|
||||||
|
const templates = this._ankiFieldTemplates;
|
||||||
const {
|
const {
|
||||||
general: {resultOutputMode, glossaryLayoutMode, compactTags},
|
general: {resultOutputMode, glossaryLayoutMode, compactTags},
|
||||||
anki: ankiOptions
|
anki: ankiOptions
|
||||||
|
Loading…
Reference in New Issue
Block a user