From 2787a9bbfc3dc2938a516fcbf2f0b9c277f66823 Mon Sep 17 00:00:00 2001 From: archipelago Date: Fri, 7 Aug 2026 14:48:55 -0400 Subject: [PATCH] fix(ui): unknown app ids fall back to the A mark, not a 404 png guess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resolveAppIcon's final arm guessed /assets/img/app-icons/.png — strfry 404'd live. DEFAULT_APP_ICON already existed; the chain now ends on it. Co-Authored-By: Claude --- neode-ui/src/views/apps/__tests__/appsConfig.test.ts | 9 ++++++++- neode-ui/src/views/apps/appsConfig.ts | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/neode-ui/src/views/apps/__tests__/appsConfig.test.ts b/neode-ui/src/views/apps/__tests__/appsConfig.test.ts index 885b1a7e..46d4157b 100644 --- a/neode-ui/src/views/apps/__tests__/appsConfig.test.ts +++ b/neode-ui/src/views/apps/__tests__/appsConfig.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest' import { ref } from 'vue' import { PackageState, type PackageDataEntry } from '@/types/api' -import { canLaunch, filterEntriesForTab, hasFrontendUi, isServiceContainer, isServicePackage, isWebsitePackage, launchBlockedReason, resolveAppIcon, useCategoriesWithApps } from '../appsConfig' +import { canLaunch, filterEntriesForTab, hasFrontendUi, isServiceContainer, isServicePackage, isWebsitePackage, launchBlockedReason, resolveAppIcon, useCategoriesWithApps, DEFAULT_APP_ICON } from '../appsConfig' function makePkg(id: string, title: string, category: string): PackageDataEntry { return { @@ -82,6 +82,13 @@ describe('appsConfig service filtering', () => { expect(resolveAppIcon('gitea', pkg)).toBe('/assets/img/app-icons/gitea.svg') }) + it('an unmapped id gets the A mark, not a guessed png that 404s', () => { + // strfry 404'd live on 2026-08-07: no curated entry, no fallback entry, + // no service prefix — the old `${id}.png` guess produced a broken tile. + const pkg = makePkg('strfry', 'strfry', 'nostr') + expect(resolveAppIcon('strfry', pkg)).toBe(DEFAULT_APP_ICON) + }) + it('classifies an unknown app by whether its manifest declares a UI (#45)', () => { // Headless: a LAN address but no declared UI → Website. const headless = makePkg('some-backend', 'Some Backend', 'other') diff --git a/neode-ui/src/views/apps/appsConfig.ts b/neode-ui/src/views/apps/appsConfig.ts index cbf1020d..dc7a49b8 100644 --- a/neode-ui/src/views/apps/appsConfig.ts +++ b/neode-ui/src/views/apps/appsConfig.ts @@ -249,7 +249,9 @@ export function resolveAppIcon(id: string, pkg: PackageDataEntry, curatedIcon?: curatedIcon || APP_ICON_FALLBACKS[id] || serviceParentIcon(id) || - `/assets/img/app-icons/${id}.png` + // Never guess `${id}.png` — an unmapped id 404s (strfry did, 2026-08-07). + // The A mark is the honest unknown-app tile. + DEFAULT_APP_ICON ) }