web-ui: карточка и страница обновляются, пока задачу может двигать фон
- условие самообновления — доменный предикат store.State.IsObservable() вместо фазы catched; один поллер на поверхность, интервалы 5 с и 15 с - отказ тика отвечает 200 и самозавершающимся фрагментом с корневым id цели вместо 404/500, который htmx не свопит - заведён ADR-2026-08-10-observability-is-not-terminality, переписан раздел «Живой поллинг» в конвенции веб-UI
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{{define "card"}}
|
||||
<article class="card" id="card-{{.ID}}"{{if .SelfPoll}} hx-get="/fragments/downloads/{{.ID}}/card" hx-trigger="every 3s" hx-swap="outerHTML"{{end}}>
|
||||
<article class="card" id="card-{{.ID}}"{{if .SelfPoll}} hx-get="/fragments/downloads/{{.ID}}/card" hx-trigger="every {{.PollEvery}}" hx-swap="outerHTML"{{end}}>
|
||||
<div class="card-top">
|
||||
<div>
|
||||
<div class="card-title">{{if eq .MediaType "series"}}<span class="type-ico" title="сериал">📺</span> {{else if eq .MediaType "movie"}}<span class="type-ico" title="фильм">🎬</span> {{end}}<a href="/download/{{.ID}}" style="color:inherit">{{.Title}}</a></div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{{define "download_main"}}
|
||||
<main class="main" id="download-main"{{if .SelfPoll}} hx-get="/download/{{.ID}}" hx-trigger="every 3s" hx-select="#download-main" hx-swap="outerHTML"{{end}}>
|
||||
<main class="main" id="download-main"{{if .SelfPoll}} hx-get="/download/{{.ID}}" hx-trigger="every {{.PollEvery}}" hx-select="#download-main" hx-swap="outerHTML"{{end}}>
|
||||
<a class="back-link" href="/">← ко всем загрузкам</a>
|
||||
|
||||
{{if .Error}}<div class="result-banner" style="background:var(--st-err-bg);border-color:color-mix(in srgb,var(--st-err) 35%,transparent)"><h2 style="color:var(--st-err)">{{.Error}}</h2></div>{{end}}
|
||||
@@ -97,7 +97,10 @@
|
||||
С JS hx-confirm показывает диалог подтверждения; без JS гейт — только
|
||||
раскрытие details и явный submit (диалога нет). -->
|
||||
{{if or .Dismissable .Deletable}}
|
||||
<details class="section danger-zone" style="margin-bottom:0;border-color:color-mix(in srgb,var(--st-err) 35%,transparent)">
|
||||
<!-- hx-preserve: страница самообновляется тиком и свопает #download-main целиком;
|
||||
без этого раскрытая «Опасная зона» захлопывалась бы у человека под курсором
|
||||
ровно там, где он читает текст про необратимое удаление раздачи с файлами. -->
|
||||
<details id="danger-zone-{{.ID}}" hx-preserve class="section danger-zone" style="margin-bottom:0;border-color:color-mix(in srgb,var(--st-err) 35%,transparent)">
|
||||
<summary style="color:var(--st-err);cursor:pointer;font-weight:600">Опасная зона</summary>
|
||||
{{if .Dismissable}}
|
||||
<p class="muted" style="margin:var(--sp-3) 0">
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{{define "frag_note"}}<div class="card" id="{{.RootID}}">
|
||||
<div class="card-foot"><span class="card-meta">{{.Text}}</span></div>
|
||||
</div>{{end}}
|
||||
@@ -1,4 +1,4 @@
|
||||
{{define "progress"}}<div class="dl-live" id="dl-live-{{.ID}}"{{if .Active}} hx-get="/fragments/downloads/{{.ID}}/progress" hx-trigger="every 3s" hx-swap="outerHTML"{{end}}>{{if .Active}}
|
||||
{{define "progress"}}<div class="dl-live" id="dl-live-{{.ID}}">{{if .Active}}
|
||||
<div class="progress"><i style="width:{{.Percent}}%"></i></div>
|
||||
{{if .Has}}<div class="dl-stats">{{.Percent}}% · ↓ {{.DlSpeed}}{{if .ETA}} · осталось {{.ETA}}{{end}}</div>{{end}}
|
||||
{{end}}</div>{{end}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{define "seeding"}}{{if .Has}}<div class="section" id="seeding-{{.ID}}" hx-get="/fragments/downloads/{{.ID}}/seeding" hx-trigger="every 3s" hx-swap="outerHTML">
|
||||
{{define "seeding"}}{{if .Has}}<div class="section" id="seeding-{{.ID}}">
|
||||
<div class="section-head"><h2>Раздача</h2><span class="hint">qBittorrent · источник продолжает раздаваться</span></div>
|
||||
<div class="stat-row">
|
||||
<div class="stat"><div class="v good">{{.Percent}}%</div><div class="k">скачано</div></div>
|
||||
|
||||
Reference in New Issue
Block a user