diff --git a/frontend/src/features/account/PreferencesCard.tsx b/frontend/src/features/account/PreferencesCard.tsx index 591cd25..c070bd6 100644 --- a/frontend/src/features/account/PreferencesCard.tsx +++ b/frontend/src/features/account/PreferencesCard.tsx @@ -25,6 +25,7 @@ export function PreferencesCard() { ordering: user?.preferences?.ordering ?? "-created_at", per_page: user?.preferences?.per_page ?? 48, zoom: user?.preferences?.zoom ?? 190, + online_hot_default: user?.preferences?.online_hot_default ?? true, }); const [saving, setSaving] = useState(false); diff --git a/frontend/src/features/online/OnlinePage.tsx b/frontend/src/features/online/OnlinePage.tsx index 2d6f372..f6ea80c 100644 --- a/frontend/src/features/online/OnlinePage.tsx +++ b/frontend/src/features/online/OnlinePage.tsx @@ -17,6 +17,7 @@ import { postIsBlacklisted, type E621Post, } from "@/lib/e621"; +import { hotDefaultAction, HOT_ORDER } from "@/features/online/hotDefault"; import { useE621 } from "@/store/e621"; import { useAuth } from "@/store/auth"; import { useUi } from "@/store/ui"; @@ -44,14 +45,21 @@ export default function OnlinePage() { const zoom = useUi((state) => state.zoom); const appliedHotDefault = useRef(false); - // Landing on Online without a search uses the order:hot default (on unless - // the account turns it off). Existing searches are left alone. + // Landing on Online follows the account's order:hot default: applied when + // there is no search, removed when the saved URL only carries the default + // and the toggle was turned off. Deliberate searches are left alone. useEffect(() => { if (!authReady || appliedHotDefault.current) return; appliedHotDefault.current = true; - if (tags) return; - if (user?.preferences?.online_hot_default === false) return; - setSearchParams(buildParams("order:hot", 1), { replace: true }); + const action = hotDefaultAction( + tags, + user?.preferences?.online_hot_default !== false, + ); + if (action === "set-hot") { + setSearchParams(buildParams(HOT_ORDER, 1), { replace: true }); + } else if (action === "clear-hot") { + setSearchParams(buildParams("", 1), { replace: true }); + } }, [authReady, tags, user, setSearchParams]); const blacklistMutation = useMutation({ diff --git a/frontend/src/features/online/hotDefault.ts b/frontend/src/features/online/hotDefault.ts new file mode 100644 index 0000000..120b245 --- /dev/null +++ b/frontend/src/features/online/hotDefault.ts @@ -0,0 +1,22 @@ +/** The metatag the Online page opens with when the account toggle is on. */ +export const HOT_ORDER = "order:hot"; + +export type HotDefaultAction = "set-hot" | "clear-hot" | "keep"; + +/** + * Decide what the Online default should do for a given search. + * + * `order:hot` on its own is the default, not a deliberate search: it is + * applied when the toggle is on and removed when the account turns it off + * (so a reload of an old URL follows the new setting). Any other search is + * left untouched. + */ +export function hotDefaultAction( + tags: string, + hotDefaultOn: boolean, +): HotDefaultAction { + const trimmed = tags.trim(); + if (trimmed === HOT_ORDER) return hotDefaultOn ? "keep" : "clear-hot"; + if (!trimmed) return hotDefaultOn ? "set-hot" : "keep"; + return "keep"; +}