Fix broken note links (#380)
* fix broken note links * remove unused prop * make comment easier to understand * handle case where root event ID is missing * add missing return * fix root finding logic * update comment
This commit is contained in:
parent
7928670153
commit
0a5491eede
@ -1,6 +1,6 @@
|
||||
import "./Text.css";
|
||||
import { useMemo, useCallback } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import { visit, SKIP } from "unist-util-visit";
|
||||
import * as unist from "unist";
|
||||
@ -28,6 +28,8 @@ export interface TextProps {
|
||||
}
|
||||
|
||||
export default function Text({ content, tags, creator }: TextProps) {
|
||||
const location = useLocation();
|
||||
|
||||
function extractLinks(fragments: Fragment[]) {
|
||||
return fragments
|
||||
.map(f => {
|
||||
@ -80,7 +82,10 @@ export default function Text({ content, tags, creator }: TextProps) {
|
||||
case "e": {
|
||||
const eText = hexToBech32("note", ref.Event).substring(0, 12);
|
||||
return (
|
||||
<Link to={eventLink(ref.Event ?? "")} onClick={e => e.stopPropagation()}>
|
||||
<Link
|
||||
to={eventLink(ref.Event ?? "")}
|
||||
onClick={e => e.stopPropagation()}
|
||||
state={{ from: location.pathname }}>
|
||||
#{eText}
|
||||
</Link>
|
||||
);
|
||||
|
@ -254,15 +254,12 @@ const TierThree = ({ active, path, isLastSubthread, from, notes, related, chains
|
||||
};
|
||||
|
||||
export interface ThreadProps {
|
||||
this?: u256;
|
||||
notes?: TaggedRawEvent[];
|
||||
}
|
||||
|
||||
export default function Thread(props: ThreadProps) {
|
||||
const notes = props.notes ?? [];
|
||||
const parsedNotes = notes.map(a => new NEvent(a));
|
||||
// root note has no thread info
|
||||
const root = useMemo(() => parsedNotes.find(a => a.Thread === null), [notes]);
|
||||
const [path, setPath] = useState<HexKey[]>([]);
|
||||
const currentId = path.length > 0 && path[path.length - 1];
|
||||
const currentRoot = useMemo(() => parsedNotes.find(a => a.Id === currentId), [notes, currentId]);
|
||||
@ -295,6 +292,33 @@ export default function Thread(props: ThreadProps) {
|
||||
return chains;
|
||||
}, [notes]);
|
||||
|
||||
const root = useMemo(() => {
|
||||
const isRoot = (ne?: NEvent) => ne?.Thread === null;
|
||||
const currentNote = parsedNotes.find(ne => ne.Id === urlNoteHex);
|
||||
|
||||
if (isRoot(currentNote)) {
|
||||
return currentNote;
|
||||
}
|
||||
|
||||
const rootEventId = currentNote?.Thread?.Root?.Event;
|
||||
|
||||
// sometimes the root event ID is missing, and we can only take the happy path if the root event ID exists
|
||||
if (rootEventId) {
|
||||
return parsedNotes.find(ne => ne.Id === rootEventId);
|
||||
}
|
||||
|
||||
const possibleRoots = parsedNotes.filter(isRoot);
|
||||
|
||||
// worst case we need to check every possible root to see which one contains the current note as a child
|
||||
for (const ne of possibleRoots) {
|
||||
const children = chains.get(ne.Id) ?? [];
|
||||
|
||||
if (children.find(ne => ne.Id === urlNoteHex)) {
|
||||
return ne;
|
||||
}
|
||||
}
|
||||
}, [notes, chains, urlNoteHex]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!root) {
|
||||
return;
|
||||
@ -370,7 +394,7 @@ export default function Thread(props: ThreadProps) {
|
||||
const newPath = path.slice(0, path.length - 1);
|
||||
setPath(newPath);
|
||||
} else {
|
||||
navigate("/");
|
||||
navigate(location.state?.from ?? "/");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,5 +8,5 @@ export default function EventPage() {
|
||||
const id = parseId(params.id ?? "");
|
||||
const thread = useThreadFeed(id);
|
||||
|
||||
return <Thread notes={thread.notes} this={id} />;
|
||||
return <Thread key={id} notes={thread.notes} />;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user