fix(player): volume slider fill

This commit is contained in:
2024-11-26 22:37:31 +01:00
parent 31f31ec2d9
commit c93d47efc1
2 changed files with 105 additions and 99 deletions

View File

@@ -1,14 +1,5 @@
<script lang="ts"> <script lang="ts">
import { import { Play, Pause, SkipBack, SkipForward, List } from 'lucide-svelte';
Play,
Pause,
SkipBack,
SkipForward,
VolumeX,
Volume1,
Volume2,
List
} from 'lucide-svelte';
import { Button } from '$lib/components/ui/button'; import { Button } from '$lib/components/ui/button';
import { Progress } from '$lib/components/ui/progress'; import { Progress } from '$lib/components/ui/progress';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@@ -18,6 +9,7 @@
import { getPlayerState } from '$lib/player.svelte'; import { getPlayerState } from '$lib/player.svelte';
import { enhance } from '$app/forms'; import { enhance } from '$app/forms';
import { getCoverUrl } from '$lib/covers'; import { getCoverUrl } from '$lib/covers';
import VolumeSlider from '$lib/components/groove/VolumeSlider.svelte';
import type { SubmitFunction } from '../../../routes/player/$types'; import type { SubmitFunction } from '../../../routes/player/$types';
dayjs.extend(duration); dayjs.extend(duration);
@@ -34,7 +26,6 @@
}); });
let progressBar = $state<HTMLElement | null>(null); let progressBar = $state<HTMLElement | null>(null);
let volumeForm = $state<HTMLFormElement | null>(null);
const seekProgressValue: SubmitFunction = ({ formData, cancel }) => { const seekProgressValue: SubmitFunction = ({ formData, cancel }) => {
if (!player.currentlyPlaying || !progressBar) { if (!player.currentlyPlaying || !progressBar) {
@@ -76,20 +67,6 @@
}; };
}; };
const submitVolumeForm: SubmitFunction = async ({ formData }) => {
formData.set('volume', player.volume.toString());
return async ({ update, result }) => {
await update({
invalidateAll: false
});
if (result.type === 'success' && result.data && 'volume' in result.data) {
player.volume = result.data.volume;
}
};
};
function onMouseMove(e: MouseEvent) { function onMouseMove(e: MouseEvent) {
mouse.offsetX = e.offsetX; mouse.offsetX = e.offsetX;
mouse.offsetY = e.offsetY; mouse.offsetY = e.offsetY;
@@ -179,47 +156,7 @@
</Popover.Content> </Popover.Content>
</Popover.Root> </Popover.Root>
<div class="flex grow flex-row items-center gap-4"> <VolumeSlider />
<div class="min-w-6 text-muted-foreground">
{#if player.volume <= 0.0}
<VolumeX class="size-full" />
{:else if player.volume < 0.5}
<Volume1 class="size-full" />
{:else}
<Volume2 class="size-full" />
{/if}
</div>
<form
bind:this={volumeForm}
class="volume-form flex-1"
method="POST"
action="/player?/volume"
use:enhance={submitVolumeForm}
>
<input
class="volume-slider min-w-40"
type="range"
min={0.0}
max={1.0}
step={0.01}
bind:value={player.volume}
oninput={() => {
volumeForm?.requestSubmit();
}}
onmousedown={() => {
player.adjustingVolume = true;
}}
onmouseup={() => {
player.adjustingVolume = false;
}}
/>
</form>
<div class="min-w-10 self-center">
<p class="text-sm text-muted-foreground">
{Math.round(player.volume * 100.0)}%
</p>
</div>
</div>
</div> </div>
</div> </div>
</nav> </nav>
@@ -249,36 +186,3 @@
</footer> </footer>
<svelte:window onmousemove={onMouseMove} /> <svelte:window onmousemove={onMouseMove} />
<style>
.volume-slider {
-webkit-appearance: none !important; /* Override default CSS styles */
appearance: none !important;
width: 100%; /* Full-width */
height: 8px; /* Specified height */
border-radius: 0.5rem;
background: hsl(var(--secondary));
outline: none; /* Remove outline */
opacity: 0.7; /* Set transparency (for mouse-over effects on hover) */
-webkit-transition: 0.2s; /* 0.2 seconds transition on hover */
transition: opacity 0.2s;
-webkit-user-drag: none;
}
.volume-slider::-webkit-slider-thumb {
@apply size-4 bg-background ring ring-secondary ring-offset-0 ring-offset-transparent transition-colors;
-webkit-user-drag: none;
appearance: none;
background-color: hsl(var(--primary));
border-radius: 100%;
}
.volume-slider::-webkit-slider-thumb:active {
@apply ring-offset-2 ring-offset-background;
}
.volume-form {
-webkit-user-drag: none;
}
</style>

View File

@@ -0,0 +1,102 @@
<script lang="ts">
import { enhance } from '$app/forms';
import { getPlayerState } from '$lib/player.svelte';
import { Volume1, Volume2, VolumeX } from 'lucide-svelte';
import type { SubmitFunction } from '../../../routes/player/$types';
const player = getPlayerState();
let volumeForm = $state<HTMLFormElement | null>(null);
const submitVolumeForm: SubmitFunction = async ({ formData }) => {
formData.set('volume', player.volume.toString());
return async ({ update, result }) => {
await update({
invalidateAll: false
});
if (result.type === 'success' && result.data && 'volume' in result.data) {
player.volume = result.data.volume;
}
};
};
</script>
<div class="flex grow flex-row items-center gap-4">
<div class="min-w-6 text-muted-foreground">
{#if player.volume <= 0.0}
<VolumeX class="size-full" />
{:else if player.volume < 0.5}
<Volume1 class="size-full" />
{:else}
<Volume2 class="size-full" />
{/if}
</div>
<form
bind:this={volumeForm}
class="volume-form flex-1"
method="POST"
action="/player?/volume"
use:enhance={submitVolumeForm}
>
<input
class="volume-slider min-w-40"
type="range"
min={0.0}
max={1.0}
step={0.01}
bind:value={player.volume}
oninput={() => {
volumeForm?.requestSubmit();
}}
onmousedown={() => {
player.adjustingVolume = true;
}}
onmouseup={() => {
player.adjustingVolume = false;
}}
style="background-size: {(player.volume / 1.0) * 100}% 100%"
/>
</form>
<div class="min-w-10 self-center">
<p class="text-sm text-muted-foreground">
{Math.round(player.volume * 100.0)}%
</p>
</div>
</div>
<style>
.volume-slider {
-webkit-user-drag: none;
appearance: none;
width: 100%;
height: 8px;
outline: none;
background: hsl(var(--secondary));
background-image: linear-gradient(hsl(var(--primary)), hsl(var(--primary)));
/* background-size: 50% 100%; */
background-repeat: no-repeat;
border-radius: 0.5rem;
-webkit-user-drag: none;
}
.volume-slider::-webkit-slider-thumb {
@apply size-4 bg-background ring ring-secondary ring-offset-0 ring-offset-transparent transition-colors;
-webkit-user-drag: none;
appearance: none;
background-color: hsl(var(--primary));
border-radius: 100%;
}
.volume-slider::-webkit-slider-thumb:active {
@apply ring-offset-2 ring-offset-background;
}
.volume-form {
-webkit-user-drag: none;
}
</style>