Implement volume control with mute functionality; update PlayerState to manage muted state
This commit is contained in:
@@ -6,7 +6,9 @@
|
|||||||
import { player } from '$lib/player/player.svelte';
|
import { player } from '$lib/player/player.svelte';
|
||||||
import { queuePanel } from '$lib/player/queuePanel.svelte';
|
import { queuePanel } from '$lib/player/queuePanel.svelte';
|
||||||
import { fmtTime } from '$lib/utils/format';
|
import { fmtTime } from '$lib/utils/format';
|
||||||
|
import Volume1 from '@lucide/svelte/icons/volume-1';
|
||||||
import Volume2 from '@lucide/svelte/icons/volume-2';
|
import Volume2 from '@lucide/svelte/icons/volume-2';
|
||||||
|
import VolumeX from '@lucide/svelte/icons/volume-x';
|
||||||
import ListMusic from '@lucide/svelte/icons/list-music';
|
import ListMusic from '@lucide/svelte/icons/list-music';
|
||||||
|
|
||||||
function seek(value: number) {
|
function seek(value: number) {
|
||||||
@@ -48,9 +50,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden w-(--mf-player-side-w) shrink-0 items-center justify-end gap-3.5 sm:flex">
|
<div class="hidden w-(--mf-player-side-w) shrink-0 items-center justify-end gap-3.5 sm:flex">
|
||||||
<Volume2 class="size-icon-sm shrink-0 text-fg-2" strokeWidth={1.8} />
|
<IconButton
|
||||||
|
label={player.muted ? 'Activar sonido' : 'Silenciar'}
|
||||||
|
tone="plain"
|
||||||
|
size="xs"
|
||||||
|
onclick={() => player.toggleMute()}
|
||||||
|
>
|
||||||
|
{#if player.muted || player.volume === 0}
|
||||||
|
<VolumeX class="size-icon-sm" strokeWidth={1.8} />
|
||||||
|
{:else if player.volume < 50}
|
||||||
|
<Volume1 class="size-icon-sm" strokeWidth={1.8} />
|
||||||
|
{:else}
|
||||||
|
<Volume2 class="size-icon-sm" strokeWidth={1.8} />
|
||||||
|
{/if}
|
||||||
|
</IconButton>
|
||||||
<Slider
|
<Slider
|
||||||
value={player.volume}
|
value={player.muted ? 0 : player.volume}
|
||||||
max={100}
|
max={100}
|
||||||
label="Volumen"
|
label="Volumen"
|
||||||
oninput={(value) => player.setVolume(value)}
|
oninput={(value) => player.setVolume(value)}
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ class PlayerState {
|
|||||||
playing = $state(false);
|
playing = $state(false);
|
||||||
progress = $state(0);
|
progress = $state(0);
|
||||||
volume = $state(browser ? Number(localStorage.getItem('player.volume') ?? 100) : 100);
|
volume = $state(browser ? Number(localStorage.getItem('player.volume') ?? 100) : 100);
|
||||||
|
muted = $state(browser ? localStorage.getItem('player.muted') === 'true' : false);
|
||||||
loading = $state(false);
|
loading = $state(false);
|
||||||
recentlyPlayed = $state<PlayerTrack[]>([]);
|
recentlyPlayed = $state<PlayerTrack[]>([]);
|
||||||
playlists = $state<Playlist[]>([]);
|
playlists = $state<Playlist[]>([]);
|
||||||
@@ -148,6 +149,7 @@ class PlayerState {
|
|||||||
const audio = new Audio();
|
const audio = new Audio();
|
||||||
audio.preload = 'auto';
|
audio.preload = 'auto';
|
||||||
audio.volume = this.volume / 100;
|
audio.volume = this.volume / 100;
|
||||||
|
audio.muted = this.muted;
|
||||||
audio.addEventListener('durationchange', () => this.#syncDuration(audio.duration));
|
audio.addEventListener('durationchange', () => this.#syncDuration(audio.duration));
|
||||||
audio.addEventListener('loadedmetadata', () => this.#syncDuration(audio.duration));
|
audio.addEventListener('loadedmetadata', () => this.#syncDuration(audio.duration));
|
||||||
audio.addEventListener('play', () => {
|
audio.addEventListener('play', () => {
|
||||||
@@ -401,6 +403,18 @@ class PlayerState {
|
|||||||
else audio.pause();
|
else audio.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleMute() {
|
||||||
|
this.#applyMuted(!this.muted);
|
||||||
|
if (!this.muted && this.volume === 0) this.setVolume(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
#applyMuted(value: boolean) {
|
||||||
|
this.muted = value;
|
||||||
|
const audio = this.#audioEl();
|
||||||
|
if (audio) audio.muted = value;
|
||||||
|
if (browser) localStorage.setItem('player.muted', String(value));
|
||||||
|
}
|
||||||
|
|
||||||
next() {
|
next() {
|
||||||
if (this.tracks.length === 0) return;
|
if (this.tracks.length === 0) return;
|
||||||
const idx = this.#index();
|
const idx = this.#index();
|
||||||
@@ -459,6 +473,7 @@ class PlayerState {
|
|||||||
|
|
||||||
setVolume(value: number) {
|
setVolume(value: number) {
|
||||||
this.volume = Math.min(100, Math.max(0, Math.round(value)));
|
this.volume = Math.min(100, Math.max(0, Math.round(value)));
|
||||||
|
if (this.muted && this.volume > 0) this.#applyMuted(false);
|
||||||
const audio = this.#audioEl();
|
const audio = this.#audioEl();
|
||||||
if (audio) {
|
if (audio) {
|
||||||
audio.volume = this.volume / 100;
|
audio.volume = this.volume / 100;
|
||||||
|
|||||||
Reference in New Issue
Block a user