diff options
Diffstat (limited to 'ext/mixed')
-rw-r--r-- | ext/mixed/css/display.css | 16 | ||||
-rw-r--r-- | ext/mixed/css/material.css | 9 | ||||
-rw-r--r-- | ext/mixed/display-templates.html | 4 | ||||
-rw-r--r-- | ext/mixed/img/plus-thick.svg | 1 | ||||
-rw-r--r-- | ext/mixed/js/display-audio.js | 49 |
5 files changed, 75 insertions, 4 deletions
diff --git a/ext/mixed/css/display.css b/ext/mixed/css/display.css index ccdb2d9c..003d0962 100644 --- a/ext/mixed/css/display.css +++ b/ext/mixed/css/display.css @@ -551,6 +551,7 @@ button.action-button { background: transparent; font-size: inherit; box-shadow: none; + position: relative; transition: opacity var(--animation-duration) linear, visibility 0s linear 0s, @@ -615,6 +616,21 @@ button.action-button[data-icon=source-term]::before { .entry[data-type=term][data-expression-multi=true] .actions>button.action-button.action-play-audio { display: none; } +.action-button-badge { + pointer-events: none; + position: absolute; + display: block; + right: 0; + top: 0; + width: calc(8em / var(--font-size-no-units)); + height: calc(8em / var(--font-size-no-units)); +} +.action-button-badge[data-icon=cross] { + background-color: var(--danger-color); +} +.action-button-badge[data-icon=plus-thick] { + background-color: var(--success-color); +} /* Tags */ diff --git a/ext/mixed/css/material.css b/ext/mixed/css/material.css index 7da515b5..c9277088 100644 --- a/ext/mixed/css/material.css +++ b/ext/mixed/css/material.css @@ -79,6 +79,8 @@ --danger-color-transparent5: rgba(200, 60, 40, 0.05); --danger-color-transparent25: rgba(200, 60, 40, 0.25); + --success-color: #51ab30; + --disabled-color: #aaaaaa; --disabled-color-light: #dddddd; --disabled-color-lighter: #eeeeee; @@ -135,6 +137,8 @@ --danger-color-transparent5: rgba(221, 103, 85, 0.05); --danger-color-transparent25: rgba(221, 103, 85, 0.25); + --success-color: #75cf54; + --disabled-color: #444444; --disabled-color-light: #585858; --disabled-color-lighter: #777777; @@ -209,6 +213,7 @@ .icon[data-icon=question-mark-thick] { --icon-image: url(/mixed/img/question-mark-thick.svg); } .icon[data-icon=left-chevron] { --icon-image: url(/mixed/img/left-chevron.svg); } .icon[data-icon=right-chevron] { --icon-image: url(/mixed/img/right-chevron.svg); } +.icon[data-icon=plus-thick] { --icon-image: url(/mixed/img/plus-thick.svg); } .icon[data-icon=material-down-arrow] { --icon-image: url(/mixed/img/material-down-arrow.svg); --icon-size: var(--material-arrow-dimension2) var(--material-arrow-dimension1); @@ -959,12 +964,14 @@ button.popup-menu-item:disabled { color: var(--text-color-light2); } .popup-menu-item-icon { - display: block; width: calc(16em / 14); height: calc(16em / 14); background-color: var(--text-color); margin-right: 0.5em; } +.popup-menu-item-icon:not([hidden]) { + display: block; +} :root[data-page-type=popup] .popup-menu.popup-menu-auto-size, .popup-menu.popup-menu-small { border-radius: calc(var(--menu-border-radius) * 0.75); diff --git a/ext/mixed/display-templates.html b/ext/mixed/display-templates.html index c261bcdb..40716469 100644 --- a/ext/mixed/display-templates.html +++ b/ext/mixed/display-templates.html @@ -10,7 +10,7 @@ <button class="action-button action-view-note" hidden disabled data-icon="view-note" title="View added note" data-hotkey='["viewNote","title","View added note ({0})"]'></button> <button class="action-button action-add-note" hidden disabled data-icon="add-term-kanji" data-mode="term-kanji" title="Add expression" data-hotkey='["addNoteTermKanji","title","Add expression ({0})"]'></button> <button class="action-button action-add-note" hidden disabled data-icon="add-term-kana" data-mode="term-kana" title="Add reading" data-hotkey='["addNoteTermKana","title","Add reading ({0})"]'></button> - <button class="action-button action-play-audio" data-icon="play-audio" title="Play audio" data-title-default="Play audio" data-hotkey='["playAudio",["title","data-title-default"],"Play audio ({0})"]'></button> + <button class="action-button action-play-audio" data-icon="play-audio" title="Play audio" data-title-default="Play audio" data-hotkey='["playAudio",["title","data-title-default"],"Play audio ({0})"]'><div class="action-button-badge icon" hidden></div></button> <span class="entry-current-indicator-icon" title="Current entry"></span> </div> <div class="term-expression-list"></div> @@ -44,7 +44,7 @@ </span> </div> <div class="term-expression-details"> - <button class="action-button action-play-audio" data-icon="play-audio" title="Play audio" data-title-default="Play audio" data-hotkey='["playAudio",["title","data-title-default"],"Play audio ({0})"]'></button> + <button class="action-button action-play-audio" data-icon="play-audio" title="Play audio" data-title-default="Play audio" data-hotkey='["playAudio",["title","data-title-default"],"Play audio ({0})"]'><div class="action-button-badge icon" hidden></div></button> <div class="tags tag-list"></div> </div> </div></template> diff --git a/ext/mixed/img/plus-thick.svg b/ext/mixed/img/plus-thick.svg new file mode 100644 index 00000000..6b1b5c5a --- /dev/null +++ b/ext/mixed/img/plus-thick.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M6 2v4H2v4h4v4h4v-4h4V6h-4V2H6z"/></svg>
\ No newline at end of file diff --git a/ext/mixed/js/display-audio.js b/ext/mixed/js/display-audio.js index 2d95eea4..e1a9e250 100644 --- a/ext/mixed/js/display-audio.js +++ b/ext/mixed/js/display-audio.js @@ -135,9 +135,11 @@ class DisplayAudio { this.stopAudio(); // Update details + const potentialAvailableAudioCount = this._getPotentialAvailableAudioCount(expression, reading); for (const button of this._getAudioPlayButtons(definitionIndex, expressionIndex)) { const titleDefault = button.dataset.titleDefault || ''; button.title = `${titleDefault}\n${title}`; + this._updateAudioPlayButtonBadge(button, potentialAvailableAudioCount); } // Play @@ -277,7 +279,7 @@ class DisplayAudio { async _getExpressionAudioInfoList(source, expression, reading, details) { const infoList = await api.getExpressionAudioInfoList(source, expression, reading, details); - return infoList.map((info) => ({info, audioPromise: null, audio: null})); + return infoList.map((info) => ({info, audioPromise: null, audioResolved: false, audio: null})); } _getExpressionAndReading(definitionIndex, expressionIndex) { @@ -313,4 +315,49 @@ class DisplayAudio { _clamp(value, min, max) { return Math.max(min, Math.min(max, value)); } + + _updateAudioPlayButtonBadge(button, potentialAvailableAudioCount) { + if (potentialAvailableAudioCount === null) { + delete button.dataset.potentialAvailableAudioCount; + } else { + button.dataset.potentialAvailableAudioCount = `${potentialAvailableAudioCount}`; + } + + const badge = button.querySelector('.action-button-badge'); + if (badge === null) { return; } + + const badgeData = badge.dataset; + switch (potentialAvailableAudioCount) { + case 0: + badgeData.icon = 'cross'; + badgeData.hidden = false; + break; + case 1: + case null: + delete badgeData.icon; + badgeData.hidden = true; + break; + default: + badgeData.icon = 'plus-thick'; + badgeData.hidden = false; + break; + } + } + + _getPotentialAvailableAudioCount(expression, reading) { + const key = this._getExpressionReadingKey(expression, reading); + const sourceMap = this._cache.get(key); + if (typeof sourceMap === 'undefined') { return null; } + + let count = 0; + for (const {infoList} of sourceMap.values()) { + if (infoList === null) { continue; } + for (const {audio, audioResolved} of infoList) { + if (!audioResolved || audio !== null) { + ++count; + } + } + } + return count; + } } |