Address PR #1214 code review feedback

- Fix template-expanded URIs not rendering: construct synthetic Resource
  from readState.uri when the URI is absent from the resources list
- Fix non-image blob content rendering raw base64: show placeholder
  message; also handle audio blobs properly
- Hide mimeType display when multiple content items to avoid confusion
- Rename ResourceControls selectedTemplate → selectedTemplateUri for
  consistency with selectedUri and selectedResourceUri

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
cliffhall 2026-04-18 18:54:48 -04:00
commit 8c9aac6df1
3 changed files with 26 additions and 12 deletions

View file

@ -22,7 +22,7 @@ export interface ResourceControlsProps {
templates: ResourceTemplate[]; templates: ResourceTemplate[];
subscriptions: InspectorResourceSubscription[]; subscriptions: InspectorResourceSubscription[];
selectedUri?: string; selectedUri?: string;
selectedTemplate?: string; selectedTemplateUri?: string;
listChanged: boolean; listChanged: boolean;
onRefreshList: () => void; onRefreshList: () => void;
onSelectUri: (uri: string) => void; onSelectUri: (uri: string) => void;
@ -46,7 +46,7 @@ export function ResourceControls({
templates, templates,
subscriptions, subscriptions,
selectedUri, selectedUri,
selectedTemplate, selectedTemplateUri,
listChanged, listChanged,
onRefreshList, onRefreshList,
onSelectUri, onSelectUri,
@ -137,9 +137,9 @@ export function ResourceControls({
<ResourceListItem <ResourceListItem
key={template.uriTemplate} key={template.uriTemplate}
resource={template} resource={template}
selected={template.uriTemplate === selectedTemplate} selected={template.uriTemplate === selectedTemplateUri}
onClick={() => { onClick={() => {
if (template.uriTemplate !== selectedTemplate) if (template.uriTemplate !== selectedTemplateUri)
onSelectTemplate(template.uriTemplate); onSelectTemplate(template.uriTemplate);
}} }}
/> />

View file

@ -30,7 +30,13 @@ function toContentBlock(
if (mimeType.startsWith("image/")) { if (mimeType.startsWith("image/")) {
return { type: "image", data: item.blob, mimeType }; return { type: "image", data: item.blob, mimeType };
} }
return { type: "text", text: item.blob }; if (mimeType.startsWith("audio/")) {
return { type: "audio", data: item.blob, mimeType };
}
return {
type: "text",
text: `[Binary content (${mimeType}) — preview not supported]`,
};
} }
function formatLastUpdated(date: Date): string { function formatLastUpdated(date: Date): string {
@ -113,7 +119,7 @@ export function ResourcePreviewPanel({
) : ( ) : (
<Spacer /> <Spacer />
)} )}
<MimeText>{mimeType}</MimeText> {contents.length <= 1 && <MimeText>{mimeType}</MimeText>}
</MetaRow> </MetaRow>
<FooterRow> <FooterRow>
<AnnotationGroup> <AnnotationGroup>

View file

@ -96,6 +96,14 @@ export function ResourcesScreen({
? templates.find((t) => t.uriTemplate === selectedTemplateUri) ? templates.find((t) => t.uriTemplate === selectedTemplateUri)
: undefined; : undefined;
// For template-expanded URIs that don't appear in the resources list,
// construct a synthetic Resource so the preview panel can render.
const readResource: Resource | undefined =
selectedResource ??
(readState?.uri && readState.uri === selectedResourceUri
? { name: readState.uri, uri: readState.uri }
: undefined);
function renderReadState() { function renderReadState() {
if (!readState) return null; if (!readState) return null;
@ -120,17 +128,17 @@ export function ResourcesScreen({
); );
} }
if (readState.result && selectedResource) { if (readState.result && readResource) {
return ( return (
<DetailCard> <DetailCard>
<ResourcePreviewPanel <ResourcePreviewPanel
resource={selectedResource} resource={readResource}
contents={readState.result.contents} contents={readState.result.contents}
lastUpdated={readState.lastUpdated} lastUpdated={readState.lastUpdated}
isSubscribed={readState.isSubscribed ?? false} isSubscribed={readState.isSubscribed ?? false}
onRefresh={() => onReadResource(selectedResource.uri)} onRefresh={() => onReadResource(readResource.uri)}
onSubscribe={() => onSubscribeResource(selectedResource.uri)} onSubscribe={() => onSubscribeResource(readResource.uri)}
onUnsubscribe={() => onUnsubscribeResource(selectedResource.uri)} onUnsubscribe={() => onUnsubscribeResource(readResource.uri)}
/> />
</DetailCard> </DetailCard>
); );
@ -148,7 +156,7 @@ export function ResourcesScreen({
templates={templates} templates={templates}
subscriptions={subscriptions} subscriptions={subscriptions}
selectedUri={selectedResourceUri} selectedUri={selectedResourceUri}
selectedTemplate={selectedTemplateUri} selectedTemplateUri={selectedTemplateUri}
listChanged={listChanged} listChanged={listChanged}
onRefreshList={onRefreshList} onRefreshList={onRefreshList}
onSelectUri={onSelectUri} onSelectUri={onSelectUri}