Files
jellybit/web/templates/partials/download_main.html
T
avandClaude Opus 4.8 17d9f23630 Веб-UI: единый вес кнопок, убрана невидимая btn-ghost из применений
Класс .btn-ghost прозрачен (нет аффорданса без hover, на тач невидим), плюс
веса действий рассогласованы между списком (card.html) и страницей
(download_main.html). Назначаем семантику весов явно:

- «Откатить» = btn-danger везде (в списке был btn-ghost); в список добавлен
  префикс ↩, чтобы список и страница совпадали.
- «Отменить/Отклонить» = btn-danger везде (на странице был btn-ghost).
- «Обновить имя» = нейтральный .btn (был btn-ghost).

Определение .btn-ghost в jellybit.css оставлено на случай легитимного
использования — правились только применения. Косметический nit-фикс, htmx-пути
и деградация без JS не затронуты.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 20:35:14 +03:00

131 lines
9.1 KiB
HTML
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.
{{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}}>
<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}}
{{if .ActionError}}<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)">{{.ActionError}}</h2></div>{{end}}
<!-- Шапка -->
<div class="review-head" style="margin-bottom:var(--sp-4)">
<div>
<div class="review-title" style="font-size:var(--fs-xl)">{{.Title}}</div>
<div class="hash-row" style="margin-top:9px">
{{template "status_badge" .State}}
<span class="hash">{{.ID}}</span>
<button class="copy-btn" type="button" onclick="copyHash(this,'{{.ID}}')">⧉ копировать</button>
</div>
{{if .Added}}<p class="muted" style="margin:var(--sp-2) 0 0">Добавлено {{.Added}} <span class="ago">({{.AddedAgo}})</span></p>{{end}}
{{if .Note}}<p class="muted" style="margin:var(--sp-2) 0 0">{{.Note}}</p>{{end}}
</div>
<div class="card-acts" style="align-items:center">
{{if .Reviewable}}<a class="btn btn-primary" href="/review/{{.ID}}">Ревью →</a>{{end}}
{{if .Nameable}}<form method="post" action="/ui/downloads/{{.ID}}/refresh-name" hx-post="/ui/downloads/{{.ID}}/refresh-name" hx-target="#download-main" hx-swap="outerHTML"><button class="btn" type="submit" title="Перелить распознанное название в имя загрузки и раздачи">Обновить имя</button></form>{{end}}
{{if .Undoable}}<form method="post" action="/ui/downloads/{{.ID}}/undo" hx-post="/ui/downloads/{{.ID}}/undo" hx-target="#download-main" hx-swap="outerHTML"><input type="hidden" name="surface" value="download"><button class="btn btn-danger" type="submit">↩ Откатить</button></form>{{end}}
{{if .Relinkable}}<form method="post" action="/ui/downloads/{{.ID}}/relink" hx-post="/ui/downloads/{{.ID}}/relink" hx-target="#download-main" hx-swap="outerHTML"><input type="hidden" name="surface" value="download"><button class="btn" type="submit">Привязать заново</button></form>{{end}}
{{if .Retriable}}<form method="post" action="/ui/downloads/{{.ID}}/retry" hx-post="/ui/downloads/{{.ID}}/retry" hx-target="#download-main" hx-swap="outerHTML"><input type="hidden" name="surface" value="download"><button class="btn" type="submit">Повторить</button></form>{{end}}
{{if not .Terminal}}<form method="post" action="/ui/downloads/{{.ID}}/cancel" hx-post="/ui/downloads/{{.ID}}/cancel" hx-target="#download-main" hx-swap="outerHTML"><input type="hidden" name="surface" value="download"><button class="btn btn-danger" type="submit">Отменить</button></form>{{end}}
</div>
</div>
<!-- Распознано как -->
<div class="section">
<div class="section-head"><h2>Распознано как</h2></div>
{{if .HasPlan}}
<dl class="kv">
<dt>Название</dt><dd>{{.RecTitle}}</dd>
<dt>Ориг. название</dt><dd>{{if .OriginalTitle}}{{.OriginalTitle}}{{else}}<span class="faint"></span>{{end}}</dd>
<dt>Тип</dt><dd>{{if .IsSeries}}сериал{{else if eq .MediaType "movie"}}фильм{{else}}{{.MediaType}}{{end}}</dd>
{{if .IsSeries}}<dt>Сезон</dt><dd>{{if .Season}}{{.Season}}{{else}}<span class="faint"></span>{{end}}</dd>{{end}}
<dt>Год</dt><dd>{{if .Year}}{{.Year}}{{else}}<span class="faint"></span>{{end}}</dd>
<dt>Режиссёр</dt><dd><span class="faint"></span></dd>
<dt>База</dt><dd>{{if .Provider}}{{if .MatchURL}}<a class="ext-link" href="{{.MatchURL}}" target="_blank" rel="noopener">{{.Provider}} · {{.ProviderID}} ↗</a>{{else}}{{.Provider}} · <span class="mono">{{.ProviderID}}</span>{{end}}{{else if .NoBase}}без базы{{else}}<span class="faint"></span>{{end}}</dd>
<dt>Уверенность</dt><dd class="mono">{{if .Confidence}}{{.Confidence}}{{else}}<span class="faint"></span>{{end}}</dd>
</dl>
{{else}}
<p class="muted" style="margin:0">Ещё не распознано.</p>
{{end}}
</div>
<!-- Файлы и раскладка -->
{{if .HasPlan}}
<div class="section">
<div class="section-head"><h2>Файлы и раскладка</h2><span class="hint">файл источника → целевой хардлинк</span></div>
{{template "layout_widget" .Files}}
<p class="faint" style="font-size:var(--fs-xs);margin:var(--sp-3) 0 0">
Целевые файлы связаны хардлинками — место не дублируется, исходник остаётся на раздаче.
</p>
</div>
{{end}}
<!-- Раздача (живая статистика; секция деградирует, если торрент не сидирует) -->
{{template "seeding" .Seeding}}
<!-- История -->
<div class="section">
<div class="section-head"><h2>История</h2></div>
<ul class="timeline">
{{if .CreatedAt}}<li class="tl-item is-done"><div class="tl-t">Добавлено</div><time>{{.CreatedAt}}</time></li>{{end}}
<li class="tl-item is-now"><div class="tl-t">{{badgeLabel .State}} <span class="badge st-{{.State}}">текущее</span></div>{{if .UpdatedAt}}<time>{{.UpdatedAt}}</time>{{end}}</li>
</ul>
</div>
<!-- Контекст -->
{{if .Context}}
<div class="section">
<div class="section-head"><h2>Контекст</h2><span class="hint">сообщение при добавлении</span></div>
<p style="margin:0;color:var(--text-dim)">«{{.Context}}»</p>
</div>
{{end}}
<!-- Информация о торренте -->
<div class="section">
<div class="section-head"><h2>Информация о торренте</h2><span class="hint">сырой источник и infohash</span></div>
<dl class="kv">
<dt>Тип источника</dt><dd>{{.SourceType}}</dd>
{{range .Infohashes}}<dt>infohash</dt><dd class="mono">{{.}}</dd>{{end}}
</dl>
{{if .SourceFull}}
<div class="src-block">
<code class="src-full">{{.SourceFull}}</code>
<button class="copy-btn" type="button" onclick="copyHash(this,'{{.SourceFull}}')">⧉ копировать</button>
</div>
{{end}}
</div>
<!-- Опасная зона: закрытие (только смена статуса) и полное удаление (снять
хардлинки + снести раздачу). Секция скрыта в details (раскрыть сознательно).
С 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)">
<summary style="color:var(--st-err);cursor:pointer;font-weight:600">Опасная зона</summary>
{{if .Dismissable}}
<p class="muted" style="margin:var(--sp-3) 0">
Закрытие снимет запись из активного списка (перевод в «отменено») —
<strong>файлы и раздачу не трогает</strong>. Стоп-кран для зависшей, спорной
или лишней загрузки; при необходимости позже можно привязать заново.
</p>
<form method="post" action="/ui/downloads/{{.ID}}/dismiss"
hx-post="/ui/downloads/{{.ID}}/dismiss" hx-target="#download-main" hx-swap="outerHTML"
hx-confirm="Закрыть загрузку? Запись уйдёт в «отменено». Файлы и раздача останутся нетронутыми.">
<input type="hidden" name="surface" value="download">
<button class="btn btn-danger" type="submit">Закрыть загрузку</button>
</form>
{{end}}
{{if .Deletable}}
<p class="muted" style="margin:var(--sp-3) 0">
Полное удаление снимет библиотечные хардлинки <strong>и</strong> снесёт раздачу
с файлами из qBittorrent — освободит место. Действие необратимо.
</p>
<form method="post" action="/ui/downloads/{{.ID}}/delete"
hx-post="/ui/downloads/{{.ID}}/delete" hx-target="#download-main" hx-swap="outerHTML"
hx-confirm="Удалить загрузку? Раздача и файлы будут снесены, место освобождено. Действие необратимо.">
<input type="hidden" name="surface" value="download">
<button class="btn btn-danger" type="submit">Удалить загрузку</button>
</form>
{{end}}
</details>
{{end}}
</main>
{{end}}