a simple web player for subsonic
tinysub.devins.page
subsonic
navidrome
javascript
1<script lang="ts">
2 import Library from "./Library.svelte";
3 import NowPlaying from "./NowPlaying.svelte";
4 import { settings } from "./app.svelte.js";
5
6 let dragging = $state(false);
7
8 function onMouseDown(e: MouseEvent) {
9 dragging = true;
10 window.addEventListener("mousemove", onMouseMove);
11 window.addEventListener("mouseup", onMouseUp);
12 }
13
14 function onMouseMove(e: MouseEvent) {
15 if (!dragging) return;
16 const base = parseFloat(
17 getComputedStyle(document.documentElement).fontSize,
18 );
19 settings.sidebarWidth = Math.max(16, Math.min(48, e.clientX / base));
20 }
21
22 function onMouseUp() {
23 dragging = false;
24 window.removeEventListener("mousemove", onMouseMove);
25 window.removeEventListener("mouseup", onMouseUp);
26 }
27
28 $effect(() => {
29 if (dragging) {
30 document.body.style.cursor = "col-resize";
31 return () => (document.body.style.cursor = "");
32 }
33 });
34</script>
35
36<div id="sidebar">
37 <Library />
38 <NowPlaying />
39 <!-- svelte-ignore a11y_no_static_element_interactions -->
40 <div class="resizer" onmousedown={onMouseDown}></div>
41</div>
42
43<style>
44 #sidebar {
45 background: var(--bg-secondary);
46 grid-area: sidebar;
47 display: flex;
48 flex-direction: column;
49 border-inline-end: 1px solid var(--border);
50 overflow: hidden;
51 position: relative;
52 }
53 .resizer {
54 position: absolute;
55 inset-block: 0;
56 inset-inline-end: 0;
57 inline-size: 4px;
58 cursor: col-resize;
59 z-index: 10;
60 }
61 .resizer:hover {
62 background: var(--text);
63 }
64 @media (max-width: 32rem) {
65 #sidebar {
66 border-inline-end: none;
67 border-block-start: 1px solid var(--border);
68 }
69 .resizer {
70 display: none;
71 }
72 }
73</style>