Online defaults to order:hot, with an Account toggle
New online_hot_default preference (on by default, so guests and accounts that never saved preferences get it): opening /online without a search replaces the URL with ?tags=order:hot — e621's metatag for the order the Hot page uses — so it is visible in the search field and shareable. Existing searches are never touched: they live in the URL, so a refresh or back/forward keeps them, while a fresh visit (nav pill, first time, after a long time away) gets the hot default again. Turning the toggle off opens Online on the site-wide newest posts as before. The toggle sits in Account -> Browsing preferences and saves with the rest of the settings; the backend validates the new boolean (400 for non-boolean input).
This commit is contained in:
@@ -170,6 +170,28 @@ export function PreferencesCard() {
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label className="flex items-start gap-2 text-sm text-ctp-subtext0">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={values.online_hot_default ?? true}
|
||||
onChange={(event) =>
|
||||
setValues((current) => ({
|
||||
...current,
|
||||
online_hot_default: event.target.checked,
|
||||
}))
|
||||
}
|
||||
className="mt-0.5 accent-ctp-mauve"
|
||||
/>
|
||||
<span>
|
||||
Online starts with{" "}
|
||||
<span className="font-mono text-ctp-blue">order:hot</span>
|
||||
<span className="mt-0.5 block text-[11px] leading-relaxed text-ctp-overlay0">
|
||||
Used when you open Online without a search. With it off, Online
|
||||
opens on the site-wide newest posts.
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<div>
|
||||
<Button onClick={() => void handleSave()} disabled={saving}>
|
||||
{saving ? "Saving…" : "Save preferences"}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { keepPreviousData, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { X } from "lucide-react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { Link, useLocation, useSearchParams } from "react-router-dom";
|
||||
|
||||
import { CollapsibleSidebar } from "@/components/CollapsibleSidebar";
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
type E621Post,
|
||||
} from "@/lib/e621";
|
||||
import { useE621 } from "@/store/e621";
|
||||
import { useAuth } from "@/store/auth";
|
||||
import { useUi } from "@/store/ui";
|
||||
import { toast } from "@/store/toasts";
|
||||
|
||||
@@ -34,11 +35,24 @@ export default function OnlinePage() {
|
||||
const credentials = useE621((state) => state.credentials);
|
||||
const blacklist = useE621((state) => state.blacklist);
|
||||
const saveBlacklist = useE621((state) => state.saveBlacklist);
|
||||
const user = useAuth((state) => state.user);
|
||||
const authReady = useAuth((state) => state.ready);
|
||||
const queryClient = useQueryClient();
|
||||
const [draft, setDraft] = useState<string | null>(null);
|
||||
const [blacklistDraft, setBlacklistDraft] = useState("");
|
||||
const tagInput = draft ?? tags;
|
||||
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.
|
||||
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 });
|
||||
}, [authReady, tags, user, setSearchParams]);
|
||||
|
||||
const blacklistMutation = useMutation({
|
||||
mutationFn: (lines: string[]) => saveBlacklist(lines),
|
||||
|
||||
@@ -4,6 +4,7 @@ export interface UserPreferences {
|
||||
ordering?: string;
|
||||
per_page?: number;
|
||||
zoom?: number;
|
||||
online_hot_default?: boolean;
|
||||
}
|
||||
|
||||
export interface User {
|
||||
|
||||
Reference in New Issue
Block a user