Audio popup menu primary card audio selection (#1406)
* Add card icon to audio menu items * Update cache data format * Create _getCacheItem * Add _playAudioFromSource function * Implement default card audio info * Specify exact audio to download when an override is assigned * Abstract using _getMenuItemSourceInfo * Update downloadability check * Update the main audio menu buttons to also assign the default source
This commit is contained in:
parent
f2a387237b
commit
55f5182ca9
@ -1670,7 +1670,7 @@ button.footer-notification-close-button:active {
|
|||||||
|
|
||||||
|
|
||||||
/* Audio menu */
|
/* Audio menu */
|
||||||
.audio-button-popup-menu[data-show-icons=false] .popup-menu-item-icon {
|
.audio-button-popup-menu[data-show-icons=false] .popup-menu-item-audio-button .popup-menu-item-icon {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.audio-button-popup-menu .popup-menu-item-icon[data-icon=checkmark] {
|
.audio-button-popup-menu .popup-menu-item-icon[data-icon=checkmark] {
|
||||||
@ -1682,6 +1682,42 @@ button.footer-notification-close-button:active {
|
|||||||
.audio-button-popup-menu .popup-menu-item-group[data-source-in-options=false][data-valid=null] .popup-menu-item {
|
.audio-button-popup-menu .popup-menu-item-group[data-source-in-options=false][data-valid=null] .popup-menu-item {
|
||||||
color: var(--text-color-light1);
|
color: var(--text-color-light1);
|
||||||
}
|
}
|
||||||
|
.popup-menu-item-audio-button .popup-menu-item-label {
|
||||||
|
padding-right: 2.5em;
|
||||||
|
}
|
||||||
|
.popup-menu-item-set-primary-audio-button {
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 2.5em;
|
||||||
|
}
|
||||||
|
.popup-menu-item-set-primary-audio-button:not([hidden]) {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.popup-menu-item-set-primary-audio-button .popup-menu-item-icon {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity var(--animation-duration) linear;
|
||||||
|
}
|
||||||
|
.popup-menu-item-group:hover .popup-menu-item-set-primary-audio-button .popup-menu-item-icon {
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
.popup-menu-item-group .popup-menu-item-set-primary-audio-button:hover .popup-menu-item-icon,
|
||||||
|
.popup-menu-item-group .popup-menu-item-set-primary-audio-button:active .popup-menu-item-icon,
|
||||||
|
.popup-menu-item-group .popup-menu-item-set-primary-audio-button:focus .popup-menu-item-icon {
|
||||||
|
opacity: 0.375;
|
||||||
|
}
|
||||||
|
.popup-menu-item-group[data-is-primary-card-audio=true] .popup-menu-item-set-primary-audio-button .popup-menu-item-icon {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.popup-menu-item-group[data-is-primary-card-audio=true] .popup-menu-item-set-primary-audio-button:hover .popup-menu-item-icon,
|
||||||
|
.popup-menu-item-group[data-is-primary-card-audio=true] .popup-menu-item-set-primary-audio-button:active .popup-menu-item-icon,
|
||||||
|
.popup-menu-item-group[data-is-primary-card-audio=true] .popup-menu-item-set-primary-audio-button:focus .popup-menu-item-icon {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Anki errors */
|
/* Anki errors */
|
||||||
|
@ -947,11 +947,11 @@ button.icon-button:active {
|
|||||||
}
|
}
|
||||||
button.popup-menu-item {
|
button.popup-menu-item {
|
||||||
padding: 0.625em 1.5em;
|
padding: 0.625em 1.5em;
|
||||||
|
flex: 1 1 auto;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
border: none;
|
border: none;
|
||||||
width: 100%;
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
@ -977,12 +977,14 @@ button.popup-menu-item:disabled {
|
|||||||
width: calc(16em / 14);
|
width: calc(16em / 14);
|
||||||
height: calc(16em / 14);
|
height: calc(16em / 14);
|
||||||
background-color: var(--text-color);
|
background-color: var(--text-color);
|
||||||
margin-right: 0.5em;
|
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
.popup-menu-item-icon:not([hidden]) {
|
.popup-menu-item-icon:not([hidden]) {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
.popup-menu-item-icon+.popup-menu-item-label {
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
:root[data-page-type=popup] .popup-menu.popup-menu-auto-size,
|
:root[data-page-type=popup] .popup-menu.popup-menu-auto-size,
|
||||||
.popup-menu.popup-menu-small {
|
.popup-menu.popup-menu-small {
|
||||||
border-radius: calc(var(--menu-border-radius) * 0.75);
|
border-radius: calc(var(--menu-border-radius) * 0.75);
|
||||||
@ -995,6 +997,7 @@ button.popup-menu-item:disabled {
|
|||||||
font-size: var(--font-size-small);
|
font-size: var(--font-size-small);
|
||||||
}
|
}
|
||||||
.popup-menu-item-group {
|
.popup-menu-item-group {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row nowrap;
|
flex-flow: row nowrap;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
|
@ -158,6 +158,9 @@
|
|||||||
|
|
||||||
<!-- Popup menu -->
|
<!-- Popup menu -->
|
||||||
<template id="audio-button-popup-menu-template"><div class="popup-menu-container scan-disable audio-button-popup-menu" tabindex="-1" role="dialog"><div class="popup-menu popup-menu-auto-size"><div class="popup-menu-body"></div></div></div></template>
|
<template id="audio-button-popup-menu-template"><div class="popup-menu-container scan-disable audio-button-popup-menu" tabindex="-1" role="dialog"><div class="popup-menu popup-menu-auto-size"><div class="popup-menu-body"></div></div></div></template>
|
||||||
<template id="audio-button-popup-menu-item-template"><div class="popup-menu-item-group"><button class="popup-menu-item" data-menu-action="playAudioFromSource"><div class="popup-menu-item-icon icon" data-icon="none"></div><span class="popup-menu-item-label"></span></button></div></template>
|
<template id="audio-button-popup-menu-item-template"><div class="popup-menu-item-group">
|
||||||
|
<button class="popup-menu-item popup-menu-item-audio-button" data-menu-action="playAudioFromSource"><div class="popup-menu-item-icon icon" data-icon="none"></div><span class="popup-menu-item-label"></span></button>
|
||||||
|
<button class="popup-menu-item popup-menu-item-set-primary-audio-button" data-menu-action="setPrimaryAudio" title="Use as audio for Anki card"><div class="popup-menu-item-icon icon" data-icon="note-card"></div></button>
|
||||||
|
</div></template>
|
||||||
|
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@ -166,6 +166,12 @@ class DisplayAudio {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPrimaryCardAudio(expression, reading) {
|
||||||
|
const cacheEntry = this._getCacheItem(expression, reading, false);
|
||||||
|
const primaryCardAudio = typeof cacheEntry !== 'undefined' ? cacheEntry.primaryCardAudio : null;
|
||||||
|
return primaryCardAudio;
|
||||||
|
}
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
|
|
||||||
_onAudioPlayButtonClick(definitionIndex, expressionIndex, e) {
|
_onAudioPlayButtonClick(definitionIndex, expressionIndex, e) {
|
||||||
@ -185,27 +191,78 @@ class DisplayAudio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onAudioPlayMenuCloseClick(definitionIndex, expressionIndex, e) {
|
_onAudioPlayMenuCloseClick(definitionIndex, expressionIndex, e) {
|
||||||
const {detail: {action, item}} = e;
|
const {detail: {action, item, menu}} = e;
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'playAudioFromSource':
|
case 'playAudioFromSource':
|
||||||
{
|
this._playAudioFromSource(definitionIndex, expressionIndex, item, menu);
|
||||||
const group = item.closest('.popup-menu-item-group');
|
break;
|
||||||
if (group === null) { break; }
|
case 'setPrimaryAudio':
|
||||||
|
e.preventDefault();
|
||||||
const {source, index} = group.dataset;
|
this._setPrimaryAudio(definitionIndex, expressionIndex, item, menu, true);
|
||||||
let sourceDetailsMap = null;
|
|
||||||
if (typeof index !== 'undefined') {
|
|
||||||
const index2 = Number.parseInt(index, 10);
|
|
||||||
sourceDetailsMap = new Map([
|
|
||||||
[source, {start: index2, end: index2 + 1}]
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
this.playAudio(definitionIndex, expressionIndex, [source], sourceDetailsMap);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_getCacheItem(expression, reading, create) {
|
||||||
|
const key = this._getExpressionReadingKey(expression, reading);
|
||||||
|
let cacheEntry = this._cache.get(key);
|
||||||
|
if (typeof cacheEntry === 'undefined' && create) {
|
||||||
|
cacheEntry = {
|
||||||
|
sourceMap: new Map(),
|
||||||
|
primaryCardAudio: null
|
||||||
|
};
|
||||||
|
this._cache.set(key, cacheEntry);
|
||||||
|
}
|
||||||
|
return cacheEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getMenuItemSourceInfo(item) {
|
||||||
|
const group = item.closest('.popup-menu-item-group');
|
||||||
|
if (group === null) { return null; }
|
||||||
|
|
||||||
|
let {source, index} = group.dataset;
|
||||||
|
if (typeof index !== 'undefined') {
|
||||||
|
index = Number.parseInt(index, 10);
|
||||||
|
}
|
||||||
|
const hasIndex = (Number.isFinite(index) && Math.floor(index) === index);
|
||||||
|
if (!hasIndex) {
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
return {source, index, hasIndex};
|
||||||
|
}
|
||||||
|
|
||||||
|
_playAudioFromSource(definitionIndex, expressionIndex, item, menu) {
|
||||||
|
const sourceInfo = this._getMenuItemSourceInfo(item);
|
||||||
|
if (sourceInfo === null) { return; }
|
||||||
|
|
||||||
|
const {source, index, hasIndex} = sourceInfo;
|
||||||
|
const sourceDetailsMap = hasIndex ? new Map([[source, {start: index, end: index + 1}]]) : null;
|
||||||
|
|
||||||
|
this._setPrimaryAudio(definitionIndex, expressionIndex, item, menu, false);
|
||||||
|
|
||||||
|
this.playAudio(definitionIndex, expressionIndex, [source], sourceDetailsMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
_setPrimaryAudio(definitionIndex, expressionIndex, item, menu, canToggleOff) {
|
||||||
|
const sourceInfo = this._getMenuItemSourceInfo(item);
|
||||||
|
if (sourceInfo === null) { return; }
|
||||||
|
|
||||||
|
const {source, index} = sourceInfo;
|
||||||
|
if (!this._sourceIsDownloadable(source)) { return; }
|
||||||
|
|
||||||
|
const expressionReading = this._getExpressionAndReading(definitionIndex, expressionIndex);
|
||||||
|
if (expressionReading === null) { return; }
|
||||||
|
|
||||||
|
const {expression, reading} = expressionReading;
|
||||||
|
const cacheEntry = this._getCacheItem(expression, reading, true);
|
||||||
|
|
||||||
|
let {primaryCardAudio} = cacheEntry;
|
||||||
|
primaryCardAudio = (!canToggleOff || primaryCardAudio === null || primaryCardAudio.source !== source || primaryCardAudio.index !== index) ? {source, index} : null;
|
||||||
|
cacheEntry.primaryCardAudio = primaryCardAudio;
|
||||||
|
|
||||||
|
this._updateMenuPrimaryCardAudio(menu.bodyNode, expression, reading);
|
||||||
|
}
|
||||||
|
|
||||||
_getAudioPlayButtonExpressionIndex(button) {
|
_getAudioPlayButtonExpressionIndex(button) {
|
||||||
const expressionNode = button.closest('.term-expression');
|
const expressionNode = button.closest('.term-expression');
|
||||||
if (expressionNode !== null) {
|
if (expressionNode !== null) {
|
||||||
@ -229,13 +286,7 @@ class DisplayAudio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _createExpressionAudio(sources, sourceDetailsMap, expression, reading, details) {
|
async _createExpressionAudio(sources, sourceDetailsMap, expression, reading, details) {
|
||||||
const key = this._getExpressionReadingKey(expression, reading);
|
const {sourceMap} = this._getCacheItem(expression, reading, true);
|
||||||
|
|
||||||
let sourceMap = this._cache.get(key);
|
|
||||||
if (typeof sourceMap === 'undefined') {
|
|
||||||
sourceMap = new Map();
|
|
||||||
this._cache.set(key, sourceMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0, ii = sources.length; i < ii; ++i) {
|
for (let i = 0, ii = sources.length; i < ii; ++i) {
|
||||||
const source = sources[i];
|
const source = sources[i];
|
||||||
@ -383,10 +434,10 @@ class DisplayAudio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_getPotentialAvailableAudioCount(expression, reading) {
|
_getPotentialAvailableAudioCount(expression, reading) {
|
||||||
const key = this._getExpressionReadingKey(expression, reading);
|
const cacheEntry = this._getCacheItem(expression, reading, false);
|
||||||
const sourceMap = this._cache.get(key);
|
if (typeof cacheEntry === 'undefined') { return null; }
|
||||||
if (typeof sourceMap === 'undefined') { return null; }
|
|
||||||
|
|
||||||
|
const {sourceMap} = cacheEntry;
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for (const {infoList} of sourceMap.values()) {
|
for (const {infoList} of sourceMap.values()) {
|
||||||
if (infoList === null) { continue; }
|
if (infoList === null) { continue; }
|
||||||
@ -408,6 +459,16 @@ class DisplayAudio {
|
|||||||
popupMenu.prepare();
|
popupMenu.prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sourceIsDownloadable(source) {
|
||||||
|
switch (source) {
|
||||||
|
case 'text-to-speech':
|
||||||
|
case 'text-to-speech-reading':
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_getAudioSources(audioOptions) {
|
_getAudioSources(audioOptions) {
|
||||||
const {sources, textToSpeechVoice, customSourceUrl} = audioOptions;
|
const {sources, textToSpeechVoice, customSourceUrl} = audioOptions;
|
||||||
const ttsSupported = (textToSpeechVoice.length > 0);
|
const ttsSupported = (textToSpeechVoice.length > 0);
|
||||||
@ -431,6 +492,7 @@ class DisplayAudio {
|
|||||||
const results = [];
|
const results = [];
|
||||||
for (const [source, displayName, supported] of rawSources) {
|
for (const [source, displayName, supported] of rawSources) {
|
||||||
if (!supported) { continue; }
|
if (!supported) { continue; }
|
||||||
|
const downloadable = this._sourceIsDownloadable(source);
|
||||||
let optionsIndex = sourceIndexMap.get(source);
|
let optionsIndex = sourceIndexMap.get(source);
|
||||||
const isInOptions = typeof optionsIndex !== 'undefined';
|
const isInOptions = typeof optionsIndex !== 'undefined';
|
||||||
if (!isInOptions) {
|
if (!isInOptions) {
|
||||||
@ -441,7 +503,8 @@ class DisplayAudio {
|
|||||||
displayName,
|
displayName,
|
||||||
index: results.length,
|
index: results.length,
|
||||||
optionsIndex,
|
optionsIndex,
|
||||||
isInOptions
|
isInOptions,
|
||||||
|
downloadable
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,24 +524,27 @@ class DisplayAudio {
|
|||||||
// Create menu
|
// Create menu
|
||||||
const {displayGenerator} = this._display;
|
const {displayGenerator} = this._display;
|
||||||
const menuNode = displayGenerator.instantiateTemplate('audio-button-popup-menu');
|
const menuNode = displayGenerator.instantiateTemplate('audio-button-popup-menu');
|
||||||
const menuBody = menuNode.querySelector('.popup-menu-body');
|
const menuBodyNode = menuNode.querySelector('.popup-menu-body');
|
||||||
|
|
||||||
// Set up items based on options and cache data
|
// Set up items based on options and cache data
|
||||||
let showIcons = false;
|
let showIcons = false;
|
||||||
for (const {source, displayName, isInOptions} of sources) {
|
for (const {source, displayName, isInOptions, downloadable} of sources) {
|
||||||
const entries = this._getMenuItemEntries(source, expression, reading);
|
const entries = this._getMenuItemEntries(source, expression, reading);
|
||||||
for (let i = 0, ii = entries.length; i < ii; ++i) {
|
for (let i = 0, ii = entries.length; i < ii; ++i) {
|
||||||
const {valid, index, name} = entries[i];
|
const {valid, index, name} = entries[i];
|
||||||
const node = displayGenerator.instantiateTemplate('audio-button-popup-menu-item');
|
const node = displayGenerator.instantiateTemplate('audio-button-popup-menu-item');
|
||||||
|
|
||||||
const labelNode = node.querySelector('.popup-menu-item-label');
|
const labelNode = node.querySelector('.popup-menu-item-audio-button .popup-menu-item-label');
|
||||||
let label = displayName;
|
let label = displayName;
|
||||||
if (ii > 1) { label = `${label} ${i + 1}`; }
|
if (ii > 1) { label = `${label} ${i + 1}`; }
|
||||||
if (typeof name === 'string' && name.length > 0) { label += `: ${name}`; }
|
if (typeof name === 'string' && name.length > 0) { label += `: ${name}`; }
|
||||||
labelNode.textContent = label;
|
labelNode.textContent = label;
|
||||||
|
|
||||||
|
const cardButton = node.querySelector('.popup-menu-item-set-primary-audio-button');
|
||||||
|
cardButton.hidden = !downloadable;
|
||||||
|
|
||||||
if (valid !== null) {
|
if (valid !== null) {
|
||||||
const icon = node.querySelector('.popup-menu-item-icon');
|
const icon = node.querySelector('.popup-menu-item-audio-button .popup-menu-item-icon');
|
||||||
icon.dataset.icon = valid ? 'checkmark' : 'cross';
|
icon.dataset.icon = valid ? 'checkmark' : 'cross';
|
||||||
showIcons = true;
|
showIcons = true;
|
||||||
}
|
}
|
||||||
@ -488,20 +554,25 @@ class DisplayAudio {
|
|||||||
}
|
}
|
||||||
node.dataset.valid = `${valid}`;
|
node.dataset.valid = `${valid}`;
|
||||||
node.dataset.sourceInOptions = `${isInOptions}`;
|
node.dataset.sourceInOptions = `${isInOptions}`;
|
||||||
|
node.dataset.downloadable = `${downloadable}`;
|
||||||
|
|
||||||
menuBody.appendChild(node);
|
menuBodyNode.appendChild(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
menuNode.dataset.showIcons = `${showIcons}`;
|
menuNode.dataset.showIcons = `${showIcons}`;
|
||||||
|
|
||||||
|
// Update primary card audio display
|
||||||
|
this._updateMenuPrimaryCardAudio(menuBodyNode, expression, reading);
|
||||||
|
|
||||||
// Create popup menu
|
// Create popup menu
|
||||||
this._menuContainer.appendChild(menuNode);
|
this._menuContainer.appendChild(menuNode);
|
||||||
return new PopupMenu(sourceButton, menuNode);
|
return new PopupMenu(sourceButton, menuNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getMenuItemEntries(source, expression, reading) {
|
_getMenuItemEntries(source, expression, reading) {
|
||||||
const sourceMap = this._cache.get(this._getExpressionReadingKey(expression, reading));
|
const cacheEntry = this._getCacheItem(expression, reading, false);
|
||||||
if (typeof sourceMap !== 'undefined') {
|
if (typeof cacheEntry !== 'undefined') {
|
||||||
|
const {sourceMap} = cacheEntry;
|
||||||
const sourceInfo = sourceMap.get(source);
|
const sourceInfo = sourceMap.get(source);
|
||||||
if (typeof sourceInfo !== 'undefined') {
|
if (typeof sourceInfo !== 'undefined') {
|
||||||
const {infoList} = sourceInfo;
|
const {infoList} = sourceInfo;
|
||||||
@ -524,4 +595,25 @@ class DisplayAudio {
|
|||||||
}
|
}
|
||||||
return [{valid: null, index: null, name: null}];
|
return [{valid: null, index: null, name: null}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_updateMenuPrimaryCardAudio(menuBodyNode, expression, reading) {
|
||||||
|
const primaryCardAudio = this.getPrimaryCardAudio(expression, reading);
|
||||||
|
const {source: primaryCardAudioSource, index: primaryCardAudioIndex} = (primaryCardAudio !== null ? primaryCardAudio : {source: null, index: -1});
|
||||||
|
|
||||||
|
const itemGroups = menuBodyNode.querySelectorAll('.popup-menu-item-group');
|
||||||
|
let sourceIndex = 0;
|
||||||
|
let sourcePre = null;
|
||||||
|
for (const node of itemGroups) {
|
||||||
|
const {source} = node.dataset;
|
||||||
|
if (source !== sourcePre) {
|
||||||
|
sourcePre = source;
|
||||||
|
sourceIndex = 0;
|
||||||
|
} else {
|
||||||
|
++sourceIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isPrimaryCardAudio = (source === primaryCardAudioSource && sourceIndex === primaryCardAudioIndex);
|
||||||
|
node.dataset.isPrimaryCardAudio = `${isPrimaryCardAudio}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1452,7 +1452,7 @@ class Display extends EventDispatcher {
|
|||||||
let injectedMedia = null;
|
let injectedMedia = null;
|
||||||
if (injectMedia) {
|
if (injectMedia) {
|
||||||
let errors2;
|
let errors2;
|
||||||
({result: injectedMedia, errors: errors2} = await this._injectAnkiNoteMedia(definition, mode, options, fields));
|
({result: injectedMedia, errors: errors2} = await this._injectAnkiNoteMedia(definition, options, fields));
|
||||||
if (Array.isArray(errors)) {
|
if (Array.isArray(errors)) {
|
||||||
for (const error of errors2) {
|
for (const error of errors2) {
|
||||||
errors.push(deserializeError(error));
|
errors.push(deserializeError(error));
|
||||||
@ -1479,20 +1479,35 @@ class Display extends EventDispatcher {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async _injectAnkiNoteMedia(definition, mode, options, fields) {
|
async _injectAnkiNoteMedia(definition, options, fields) {
|
||||||
const {
|
const {
|
||||||
anki: {screenshot: {format, quality}},
|
anki: {screenshot: {format, quality}},
|
||||||
audio: {sources, customSourceUrl, customSourceType}
|
audio: {sources, customSourceUrl, customSourceType}
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
|
|
||||||
const definitionDetails = this._getDefinitionDetailsForNote(definition);
|
const definitionDetails = this._getDefinitionDetailsForNote(definition);
|
||||||
const audioDetails = (mode !== 'kanji' && this._ankiNoteBuilder.containsMarker(fields, 'audio') ? {sources, preferredAudioIndex: null, customSourceUrl, customSourceType} : null);
|
|
||||||
|
let audioDetails = null;
|
||||||
|
if (definitionDetails.type !== 'kanji' && this._ankiNoteBuilder.containsMarker(fields, 'audio')) {
|
||||||
|
const primaryCardAudio = this._displayAudio.getPrimaryCardAudio(definitionDetails.expression, definitionDetails.reading);
|
||||||
|
let preferredAudioIndex = null;
|
||||||
|
let sources2 = sources;
|
||||||
|
if (primaryCardAudio !== null) {
|
||||||
|
sources2 = [primaryCardAudio.source];
|
||||||
|
preferredAudioIndex = primaryCardAudio.index;
|
||||||
|
}
|
||||||
|
audioDetails = {sources: sources2, preferredAudioIndex, customSourceUrl, customSourceType};
|
||||||
|
}
|
||||||
|
|
||||||
const screenshotDetails = (this._ankiNoteBuilder.containsMarker(fields, 'screenshot') ? {tabId: this._contentOriginTabId, frameId: this._contentOriginFrameId, format, quality} : null);
|
const screenshotDetails = (this._ankiNoteBuilder.containsMarker(fields, 'screenshot') ? {tabId: this._contentOriginTabId, frameId: this._contentOriginFrameId, format, quality} : null);
|
||||||
|
|
||||||
const clipboardDetails = {
|
const clipboardDetails = {
|
||||||
image: this._ankiNoteBuilder.containsMarker(fields, 'clipboard-image'),
|
image: this._ankiNoteBuilder.containsMarker(fields, 'clipboard-image'),
|
||||||
text: this._ankiNoteBuilder.containsMarker(fields, 'clipboard-text')
|
text: this._ankiNoteBuilder.containsMarker(fields, 'clipboard-text')
|
||||||
};
|
};
|
||||||
|
|
||||||
return await yomichan.api.injectAnkiNoteMedia(
|
return await yomichan.api.injectAnkiNoteMedia(
|
||||||
timestamp,
|
timestamp,
|
||||||
definitionDetails,
|
definitionDetails,
|
||||||
|
Loading…
Reference in New Issue
Block a user