Update how anki data is updated

This commit is contained in:
toasted-nutbread 2019-12-02 22:17:45 -05:00
parent f89806e05d
commit 5339381c30
3 changed files with 93 additions and 74 deletions

View File

@ -44,26 +44,44 @@ function _ankiSetError(error) {
} }
} }
function _ankiSetDropdownOptions(dropdown, optionValues) {
const fragment = document.createDocumentFragment();
for (const optionValue of optionValues) {
const option = document.createElement('option');
option.value = optionValue;
option.textContent = optionValue;
fragment.appendChild(option);
}
dropdown.textContent = '';
dropdown.appendChild(fragment);
}
async function _ankiDeckAndModelPopulate(options) { async function _ankiDeckAndModelPopulate(options) {
const ankiFormat = $('#anki-format').hide(); const termsDeck = {value: options.anki.terms.deck, selector: '#anki-terms-deck'};
const kanjiDeck = {value: options.anki.kanji.deck, selector: '#anki-kanji-deck'};
const termsModel = {value: options.anki.terms.model, selector: '#anki-terms-model'};
const kanjiModel = {value: options.anki.kanji.model, selector: '#anki-kanji-model'};
try {
_ankiSpinnerShow(true);
const [deckNames, modelNames] = await Promise.all([utilAnkiGetDeckNames(), utilAnkiGetModelNames()]);
deckNames.sort();
modelNames.sort();
termsDeck.values = deckNames;
kanjiDeck.values = deckNames;
termsModel.values = modelNames;
kanjiModel.values = modelNames;
_ankiSetError(null);
} catch (error) {
_ankiSetError(error);
} finally {
_ankiSpinnerShow(false);
}
const deckNames = await utilAnkiGetDeckNames(); for (const {value, values, selector} of [termsDeck, kanjiDeck, termsModel, kanjiModel]) {
const ankiDeck = $('.anki-deck'); const node = document.querySelector(selector);
ankiDeck.find('option').remove(); _ankiSetDropdownOptions(node, Array.isArray(values) ? values : [value]);
deckNames.sort().forEach((name) => ankiDeck.append($('<option/>', {value: name, text: name}))); node.value = value;
}
const modelNames = await utilAnkiGetModelNames();
const ankiModel = $('.anki-model');
ankiModel.find('option').remove();
modelNames.sort().forEach((name) => ankiModel.append($('<option/>', {value: name, text: name})));
$('#anki-terms-deck').val(options.anki.terms.deck);
await _ankiFieldsPopulate($('#anki-terms-model').val(options.anki.terms.model), options);
$('#anki-kanji-deck').val(options.anki.kanji.deck);
await _ankiFieldsPopulate($('#anki-kanji-model').val(options.anki.kanji.model), options);
ankiFormat.show();
} }
function _ankiCreateFieldTemplate(name, value, markers) { function _ankiCreateFieldTemplate(name, value, markers) {
@ -81,53 +99,66 @@ function _ankiCreateFieldTemplate(name, value, markers) {
return content; return content;
} }
async function _ankiFieldsPopulate(element, options) { async function _ankiFieldsPopulate(tabId, options) {
const modelName = element.val(); const tab = document.querySelector(`.tab-pane[data-anki-card-type=${tabId}]`);
if (!modelName) { const container = tab.querySelector('tbody');
return;
}
const tab = element.closest('.tab-pane');
const tabId = tab.attr('id');
const container = tab.find('tbody').empty();
const markers = ankiGetFieldMarkers(tabId); const markers = ankiGetFieldMarkers(tabId);
for (const name of await utilAnkiGetModelFieldNames(modelName)) { const fragment = document.createDocumentFragment();
const value = options.anki[tabId].fields[name] || ''; const fields = options.anki[tabId].fields;
for (const name of Object.keys(fields)) {
const value = fields[name];
const html = _ankiCreateFieldTemplate(name, value, markers); const html = _ankiCreateFieldTemplate(name, value, markers);
container.append($(html)); fragment.appendChild(html);
} }
tab.find('.anki-field-value').change((e) => onFormOptionsChanged(e)); container.textContent = '';
tab.find('.marker-link').click((e) => _onAnkiMarkerClicked(e)); container.appendChild(fragment);
for (const node of container.querySelectorAll('.anki-field-value')) {
node.addEventListener('change', (e) => onFormOptionsChanged(e), false);
}
for (const node of container.querySelectorAll('.marker-link')) {
node.addEventListener('click', (e) => _onAnkiMarkerClicked(e), false);
}
} }
function _onAnkiMarkerClicked(e) { function _onAnkiMarkerClicked(e) {
e.preventDefault(); e.preventDefault();
const link = e.target; const link = e.currentTarget;
$(link).closest('.input-group').find('.anki-field-value').val(`{${link.text}}`).trigger('change'); const input = $(link).closest('.input-group').find('.anki-field-value')[0];
input.value = `{${link.textContent}}`;
input.dispatchEvent(new Event('change'));
} }
async function _onAnkiModelChanged(e) { async function _onAnkiModelChanged(e) {
const node = e.currentTarget;
let fieldNames;
try { try {
const element = $(e.currentTarget); const modelName = node.value;
const tab = element.closest('.tab-pane'); fieldNames = await utilAnkiGetModelFieldNames(modelName);
const tabId = tab.attr('id');
const optionsContext = getOptionsContext();
const options = await apiOptionsGet(optionsContext);
await formRead(options);
options.anki[tabId].fields = utilBackgroundIsolate({});
await settingsSaveOptions();
_ankiSpinnerShow(true);
await _ankiFieldsPopulate(element, options);
_ankiSetError(null); _ankiSetError(null);
} catch (error) { } catch (error) {
_ankiSetError(error); _ankiSetError(error);
return;
} finally { } finally {
_ankiSpinnerShow(false); _ankiSpinnerShow(false);
} }
const tabId = node.dataset.ankiCardType;
if (tabId !== 'terms' && tabId !== 'kanji') { return; }
const fields = {};
for (const name of fieldNames) {
fields[name] = '';
}
const optionsContext = getOptionsContext();
const options = await apiOptionsGet(optionsContext);
options.anki[tabId].fields = utilBackgroundIsolate(fields);
await settingsSaveOptions();
await _ankiFieldsPopulate(tabId, options);
} }
@ -138,12 +169,11 @@ function ankiErrorShown() {
return node && !node.hidden; return node && !node.hidden;
} }
function ankiFieldsToDict(selection) { function ankiFieldsToDict(elements) {
const result = {}; const result = {};
selection.each((index, element) => { for (const element of elements) {
result[$(element).data('field')] = $(element).val(); result[element.dataset.field] = element.value;
}); }
return result; return result;
} }
@ -213,14 +243,7 @@ async function onAnkiOptionsChanged(options) {
if (_ankiDataPopulated) { return; } if (_ankiDataPopulated) { return; }
try { await _ankiDeckAndModelPopulate(options);
_ankiSpinnerShow(true); _ankiDataPopulated = true;
await _ankiDeckAndModelPopulate(options); await Promise.all([_ankiFieldsPopulate('terms', options), _ankiFieldsPopulate('kanji', options)]);
_ankiSetError(null);
_ankiDataPopulated = true;
} catch (error) {
_ankiSetError(error);
} finally {
_ankiSpinnerShow(false);
}
} }

View File

@ -80,10 +80,10 @@ async function formRead(options) {
if (optionsAnkiEnableOld && !ankiErrorShown()) { if (optionsAnkiEnableOld && !ankiErrorShown()) {
options.anki.terms.deck = $('#anki-terms-deck').val(); options.anki.terms.deck = $('#anki-terms-deck').val();
options.anki.terms.model = $('#anki-terms-model').val(); options.anki.terms.model = $('#anki-terms-model').val();
options.anki.terms.fields = utilBackgroundIsolate(ankiFieldsToDict($('#terms .anki-field-value'))); options.anki.terms.fields = utilBackgroundIsolate(ankiFieldsToDict(document.querySelectorAll('#terms .anki-field-value')));
options.anki.kanji.deck = $('#anki-kanji-deck').val(); options.anki.kanji.deck = $('#anki-kanji-deck').val();
options.anki.kanji.model = $('#anki-kanji-model').val(); options.anki.kanji.model = $('#anki-kanji-model').val();
options.anki.kanji.fields = utilBackgroundIsolate(ankiFieldsToDict($('#kanji .anki-field-value'))); options.anki.kanji.fields = utilBackgroundIsolate(ankiFieldsToDict(document.querySelectorAll('#kanji .anki-field-value')));
} }
} }
@ -167,11 +167,7 @@ function formUpdateVisibility(options) {
} }
} }
async function onFormOptionsChanged(e) { async function onFormOptionsChanged() {
if (!e.originalEvent && !e.isTrigger) {
return;
}
const optionsContext = getOptionsContext(); const optionsContext = getOptionsContext();
const options = await apiOptionsGet(optionsContext); const options = await apiOptionsGet(optionsContext);

View File

@ -694,16 +694,16 @@
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div id="terms" class="tab-pane fade in active"> <div id="terms" class="tab-pane fade in active" data-anki-card-type="terms">
<div class="row"> <div class="row">
<div class="form-group col-xs-6"> <div class="form-group col-xs-6">
<label for="anki-terms-deck">Deck</label> <label for="anki-terms-deck">Deck</label>
<select class="form-control anki-deck" id="anki-terms-deck"></select> <select class="form-control anki-deck" id="anki-terms-deck" data-anki-card-type="terms"></select>
</div> </div>
<div class="form-group col-xs-6"> <div class="form-group col-xs-6">
<label for="anki-terms-model">Model</label> <label for="anki-terms-model">Model</label>
<select class="form-control anki-model" id="anki-terms-model"></select> <select class="form-control anki-model" id="anki-terms-model" data-anki-card-type="terms"></select>
</div> </div>
</div> </div>
@ -713,16 +713,16 @@
</table> </table>
</div> </div>
<div id="kanji" class="tab-pane fade"> <div id="kanji" class="tab-pane fade" data-anki-card-type="kanji">
<div class="row"> <div class="row">
<div class="form-group col-xs-6"> <div class="form-group col-xs-6">
<label for="anki-kanji-deck">Deck</label> <label for="anki-kanji-deck">Deck</label>
<select class="form-control anki-deck" id="anki-kanji-deck"></select> <select class="form-control anki-deck" id="anki-kanji-deck" data-anki-card-type="kanji"></select>
</div> </div>
<div class="form-group col-xs-6"> <div class="form-group col-xs-6">
<label for="anki-kanji-model">Model</label> <label for="anki-kanji-model">Model</label>
<select class="form-control anki-model" id="anki-kanji-model"></select> <select class="form-control anki-model" id="anki-kanji-model" data-anki-card-type="kanji"></select>
</div> </div>
</div> </div>