New web project with Beat Saber tools
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
<script lang="ts">
|
||||
const links = [
|
||||
{ href: '/', label: 'Home' },
|
||||
{ href: '/tools', label: 'Tools' },
|
||||
{ href: '/guides', label: 'Guides' }
|
||||
];
|
||||
let open = false;
|
||||
const toggle = () => (open = !open);
|
||||
const close = () => (open = false);
|
||||
const year = new Date().getFullYear();
|
||||
</script>
|
||||
|
||||
<header class="sticky top-0 z-40 backdrop-blur supports-[backdrop-filter]:bg-surface/50 border-b border-white/10">
|
||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex h-14 items-center justify-between">
|
||||
<a href="/" class="flex items-center gap-2">
|
||||
<span class="h-2 w-2 rounded-full bg-neon" style="box-shadow: 0 0 12px rgba(34,211,238,0.60);"></span>
|
||||
<span class="font-display text-lg tracking-widest">
|
||||
<span class="neon-text">PLEBSABER</span><span class="text-muted">.stream</span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="hidden md:flex items-center gap-6">
|
||||
{#each links as link}
|
||||
<a href={link.href} class="text-muted hover:text-white transition">{link.label}</a>
|
||||
{/each}
|
||||
<a href="/tools" class="btn-neon">Launch Tools</a>
|
||||
</nav>
|
||||
|
||||
<button class="md:hidden btn-neon px-3 py-1.5" on:click={toggle} aria-expanded={open} aria-controls="mobile-nav">
|
||||
Menu
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if open}
|
||||
<div id="mobile-nav" class="md:hidden border-t border-white/10 bg-surface/80">
|
||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-3 grid gap-3">
|
||||
{#each links as link}
|
||||
<a href={link.href} on:click={close} class="text-muted hover:text-white transition">{link.label}</a>
|
||||
{/each}
|
||||
<a href="/tools" on:click={close} class="btn-neon w-max">Launch Tools</a>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</header>
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<script lang="ts">
|
||||
import { songPlayerStore, currentTimeStore, togglePlay, setVolume } from '$lib/stores/songPlayer';
|
||||
|
||||
export let hash: string;
|
||||
export let preferBeatLeader = false;
|
||||
|
||||
let isCurrent = false;
|
||||
$: isCurrent = $songPlayerStore?.currentHash === hash;
|
||||
$: currentTime = isCurrent ? $currentTimeStore : 0;
|
||||
|
||||
function onToggle() {
|
||||
togglePlay(hash, preferBeatLeader);
|
||||
}
|
||||
|
||||
function onVolumeInput(e: Event) {
|
||||
const v = Number((e.target as HTMLInputElement).value);
|
||||
setVolume(v);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="player">
|
||||
<button class="play" on:click={onToggle} aria-label="Play/Pause">
|
||||
{#if isCurrent && $songPlayerStore?.playing}
|
||||
❚❚
|
||||
{:else}
|
||||
▶
|
||||
{/if}
|
||||
</button>
|
||||
<div class="timeline" title="Progress">
|
||||
<div class="progress" style="width: {($songPlayerStore?.currentHash ? (currentTime / ($songPlayerStore?.duration || 1)) : 0) * 100}%"></div>
|
||||
</div>
|
||||
<div class="time">
|
||||
{Math.floor(currentTime / 60)}:{String(Math.floor(currentTime % 60)).padStart(2, '0')} /
|
||||
{Math.floor(($songPlayerStore?.duration || 0) / 60)}:{String(Math.floor(($songPlayerStore?.duration || 0) % 60)).padStart(2, '0')}
|
||||
</div>
|
||||
<div class="volume">
|
||||
<input type="range" min="0" max="1" step="0.01" value={$songPlayerStore?.volume} on:input={onVolumeInput} />
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.player { display: flex; align-items: center; gap: 0.5rem; }
|
||||
.play { width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid rgba(255,255,255,0.15); border-radius: 6px; background: transparent; color: white; cursor: pointer; }
|
||||
.timeline { flex: 1; height: 6px; background: rgba(255,255,255,0.1); border-radius: 3px; overflow: hidden; }
|
||||
.progress { height: 100%; background: rgba(255,255,255,0.6); }
|
||||
.time { font-size: 11px; opacity: 0.8; min-width: 80px; text-align: right; }
|
||||
.volume input { width: 80px; }
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user