Route resource card clicks to /browse?post=<id> instead of relying on hash anchors, then manually calculate the sticky filter offset when scrolling to the target bubble. Start from the top and smooth-scroll to the card for a clear transition, with delayed auto realignments after media above the target settles.
44 lines
1.2 KiB
TypeScript
44 lines
1.2 KiB
TypeScript
import { useEffect } from "react";
|
|
import { useNavigate, useParams } from "react-router-dom";
|
|
import { getJSON } from "../../api";
|
|
import { langQuery, useI18n } from "../../i18n";
|
|
import { MOCK_POSTS } from "../../mocks/mockPosts";
|
|
import { POST_STREAM_USES_MOCK } from "../../components/messageStream/hooks/usePostStream";
|
|
import type { Post } from "../../types/post";
|
|
|
|
export function PostRedirect() {
|
|
const { id } = useParams();
|
|
const { lang } = useI18n();
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
if (!id) {
|
|
navigate("/browse", { replace: true });
|
|
return;
|
|
}
|
|
|
|
if (POST_STREAM_USES_MOCK) {
|
|
const post = MOCK_POSTS.find((p) => p.id === id);
|
|
navigate(
|
|
post ? `/browse?post=${encodeURIComponent(post.id)}` : "/browse",
|
|
{
|
|
replace: true,
|
|
},
|
|
);
|
|
return;
|
|
}
|
|
|
|
getJSON<Post>(
|
|
`/api/posts/${id}?lang=${encodeURIComponent(langQuery(lang))}`,
|
|
)
|
|
.then((post) => {
|
|
navigate(`/browse?post=${encodeURIComponent(post.id)}`, {
|
|
replace: true,
|
|
});
|
|
})
|
|
.catch(() => navigate("/browse", { replace: true }));
|
|
}, [id, lang, navigate]);
|
|
|
|
return <div className="text-neutral-400">…</div>;
|
|
}
|