feat(web): add 'Summarized only' filter checkbox to video list
This commit is contained in:
@@ -167,6 +167,7 @@ func (a *App) handleList(w http.ResponseWriter, r *http.Request) {
|
|||||||
Channel: q.Get("channel"),
|
Channel: q.Get("channel"),
|
||||||
From: q.Get("from"),
|
From: q.Get("from"),
|
||||||
To: q.Get("to"),
|
To: q.Get("to"),
|
||||||
|
OnlySummarized: q.Get("summarized") == "1",
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := a.Store.ListVideos(r.Context(), userID, 0)
|
rows, err := a.Store.ListVideos(r.Context(), userID, 0)
|
||||||
|
|||||||
@@ -395,6 +395,7 @@ type Filter struct {
|
|||||||
Channel string
|
Channel string
|
||||||
From string
|
From string
|
||||||
To string
|
To string
|
||||||
|
OnlySummarized bool // show only videos that have a summary
|
||||||
}
|
}
|
||||||
|
|
||||||
// matches reports whether a row satisfies the filter. Channel is an exact match;
|
// matches reports whether a row satisfies the filter. Channel is an exact match;
|
||||||
@@ -402,6 +403,9 @@ type Filter struct {
|
|||||||
// (no constraint) — Stage-0 filtering is in-memory over the listed rows, not a
|
// (no constraint) — Stage-0 filtering is in-memory over the listed rows, not a
|
||||||
// store query.
|
// store query.
|
||||||
func (f Filter) matches(r store.SummaryRow) bool {
|
func (f Filter) matches(r store.SummaryRow) bool {
|
||||||
|
if f.OnlySummarized && !r.Summarized {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if f.Channel != "" && r.Channel != f.Channel {
|
if f.Channel != "" && r.Channel != f.Channel {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -432,7 +436,7 @@ func parseDate(s string) (time.Time, bool) {
|
|||||||
|
|
||||||
// apply returns the subset of rows matching the filter, preserving order.
|
// apply returns the subset of rows matching the filter, preserving order.
|
||||||
func (f Filter) apply(rows []store.SummaryRow) []store.SummaryRow {
|
func (f Filter) apply(rows []store.SummaryRow) []store.SummaryRow {
|
||||||
if f == (Filter{}) {
|
if f.Channel == "" && f.From == "" && f.To == "" && !f.OnlySummarized {
|
||||||
return rows
|
return rows
|
||||||
}
|
}
|
||||||
out := rows[:0:0]
|
out := rows[:0:0]
|
||||||
@@ -484,6 +488,8 @@ main { max-width: 60rem; margin: 0 auto; padding: var(--s4) var(--s3); }
|
|||||||
.filters label { display: flex; flex-direction: column; font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); gap: var(--s1); }
|
.filters label { display: flex; flex-direction: column; font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); gap: var(--s1); }
|
||||||
.filters input { font: inherit; padding: .4rem .55rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); color: var(--fg); min-width: 9rem; }
|
.filters input { font: inherit; padding: .4rem .55rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); color: var(--fg); min-width: 9rem; }
|
||||||
.filters input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
|
.filters input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
|
||||||
|
.filter-check { flex-direction: row !important; align-items: center; gap: var(--s2) !important; padding-bottom: .45rem; }
|
||||||
|
.filter-check input[type=checkbox] { width: 1rem; height: 1rem; min-width: 0; padding: 0; accent-color: var(--accent); cursor: pointer; }
|
||||||
.btn { font: inherit; font-weight: 600; padding: .45rem 1rem; border: 1px solid var(--accent); border-radius: var(--radius); background: var(--accent); color: var(--accent-fg); cursor: pointer; }
|
.btn { font: inherit; font-weight: 600; padding: .45rem 1rem; border: 1px solid var(--accent); border-radius: var(--radius); background: var(--accent); color: var(--accent-fg); cursor: pointer; }
|
||||||
/* anchors styled as buttons: the generic a{} / a:visited{} colour rules outrank
|
/* anchors styled as buttons: the generic a{} / a:visited{} colour rules outrank
|
||||||
.btn on <a>, painting the label accent-on-accent (invisible). Restore the
|
.btn on <a>, painting the label accent-on-accent (invisible). Restore the
|
||||||
|
|||||||
@@ -127,6 +127,10 @@ templ filterForm(f Filter) {
|
|||||||
<label>Channel <input type="text" name="channel" value={ f.Channel } placeholder="any"/></label>
|
<label>Channel <input type="text" name="channel" value={ f.Channel } placeholder="any"/></label>
|
||||||
<label>From <input type="date" name="from" value={ f.From }/></label>
|
<label>From <input type="date" name="from" value={ f.From }/></label>
|
||||||
<label>To <input type="date" name="to" value={ f.To }/></label>
|
<label>To <input type="date" name="to" value={ f.To }/></label>
|
||||||
|
<label class="filter-check">
|
||||||
|
<input type="checkbox" name="summarized" value="1" if f.OnlySummarized { checked }/>
|
||||||
|
Summarized only
|
||||||
|
</label>
|
||||||
<button type="submit" class="btn">Filter</button>
|
<button type="submit" class="btn">Filter</button>
|
||||||
<span id="filter-indicator" class="htmx-indicator">filtering…</span>
|
<span id="filter-indicator" class="htmx-indicator">filtering…</span>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
+254
-244
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user