summaryrefslogtreecommitdiff
path: root/ext/mixed
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mixed')
-rw-r--r--ext/mixed/css/display.css16
-rw-r--r--ext/mixed/css/material.css9
-rw-r--r--ext/mixed/display-templates.html4
-rw-r--r--ext/mixed/img/plus-thick.svg1
-rw-r--r--ext/mixed/js/display-audio.js49
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;
+ }
}