feat(feed): reshuffle button for the "surprise me" sort
The backend shuffle sort already accepts a seed param. Add a circular reshuffle button next to the sort control (shown only when shuffle is active) that re-rolls the seed and re-queries the feed; selecting shuffle also seeds a fresh order instead of the deterministic seed-0 one. The seed lives in FeedFilters but is intentionally kept out of the URL state.
This commit is contained in:
parent
b325893b22
commit
5a96607557
5 changed files with 43 additions and 11 deletions
|
|
@ -8,6 +8,7 @@ import {
|
|||
EyeOff,
|
||||
GripVertical,
|
||||
Pencil,
|
||||
RefreshCw,
|
||||
RotateCcw,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
|
|
@ -48,6 +49,9 @@ const SORT_IDS = [
|
|||
|
||||
const SHOW_IDS = ["unwatched", "in_progress", "all", "watched", "saved", "hidden"];
|
||||
|
||||
// Fresh shuffle token for the "surprise me" sort.
|
||||
const rollSeed = () => Math.floor(Math.random() * 1_000_000_000);
|
||||
|
||||
const DATE_PRESETS: { days: number; key: string }[] = [
|
||||
{ days: 1, key: "24h" },
|
||||
{ days: 7, key: "1week" },
|
||||
|
|
@ -215,17 +219,38 @@ export default function Sidebar({
|
|||
);
|
||||
case "sort":
|
||||
return (
|
||||
<select
|
||||
value={filters.sort}
|
||||
onChange={(e) => setFilters({ ...filters, sort: e.target.value })}
|
||||
className="w-full bg-card border border-border rounded-lg px-2 py-1.5 text-sm outline-none focus:border-accent"
|
||||
>
|
||||
{SORT_IDS.map((id) => (
|
||||
<option key={id} value={id}>
|
||||
{t("sidebar.sort." + id)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<select
|
||||
value={filters.sort}
|
||||
onChange={(e) => {
|
||||
const sort = e.target.value;
|
||||
// Seed shuffle on selection so it lands on a fresh order, not the
|
||||
// deterministic seed-0 one every time.
|
||||
setFilters({
|
||||
...filters,
|
||||
sort,
|
||||
seed: sort === "shuffle" ? rollSeed() : undefined,
|
||||
});
|
||||
}}
|
||||
className="w-full bg-card border border-border rounded-lg px-2 py-1.5 text-sm outline-none focus:border-accent"
|
||||
>
|
||||
{SORT_IDS.map((id) => (
|
||||
<option key={id} value={id}>
|
||||
{t("sidebar.sort." + id)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{filters.sort === "shuffle" && (
|
||||
<button
|
||||
onClick={() => setFilters({ ...filters, seed: rollSeed() })}
|
||||
title={t("sidebar.reshuffle")}
|
||||
aria-label={t("sidebar.reshuffle")}
|
||||
className="shrink-0 p-1.5 rounded-lg border border-border bg-card text-fg shadow-sm hover:border-accent hover:text-accent active:translate-y-px transition"
|
||||
>
|
||||
<RefreshCw className="w-4 h-4" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
case "date":
|
||||
return (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue