fix(nav): the address keeps what the app rewrites around it (review round 3)
- The Feed press over a live search ends only the search: the feed's own view stays named. - Leaving a search steps back only off an entry the app pushed (_ytOwn); one a link or a reload opened is cleared in place, also where the Navigation API is missing. - useUrlMirror rewrites a changed view through replaceView, so a reload's overlay marks go; its first write and its landing writes keep them for an overlay that reopens. - Files and Playlists: a box emptied and filled again settles at once, never naming the ended search. - Playlists: a linked player is scoped to the playlist the store started with, and only the rail's own move to the first playlist is no pick. - Contract: writer objects are scanned to their matching brace, a computed or shorthand key is refused, and every useHistorySubview call hands a named definition. - Lint: playwright/no-skipped-test also refuses fixme (gate snapshot regenerated). - FEED_DEFAULT_SORT at the three remaining sites; linkedNotListed says to search by name.
This commit is contained in:
@@ -24,6 +24,7 @@ import {
|
||||
import { YouTubeIcon } from "../../lib/brandIcons";
|
||||
import {
|
||||
api,
|
||||
FEED_DEFAULT_SORT,
|
||||
HttpError,
|
||||
refusalReason,
|
||||
type FeedFilters,
|
||||
@@ -318,7 +319,7 @@ export default function Feed({
|
||||
const qEmpty = !filters.q.trim();
|
||||
useEffect(() => {
|
||||
if (qEmpty && parseSort(filters.sort).key === "relevance") {
|
||||
setFilters({ ...filters, sort: buildSort("date", "desc") });
|
||||
setFilters({ ...filters, sort: FEED_DEFAULT_SORT });
|
||||
}
|
||||
// Naming `filters` is safe precisely because the write below falsifies the condition above: the
|
||||
// sort it sets is "date", so the one re-run it causes does nothing. The old `[qEmpty]` was
|
||||
@@ -624,7 +625,7 @@ export default function Feed({
|
||||
.catch((e: unknown) =>
|
||||
notifyActionError(e, i18n.t("errors.writeFailed.clearSearch")),
|
||||
);
|
||||
setFilters({ ...filters, librarySource: "organic", sort: "newest" });
|
||||
setFilters({ ...filters, librarySource: "organic", sort: FEED_DEFAULT_SORT });
|
||||
onExitYtSearch();
|
||||
dropFeedCaches();
|
||||
qc.removeQueries({ queryKey: qk.ytSearch() });
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FEED_DEFAULT_SORT } from "../../lib/api";
|
||||
import { YouTubeIcon } from "../../lib/brandIcons";
|
||||
import { useMe } from "../../lib/useMe";
|
||||
import { PageHeader } from "../../components/ui/PageShell";
|
||||
@@ -25,9 +26,9 @@ export default function FeedHeader() {
|
||||
placeholder={t("header.searchPlaceholder")}
|
||||
onChange={(q) => {
|
||||
// When a search first appears, rank the feed by relevance — set atomically with the
|
||||
// query (race-free vs. per-keystroke updates). Only overrides the default "newest"
|
||||
// query (race-free vs. per-keystroke updates). Only overrides the default
|
||||
// sort; a custom sort the user chose is left alone. Cleared in Feed.
|
||||
const startSearch = !filters.q.trim() && !!q.trim() && filters.sort === "newest";
|
||||
const startSearch = !filters.q.trim() && !!q.trim() && filters.sort === FEED_DEFAULT_SORT;
|
||||
setFilters({ ...filters, q, ...(startSearch ? { sort: "relevance" } : {}) });
|
||||
}}
|
||||
// Turned off on this instance, the box only filters: no Go that could only be refused.
|
||||
|
||||
Reference in New Issue
Block a user