Something went wrong. Try again.
a simple but full-featured web player for OpenSubsonic music servers (Navidrome, Gonic, Ampache, etc) devins.page/tinysub
svelte typescript javascript subsonic gonic navidrome
Something went wrong. Try again.
Svelte
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798<script lang="ts">import Library from "./Library.svelte";import { t } from "./languages/translate.svelte.js";import NowPlaying from "./NowPlaying.svelte";import { settings } from "./settings.svelte.js";
const minSidebarWidth = 12;const maxSidebarWidth = 24;const setSidebarWidth = (width: number) => (settings.sidebarWidth = Math.max( minSidebarWidth, Math.min(maxSidebarWidth, width), ));
let draggingSidebar = $state(false);let rootFontSize = 16;
$effect(() => { if (!draggingSidebar) return;
const cursor = document.body.style.cursor; document.body.style.cursor = "col-resize"; return () => { document.body.style.cursor = cursor; };});</script>
<div id="sidebar" class:transparent-sidebar={settings.transparentSidebar} style:inline-size={`${settings.sidebarWidth}rem`}> <Library /> <NowPlaying /> <div role="slider" tabindex="-1" aria-controls="sidebar" aria-label={t("settings.sidebar_width")} aria-orientation="horizontal" aria-valuemin={minSidebarWidth} aria-valuemax={maxSidebarWidth} aria-valuenow={Math.round(settings.sidebarWidth)} aria-valuetext={`${Math.round(settings.sidebarWidth)} rem`} onpointerdown={(e) => { if (draggingSidebar || e.button !== 0) return;
rootFontSize = parseFloat( getComputedStyle(document.documentElement).fontSize, ); e.currentTarget.setPointerCapture(e.pointerId); draggingSidebar = true; }} onpointermove={(e) => { if (!e.currentTarget.hasPointerCapture(e.pointerId)) return;
const parentElement = e.currentTarget.parentElement; if (!parentElement) return; const { left, right } = parentElement.getBoundingClientRect(); setSidebarWidth( (document.documentElement.dir === "rtl" ? right - e.clientX : e.clientX - left) / rootFontSize, ); }} onlostpointercapture={() => (draggingSidebar = false)} ></div></div>
<style>#sidebar { background-color: var(--bg-layer);
&.transparent-sidebar { background-color: transparent; }}
div[role="slider"] { position: absolute; inset-block: 0; inset-inline-end: -2px; inline-size: 4px; cursor: col-resize; touch-action: none; z-index: 10;
:global(html.miniplayer) & { display: none; }
@media (width <= 32rem) { display: none; }}</style>