diff options
| -rw-r--r-- | docs/anki-integration.md | 11 | ||||
| -rw-r--r-- | ext/data/schemas/options-schema.json | 5 | ||||
| -rw-r--r-- | ext/js/data/options-util.js | 13 | ||||
| -rw-r--r-- | ext/js/display/display-anki.js | 19 | ||||
| -rw-r--r-- | ext/settings.html | 16 | ||||
| -rw-r--r-- | test/options-util.test.js | 3 | ||||
| -rw-r--r-- | types/ext/settings.d.ts | 3 | 
7 files changed, 60 insertions, 10 deletions
| diff --git a/docs/anki-integration.md b/docs/anki-integration.md index 3e753015..cae3d96e 100644 --- a/docs/anki-integration.md +++ b/docs/anki-integration.md @@ -101,13 +101,14 @@ be able to create a flashcard for <ruby>箸<rt>はし</rt></ruby> because they s  Once Yomitan is configured, it becomes trivial to create new flashcards with a single click. You will see the following  icons next to term definitions: -- Clicking  adds the current expression as kanji (e.g. 食べる). -- Clicking  adds the current expression as hiragana or katakana (e.g. たべる). +- Clicking  adds the current expression (e.g. 食べる). +- Clicking  adds the current expression's reading (e.g. たべる). -If "Check for card duplicates" is on, and a card for the current definition already exists in the deck, you will see the following icons instead: +If _Check for card duplicates_ is on, and a card for the current definition already exists in the deck, you will see the book icon. +If _When a duplicate is detected_ is set to `Prevent adding`, the icons will appear grayed out. If set to `Allow adding`, the icons will change to: -- Adding the current expression:  -- Adding as hiragana or katakana:  +- : to add the expression +- : to add the reading  Below are some troubleshooting tips you can try if you are unable to create new flashcards: diff --git a/ext/data/schemas/options-schema.json b/ext/data/schemas/options-schema.json index 660961a8..f9d11dcf 100644 --- a/ext/data/schemas/options-schema.json +++ b/ext/data/schemas/options-schema.json @@ -988,6 +988,11 @@                                          "type": "boolean",                                          "default": true                                      }, +                                    "duplicateBehavior": { +                                        "type": "string", +                                        "enum": ["prevent", "new"], +                                        "default": "prevent" +                                    },                                      "fieldTemplates": {                                          "type": ["string", "null"],                                          "default": null diff --git a/ext/js/data/options-util.js b/ext/js/data/options-util.js index 4e468aea..62b062aa 100644 --- a/ext/js/data/options-util.js +++ b/ext/js/data/options-util.js @@ -536,7 +536,8 @@ export class OptionsUtil {              this._updateVersion27,              this._updateVersion28,              this._updateVersion29, -            this._updateVersion30 +            this._updateVersion30, +            this._updateVersion31          ];          /* eslint-enable @typescript-eslint/unbound-method */          if (typeof targetVersion === 'number' && targetVersion < result.length) { @@ -1234,6 +1235,16 @@ export class OptionsUtil {      }      /** +     *  - Added anki.duplicateBehavior +     *  @type {import('options-util').UpdateFunction} +     */ +    _updateVersion31(options) { +        for (const {options: profileOptions} of options.profiles) { +            profileOptions.anki.duplicateBehavior = 'new'; +        } +    } + +    /**       * @param {string} url       * @returns {Promise<chrome.tabs.Tab>}       */ diff --git a/ext/js/display/display-anki.js b/ext/js/display/display-anki.js index 446b8b48..23f7157f 100644 --- a/ext/js/display/display-anki.js +++ b/ext/js/display/display-anki.js @@ -74,6 +74,8 @@ export class DisplayAnki {          this._duplicateScope = 'collection';          /** @type {boolean} */          this._duplicateScopeCheckAllModels = false; +        /** @type {import('settings').AnkiDuplicateBehavior} */ +        this._duplicateBehavior = 'prevent';          /** @type {import('settings').AnkiScreenshotFormat} */          this._screenshotFormat = 'png';          /** @type {number} */ @@ -192,6 +194,7 @@ export class DisplayAnki {                  tags,                  duplicateScope,                  duplicateScopeCheckAllModels, +                duplicateBehavior,                  suspendNewCards,                  checkForDuplicates,                  displayTags, @@ -212,6 +215,7 @@ export class DisplayAnki {          this._displayTags = displayTags;          this._duplicateScope = duplicateScope;          this._duplicateScopeCheckAllModels = duplicateScopeCheckAllModels; +        this._duplicateBehavior = duplicateBehavior;          this._screenshotFormat = format;          this._screenshotQuality = quality;          this._scanLength = scanLength; @@ -419,7 +423,7 @@ export class DisplayAnki {                      // If entry has noteIds, show the "add duplicate" button.                      if (Array.isArray(noteIds) && noteIds.length > 0) { -                        this._showDuplicateAddButton(button); +                        this._updateButtonForDuplicate(button);                      }                  } @@ -442,6 +446,17 @@ export class DisplayAnki {      }      /** +     * @param {HTMLButtonElement} button +     */ +    _updateButtonForDuplicate(button) { +        if (this._duplicateBehavior === 'prevent') { +            button.disabled = true; +        } else { +            this._showDuplicateAddButton(button); +        } +    } + +    /**       * @param {number} i       * @param {(?import('anki').NoteInfo)[]} noteInfos       */ @@ -550,7 +565,7 @@ export class DisplayAnki {                          }                      }                      // Now that this dictionary entry has a duplicate in Anki, show the "add duplicate" buttons. -                    this._showDuplicateAddButton(button); +                    this._updateButtonForDuplicate(button);                      this._updateViewNoteButton(dictionaryEntryIndex, [noteId], true);                  } diff --git a/ext/settings.html b/ext/settings.html index ae559f4a..3c94b95e 100644 --- a/ext/settings.html +++ b/ext/settings.html @@ -1619,7 +1619,6 @@              <div class="settings-item-inner">                  <div class="settings-item-left">                      <div class="settings-item-label">Check for card duplicates</div> -                    <div class="settings-item-description">When a card is detected as a duplicate, the add buttons will turn red and change appearance.</div>                  </div>                  <div class="settings-item-right">                      <label class="toggle"><input type="checkbox" data-setting="anki.checkForDuplicates" @@ -1687,6 +1686,21 @@                          </p>                      </div>                  </div> +                <div class="settings-item"> +                    <div class="settings-item-inner settings-item-inner-wrappable"> +                        <div class="settings-item-left"> +                            <div class="settings-item-label"> +                                When a duplicate is detected +                            </div> +                        </div> +                        <div class="settings-item-right"> +                            <select data-setting="anki.duplicateBehavior"> +                                <option value="prevent">Prevent adding</option> +                                <option value="new">Allow adding</option> +                            </select> +                        </div> +                    </div> +                </div>              </div>          </div>          <div class="settings-item advanced-only"><div class="settings-item-inner settings-item-inner-wrappable"> diff --git a/test/options-util.test.js b/test/options-util.test.js index d1e9389c..5155d533 100644 --- a/test/options-util.test.js +++ b/test/options-util.test.js @@ -440,6 +440,7 @@ function createProfileOptionsUpdatedTestData1() {              screenshot: {format: 'png', quality: 92},              terms: {deck: '', model: '', fields: {}},              kanji: {deck: '', model: '', fields: {}}, +            duplicateBehavior: 'new',              duplicateScope: 'collection',              duplicateScopeCheckAllModels: false,              displayTags: 'never', @@ -602,7 +603,7 @@ function createOptionsUpdatedTestData1() {              }          ],          profileCurrent: 0, -        version: 30, +        version: 31,          global: {              database: {                  prefixWildcardsSupported: false diff --git a/types/ext/settings.d.ts b/types/ext/settings.d.ts index 8075476b..4e3b185a 100644 --- a/types/ext/settings.d.ts +++ b/types/ext/settings.d.ts @@ -281,6 +281,7 @@ export type AnkiOptions = {      kanji: AnkiNoteOptions;      duplicateScope: AnkiDuplicateScope;      duplicateScopeCheckAllModels: boolean; +    duplicateBehavior: AnkiDuplicateBehavior;      checkForDuplicates: boolean;      fieldTemplates: string | null;      suspendNewCards: boolean; @@ -394,6 +395,8 @@ export type AnkiScreenshotFormat = 'png' | 'jpeg';  export type AnkiDuplicateScope = 'collection' | 'deck' | 'deck-root'; +export type AnkiDuplicateBehavior = 'prevent' | 'new'; +  export type AnkiDisplayTags = 'never' | 'always' | 'non-standard';  export type AnkiNoteGuiMode = 'browse' | 'edit'; |