fix: route favorites cards through /resource so they survive language switch
All checks were successful
Deploy Staging (terry-wallet-login) / deploy (push) Successful in 1m18s

Favorites are stored regardless of language but the card click was navigating to /browse?post=<id>&single=1 in the current UI language. When the user switched languages (e.g. zh→en) and tapped a zh-only favorite, the /browse stream couldn't find the post in its English view and showed "Couldn't find this post in the current view".

Make Favorites navigate via /resource/<id> instead. PostRedirect already tries the current UI language first, then falls back to the post's source language and shows a toast. Renamed PopularRankRow's seldom-used `singlePostLink` to `linkToResource` to make the intent obvious; Favorites passes the new prop.
This commit is contained in:
TerryM
2026-06-06 00:04:19 +08:00
parent e80330b13c
commit 37e6e4901f
2 changed files with 13 additions and 4 deletions

View File

@@ -90,7 +90,7 @@ export function PopularRankRow({
browseSort = "popular", browseSort = "popular",
showRank = true, showRank = true,
showDownload = true, showDownload = true,
singlePostLink = false, linkToResource = false,
onFavoriteChange, onFavoriteChange,
}: { }: {
post: Post; post: Post;
@@ -99,7 +99,13 @@ export function PopularRankRow({
browseSort?: string; browseSort?: string;
showRank?: boolean; showRank?: boolean;
showDownload?: boolean; showDownload?: boolean;
singlePostLink?: boolean; /**
* When true, the card and download button route to `/resource/:id` so the
* `PostRedirect` page can fall back to the post's source language if the
* current UI language has no translation. Otherwise navigate inside the
* `/browse` stream which assumes the post exists in the current language.
*/
linkToResource?: boolean;
onFavoriteChange?: (postId: string, favorited: boolean) => void; onFavoriteChange?: (postId: string, favorited: boolean) => void;
}) { }) {
const { t, lang } = useI18n(); const { t, lang } = useI18n();
@@ -143,10 +149,13 @@ export function PopularRankRow({
<button <button
type="button" type="button"
onClick={() => { onClick={() => {
if (linkToResource) {
navigate(lp(`/resource/${encodeURIComponent(post.id)}`));
return;
}
const params = new URLSearchParams(); const params = new URLSearchParams();
if (browseSort) params.set("sort", browseSort); if (browseSort) params.set("sort", browseSort);
params.set("post", post.id); params.set("post", post.id);
if (singlePostLink) params.set("single", "1");
navigate(lp(`/browse?${params.toString()}`)); navigate(lp(`/browse?${params.toString()}`));
}} }}
aria-label={r.title} aria-label={r.title}

View File

@@ -201,7 +201,7 @@ export default function Favorites() {
browseSort="" browseSort=""
showRank={false} showRank={false}
showDownload={false} showDownload={false}
singlePostLink linkToResource
onFavoriteChange={(_, favorited) => { onFavoriteChange={(_, favorited) => {
if (!favorited) setReloadKey((value) => value + 1); if (!favorited) setReloadKey((value) => value + 1);
}} }}