Move speaker and playback mode beside the volume slider with a volume-aware icon
This commit is contained in:
@@ -1091,6 +1091,21 @@ function escapeHtml(s) {
|
||||
|
||||
const ICON_PLAY = '<svg viewBox="0 0 24 24" aria-hidden="true" class="fill"><path d="M9 5.5v13l10-6.5z"/></svg>';
|
||||
const ICON_PAUSE = '<svg viewBox="0 0 24 24" aria-hidden="true" class="fill"><path d="M7 5h3.5v14H7zM13.5 5H17v14h-3.5z"/></svg>';
|
||||
// Speaker icon follows the volume (muted / low / high); the level before a mute
|
||||
// is remembered so un-muting returns to it.
|
||||
let lastVolume = 1;
|
||||
function syncMuteIcon() {
|
||||
const b = els.muteBtn;
|
||||
if (!b) return;
|
||||
const v = parseFloat(els.volume.value);
|
||||
if (v > 0) lastVolume = v;
|
||||
const lvl = v === 0 ? 0 : v < 0.5 ? 1 : 2;
|
||||
const waves = lvl === 0 ? '<path d="M16 9l5 6M21 9l-5 6"/>' : lvl === 1 ? '<path d="M15.5 9.5a4 4 0 0 1 0 5"/>' : '<path d="M15.5 9.5a4 4 0 0 1 0 5M18.5 6.5a8 8 0 0 1 0 11"/>';
|
||||
b.innerHTML = `<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 9.5v5h3.5L12 18.5v-13L7.5 9.5z" class="spk"/>${waves}</svg>`;
|
||||
b.classList.toggle('muted', lvl === 0);
|
||||
b.title = lvl === 0 ? 'Unmute' : 'Mute';
|
||||
b.setAttribute('aria-label', b.title);
|
||||
}
|
||||
function fmtTime(sec) {
|
||||
if (!sec || !isFinite(sec)) return '0:00';
|
||||
sec = Math.floor(sec);
|
||||
@@ -4009,7 +4024,7 @@ const Remote = (() => {
|
||||
data.settings.volume = v;
|
||||
els.volume.value = String(v);
|
||||
Player.applyVolume();
|
||||
els.muteBtn.textContent = v === 0 ? '🔇' : '🔊';
|
||||
syncMuteIcon();
|
||||
persist();
|
||||
break;
|
||||
}
|
||||
@@ -5808,7 +5823,7 @@ const Gestures = (() => {
|
||||
data.settings.volume = Math.round(v * 100) / 100;
|
||||
els.volume.value = String(data.settings.volume);
|
||||
Player.applyVolume();
|
||||
els.muteBtn.textContent = data.settings.volume === 0 ? '🔇' : '🔊';
|
||||
syncMuteIcon();
|
||||
showHud(bar(`🔊 Volume ${Math.round(v * 100)}%`, v));
|
||||
} else {
|
||||
st.bright = Math.max(0.3, Math.min(1.6, sw.b0 + delta));
|
||||
@@ -8145,7 +8160,7 @@ async function renderSettings() {
|
||||
data.settings.volume = parseFloat(e.target.value);
|
||||
els.volume.value = e.target.value;
|
||||
Player.applyVolume();
|
||||
els.muteBtn.textContent = data.settings.volume === 0 ? '🔇' : '🔊';
|
||||
syncMuteIcon();
|
||||
persist();
|
||||
});
|
||||
$('setAudioOnly').addEventListener('change', (e) => {
|
||||
@@ -9563,15 +9578,15 @@ document.querySelectorAll('.chip').forEach((c) => {
|
||||
els.volume.addEventListener('input', () => {
|
||||
data.settings.volume = parseFloat(els.volume.value);
|
||||
Player.applyVolume();
|
||||
els.muteBtn.textContent = data.settings.volume === 0 ? '🔇' : '🔊';
|
||||
syncMuteIcon();
|
||||
persist();
|
||||
});
|
||||
els.muteBtn.addEventListener('click', () => {
|
||||
if (data.settings.volume > 0) { els.muteBtn.dataset.prev = data.settings.volume; data.settings.volume = 0; }
|
||||
else { data.settings.volume = parseFloat(els.muteBtn.dataset.prev || '1'); }
|
||||
if (data.settings.volume > 0) { lastVolume = data.settings.volume; data.settings.volume = 0; }
|
||||
else { data.settings.volume = lastVolume > 0 ? lastVolume : 1; }
|
||||
els.volume.value = String(data.settings.volume);
|
||||
Player.applyVolume();
|
||||
els.muteBtn.textContent = data.settings.volume === 0 ? '🔇' : '🔊';
|
||||
syncMuteIcon();
|
||||
persist();
|
||||
});
|
||||
|
||||
@@ -10475,6 +10490,7 @@ async function boot() {
|
||||
applyAppearance();
|
||||
updateProfileStatus();
|
||||
updateLoopRepeatButtons();
|
||||
syncMuteIcon();
|
||||
updateQueueBadge();
|
||||
els.volume.value = String(data.settings.volume ?? 1);
|
||||
els.quality.value = data.settings.quality || 'auto';
|
||||
|
||||
@@ -172,15 +172,15 @@
|
||||
</div>
|
||||
<button id="waveLoud" class="wave-loud hidden" type="button">⚡ Jump to the loudest part</button>
|
||||
<div class="deck-main">
|
||||
<button id="modeBtn" class="ctrl" type="button" title="Playback mode" aria-label="Playback mode"></button>
|
||||
<button id="prevBtn" class="ctrl" title="Previous" aria-label="Previous"><svg viewBox="0 0 24 24" aria-hidden="true" class="fill"><rect x="5" y="5" width="2.8" height="14" rx="1.2"/><path d="M19 5.5v13L9.5 12z"/></svg></button>
|
||||
<button id="playBtn" class="ctrl play" title="Play/Pause" aria-label="Play or pause"><svg viewBox="0 0 24 24" aria-hidden="true" class="fill"><path d="M9 5.5v13l10-6.5z"/></svg></button>
|
||||
<button id="nextBtn" class="ctrl" title="Next" aria-label="Next"><svg viewBox="0 0 24 24" aria-hidden="true" class="fill"><rect x="16.2" y="5" width="2.8" height="14" rx="1.2"/><path d="M5 5.5v13l9.5-6.5z"/></svg></button>
|
||||
<button id="muteBtn" class="ctrl" title="Mute" aria-label="Mute">🔊</button>
|
||||
<div id="dkModeHost" hidden><button id="shuffleBtn" class="ctrl" title="Shuffle upcoming tracks (S)" aria-label="Shuffle"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M16 3h5v5M4 20 21 3M21 16v5h-5M15 15l6 6M4 4l5 5"/></svg></button><button id="repeatBtn" class="ctrl" title="Repeat list when finished (R)" aria-label="Repeat list"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M17 2l4 4-4 4M3 12v-2a4 4 0 0 1 4-4h14M7 22l-4-4 4-4M21 12v2a4 4 0 0 1-4 4H3"/></svg></button><button id="loopBtn" class="ctrl" title="Loop this video (L)"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M17 2l4 4-4 4M3 12v-2a4 4 0 0 1 4-4h14M7 22l-4-4 4-4M21 12v2a4 4 0 0 1-4 4H3M11 10.2l1.6-.9v5.4"/></svg></button></div>
|
||||
</div>
|
||||
<div class="deck-vol vol">
|
||||
<input id="volume" type="range" min="0" max="1" step="0.01" value="1" aria-label="Volume" />
|
||||
<button id="muteBtn" class="ctrl" title="Mute" aria-label="Mute"></button>
|
||||
<button id="modeBtn" class="ctrl" type="button" title="Playback mode" aria-label="Playback mode"></button>
|
||||
</div>
|
||||
<div class="dk-quick">
|
||||
<button id="fsBtn" class="ctrl" title="Fullscreen" aria-label="Fullscreen"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5"/></svg><span class="fs-label">Fullscreen</span></button>
|
||||
|
||||
@@ -516,3 +516,14 @@
|
||||
#controls .dk-quick.ab-on .mc-label { display: none; }
|
||||
#controls .dk-quick.ab-on .dk-more span { font-size: 22px; line-height: 1; }
|
||||
#controls .dk-quick.ab-on .dk-more { flex: 1 1 52px; min-width: 52px; }
|
||||
|
||||
/* Transport = prev · play · next; volume row = slider · speaker · playback mode */
|
||||
#controls .deck-main { grid-template-columns: repeat(3, auto); justify-content: center; gap: 28px; }
|
||||
#controls .deck-vol { gap: 6px; }
|
||||
#controls .deck-vol input[type="range"] { order: 0; }
|
||||
#controls .deck-vol .ctrl { order: 1; width: 42px; height: 42px; flex: none; border-radius: 12px; border-color: transparent; background: transparent; }
|
||||
#controls .deck-vol .ctrl:hover { background: var(--bg-3); }
|
||||
#controls .deck-vol .ctrl svg { width: 22px; height: 22px; }
|
||||
#controls .deck-vol #muteBtn svg { fill: currentColor; stroke: currentColor; stroke-width: 1.8; }
|
||||
#controls .deck-vol #muteBtn svg path:not(.spk) { fill: none; }
|
||||
#controls .deck-vol #muteBtn.muted { color: var(--accent-bright); }
|
||||
|
||||
Reference in New Issue
Block a user