Support suspending new anki cards (#1240)
* Add new option: anki.suspendNewCards * Update Anki APIs * Suspend card based on options * Add setting * Disable wrap for toggle property
This commit is contained in:
parent
d9f5d21d15
commit
1dcfbf6ba6
@ -739,7 +739,8 @@
|
|||||||
"kanji",
|
"kanji",
|
||||||
"duplicateScope",
|
"duplicateScope",
|
||||||
"checkForDuplicates",
|
"checkForDuplicates",
|
||||||
"fieldTemplates"
|
"fieldTemplates",
|
||||||
|
"suspendNewCards"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"enable": {
|
"enable": {
|
||||||
@ -841,6 +842,10 @@
|
|||||||
"fieldTemplates": {
|
"fieldTemplates": {
|
||||||
"type": ["string", "null"],
|
"type": ["string", "null"],
|
||||||
"default": null
|
"default": null
|
||||||
|
},
|
||||||
|
"suspendNewCards": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -122,6 +122,22 @@ class AnkiConnect {
|
|||||||
return await this._invoke('multi', {actions});
|
return await this._invoke('multi', {actions});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async suspendCards(cardIds) {
|
||||||
|
if (!this._enabled) { return false; }
|
||||||
|
await this._checkVersion();
|
||||||
|
return await this._invoke('suspend', {cards: cardIds});
|
||||||
|
}
|
||||||
|
|
||||||
|
async findCards(query) {
|
||||||
|
if (!this._enabled) { return []; }
|
||||||
|
await this._checkVersion();
|
||||||
|
return await this._invoke('findCards', {query});
|
||||||
|
}
|
||||||
|
|
||||||
|
async findCardsForNote(noteId) {
|
||||||
|
return await this.findCards(`nid:${noteId}`);
|
||||||
|
}
|
||||||
|
|
||||||
getRootDeckName(deckName) {
|
getRootDeckName(deckName) {
|
||||||
const index = deckName.indexOf('::');
|
const index = deckName.indexOf('::');
|
||||||
return index >= 0 ? deckName.substring(0, index) : deckName;
|
return index >= 0 ? deckName.substring(0, index) : deckName;
|
||||||
|
@ -97,6 +97,7 @@ class Backend {
|
|||||||
['getAnkiNoteInfo', {async: true, contentScript: true, handler: this._onApiGetAnkiNoteInfo.bind(this)}],
|
['getAnkiNoteInfo', {async: true, contentScript: true, handler: this._onApiGetAnkiNoteInfo.bind(this)}],
|
||||||
['injectAnkiNoteMedia', {async: true, contentScript: true, handler: this._onApiInjectAnkiNoteMedia.bind(this)}],
|
['injectAnkiNoteMedia', {async: true, contentScript: true, handler: this._onApiInjectAnkiNoteMedia.bind(this)}],
|
||||||
['noteView', {async: true, contentScript: true, handler: this._onApiNoteView.bind(this)}],
|
['noteView', {async: true, contentScript: true, handler: this._onApiNoteView.bind(this)}],
|
||||||
|
['suspendAnkiCardsForNote', {async: true, contentScript: true, handler: this._onApiSuspendAnkiCardsForNote.bind(this)}],
|
||||||
['commandExec', {async: false, contentScript: true, handler: this._onApiCommandExec.bind(this)}],
|
['commandExec', {async: false, contentScript: true, handler: this._onApiCommandExec.bind(this)}],
|
||||||
['getDefinitionAudioInfo', {async: true, contentScript: true, handler: this._onApiGetDefinitionAudioInfo.bind(this)}],
|
['getDefinitionAudioInfo', {async: true, contentScript: true, handler: this._onApiGetDefinitionAudioInfo.bind(this)}],
|
||||||
['downloadDefinitionAudio', {async: true, contentScript: true, handler: this._onApiDownloadDefinitionAudio.bind(this)}],
|
['downloadDefinitionAudio', {async: true, contentScript: true, handler: this._onApiDownloadDefinitionAudio.bind(this)}],
|
||||||
@ -495,6 +496,16 @@ class Backend {
|
|||||||
return await this._anki.guiBrowseNote(noteId);
|
return await this._anki.guiBrowseNote(noteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _onApiSuspendAnkiCardsForNote({noteId}) {
|
||||||
|
const cardIds = await this._anki.findCardsForNote(noteId);
|
||||||
|
const count = cardIds.length;
|
||||||
|
if (count > 0) {
|
||||||
|
const okay = await this._anki.suspendCards(cardIds);
|
||||||
|
if (!okay) { return 0; }
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
_onApiCommandExec({command, params}) {
|
_onApiCommandExec({command, params}) {
|
||||||
return this._runCommand(command, params);
|
return this._runCommand(command, params);
|
||||||
}
|
}
|
||||||
|
@ -687,6 +687,8 @@ class OptionsUtil {
|
|||||||
// Added sentenceParsing.enableTerminationCharacters.
|
// Added sentenceParsing.enableTerminationCharacters.
|
||||||
// Added sentenceParsing.terminationCharacters.
|
// Added sentenceParsing.terminationCharacters.
|
||||||
// Changed general.popupActionBarLocation.
|
// Changed general.popupActionBarLocation.
|
||||||
|
// Added inputs.hotkeys.
|
||||||
|
// Added anki.suspendNewCards.
|
||||||
for (const profile of options.profiles) {
|
for (const profile of options.profiles) {
|
||||||
profile.options.translation.textReplacements = {
|
profile.options.translation.textReplacements = {
|
||||||
searchOriginal: true,
|
searchOriginal: true,
|
||||||
@ -731,6 +733,7 @@ class OptionsUtil {
|
|||||||
{action: 'copyHostSelection', key: 'KeyC', modifiers: ['ctrl'], scopes: ['popup', 'search'], enabled: true}
|
{action: 'copyHostSelection', key: 'KeyC', modifiers: ['ctrl'], scopes: ['popup', 'search'], enabled: true}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
profile.options.anki.suspendNewCards = false;
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
@ -1357,7 +1357,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div></div>
|
</div></div>
|
||||||
<div class="settings-item advanced-only">
|
<div class="settings-item advanced-only">
|
||||||
<div class="settings-item-inner settings-item-inner-wrappable">
|
<div class="settings-item-inner">
|
||||||
<div class="settings-item-left">
|
<div class="settings-item-left">
|
||||||
<div class="settings-item-label">Check for card duplicates</div>
|
<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 be disabled.</div>
|
<div class="settings-item-description">When a card is detected as a duplicate, the add buttons will be disabled.</div>
|
||||||
@ -1435,6 +1435,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div></div>
|
</div></div>
|
||||||
|
|
||||||
|
<div class="settings-item advanced-only"><div class="settings-item-inner">
|
||||||
|
<div class="settings-item-left">
|
||||||
|
<div class="settings-item-label">Suspend new cards</div>
|
||||||
|
<div class="settings-item-description">New cards will be suspended when a note is added.</div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-item-right">
|
||||||
|
<label class="toggle"><input type="checkbox" data-setting="anki.suspendNewCards"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
<div class="settings-item settings-item-button" data-modal-action="show,anki-cards"><div class="settings-item-inner">
|
<div class="settings-item settings-item-button" data-modal-action="show,anki-cards"><div class="settings-item-inner">
|
||||||
<div class="settings-item-left">
|
<div class="settings-item-left">
|
||||||
<div class="settings-item-label">Configure Anki card format…</div>
|
<div class="settings-item-label">Configure Anki card format…</div>
|
||||||
|
@ -93,6 +93,10 @@ const api = (() => {
|
|||||||
return this._invoke('noteView', {noteId});
|
return this._invoke('noteView', {noteId});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspendAnkiCardsForNote(noteId) {
|
||||||
|
return this._invoke('suspendAnkiCardsForNote', {noteId});
|
||||||
|
}
|
||||||
|
|
||||||
getDefinitionAudioInfo(source, expression, reading, details) {
|
getDefinitionAudioInfo(source, expression, reading, details) {
|
||||||
return this._invoke('getDefinitionAudioInfo', {source, expression, reading, details});
|
return this._invoke('getDefinitionAudioInfo', {source, expression, reading, details});
|
||||||
}
|
}
|
||||||
|
@ -1181,10 +1181,18 @@ class Display extends EventDispatcher {
|
|||||||
|
|
||||||
const overrideToken = this._progressIndicatorVisible.setOverride(true);
|
const overrideToken = this._progressIndicatorVisible.setOverride(true);
|
||||||
try {
|
try {
|
||||||
|
const {anki: {suspendNewCards}} = this._options;
|
||||||
const noteContext = this._getNoteContext();
|
const noteContext = this._getNoteContext();
|
||||||
const note = await this._createNote(definition, mode, noteContext, true);
|
const note = await this._createNote(definition, mode, noteContext, true);
|
||||||
const noteId = await api.addAnkiNote(note);
|
const noteId = await api.addAnkiNote(note);
|
||||||
if (noteId) {
|
if (noteId) {
|
||||||
|
if (suspendNewCards) {
|
||||||
|
try {
|
||||||
|
await api.suspendAnkiCardsForNote(noteId);
|
||||||
|
} catch (e) {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
|
}
|
||||||
button.disabled = true;
|
button.disabled = true;
|
||||||
this._viewerButtonShow(definitionIndex, noteId);
|
this._viewerButtonShow(definitionIndex, noteId);
|
||||||
} else {
|
} else {
|
||||||
|
@ -417,7 +417,8 @@ function createProfileOptionsUpdatedTestData1() {
|
|||||||
kanji: {deck: '', model: '', fields: {}},
|
kanji: {deck: '', model: '', fields: {}},
|
||||||
duplicateScope: 'collection',
|
duplicateScope: 'collection',
|
||||||
checkForDuplicates: true,
|
checkForDuplicates: true,
|
||||||
fieldTemplates: null
|
fieldTemplates: null,
|
||||||
|
suspendNewCards: false
|
||||||
},
|
},
|
||||||
sentenceParsing: {
|
sentenceParsing: {
|
||||||
scanExtent: 200,
|
scanExtent: 200,
|
||||||
|
Loading…
Reference in New Issue
Block a user