#59 took the seek bar off the phone's transport, so the one thing a mini player is expected to say without being opened -- how far through the song it is -- had nowhere left to be said. It is the shell's element and its own 2px grid row between `bottom-bar` and `bottom-nav`, because those two are separate components and either one drawing the line means reaching into the other's box. The fill is `scaleX()` off the same `PlaybackPositionChanged` the seek bar renders, with the same `trackChangeId`/`seq` guards and an interval that only interpolates *between* reports -- never its own clock, which is the rule that exists because a local counter drifted 30 s away from the backend across four keyboard seeks. It is `aria-hidden` and takes no pointer events at any depth: Now Playing's seek bar is what announces the position, and a 2px strip on the top edge of the tab bar is exactly where a thumb aiming at a tab lands. It renders nothing above 600px, from `matchMedia` rather than a media query, because a stylesheet cannot stop a 1 Hz interval running for the life of every desktop session about a line nobody can see. Its phone rule is at the foot of index.css beside `job-band`'s, not in the phone block above: a media query adds no specificity, so a `display: block` written before the `display: none` that takes it out of the desktop grid loses to it and the line never appears at all. Closes #58
113 lines
5.5 KiB
HTML
113 lines
5.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
|
<link href="./index.css" rel="stylesheet" />
|
|
<title>yellowjacket</title>
|
|
<script src="/index.ts" type="module"></script>
|
|
</head>
|
|
|
|
<body>
|
|
<!-- a11y.30. First focusable thing in the document, so a keyboard
|
|
user is not walked through the header, the library filter, the
|
|
search box and eleven nav items on every navigation. -->
|
|
<a class="skip-link" href="#main-content">Skip to content</a>
|
|
<!-- Below 600px this bar is not in the layout at all (#57): index.css
|
|
takes its grid row away and leaves the element visually hidden,
|
|
carrying nothing but the `h1` below. Every control in it has
|
|
somewhere else to be there -- `nav-history` is the platform's
|
|
own back gesture, `job-indicator` is `<job-band>`, `search-bar`
|
|
is `<search-dialog>` opened from the view's own header, and
|
|
`library-filter` is Settings -> Libraries (#148). -->
|
|
<header class="top-bar">
|
|
<hgroup>
|
|
<h1 class="title">YellowJacket</h1>
|
|
<!-- a11y.29: a heading level was being used for type size. -->
|
|
<p class="subtitle">Music how it was meant to bee.</p>
|
|
</hgroup>
|
|
<!-- Global back/forward (#6). Before the library filter so the
|
|
two navigation controls in this bar are adjacent, and after
|
|
the brand because that is where a window's chrome ends and
|
|
the app's begins. Hidden below 600px by index.css: the
|
|
phone has a system back, and this bar has no room. -->
|
|
<nav-history></nav-history>
|
|
<library-filter></library-filter>
|
|
<search-bar></search-bar>
|
|
<job-indicator></job-indicator>
|
|
</header>
|
|
<!-- The phone's view of background work (#62): below 600px the
|
|
indicator above stands down and its rows appear here instead,
|
|
in the layout rather than over it. `display: none` above that
|
|
width in index.css, which is also what keeps it out of the
|
|
desktop grid -- an in-flow child with no named area is
|
|
auto-placed into one of the shell's rows, which is the trap the
|
|
skip link is absolutely positioned to avoid. -->
|
|
<job-band></job-band>
|
|
<div class="sidebar">
|
|
<app-sidebar></app-sidebar>
|
|
</div>
|
|
<div class="content-area">
|
|
<main class="main-panel" data-active-view="tracks" data-testid="main-content" id="main-content"
|
|
tabindex="-1">
|
|
<track-list></track-list>
|
|
</main>
|
|
<queue-panel id="queue-panel"></queue-panel>
|
|
</div>
|
|
<!-- Three columns, and the outer two are the same width, which is
|
|
what makes the middle one *centred* rather than merely in the
|
|
middle of what is left (#23). The transport used to sit in a
|
|
`320px 1fr auto` grid, so its centre was ~140px right of the
|
|
window's.
|
|
|
|
That is also why the volume moved out of `audio-player` and
|
|
into the bar (#42): the transport column has to contain the
|
|
transport and nothing else, or "centred" means centred with a
|
|
slider bolted to one side. It joins the queue button in
|
|
`.bar-end`, whose width is what the left column is matched
|
|
against. -->
|
|
<footer class="bottom-bar">
|
|
<now-playing></now-playing>
|
|
<audio-player></audio-player>
|
|
<div class="bar-end">
|
|
<volume-control></volume-control>
|
|
<button aria-label="Toggle queue" aria-controls="queue-panel" aria-expanded="false"
|
|
id="queue-button">
|
|
<!-- ICON_QUEUE in src/utils/icon-language.ts, written out
|
|
because this file has no module scope. It was `list`,
|
|
which is the Playlists destination's icon. -->
|
|
<wa-icon name="bars-staggered"></wa-icon>
|
|
</button>
|
|
</div>
|
|
</footer>
|
|
<!-- How far through the song we are, on the border between the two
|
|
bars (#58). The shell's element rather than either bar's:
|
|
they are separate components stacked in this grid, so a line
|
|
on the border between them is a row of it, and neither one has
|
|
to reach into the other's box for two pixels. It renders
|
|
nothing above 600px and nothing with no track, is `aria-hidden`
|
|
(Now Playing's seek bar is what announces the position) and
|
|
takes no pointer events at all -- a thin line that sometimes
|
|
seeks is worse than one that never does. -->
|
|
<player-progress-line></player-progress-line>
|
|
<!-- The phone's primary navigation, hidden above 600px by
|
|
index.css. Eager rather than a chunk, for the reason
|
|
notification-host is: it is the only way to move around the
|
|
app on a phone. After the footer, because that is where it
|
|
renders -- the tab bar sits below the transport, and DOM order
|
|
is what a screen reader and the tab sequence follow. -->
|
|
<bottom-nav></bottom-nav>
|
|
<first-run-wizard></first-run-wizard>
|
|
<notification-host></notification-host>
|
|
<shortcuts-overlay></shortcuts-overlay>
|
|
<!-- The phone's search surface (#57). A singleton here for the
|
|
reason shortcuts-overlay is one: one instance, one document
|
|
listener, and no `data-testid="search-input"` resolving to two
|
|
elements. It renders nothing while shut, so the header's box
|
|
is still the only one on a desktop. -->
|
|
<search-dialog></search-dialog>
|
|
</body>
|
|
|
|
</html>
|