frontend: polish app launch and release experience
This commit is contained in:
@@ -50,7 +50,7 @@ export function isServicePackage(id: string, pkg?: PackageDataEntry): boolean {
|
||||
// Known app -> category mappings (matches App Store categorisation)
|
||||
export const APP_CATEGORY_MAP: Record<string, string> = {
|
||||
'bitcoin-knots': 'money', 'bitcoin-ui': 'money', 'electrumx': 'money', 'electrs': 'money',
|
||||
'lnd': 'money', 'mempool': 'money', 'mempool-web': 'money', 'btcpay-server': 'commerce', 'saleor': 'commerce',
|
||||
'lnd': 'money', 'mempool': 'money', 'mempool-web': 'money', 'btcpay-server': 'commerce',
|
||||
'fedimint': 'money', 'fedimint-gateway': 'money',
|
||||
'indeedhub': 'media', 'jellyfin': 'media', 'photoprism': 'media', 'immich': 'media',
|
||||
'nextcloud': 'data', 'vaultwarden': 'data', 'filebrowser': 'data', 'cryptpad': 'data',
|
||||
@@ -165,6 +165,8 @@ const APP_ICON_FALLBACKS: Record<string, string> = {
|
||||
gitea: '/assets/img/app-icons/gitea.svg',
|
||||
}
|
||||
|
||||
export const DEFAULT_APP_ICON = '/assets/icon/favico-black-v2.svg'
|
||||
|
||||
export function resolveAppIcon(id: string, pkg: PackageDataEntry, curatedIcon?: string): string {
|
||||
const rawIcon = (pkg["static-files"]?.icon || "").trim()
|
||||
const icon = rawIcon === '/assets/img/favico.png' ? '' : rawIcon
|
||||
@@ -184,9 +186,23 @@ export function canLaunch(pkg: PackageDataEntry): boolean {
|
||||
const hasRuntimeAddress = !!pkg.installed?.['interface-addresses']?.main?.['lan-address']
|
||||
const hasKnownLaunchUrl = typeof window !== 'undefined' && !!resolveAppUrl(pkg.manifest.id)
|
||||
const hasUI = pkg.manifest.interfaces?.main?.ui || hasRuntimeAddress || hasKnownLaunchUrl
|
||||
if ((pkg.manifest.id === 'fedimint' || pkg.manifest.id === 'fedimintd') && hasUI) {
|
||||
return pkg.state === PackageState.Running || pkg.state === PackageState.Starting
|
||||
}
|
||||
return !!hasUI && pkg.state === 'running' && pkg.health !== 'starting' && pkg.health !== 'unhealthy'
|
||||
}
|
||||
|
||||
export function launchBlockedReason(id: string, pkg?: PackageDataEntry | null): string {
|
||||
const appId = pkg?.manifest?.id || id
|
||||
if (
|
||||
(appId === 'fedimint' || appId === 'fedimintd') &&
|
||||
(pkg?.state === PackageState.Starting || (pkg?.state === PackageState.Running && pkg?.health === 'starting'))
|
||||
) {
|
||||
return 'Guardian opens a wait page until Bitcoin finishes initial sync.'
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
export function resolveRuntimeLaunchUrl(pkg: PackageDataEntry): string {
|
||||
const addr = runtimeLanAddress(pkg)
|
||||
if (!addr || typeof window === 'undefined') return addr
|
||||
@@ -272,14 +288,8 @@ export function handleImageError(e: Event) {
|
||||
return
|
||||
}
|
||||
|
||||
const placeholderSvg = `data:image/svg+xml,${encodeURIComponent(`
|
||||
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="64" height="64" rx="12" fill="rgba(255,255,255,0.1)"/>
|
||||
<path d="M32 20L40 28H36V40H28V28H24L32 20Z" fill="rgba(255,255,255,0.6)"/>
|
||||
<path d="M20 44H44V48H20V44Z" fill="rgba(255,255,255,0.4)"/>
|
||||
</svg>
|
||||
`)}`
|
||||
if (!currentSrc.includes("data:image")) {
|
||||
target.src = placeholderSvg
|
||||
if (!currentSrc.includes(DEFAULT_APP_ICON)) {
|
||||
target.src = DEFAULT_APP_ICON
|
||||
target.dataset.defaultIcon = "1"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user