mirror of
https://github.com/p-stream/p-stream.git
synced 2026-04-21 06:52:18 +00:00
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:
parent
10bde63575
commit
b24ada9b77
4 changed files with 55 additions and 19 deletions
|
|
@ -39,19 +39,33 @@ export function EmbedOption(props: {
|
||||||
return sourceMeta?.name ?? unknownEmbedName;
|
return sourceMeta?.name ?? unknownEmbedName;
|
||||||
}, [props.embedId, unknownEmbedName]);
|
}, [props.embedId, unknownEmbedName]);
|
||||||
|
|
||||||
const { run, errored, loading } = useEmbedScraping(
|
const { run, errored, loading, notFound } = useEmbedScraping(
|
||||||
props.routerId,
|
props.routerId,
|
||||||
props.sourceId,
|
props.sourceId,
|
||||||
props.url,
|
props.url,
|
||||||
props.embedId,
|
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 (
|
return (
|
||||||
<SelectableLink
|
<SelectableLink
|
||||||
loading={loading}
|
loading={loading}
|
||||||
error={errored}
|
error={errored && !notFound}
|
||||||
onClick={run}
|
onClick={run}
|
||||||
selected={props.embedId === currentEmbedId}
|
selected={props.embedId === currentEmbedId}
|
||||||
|
rightSide={rightSide}
|
||||||
>
|
>
|
||||||
<span className="flex flex-col">
|
<span className="flex flex-col">
|
||||||
<span>{embedName}</span>
|
<span>{embedName}</span>
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,7 @@ export function useEmbedScraping(
|
||||||
run,
|
run,
|
||||||
loading: request.loading,
|
loading: request.loading,
|
||||||
errored: !!request.error,
|
errored: !!request.error,
|
||||||
|
notFound: request.error instanceof NotFoundError,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -169,23 +169,26 @@ export function SelectableLink(props: {
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
error?: ReactNode;
|
error?: ReactNode;
|
||||||
box?: boolean;
|
box?: boolean;
|
||||||
|
rightSide?: ReactNode;
|
||||||
}) {
|
}) {
|
||||||
let rightContent;
|
let rightContent = props.rightSide; // Use custom rightSide if provided
|
||||||
if (props.selected) {
|
if (!rightContent) {
|
||||||
rightContent = (
|
if (props.selected) {
|
||||||
<Icon
|
rightContent = (
|
||||||
icon={Icons.CIRCLE_CHECK}
|
<Icon
|
||||||
className="text-xl text-video-context-type-accent"
|
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 (
|
return (
|
||||||
<Link
|
<Link
|
||||||
|
|
|
||||||
|
|
@ -28,15 +28,33 @@ function EmbedOption(props: {
|
||||||
return sourceMeta?.name ?? unknownEmbedName;
|
return sourceMeta?.name ?? unknownEmbedName;
|
||||||
}, [props.embedId, unknownEmbedName]);
|
}, [props.embedId, unknownEmbedName]);
|
||||||
|
|
||||||
const { run, errored, loading } = useEmbedScraping(
|
const { run, errored, loading, notFound } = useEmbedScraping(
|
||||||
props.routerId,
|
props.routerId,
|
||||||
props.sourceId,
|
props.sourceId,
|
||||||
props.url,
|
props.url,
|
||||||
props.embedId,
|
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 (
|
return (
|
||||||
<SelectableLink loading={loading} error={errored} onClick={run}>
|
<SelectableLink
|
||||||
|
loading={loading}
|
||||||
|
error={errored && !notFound}
|
||||||
|
onClick={run}
|
||||||
|
rightSide={rightSide}
|
||||||
|
>
|
||||||
<span className="flex flex-col">
|
<span className="flex flex-col">
|
||||||
<span>{embedName}</span>
|
<span>{embedName}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue