fix(plugin-manager): reset a failed preview by source instead of a key

Co-authored-by: ZiyaZhang <[email protected]>
This commit is contained in:
turtle1999andZiyaZhang committed 2026-10-14 16:55:21 +08:00
1 parent aac50c7923
commit a2141868de
5 files changed
+9 -6

No files matched your search

+1
View File
@@ -688,6 +688,7 @@ describe('web e2e: plugin manager', () => {
})
it('shows an optional feature preview before activation and leaves other plugin details unchanged', async () => {
onTestFailed(() => saveFailureShot(page, 'web-e2e-plugin-manager-preview'))
const panel = await openPluginsPanel()
await panel.getByRole('button', { name: '更多', exact: true }).click()
await panel.getByRole('button', { name: '查看 DSH 徽章技能', exact: true }).click()
@@ -54,8 +54,8 @@
en: ca75c51c89c2c9b0
zh: 2064958b0754647e
/deepseek-ai-dsh-client-ui-plugin-manager/known-limitations-and-deferred-work:
en: 149c0d23a56a4944
zh: e2feaadc871581ae
en: 344ba1e802163bb4
zh: f3cc2e30ffb037cb
/deepseek-ai-dsh-client-ui-plugin-manager/known-limitations-and-deferred-work/dev-note:
en: e67f633dc6fe7773
zh: 3bb0c20c93f16f98
@@ -153,6 +153,7 @@ None; this package neither assembles nor sends a provider request.
## Known Limitations and Deferred Work
- Feature previews have one image per language and no dark-theme variant, so the badge skill preview keeps its light background in dark theme.
- Ping response time does not measure package-download throughput. Probes use the Host fetch route, which pnpm-specific proxy settings can differ from; users can always choose the registry manually, and installation retains its existing fallback rules.
<a id="known-limitations-and-deferred-work"></a>
@@ -153,6 +153,7 @@ Host 入口通过生成的 Remote 接口暴露 `pluginRegistryProbe.fastest()`
## 已知限制与延期工作
- 功能配图每种语言只有一张,没有深色主题版本,因此徽章技能配图在深色主题中仍为浅色背景。
- Ping 响应时间不代表包下载吞吐量。探测使用 Host fetch 的网络路径,pnpm 专用代理设置可能使用不同路径;用户始终可以手动选择安装源,安装仍遵循现有回退规则。
<a id="known-limitations-and-deferred-work"></a>
@@ -247,10 +247,10 @@ function PackageArtwork({ src, row = false, size = row ? ROW_ARTWORK_SIZE : CARD
/** A bundle's feature preview; a failed decode is reported in place without blocking management. */
function PackagePreview({ src, title, t }: { readonly src: string; readonly title: string; readonly t: Translate }): ReactNode {
const [failed, setFailed] = useState(false)
return failed
const [failedSource, setFailedSource] = useState<string>()
return src === failedSource
? <p className={css.reason} role="status">{t('previewUnavailable')}</p>
: <img className={css.packagePreview} src={src} alt={t('previewAlt', { name: title })} onError={() => { setFailed(true) }} />
: <img className={css.packagePreview} src={src} alt={t('previewAlt', { name: title })} onError={() => { setFailedSource(src) }} />
}
/** A row's switch: locked, saying why, when the Host refuses to address the row through the profile patch. */
@@ -771,7 +771,7 @@ function PackageDetail({
<MetadataError error={pkg.meta?.error} t={t} />
{pkg.error === undefined ? null : <p className={css.reason} role="status">{t('reasonLabel')}: {managementText(pkg.error, t)}</p>}
{pkg.readOnlyReason === undefined ? null : <p className={css.reason} role="status">{managementText({ code: pkg.readOnlyReason }, t)}</p>}
{preview === undefined ? null : <PackagePreview key={preview} src={preview} title={title} t={t} />}
{preview === undefined ? null : <PackagePreview src={preview} title={title} t={t} />}
<div className={css.detailSections}>
{configured
? (