Rebuild the review page as a channel strip
The app is about operating something — playing a track and setting a level on it — but every screen looked like a form. One metaphor now does three jobs. - Reviewing: a vertical fader beside the text, so the two things you do at once stop being a screen apart. Native range input, so keyboard, focus and form submission are unchanged; on mobile it lies down and the ticks reverse - The reveal: everyone's scores as a row of channels. The silhouette of that row is the spread, which the stats page can only tell you as a number - Profiles: given versus received as two faders, the one comparison that says something about a person The player is now a transport: play/pause, a range input for seeking so arrow keys come free, and a stereo level meter driven by a real AnalyserNode. It is progressive enhancement — the page ships native audio controls and the script takes over, so no JS means the browser's own player. The meter is dark until audio actually plays and stops when it does; reduced motion skips it entirely. Also: hidden scores are hatched rather than blank, the nav carries the queue count, "Seuraava jonossa" keeps the loop going after a review, leaderboards gained level bars and a range bar where divisive is the point, durations read 3:54, both lists can get back to the start, and the admin invite table lists unused codes instead of silently truncating at 50. Slogan restored from the original app, three decades on.
This commit is contained in:
@@ -14,21 +14,19 @@
|
||||
{{range .Data.Invites}}
|
||||
<tr>
|
||||
<td>
|
||||
{{if .IsValid}}
|
||||
<a href="{{.Link}}">{{.Link}}</a>
|
||||
{{else}}
|
||||
<code class="muted">{{.Code}}</code>
|
||||
{{end}}
|
||||
<a href="{{.Link}}">{{.Link}}</a>
|
||||
</td>
|
||||
<td class="nowrap"><span class="dot {{if .IsValid}}on{{else}}off{{end}}"></span> {{if .IsValid}}käyttämätön{{else}}käytetty{{end}}</td>
|
||||
<td class="nowrap"><span class="dot on"></span> käyttämätön</td>
|
||||
<td>{{fidate .CreatedAt}}</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr><td colspan="3" class="muted">Ei kutsuja.</td></tr>
|
||||
<tr><td colspan="3" class="muted">Ei käyttämättömiä kutsuja.</td></tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="muted small">Lähetä linkki kaverille — se avaa liittymislomakkeen koodi valmiiksi täytettynä.</p>
|
||||
<p class="muted small">Lähetä linkki kaverille — se avaa liittymislomakkeen koodi valmiiksi
|
||||
täytettynä. Lista näyttää käyttämättömät kutsut{{if .Data.SpentCount}}; käytettyjä on
|
||||
{{.Data.SpentCount}}{{end}}.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<link rel="preload" href="/static/fonts/oswald.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<script src="/static/htmx.min.js" defer></script>
|
||||
<script src="/static/player.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="topbar">
|
||||
@@ -19,7 +20,7 @@
|
||||
<span></span>
|
||||
{{else if .Member}}
|
||||
<nav class="navlinks">
|
||||
<a href="/" {{if eq .Path "/"}}aria-current="page"{{end}}>Jono</a>
|
||||
<a href="/" {{if eq .Path "/"}}aria-current="page"{{end}}>Jono{{if .Queued}} <span class="count">{{.Queued}}</span>{{end}}</a>
|
||||
<a href="/songs" {{if eq .Path "/songs"}}aria-current="page"{{end}}>Kappaleet</a>
|
||||
<a href="/submit" {{if eq .Path "/submit"}}aria-current="page"{{end}}>Lähetä</a>
|
||||
<a href="/stats" {{if eq .Path "/stats"}}aria-current="page"{{end}}>Tilastot</a>
|
||||
@@ -39,7 +40,7 @@
|
||||
<details class="mobilenav">
|
||||
<summary aria-label="Valikko">☰</summary>
|
||||
<div class="panel">
|
||||
<a href="/">Jono</a>
|
||||
<a href="/">Jono{{if .Queued}} <span class="count">{{.Queued}}</span>{{end}}</a>
|
||||
<a href="/songs">Kappaleet</a>
|
||||
<a href="/submit">Lähetä</a>
|
||||
<a href="/stats">Tilastot</a>
|
||||
@@ -62,7 +63,7 @@
|
||||
<!-- The server already knows where they were, so the path travels in the link — no JS. -->
|
||||
<a href="/report?from={{.Path}}">Ilmoita ongelmasta</a> ·
|
||||
{{end}}
|
||||
Levyraati — kymmenen kaverin levyraati.
|
||||
<span class="slogan">We know good music, baby!</span>
|
||||
</footer>
|
||||
|
||||
{{with .Flash}}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{{define "content"}}
|
||||
<h1>Kirjaudu</h1>
|
||||
<!-- The app's own slogan, three decades old. A mark, not interface copy, so it stays English. -->
|
||||
<p class="slogan hero">We know good music, baby!</p>
|
||||
|
||||
{{with .Data.Errors.form}}<p class="error">{{.}}</p>{{end}}
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
{{define "player"}}
|
||||
<audio controls preload="none" src="/audio/{{.ID}}" class="player"></audio>
|
||||
<!-- Ships with native controls; player.js removes them and drives the same element. No JS means
|
||||
the browser's own player, which is plain but complete. -->
|
||||
<div class="playerwrap" data-duration="{{.Duration}}">
|
||||
<audio controls preload="none" src="/audio/{{.ID}}" class="player"></audio>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{define "songcard"}}
|
||||
<a class="songcard{{if and (not .Own) (not .Reviewed)}} unreviewed{{end}}" href="/songs/{{.ID}}">
|
||||
{{with .Average}}<span class="scorebadge">{{score .}}</span>{{end}}
|
||||
{{if .Average}}<span class="scorebadge">{{score .Average}}</span>
|
||||
{{else if .ReviewCount}}<span class="scorebadge sealed" title="Pisteet paljastuvat kun arvostelet"></span>{{end}}
|
||||
<span class="title">{{.Title}}</span>
|
||||
<span class="artist">{{.Artist}}</span>
|
||||
<span class="meta">
|
||||
@@ -19,15 +24,15 @@
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{define "scorefield"}}
|
||||
<label>Pisteet
|
||||
<span class="scorerow">
|
||||
<input type="range" name="score" min="1" max="100" value="{{.}}"
|
||||
oninput="this.nextElementSibling.value = this.value">
|
||||
<output>{{.}}</output>
|
||||
{{define "fader"}}
|
||||
<!-- A native range input turned vertical: keyboard, form submission and the value all stay free. -->
|
||||
<div class="fader">
|
||||
<span class="ticks" aria-hidden="true">
|
||||
<span>100</span><span>75</span><span>50</span><span>25</span><span>1</span>
|
||||
</span>
|
||||
</label>
|
||||
<span class="scorescale" aria-hidden="true">
|
||||
<span>1</span><span>25</span><span>50</span><span>75</span><span>100</span>
|
||||
</span>
|
||||
<input type="range" name="score" min="1" max="100" value="{{.}}"
|
||||
aria-label="Pisteet 1–100"
|
||||
oninput="this.closest('.fader').querySelector('output').value = this.value">
|
||||
<output class="readout">{{.}}</output>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
+24
-2
@@ -15,8 +15,30 @@
|
||||
<div class="statgrid">
|
||||
<div class="statcard"><span class="statvalue">{{$p.Stats.SongsSubmitted}}</span><span class="muted small">kappaletta</span></div>
|
||||
<div class="statcard"><span class="statvalue">{{$p.Stats.ReviewsWritten}}</span><span class="muted small">arvostelua</span></div>
|
||||
<div class="statcard"><span class="statvalue">{{if $p.Stats.AverageGiven}}{{score $p.Stats.AverageGiven}}{{else}}—{{end}}</span><span class="muted small">antanut ka.</span></div>
|
||||
<div class="statcard"><span class="statvalue">{{if $p.Stats.AverageReceived}}{{score $p.Stats.AverageReceived}}{{else}}—{{end}}</span><span class="muted small">saanut ka.</span></div>
|
||||
|
||||
<!-- The one comparison that says something about a person, in the same language as the review
|
||||
form: what they give versus what they get. -->
|
||||
<div class="statcard wide">
|
||||
<div class="channels compare">
|
||||
{{if $p.Stats.AverageGiven}}
|
||||
<div class="chan" style="--v: {{score $p.Stats.AverageGiven}}">
|
||||
<span class="chan-track"><span class="chan-cap"></span></span>
|
||||
<span class="chan-score">{{score $p.Stats.AverageGiven}}</span>
|
||||
<span class="chan-who">antanut</span>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $p.Stats.AverageReceived}}
|
||||
<div class="chan own" style="--v: {{score $p.Stats.AverageReceived}}">
|
||||
<span class="chan-track"><span class="chan-cap"></span></span>
|
||||
<span class="chan-score">{{score $p.Stats.AverageReceived}}</span>
|
||||
<span class="chan-who">saanut</span>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if and (not $p.Stats.AverageGiven) (not $p.Stats.AverageReceived)}}
|
||||
<p class="muted small">Ei vielä pisteitä kumpaankaan suuntaan.</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if $p.Own}}
|
||||
|
||||
@@ -7,9 +7,13 @@
|
||||
<div class="songgrid">
|
||||
{{range .Data.Items}}{{template "songcard" .}}{{end}}
|
||||
</div>
|
||||
{{with .Data.NextCursor}}<p><a href="/?cursor={{.}}">Lisää →</a></p>{{end}}
|
||||
<p class="pager">
|
||||
{{if .Data.Cursor}}<a href="/">← Alkuun</a>{{end}}
|
||||
{{with .Data.NextCursor}}<a href="/?cursor={{.}}">Lisää →</a>{{end}}
|
||||
</p>
|
||||
{{else}}
|
||||
<p class="empty">Jono on tyhjä. Olet arvostellut kaiken, mitä muut ovat lähettäneet.</p>
|
||||
<p><a href="/submit">Lähetä kappale</a> tai selaa <a href="/songs">kaikkia kappaleita</a>.</p>
|
||||
<p class="empty">Kaikki kuunneltu.</p>
|
||||
<p>Olet arvostellut kaiken, mitä muut ovat lähettäneet.
|
||||
<a href="/submit">Lähetä kappale</a> tai lue <a href="/songs">mitä muut sanoivat</a>.</p>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
+91
-52
@@ -5,15 +5,10 @@
|
||||
<strong>{{$s.Artist}}</strong>
|
||||
<span class="badge genre">{{$s.GenreLabel}}</span>
|
||||
<span>{{$s.Length}}</span>
|
||||
<span>lähettänyt {{$s.Submitter}} {{fidate $s.CreatedAt}}</span>
|
||||
<span>lähetti {{$s.Submitter}} {{fidate $s.CreatedAt}}</span>
|
||||
{{if $s.Own}}<span class="badge admin">oma kappale</span>{{end}}
|
||||
</p>
|
||||
|
||||
{{template "player" $s}}
|
||||
|
||||
{{with $s.Description}}<p class="intro">{{.}}</p>{{end}}
|
||||
{{with $s.SourceURL}}<p class="muted"><a href="{{.}}" rel="noreferrer">Kuuntele YouTubessa</a></p>{{end}}
|
||||
|
||||
{{if $s.CanEdit}}
|
||||
<details class="editbox">
|
||||
<summary>Muokkaa tietoja</summary>
|
||||
@@ -33,7 +28,7 @@
|
||||
</form>
|
||||
<form method="post" action="/songs/{{$s.ID}}/delete"
|
||||
onsubmit="return confirm('Poistetaanko kappale lopullisesti?')">
|
||||
<button type="submit" class="danger ghost">Poista kappale</button>
|
||||
<button type="submit" class="ghost danger">Poista kappale</button>
|
||||
</form>
|
||||
<p class="muted small">Muokkaus ja poisto ovat mahdollisia vain ennen ensimmäistä arvostelua.</p>
|
||||
</details>
|
||||
@@ -41,67 +36,111 @@
|
||||
<p class="muted small">Kappaletta on jo arvosteltu, joten tietoja ei voi enää muuttaa.</p>
|
||||
{{end}}
|
||||
|
||||
<section>
|
||||
{{if $s.CanReview}}
|
||||
<h2>Arvostele</h2>
|
||||
<form method="post" action="/songs/{{$s.ID}}/review" class="stack">
|
||||
{{template "scorefield" 50}}
|
||||
<label>Arvostelu
|
||||
<textarea name="text" rows="6" maxlength="5000" required
|
||||
{{if $s.CanReview}}
|
||||
<!-- The channel strip: the fader is the score, the panel beside it is everything else you do
|
||||
while the track plays. -->
|
||||
<form method="post" action="/songs/{{$s.ID}}/review" class="strip">
|
||||
{{template "fader" 50}}
|
||||
<div class="deck">
|
||||
{{template "player" $s}}
|
||||
{{with $s.Description}}<p class="intro">{{.}}</p>{{end}}
|
||||
<label class="grow">Arvostelu
|
||||
<textarea name="text" rows="8" maxlength="5000" required
|
||||
placeholder="Mitä kuulit?"></textarea>
|
||||
</label>
|
||||
<button type="submit">Tallenna arvostelu</button>
|
||||
</form>
|
||||
<p class="muted small">Muiden arvostelut ja pisteet paljastuvat kun olet tallentanut omasi.
|
||||
Voit muokata tai poistaa arvostelusi 30 minuutin ajan.</p>
|
||||
{{else if $s.ViewerReview}}
|
||||
<h2>Oma arvostelusi</h2>
|
||||
{{with $s.ViewerReview}}
|
||||
{{if .CanEdit}}
|
||||
<form method="post" action="/reviews/{{.ID}}" class="stack">
|
||||
<input type="hidden" name="from" value="/songs/{{$s.ID}}">
|
||||
{{template "scorefield" .Score}}
|
||||
<label>Arvostelu
|
||||
<div class="deckfoot">
|
||||
<button type="submit">Tallenna arvostelu</button>
|
||||
<span class="muted small">Muiden pisteet paljastuvat kun tallennat omasi. Voit muokata
|
||||
tai poistaa arvostelusi 30 minuutin ajan.</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{else}}
|
||||
{{template "player" $s}}
|
||||
{{with $s.Description}}<p class="intro">{{.}}</p>{{end}}
|
||||
{{end}}
|
||||
|
||||
{{with $s.SourceURL}}<p class="muted small"><a href="{{.}}" rel="noreferrer">Kuuntele YouTubessa</a></p>{{end}}
|
||||
|
||||
{{if $s.ViewerReview}}
|
||||
<section>
|
||||
<h2>Oma arvostelusi</h2>
|
||||
{{with $s.ViewerReview}}
|
||||
{{if .CanEdit}}
|
||||
<form method="post" action="/reviews/{{.ID}}" class="strip">
|
||||
<input type="hidden" name="from" value="/songs/{{$s.ID}}">
|
||||
{{template "fader" .Score}}
|
||||
<div class="deck">
|
||||
<label class="grow">Arvostelu
|
||||
<textarea name="text" rows="6" maxlength="5000" required>{{.Text}}</textarea>
|
||||
</label>
|
||||
<button type="submit">Päivitä</button>
|
||||
</form>
|
||||
<form method="post" action="/reviews/{{.ID}}/delete"
|
||||
onsubmit="return confirm('Poistetaanko arvostelu?')">
|
||||
<input type="hidden" name="from" value="/songs/{{$s.ID}}">
|
||||
<button type="submit" class="danger">Poista arvostelu</button>
|
||||
</form>
|
||||
<p class="muted small">Muokkausaika päättyy {{fidate .EditableUntil}}.</p>
|
||||
{{else}}
|
||||
<p class="score">{{.Score}}</p>
|
||||
<p>{{.Text}}</p>
|
||||
<p class="muted small">Muokkausaika on päättynyt.</p>
|
||||
{{end}}
|
||||
<div class="deckfoot">
|
||||
<button type="submit">Päivitä</button>
|
||||
<span class="muted small">Muokkausaika päättyy {{fidate .EditableUntil}}.</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form method="post" action="/reviews/{{.ID}}/delete"
|
||||
onsubmit="return confirm('Poistetaanko arvostelu?')">
|
||||
<input type="hidden" name="from" value="/songs/{{$s.ID}}">
|
||||
<button type="submit" class="ghost danger">Poista arvostelu</button>
|
||||
</form>
|
||||
{{else}}
|
||||
<p class="score">{{.Score}}</p>
|
||||
<p class="reviewtext">{{.Text}}</p>
|
||||
<p class="muted small">Muokkausaika on päättynyt.</p>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</section>
|
||||
{{end}}
|
||||
|
||||
<section>
|
||||
<h2>Arvostelut{{if $s.ReviewCount}} ({{$s.ReviewCount}}){{end}}</h2>
|
||||
|
||||
{{if $s.Revealed}}
|
||||
{{if $s.Average}}<p class="average">Keskiarvo <strong>{{score $s.Average}}</strong></p>{{end}}
|
||||
{{range $s.Reviews}}
|
||||
<article class="review{{if .Own}} own{{end}}">
|
||||
<header>
|
||||
<span class="avatar small">{{.Initials}}</span>
|
||||
<span class="who">{{.Reviewer}}</span>
|
||||
<span class="score">{{.Score}}</span>
|
||||
<span class="meta">{{fidate .CreatedAt}}</span>
|
||||
</header>
|
||||
<p>{{.Text}}</p>
|
||||
</article>
|
||||
{{if $s.Reviews}}
|
||||
<!-- One channel per reviewer: the spread across the row is what "divisive" looks like. -->
|
||||
<div class="channels">
|
||||
{{range $i, $r := $s.Reviews}}
|
||||
<div class="chan{{if $r.Own}} own{{end}}" style="--v: {{$r.Score}}; --i: {{$i}}">
|
||||
<span class="chan-track"><span class="chan-cap"></span></span>
|
||||
<span class="chan-score">{{$r.Score}}</span>
|
||||
<span class="chan-who" title="{{$r.Reviewer}}">{{$r.Initials}}</span>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $s.Average}}
|
||||
<div class="chan avg" style="--v: {{score $s.Average}}">
|
||||
<span class="chan-track"><span class="chan-cap"></span></span>
|
||||
<span class="chan-score">{{score $s.Average}}</span>
|
||||
<span class="chan-who">ka.</span>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
{{range $s.Reviews}}
|
||||
<article class="review{{if .Own}} own{{end}}">
|
||||
<header>
|
||||
<span class="avatar small">{{.Initials}}</span>
|
||||
<span class="who">{{.Reviewer}}</span>
|
||||
<span class="score">{{.Score}}</span>
|
||||
<span class="meta">{{fidate .CreatedAt}}</span>
|
||||
</header>
|
||||
<p>{{.Text}}</p>
|
||||
</article>
|
||||
{{end}}
|
||||
{{else}}
|
||||
<p class="muted">Kukaan ei ole vielä arvostellut tätä kappaletta.</p>
|
||||
{{end}}
|
||||
{{else}}
|
||||
<p class="muted">Muiden arvostelut ja keskiarvo näkyvät kun olet kirjoittanut omasi.
|
||||
{{if $s.ReviewCount}}Arvosteluja on {{$s.ReviewCount}}.{{end}}</p>
|
||||
<p class="sealed-note">
|
||||
<span class="sealed" aria-hidden="true"></span>
|
||||
Muiden pisteet ja arvostelut paljastuvat kun kirjoitat omasi.
|
||||
{{if $s.ReviewCount}}Arvosteluja on {{$s.ReviewCount}}.{{end}}
|
||||
</p>
|
||||
{{end}}
|
||||
</section>
|
||||
|
||||
{{if $s.NextInQueue}}
|
||||
<p class="nextup"><a href="/songs/{{$s.NextInQueue}}">Seuraava jonossa →</a></p>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
<div class="songgrid">
|
||||
{{range .Data.Items}}{{template "songcard" .}}{{end}}
|
||||
</div>
|
||||
{{with .Data.NextCursor}}<p><a href="/songs?cursor={{.}}">Vanhempia →</a></p>{{end}}
|
||||
<p class="pager">
|
||||
{{if .Data.Cursor}}<a href="/songs">← Uusimmat</a>{{end}}
|
||||
{{with .Data.NextCursor}}<a href="/songs?cursor={{.}}">Vanhempia →</a>{{end}}
|
||||
</p>
|
||||
{{else}}
|
||||
<p class="empty">Yhtään kappaletta ei ole vielä julkaistu.</p>
|
||||
<p><a href="/submit">Lähetä ensimmäinen</a>.</p>
|
||||
|
||||
+11
-2
@@ -9,6 +9,14 @@
|
||||
<span class="muted small">{{.Artist}}</span>
|
||||
<span class="value">{{if $.Count}}{{.ReviewCount}}{{else}}{{value .Value}}{{end}}</span>
|
||||
{{if not $.Count}}<span class="muted small">{{.ReviewCount}} arv.</span>{{end}}
|
||||
{{if $.Spread}}
|
||||
<!-- Where the scores actually landed: a range says more than a deviation. -->
|
||||
<span class="bar range" title="{{.Min}}–{{.Max}}">
|
||||
<span class="fill" style="left: {{.MinPct}}%; width: {{.SpanPct}}%"></span>
|
||||
</span>
|
||||
{{else if not $.Count}}
|
||||
<span class="bar"><span class="fill" style="width: {{.Pct}}%"></span></span>
|
||||
{{end}}
|
||||
</li>
|
||||
{{end}}
|
||||
</ol>
|
||||
@@ -28,6 +36,7 @@
|
||||
<a href="/profile/{{.ID}}">{{.Name}}</a>
|
||||
<span class="value">{{if $.Count}}{{.Count}}{{else}}{{value .Value}}{{end}}</span>
|
||||
{{if not $.Count}}<span class="muted small">{{.Count}} kpl</span>{{end}}
|
||||
{{if not $.Count}}<span class="bar"><span class="fill" style="width: {{value .Value}}%"></span></span>{{end}}
|
||||
</li>
|
||||
{{end}}
|
||||
</ol>
|
||||
@@ -45,8 +54,8 @@
|
||||
<div class="boards">
|
||||
{{template "songboard" dict "Title" "Parhaat" "Items" .Data.TopSongs}}
|
||||
{{template "songboard" dict "Title" "Heikoimmat" "Items" .Data.BottomSongs}}
|
||||
{{template "songboard" dict "Title" "Riitaisimmat" "Items" .Data.MostDivisive}}
|
||||
{{template "songboard" dict "Title" "Yksimielisimmät" "Items" .Data.MostUnified}}
|
||||
{{template "songboard" dict "Title" "Riitaisimmat" "Items" .Data.MostDivisive "Spread" true}}
|
||||
{{template "songboard" dict "Title" "Yksimielisimmät" "Items" .Data.MostUnified "Spread" true}}
|
||||
{{template "songboard" dict "Title" "Eniten arvosteltu" "Items" .Data.MostReviewed "Count" true}}
|
||||
{{template "userboard" dict "Title" "Ankarin arvostelija" "Items" .Data.Harshest}}
|
||||
{{template "userboard" dict "Title" "Anteliain" "Items" .Data.MostGenerous}}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
{{define "submission-status"}}
|
||||
<div class="status{{if .Failed}} failed{{end}}" {{if not .Done}}hx-get="/submit/{{.ID}}/status" hx-trigger="every 2s" hx-swap="outerHTML"{{end}}>
|
||||
<ol class="segments" aria-label="Lähetyksen tila">
|
||||
<li class="{{if .Done}}done{{else}}now{{end}}">Lähetetty</li>
|
||||
<li class="{{if .Done}}done{{else if eq .Status "converting"}}now{{else if eq .Status "downloading"}}now{{end}}">
|
||||
{{if eq .Status "downloading"}}Ladataan{{else}}Muunnetaan{{end}}</li>
|
||||
<li class="{{if .Ready}}done{{else if .Failed}}failed{{end}}">{{if .Failed}}Epäonnistui{{else}}Valmis{{end}}</li>
|
||||
</ol>
|
||||
<p class="{{if .Failed}}error{{end}}"><strong>{{.Label}}</strong></p>
|
||||
{{if .Failed}}
|
||||
{{with .StatusMsg}}<p class="muted small">{{.}}</p>{{end}}
|
||||
|
||||
Reference in New Issue
Block a user