Handle 'not found' state in embed source selection

Adds a 'notFound' state to useEmbedScraping and updates SourceSelectingView, SourceSelectPart, and SelectableLink to display a distinct UI when an embed source is not found. This improves user feedback for unavailable sources and refines error handling logic.
This commit is contained in:
Pas 2025-12-06 21:48:28 -07:00
parent 10bde63575
commit b24ada9b77
4 changed files with 55 additions and 19 deletions

View file

@ -39,19 +39,33 @@ export function EmbedOption(props: {
return sourceMeta?.name ?? unknownEmbedName;
}, [props.embedId, unknownEmbedName]);
const { run, errored, loading } = useEmbedScraping(
const { run, errored, loading, notFound } = useEmbedScraping(
props.routerId,
props.sourceId,
props.url,
props.embedId,
);
let rightSide;
if (loading) {
rightSide = undefined; // Let SelectableLink handle loading
} else if (notFound) {
rightSide = (
<div className="flex items-center text-video-scraping-noresult">
<div className="w-4 h-4 rounded-full border-2 border-current bg-current flex items-center justify-center">
<div className="w-2 h-0.5 bg-background-main rounded-full" />
</div>
</div>
);
}
return (
<SelectableLink
loading={loading}
error={errored}
error={errored && !notFound}
onClick={run}
selected={props.embedId === currentEmbedId}
rightSide={rightSide}
>
<span className="flex flex-col">
<span>{embedName}</span>

View file

@ -124,6 +124,7 @@ export function useEmbedScraping(
run,
loading: request.loading,
errored: !!request.error,
notFound: request.error instanceof NotFoundError,
};
}

View file

@ -169,23 +169,26 @@ export function SelectableLink(props: {
disabled?: boolean;
error?: ReactNode;
box?: boolean;
rightSide?: ReactNode;
}) {
let rightContent;
if (props.selected) {
rightContent = (
<Icon
icon={Icons.CIRCLE_CHECK}
className="text-xl text-video-context-type-accent"
/>
);
let rightContent = props.rightSide; // Use custom rightSide if provided
if (!rightContent) {
if (props.selected) {
rightContent = (
<Icon
icon={Icons.CIRCLE_CHECK}
className="text-xl text-video-context-type-accent"
/>
);
}
if (props.error)
rightContent = (
<span className="flex items-center text-video-context-error">
<Icon className="ml-2" icon={Icons.WARNING} />
</span>
);
if (props.loading) rightContent = <Spinner className="text-lg" />; // should override selected and error
}
if (props.error)
rightContent = (
<span className="flex items-center text-video-context-error">
<Icon className="ml-2" icon={Icons.WARNING} />
</span>
);
if (props.loading) rightContent = <Spinner className="text-lg" />; // should override selected and error
return (
<Link

View file

@ -28,15 +28,33 @@ function EmbedOption(props: {
return sourceMeta?.name ?? unknownEmbedName;
}, [props.embedId, unknownEmbedName]);
const { run, errored, loading } = useEmbedScraping(
const { run, errored, loading, notFound } = useEmbedScraping(
props.routerId,
props.sourceId,
props.url,
props.embedId,
);
let rightSide;
if (loading) {
rightSide = undefined; // Let SelectableLink handle loading
} else if (notFound) {
rightSide = (
<div className="flex items-center text-video-scraping-noresult">
<div className="w-4 h-4 rounded-full border-2 border-current bg-current flex items-center justify-center">
<div className="w-2 h-0.5 bg-background-main rounded-full" />
</div>
</div>
);
}
return (
<SelectableLink loading={loading} error={errored} onClick={run}>
<SelectableLink
loading={loading}
error={errored && !notFound}
onClick={run}
rightSide={rightSide}
>
<span className="flex flex-col">
<span>{embedName}</span>
</span>