Files
SoulStream/src/mini/Mini.svelte
T

133 lines
4.5 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script>
// The mini player window's root: boots the mirror, sizes the window to
// the chosen shape, and mounts it. The shared control classes (.m-disc,
// .m-skip, .m-mode) live here as :global so eight shapes speak one
// dialect — the disc is the app's one true play control (filled accent,
// padding: 0 against the UA-padding trap).
import { getCurrentWindow } from "@tauri-apps/api/window";
import { initMini, shapeState, setShape, mini } from "./mini.svelte.js";
import Strip from "./shapes/Strip.svelte";
import Sleeve from "./shapes/Sleeve.svelte";
import Sliver from "./shapes/Sliver.svelte";
import Wave from "./shapes/Wave.svelte";
import Focus from "./shapes/Focus.svelte";
import Deck from "./shapes/Deck.svelte";
import OnDeck from "./shapes/OnDeck.svelte";
import Queue from "./shapes/Queue.svelte";
const SHAPE_MAP = {
strip: Strip,
sleeve: Sleeve,
sliver: Sliver,
wave: Wave,
focus: Focus,
deck: Deck,
ondeck: OnDeck,
queue: Queue,
};
const Current = $derived(SHAPE_MAP[shapeState.id] ?? Strip);
initMini();
// Assert the stored shape's size on boot (the window opens with the
// last-known size from mini_open, which may belong to another shape).
void setShape(shapeState.id);
// Drag ANYWHERE to move the window — the whole mini is a titlebar except
// the things you actually operate. One owner for dragging: the shapes'
// data-tauri-drag-region patchwork is gone (the attribute only fires when
// the press lands ON the attributed element, so art, wash, padding and
// rows were all dead zones — "finicky").
const NO_DRAG =
"button, a, input, select, textarea, [role='slider'], .wave-wrap, .volwrap, .fly, .qlist, .picker, [data-nodrag]";
function dragAnywhere(e) {
if (e.button !== 0) return;
if (e.target.closest?.(NO_DRAG)) return;
void getCurrentWindow().startDragging();
}
</script>
<svelte:window onpointerdown={dragAnywhere} />
<div class="miniroot">
<Current />
</div>
<style>
/* The accent crossfade, the mini's way: --accent is a registered
@property (<color>), so a CSS transition interpolates it and every
var() consumer — plus the per-frame getComputedStyle readers in Lane
and Wave — rides one fade. Ease matches the main's t·(2−t) lerp. */
:global(html) {
transition:
--accent 1200ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
--accent-hover 1200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.miniroot {
width: 100vw;
height: 100vh;
overflow: hidden;
background: var(--bg-player);
user-select: none;
}
/* Dark glass, mini edition: unlike the main window (only the canvas
BETWEEN panes thins), the mini is all pane — so the pane itself thins
to the same black tint the main's .app uses (one dial, two files —
keep the alphas in step), over the OS acrylic (window_glass).
global.css already stops html/body painting under .glass; every
shape's own --bg-player fill is overridden in one place here. The
Wash art bleed stays as-is above it. */
:global(:root.glass) .miniroot {
background: transparent;
}
:global(:root.glass) .miniroot :global(.shape) {
background: rgba(0, 0, 0, 0.55);
}
:global(.m-disc) {
border-radius: 50%;
background: var(--accent);
color: #0b0b0e;
display: grid;
place-items: center;
flex: none;
width: 34px;
height: 34px;
padding: 0; /* global.css leaves UA button padding on — never trust it */
transition: background 120ms, transform 120ms;
}
:global(.m-disc:hover) {
background: var(--accent-hover);
transform: scale(1.05);
}
:global(.m-disc.big) {
width: 44px;
height: 44px;
}
:global(.m-disc.small) {
width: 30px;
height: 30px;
}
:global(.m-skip) {
color: var(--text-secondary);
display: grid;
place-items: center;
padding: 0;
flex: none;
}
:global(.m-skip:hover) {
color: #fff;
}
:global(.m-mode) {
color: var(--text-muted);
display: grid;
place-items: center;
padding: 0;
flex: none;
}
:global(.m-mode:hover) {
color: var(--text-secondary);
}
:global(.m-mode.on) {
color: var(--accent);
}
</style>