Список: скрытие cancelled, значок типа, ellipsis имени .torrent
Три мелкие правки веб-UI списка загрузок: - Скрываем cancelled в общем списке наравне с deleted: под группой all без IncludeDeleted теперь `state NOT IN (deleted, cancelled)`. reverted остаётся видимым. Тумблер и комментарии-инварианты приведены в соответствие («включая отменённые и удалённые»). - Значок типа (🎬 фильм / 📺 сериал) в строке списка: media_type текущей попытки распознавания протянут через LEFT JOIN в ListDownloadsPage (Download.RecMediaType, симметрично RecTitle) и downloadView.MediaType; значок рендерится в card.html, при нераспознанном типе значка нет. - Ellipsis для длинного имени .torrent-файла: у .btn-file max-width + overflow/ellipsis на лейбле, чтобы длинное имя не распирало .add-row; показываем базовое имя без .torrent, полное — в title (JS-энхансмент). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+14
-10
@@ -11,7 +11,7 @@ import (
|
||||
type StateGroup string
|
||||
|
||||
const (
|
||||
GroupAll StateGroup = "all" // все, кроме deleted (если не IncludeDeleted)
|
||||
GroupAll StateGroup = "all" // все, кроме скрытых терминальных (deleted/cancelled), если не IncludeDeleted
|
||||
GroupReview StateGroup = "review" // ждут человека
|
||||
GroupActive StateGroup = "active" // в работе
|
||||
GroupDone StateGroup = "done" // готово
|
||||
@@ -21,8 +21,9 @@ const (
|
||||
// statesInGroup возвращает состояния группы фильтра. nil — группа не сужает
|
||||
// выборку по состоянию (all/неизвестная): состояния перечисляются здесь и
|
||||
// нигде больше, чтобы UI и запрос не разъезжались. Терминальные cancelled/
|
||||
// reverted/deleted своей группы (чипа) не имеют — под all они видны (deleted —
|
||||
// только при IncludeDeleted), точечно к ним не фильтруем (см. tasks 2.1).
|
||||
// reverted/deleted своей группы (чипа) не имеют. Под all скрытые терминальные
|
||||
// (deleted и cancelled — шум в ленте) видны только при IncludeDeleted; reverted
|
||||
// остаётся видимым по умолчанию. Точечно к ним не фильтруем (см. tasks 2.1).
|
||||
func statesInGroup(g StateGroup) []State {
|
||||
switch g {
|
||||
case GroupReview:
|
||||
@@ -42,7 +43,7 @@ func statesInGroup(g StateGroup) []State {
|
||||
type ListFilter struct {
|
||||
Group StateGroup // группа состояний ("" / all — без сужения)
|
||||
Query string // поиск по id/названию/infohash/контексту (подстрока)
|
||||
IncludeDeleted bool // показывать состояние deleted (только под all)
|
||||
IncludeDeleted bool // показывать скрытые терминальные deleted+cancelled (только под all)
|
||||
Limit int // размер страницы
|
||||
Offset int // смещение страницы
|
||||
}
|
||||
@@ -60,9 +61,11 @@ func listWhere(f ListFilter) (string, []any) {
|
||||
}
|
||||
conds = append(conds, "state IN ("+strings.Join(ph, ",")+")")
|
||||
} else if !f.IncludeDeleted {
|
||||
// Группа all: скрываем удалённые по умолчанию (шум в ленте).
|
||||
conds = append(conds, "state <> ?")
|
||||
args = append(args, string(StateDeleted))
|
||||
// Группа all: скрываем терминальные deleted и cancelled по умолчанию (шум
|
||||
// в ленте; cancelled плодит универсальный стоп-кран «Закрыть»). reverted
|
||||
// оставляем видимым. Оба показываются тумблером IncludeDeleted.
|
||||
conds = append(conds, "state NOT IN (?, ?)")
|
||||
args = append(args, string(StateDeleted), string(StateCancelled))
|
||||
}
|
||||
|
||||
if q := strings.TrimSpace(f.Query); q != "" {
|
||||
@@ -90,8 +93,9 @@ func listWhere(f ListFilter) (string, []any) {
|
||||
// строк, удовлетворяющих фильтру (для пагинации). Сортировка — по времени
|
||||
// добавления в источник (source_added_at) с фолбеком на created_at и tie-break
|
||||
// по id: без вторичного ключа при равных метках порядок неустойчив, и строки
|
||||
// задваивались бы/пропадали между страницами. RecTitle подтягивается LEFT JOIN
|
||||
// текущей попытки распознавания — для фолбека заголовка карточки.
|
||||
// задваивались бы/пропадали между страницами. RecTitle и RecMediaType
|
||||
// подтягиваются LEFT JOIN текущей попытки распознавания — для фолбека заголовка
|
||||
// и значка типа карточки.
|
||||
func (s *Store) ListDownloadsPage(ctx context.Context, f ListFilter) ([]Download, int, error) {
|
||||
where, args := listWhere(f)
|
||||
|
||||
@@ -100,7 +104,7 @@ func (s *Store) ListDownloadsPage(ctx context.Context, f ListFilter) ([]Download
|
||||
return nil, 0, fmt.Errorf("list downloads page count: %w", err)
|
||||
}
|
||||
|
||||
q := `SELECT download.*, r.title AS rec_title
|
||||
q := `SELECT download.*, r.title AS rec_title, r.media_type AS rec_media_type
|
||||
FROM download
|
||||
LEFT JOIN recognition r ON r.download_id = download.id AND r.is_current = 1` + where +
|
||||
` ORDER BY COALESCE(download.source_added_at, download.created_at) DESC, download.id DESC
|
||||
|
||||
Reference in New Issue
Block a user