Add duplicate check option (#1012)

* Add anki.checkForDuplicates option

* Use checkForDuplicates for button display

* Add property to card creation
This commit is contained in:
toasted-nutbread 2020-11-08 16:25:07 -05:00 committed by GitHub
parent 4e30409410
commit 16321a1f8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 3 deletions

View File

@ -671,6 +671,7 @@
"terms", "terms",
"kanji", "kanji",
"duplicateScope", "duplicateScope",
"checkForDuplicates",
"fieldTemplates" "fieldTemplates"
], ],
"properties": { "properties": {
@ -771,6 +772,10 @@
"default": "collection", "default": "collection",
"enum": ["collection", "deck", "deck-root"] "enum": ["collection", "deck", "deck-root"]
}, },
"checkForDuplicates": {
"type": "boolean",
"default": true
},
"fieldTemplates": { "fieldTemplates": {
"type": ["string", "null"], "type": ["string", "null"],
"default": null "default": null

View File

@ -31,6 +31,7 @@ class AnkiNoteBuilder {
context, context,
templates, templates,
tags=[], tags=[],
checkForDuplicates=true,
duplicateScope='collection', duplicateScope='collection',
resultOutputMode='split', resultOutputMode='split',
compactGlossaries=false, compactGlossaries=false,
@ -60,6 +61,7 @@ class AnkiNoteBuilder {
deckName: deck, deckName: deck,
modelName: model, modelName: model,
options: { options: {
allowDuplicate: !checkForDuplicates,
duplicateScope, duplicateScope,
duplicateScopeOptions: { duplicateScopeOptions: {
deckName: duplicateScopeDeckName, deckName: duplicateScopeDeckName,

View File

@ -613,8 +613,12 @@ class OptionsUtil {
// Version 6 changes: // Version 6 changes:
// Updated handlebars templates to include "conjugation" definition. // Updated handlebars templates to include "conjugation" definition.
// Added global option showPopupPreview. // Added global option showPopupPreview.
// Added anki.checkForDuplicates.
await this._addFieldTemplatesToOptions(options, '/bg/data/anki-field-templates-upgrade-v6.handlebars'); await this._addFieldTemplatesToOptions(options, '/bg/data/anki-field-templates-upgrade-v6.handlebars');
options.global.showPopupPreview = false; options.global.showPopupPreview = false;
for (const profile of options.profiles) {
profile.options.anki.checkForDuplicates = true;
}
return options; return options;
} }
} }

View File

@ -921,6 +921,11 @@
<input type="text" id="interface-server" class="form-control" data-setting="anki.server"> <input type="text" id="interface-server" class="form-control" data-setting="anki.server">
</div> </div>
<div class="form-group options-advanced">
<label>Duplicates</label><br>
<label style="font-weight: normal;"><input type="checkbox" data-setting="anki.checkForDuplicates"> Check for duplicate cards</label><br>
</div>
<div class="form-group options-advanced"> <div class="form-group options-advanced">
<label for="duplicate-scope">Duplicate scope</label> <label for="duplicate-scope">Duplicate scope</label>
<select class="form-control" id="duplicate-scope" data-setting="anki.duplicateScope"> <select class="form-control" id="duplicate-scope" data-setting="anki.duplicateScope">

View File

@ -901,8 +901,15 @@ class Display extends EventDispatcher {
const modes = isTerms ? ['term-kanji', 'term-kana'] : ['kanji']; const modes = isTerms ? ['term-kanji', 'term-kana'] : ['kanji'];
let states; let states;
try { try {
if (this._options.anki.checkForDuplicates) {
const noteContext = await this._getNoteContext(); const noteContext = await this._getNoteContext();
states = await this._areDefinitionsAddable(definitions, modes, noteContext); states = await this._areDefinitionsAddable(definitions, modes, noteContext);
} else {
if (!await api.isAnkiConnected()) {
throw new Error('Anki not connected');
}
states = this._areDefinitionsAddableForcedValue(definitions, modes, true);
}
} catch (e) { } catch (e) {
return; return;
} }
@ -1377,10 +1384,24 @@ class Display extends EventDispatcher {
return results; return results;
} }
_areDefinitionsAddableForcedValue(definitions, modes, canAdd) {
const results = [];
const definitionCount = definitions.length;
const modeCount = modes.length;
for (let i = 0; i < definitionCount; ++i) {
const modeArray = [];
for (let j = 0; j < modeCount; ++j) {
modeArray.push({canAdd, noteIds: null});
}
results.push(modeArray);
}
return results;
}
async _createNote(definition, mode, context, options, templates, injectMedia) { async _createNote(definition, mode, context, options, templates, injectMedia) {
const { const {
general: {resultOutputMode, compactGlossaries}, general: {resultOutputMode, compactGlossaries},
anki: {tags, duplicateScope, kanji, terms, screenshot: {format, quality}}, anki: {tags, checkForDuplicates, duplicateScope, kanji, terms, screenshot: {format, quality}},
audio: {sources, customSourceUrl} audio: {sources, customSourceUrl}
} = options; } = options;
const modeOptions = (mode === 'kanji') ? kanji : terms; const modeOptions = (mode === 'kanji') ? kanji : terms;
@ -1416,6 +1437,7 @@ class Display extends EventDispatcher {
context, context,
templates, templates,
tags, tags,
checkForDuplicates,
duplicateScope, duplicateScope,
resultOutputMode, resultOutputMode,
compactGlossaries, compactGlossaries,

View File

@ -409,6 +409,7 @@ function createProfileOptionsUpdatedTestData1() {
terms: {deck: '', model: '', fields: {}}, terms: {deck: '', model: '', fields: {}},
kanji: {deck: '', model: '', fields: {}}, kanji: {deck: '', model: '', fields: {}},
duplicateScope: 'collection', duplicateScope: 'collection',
checkForDuplicates: true,
fieldTemplates: null fieldTemplates: null
} }
}; };