fix: address reader-UI feedback (shorts, search, tags, login, UX)
- Shorts: confirm via youtube.com/shorts/<id> probe (SOCS cookie bypasses the consent redirect) instead of a 60s heuristic; concurrent probing, shorts_probed flag, scheduled refinement (migration 0005) - Search: match title + channel name only (descriptions caused noisy results) - Faceted tag filtering: AND across categories (language AND topic narrows), OR within a category; any/all toggle applies to topics - Language detection: majority vote over individual titles (fixes misdetections like multipoleguy -> English; drops bogus Polish/Romanian) - Login: drop forced consent so returning sign-in is quick (select_account) - Feed cards: clickable channel name (opens channel), persistent saved badge, undo toast on hide, Hidden view to restore; tag chips show counts in tooltip
This commit is contained in:
parent
e56502789f
commit
8c245e986f
17 changed files with 306 additions and 35 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import { useEffect, useRef, useState } from "react";
|
||||
import { useInfiniteQuery } from "@tanstack/react-query";
|
||||
import { api, type FeedFilters, type Video } from "../lib/api";
|
||||
import { toast } from "../lib/toast";
|
||||
import VideoCard from "./VideoCard";
|
||||
|
||||
const PAGE = 60;
|
||||
|
|
@ -43,12 +44,19 @@ export default function Feed({
|
|||
function onState(id: string, status: string) {
|
||||
setOverrides((o) => ({ ...o, [id]: status }));
|
||||
api.setState(id, status).catch(() => {});
|
||||
if (status === "hidden") {
|
||||
toast("Video hidden", { label: "Undo", onClick: () => onState(id, "new") });
|
||||
}
|
||||
}
|
||||
|
||||
const items: Video[] = (query.data?.pages ?? [])
|
||||
.flatMap((p) => p.items)
|
||||
.map((v) => (overrides[v.id] ? { ...v, status: overrides[v.id] } : v))
|
||||
.filter((v) => overrides[v.id] !== "hidden");
|
||||
.filter((v) => {
|
||||
const ov = overrides[v.id];
|
||||
// In the Hidden view, drop just-unhidden items; elsewhere drop just-hidden ones.
|
||||
return filters.show === "hidden" ? ov !== "new" : ov !== "hidden";
|
||||
});
|
||||
|
||||
if (query.isLoading) return <div className="p-8 text-muted">Loading feed…</div>;
|
||||
if (query.isError) return <div className="p-8 text-muted">Couldn't load the feed.</div>;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue