WIP
This commit is contained in:
parent
71d8cd4a32
commit
4e89d27fda
@ -87,6 +87,40 @@ function updateVisibility(opts) {
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(() => {
|
||||
Handlebars.partials = Handlebars.templates;
|
||||
|
||||
loadOptions().then(opts => {
|
||||
$('#activate-on-startup').prop('checked', opts.activateOnStartup);
|
||||
$('#enable-audio-playback').prop('checked', opts.enableAudioPlayback);
|
||||
$('#enable-soft-katakana-search').prop('checked', opts.enableSoftKatakanaSearch);
|
||||
$('#show-advanced-options').prop('checked', opts.showAdvancedOptions);
|
||||
|
||||
$('#hold-shift-to-scan').prop('checked', opts.holdShiftToScan);
|
||||
$('#select-matched-text').prop('checked', opts.selectMatchedText);
|
||||
$('#scan-delay').val(opts.scanDelay);
|
||||
$('#scan-length').val(opts.scanLength);
|
||||
|
||||
$('#anki-method').val(opts.ankiMethod);
|
||||
$('#anki-username').val(opts.ankiUsername);
|
||||
$('#anki-password').val(opts.ankiPassword);
|
||||
$('#anki-card-tags').val(opts.ankiCardTags.join(' '));
|
||||
$('#sentence-extent').val(opts.sentenceExtent);
|
||||
|
||||
$('input, select').not('.anki-model').change(onOptionsChanged);
|
||||
$('.anki-model').change(onAnkiModelChanged);
|
||||
|
||||
$('#dict-purge').click(onDictionaryPurge);
|
||||
$('#dict-importer a').click(onDictionarySetUrl);
|
||||
$('#dict-import').click(onDictionaryImport);
|
||||
$('#dict-url').on('input', onDictionaryUpdateUrl);
|
||||
|
||||
populateDictionaries(opts);
|
||||
populateAnkiDeckAndModel(opts);
|
||||
updateVisibility(opts);
|
||||
});
|
||||
});
|
||||
|
||||
//
|
||||
// Dictionary
|
||||
//
|
||||
@ -211,11 +245,11 @@ function onDictionaryImport() {
|
||||
}).catch(error => {
|
||||
showDictionaryError(error);
|
||||
}).then(() => {
|
||||
showDictionaryError(false);
|
||||
showDictionarySpinner(false);
|
||||
dictProgress.hide();
|
||||
dictImporter.show();
|
||||
dictUrl.val('');
|
||||
dictUrl.trigger('input');
|
||||
dictProgress.hide();
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -225,7 +259,6 @@ function onDictionarySetUrl(e) {
|
||||
|
||||
const dictUrl = $('#dict-url');
|
||||
const url = $(this).data('url');
|
||||
|
||||
if (url.includes('/')) {
|
||||
dictUrl.val(url);
|
||||
} else {
|
||||
@ -247,6 +280,25 @@ function anki() {
|
||||
return yomichan().anki;
|
||||
}
|
||||
|
||||
function showAnkiSpinner(show) {
|
||||
const spinner = $('#anki-spinner');
|
||||
if (show) {
|
||||
spinner.show();
|
||||
} else {
|
||||
spinner.hide();
|
||||
}
|
||||
}
|
||||
|
||||
function showAnkiError(error) {
|
||||
const dialog = $('#anki-error');
|
||||
if (error) {
|
||||
dialog.show().find('span').text(error);
|
||||
}
|
||||
else {
|
||||
dialog.hide();
|
||||
}
|
||||
}
|
||||
|
||||
function fieldsToDict(selection) {
|
||||
const result = {};
|
||||
selection.each((index, element) => {
|
||||
@ -265,49 +317,62 @@ function modelIdToFieldOptKey(id) {
|
||||
|
||||
function modelIdToMarkers(id) {
|
||||
return {
|
||||
'anki-term-model': ['audio', 'expression', 'expression-furigana', 'glossary', 'glossary-list', 'reading', 'sentence', 'tags', 'url'],
|
||||
'anki-kanji-model': ['character', 'glossary', 'glossary-list', 'kunyomi', 'onyomi', 'url'],
|
||||
'anki-term-model': [
|
||||
'audio',
|
||||
'expression',
|
||||
'expression-furigana',
|
||||
'glossary',
|
||||
'glossary-list',
|
||||
'reading',
|
||||
'sentence',
|
||||
'tags',
|
||||
'url'
|
||||
],
|
||||
'anki-kanji-model': [
|
||||
'character',
|
||||
'glossary',
|
||||
'glossary-list',
|
||||
'kunyomi',
|
||||
'onyomi',
|
||||
'url'
|
||||
],
|
||||
}[id];
|
||||
}
|
||||
|
||||
function populateAnkiDeckAndModel(opts) {
|
||||
const ankiSpinner = $('#anki-spinner');
|
||||
ankiSpinner.show();
|
||||
showAnkiError(null);
|
||||
showAnkiSpinner(true);
|
||||
|
||||
const ankiFormat = $('#anki-format');
|
||||
ankiFormat.hide();
|
||||
const ankiFormat = $('#anki-format').hide();
|
||||
|
||||
const ankiDeck = $('.anki-deck');
|
||||
ankiDeck.find('option').remove();
|
||||
return Promise.all([anki().getDeckNames(), anki().getModelNames()]).then(([deckNames, modelNames]) => {
|
||||
const ankiDeck = $('.anki-deck');
|
||||
ankiDeck.find('option').remove();
|
||||
deckNames.forEach(name => ankiDeck.append($('<option/>', {value: name, text: name})));
|
||||
|
||||
const ankiModel = $('.anki-model');
|
||||
ankiModel.find('option').remove();
|
||||
|
||||
return anki().getDeckNames().then(names => {
|
||||
names.forEach(name => ankiDeck.append($('<option/>', {value: name, text: name})));
|
||||
$('#anki-term-deck').val(opts.ankiTermDeck);
|
||||
$('#anki-kanji-deck').val(opts.ankiKanjiDeck);
|
||||
|
||||
const ankiModel = $('.anki-model');
|
||||
ankiModel.find('option').remove();
|
||||
modelNames.forEach(name => ankiModel.append($('<option/>', {value: name, text: name})));
|
||||
|
||||
return Promise.all([
|
||||
populateAnkiFields($('#anki-term-model').val(opts.ankiTermModel), opts),
|
||||
populateAnkiFields($('#anki-kanji-model').val(opts.ankiKanjiModel), opts)
|
||||
]);
|
||||
}).then(() => {
|
||||
return anki().getModelNames();
|
||||
}).then(names => {
|
||||
names.forEach(name => ankiModel.append($('<option/>', {value: name, text: name})));
|
||||
return populateAnkiFields($('#anki-term-model').val(opts.ankiTermModel), opts);
|
||||
}).then(() => {
|
||||
return populateAnkiFields($('#anki-kanji-model').val(opts.ankiKanjiModel), opts);
|
||||
}).then(() => {
|
||||
$('#anki-error').hide();
|
||||
ankiFormat.show();
|
||||
}).catch(error => {
|
||||
$('#anki-error').show().find('span').text(error);
|
||||
showAnkiError(error);
|
||||
}).then(() => {
|
||||
ankiSpinner.hide();
|
||||
showAnkiSpinner(false);
|
||||
});
|
||||
}
|
||||
|
||||
function populateAnkiFields(element, opts) {
|
||||
const tab = element.closest('.tab-pane');
|
||||
const container = tab.find('tbody');
|
||||
container.empty();
|
||||
const container = tab.find('tbody').empty();
|
||||
|
||||
const modelName = element.val();
|
||||
if (modelName === null) {
|
||||
@ -320,12 +385,7 @@ function populateAnkiFields(element, opts) {
|
||||
|
||||
return anki().getModelFieldNames(modelName).then(names => {
|
||||
names.forEach(name => {
|
||||
const html = Handlebars.templates['model.html']({
|
||||
name,
|
||||
markers,
|
||||
value: opts[optKey][name] || ''
|
||||
});
|
||||
|
||||
const html = Handlebars.templates['model.html']({name, markers, value: opts[optKey][name] || ''});
|
||||
container.append($(html));
|
||||
});
|
||||
|
||||
@ -343,19 +403,17 @@ function onAnkiModelChanged(e) {
|
||||
return;
|
||||
}
|
||||
|
||||
showAnkiError(null);
|
||||
showAnkiSpinner(true);
|
||||
|
||||
getFormValues().then(({optsNew, optsOld}) => {
|
||||
optsNew[modelIdToFieldOptKey($(this).id)] = {};
|
||||
|
||||
const ankiSpinner = $('#anki-spinner');
|
||||
ankiSpinner.show();
|
||||
|
||||
populateAnkiFields($(this), optsNew).then(() => {
|
||||
saveOptions(optsNew).then(() => yomichan().setOptions(optsNew));
|
||||
}).catch(error => {
|
||||
$('#anki-error').show().find('span').text(error);
|
||||
showAnkiError(error);
|
||||
}).then(() => {
|
||||
$('#anki-error').hide();
|
||||
ankiSpinner.hide();
|
||||
showAnkiSpinner(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -366,7 +424,7 @@ function onOptionsChanged(e) {
|
||||
}
|
||||
|
||||
getFormValues().then(({optsNew, optsOld}) => {
|
||||
saveOptions(optsNew).then(() => {
|
||||
return saveOptions(optsNew).then(() => {
|
||||
yomichan().setOptions(optsNew);
|
||||
updateVisibility(optsNew);
|
||||
|
||||
@ -375,50 +433,18 @@ function onOptionsChanged(e) {
|
||||
optsNew.ankiPassword !== optsOld.ankiPassword;
|
||||
|
||||
if (loginChanged && optsNew.ankiMethod === 'ankiweb') {
|
||||
anki().logout().then(() => populateAnkiDeckAndModel(optsNew)).catch(error => {
|
||||
$('#anki-error').show().find('span').text(error);
|
||||
});
|
||||
showAnkiError(null);
|
||||
showAnkiSpinner(true);
|
||||
return anki().logout().then(() => populateAnkiDeckAndModel(optsNew));
|
||||
} else if (loginChanged || optsNew.ankiMethod !== optsOld.ankiMethod) {
|
||||
populateAnkiDeckAndModel(optsNew);
|
||||
showAnkiError(null);
|
||||
showAnkiSpinner(true);
|
||||
return populateAnkiDeckAndModel(optsNew);
|
||||
}
|
||||
});
|
||||
}).catch(error => {
|
||||
showAnkiError(error);
|
||||
}).then(() => {
|
||||
showAnkiSpinner(false);
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Initialization
|
||||
//
|
||||
|
||||
$(document).ready(() => {
|
||||
Handlebars.partials = Handlebars.templates;
|
||||
|
||||
loadOptions().then(opts => {
|
||||
$('#activate-on-startup').prop('checked', opts.activateOnStartup);
|
||||
$('#enable-audio-playback').prop('checked', opts.enableAudioPlayback);
|
||||
$('#enable-soft-katakana-search').prop('checked', opts.enableSoftKatakanaSearch);
|
||||
$('#show-advanced-options').prop('checked', opts.showAdvancedOptions);
|
||||
|
||||
$('#hold-shift-to-scan').prop('checked', opts.holdShiftToScan);
|
||||
$('#select-matched-text').prop('checked', opts.selectMatchedText);
|
||||
$('#scan-delay').val(opts.scanDelay);
|
||||
$('#scan-length').val(opts.scanLength);
|
||||
|
||||
$('#anki-method').val(opts.ankiMethod);
|
||||
$('#anki-username').val(opts.ankiUsername);
|
||||
$('#anki-password').val(opts.ankiPassword);
|
||||
$('#anki-card-tags').val(opts.ankiCardTags.join(' '));
|
||||
$('#sentence-extent').val(opts.sentenceExtent);
|
||||
|
||||
$('input, select').not('.anki-model').change(onOptionsChanged);
|
||||
$('.anki-model').change(onAnkiModelChanged);
|
||||
|
||||
$('#dict-purge').click(onDictionaryPurge);
|
||||
$('#dict-importer a').click(onDictionarySetUrl);
|
||||
$('#dict-import').click(onDictionaryImport);
|
||||
$('#dict-url').on('input', onDictionaryUpdateUrl);
|
||||
|
||||
populateDictionaries(opts);
|
||||
populateAnkiDeckAndModel(opts);
|
||||
updateVisibility(opts);
|
||||
});
|
||||
});
|
||||
|
@ -73,21 +73,15 @@
|
||||
<p class="help-block">
|
||||
Yomichan can import both bundled and custom (see the <a href="https://foosoft.net/projects/yomichan-import">Yomichan Import</a>
|
||||
page for details) dictionaries. Although it is also possible to delete unneeded dictionaries, this operation is <em>extremely slow</em> and it is often
|
||||
easier to disable them or simply <a id="dict-purge">purge the database</a>. Finally, please make sure to
|
||||
easier to disable them or simply <a id="dict-purge">purge the database</a>. Please make sure to
|
||||
wait for import and delete operations to complete before closing this page.
|
||||
</p>
|
||||
|
||||
<div id="dict-purge-progress">
|
||||
Dictionary data is being purged, please be patient...
|
||||
</div>
|
||||
|
||||
<div id="dict-groups"></div>
|
||||
<div id="dict-purge-progress" class="text-danger">Dictionary data is being purged, please be patient...</div>
|
||||
|
||||
<div class="alert alert-warning" id="dict-warning">
|
||||
<strong>Warning:</strong>
|
||||
<span>
|
||||
No dictionaries found, use the importer below to install packaged and external dictionaries
|
||||
</span>
|
||||
<span>No dictionaries found, use the importer below to install packaged and external dictionaries</span>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-danger" id="dict-error">
|
||||
@ -95,6 +89,8 @@
|
||||
<span></span>
|
||||
</div>
|
||||
|
||||
<div id="dict-groups"></div>
|
||||
|
||||
<div id="dict-import-progress">
|
||||
Dictionary data is being imported, please be patient...
|
||||
<div class="progress">
|
||||
|
@ -50,7 +50,7 @@ function renderText(data, template) {
|
||||
}
|
||||
|
||||
function canAddDefinitions(definitions, modes) {
|
||||
return invokeApiBg('canAddDefinitions', {definitions, modes});
|
||||
return invokeApiBg('canAddDefinitions', {definitions, modes}).catch(() => null);
|
||||
}
|
||||
|
||||
function addDefinition(definition, mode) {
|
||||
|
Loading…
Reference in New Issue
Block a user