Audio play button status badge (#1300)

* Add plus-thick.svg

* Add success-color variable

* Fix icon display

* Add badge

* Add missing audioResolved

* Update audio badge

* Expose attribute
This commit is contained in:
toasted-nutbread 2021-01-23 20:24:52 -05:00 committed by GitHub
parent 643afcddd2
commit 85c039850c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 89 additions and 9 deletions

View File

@ -551,6 +551,7 @@ button.action-button {
background: transparent; background: transparent;
font-size: inherit; font-size: inherit;
box-shadow: none; box-shadow: none;
position: relative;
transition: transition:
opacity var(--animation-duration) linear, opacity var(--animation-duration) linear,
visibility 0s linear 0s, 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 { .entry[data-type=term][data-expression-multi=true] .actions>button.action-button.action-play-audio {
display: none; 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 */ /* Tags */

View File

@ -79,6 +79,8 @@
--danger-color-transparent5: rgba(200, 60, 40, 0.05); --danger-color-transparent5: rgba(200, 60, 40, 0.05);
--danger-color-transparent25: rgba(200, 60, 40, 0.25); --danger-color-transparent25: rgba(200, 60, 40, 0.25);
--success-color: #51ab30;
--disabled-color: #aaaaaa; --disabled-color: #aaaaaa;
--disabled-color-light: #dddddd; --disabled-color-light: #dddddd;
--disabled-color-lighter: #eeeeee; --disabled-color-lighter: #eeeeee;
@ -135,6 +137,8 @@
--danger-color-transparent5: rgba(221, 103, 85, 0.05); --danger-color-transparent5: rgba(221, 103, 85, 0.05);
--danger-color-transparent25: rgba(221, 103, 85, 0.25); --danger-color-transparent25: rgba(221, 103, 85, 0.25);
--success-color: #75cf54;
--disabled-color: #444444; --disabled-color: #444444;
--disabled-color-light: #585858; --disabled-color-light: #585858;
--disabled-color-lighter: #777777; --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=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=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=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[data-icon=material-down-arrow] {
--icon-image: url(/mixed/img/material-down-arrow.svg); --icon-image: url(/mixed/img/material-down-arrow.svg);
--icon-size: var(--material-arrow-dimension2) var(--material-arrow-dimension1); --icon-size: var(--material-arrow-dimension2) var(--material-arrow-dimension1);
@ -959,12 +964,14 @@ button.popup-menu-item:disabled {
color: var(--text-color-light2); color: var(--text-color-light2);
} }
.popup-menu-item-icon { .popup-menu-item-icon {
display: block;
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; margin-right: 0.5em;
} }
.popup-menu-item-icon:not([hidden]) {
display: block;
}
: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);

View File

@ -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-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-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-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> <span class="entry-current-indicator-icon" title="Current entry"></span>
</div> </div>
<div class="term-expression-list"></div> <div class="term-expression-list"></div>
@ -44,7 +44,7 @@
</span> </span>
</div> </div>
<div class="term-expression-details"> <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 class="tags tag-list"></div>
</div> </div>
</div></template> </div></template>

View File

@ -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>

After

Width:  |  Height:  |  Size: 150 B

View File

@ -135,9 +135,11 @@ class DisplayAudio {
this.stopAudio(); this.stopAudio();
// Update details // Update details
const potentialAvailableAudioCount = this._getPotentialAvailableAudioCount(expression, reading);
for (const button of this._getAudioPlayButtons(definitionIndex, expressionIndex)) { for (const button of this._getAudioPlayButtons(definitionIndex, expressionIndex)) {
const titleDefault = button.dataset.titleDefault || ''; const titleDefault = button.dataset.titleDefault || '';
button.title = `${titleDefault}\n${title}`; button.title = `${titleDefault}\n${title}`;
this._updateAudioPlayButtonBadge(button, potentialAvailableAudioCount);
} }
// Play // Play
@ -277,7 +279,7 @@ class DisplayAudio {
async _getExpressionAudioInfoList(source, expression, reading, details) { async _getExpressionAudioInfoList(source, expression, reading, details) {
const infoList = await api.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) { _getExpressionAndReading(definitionIndex, expressionIndex) {
@ -313,4 +315,49 @@ class DisplayAudio {
_clamp(value, min, max) { _clamp(value, min, max) {
return Math.max(min, Math.min(max, value)); 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;
}
} }

View File

@ -27,11 +27,11 @@
borderopacity="1.0" borderopacity="1.0"
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="32" inkscape:zoom="45.254834"
inkscape:cx="10.107295" inkscape:cx="8.4539164"
inkscape:cy="8.7280255" inkscape:cy="8.0625778"
inkscape:document-units="px" inkscape:document-units="px"
inkscape:current-layer="layer41" inkscape:current-layer="layer49"
showgrid="true" showgrid="true"
units="px" units="px"
inkscape:snap-center="true" inkscape:snap-center="true"
@ -1536,7 +1536,7 @@
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
</g> </g>
<g <g
style="display:inline" style="display:none"
inkscape:label="Check" inkscape:label="Check"
id="g1068" id="g1068"
inkscape:groupmode="layer"> inkscape:groupmode="layer">
@ -1547,4 +1547,13 @@
d="M 6.4999999,13 14.5,5 l -2,-2 -6.0000001,6 -3,-3 -2,2 z" d="M 6.4999999,13 14.5,5 l -2,-2 -6.0000001,6 -3,-3 -2,2 z"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g> </g>
<g
inkscape:groupmode="layer"
id="layer49"
inkscape:label="Plus Thick">
<path
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
d="M 6 2 L 6 6 L 2 6 L 2 10 L 6 10 L 6 14 L 10 14 L 10 10 L 14 10 L 14 6 L 10 6 L 10 2 L 6 2 z "
id="rect1068" />
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 94 KiB