diff --git a/src/gui/src/UI/Dashboard/TabApps.js b/src/gui/src/UI/Dashboard/TabApps.js index 2f5aba676..4f028a55b 100644 --- a/src/gui/src/UI/Dashboard/TabApps.js +++ b/src/gui/src/UI/Dashboard/TabApps.js @@ -73,7 +73,7 @@ function buildTileHtml (app) { const { title, targetLink } = resolveTileDisplay(app); const iconUrl = app.iconUrl || window.icons['app.svg']; - let h = `
`; + let h = `
`; h += '
'; h += ``; h += '
'; @@ -292,10 +292,10 @@ const TabApps = { const appName = $(this).attr('data-app-name'); const appTitle = $(this).attr('data-app-title'); const appUid = $(this).attr('data-app-uid'); - const nameLower = (appName || '').toLowerCase(); - const noUninstall = APP_NAMES_NO_UNINSTALL.has(nameLower); + // Only offer Uninstall when it will actually stick (see loadApps). + const canUninstall = $(this).attr('data-app-uninstallable') === '1'; - const items = noUninstall + const items = ! canUninstall ? [] : [ { @@ -943,6 +943,22 @@ const TabApps = { iconUrl: app.iconUrl || app.icon || null, })); + // Uninstall only sticks for apps the user actually installed that + // are NOT in the hardcoded recommended list — revokeApp on a + // recommended app does nothing lasting because get-launch-apps + // re-adds it on the next load, so the tile "comes back" and the + // uninstall looks broken. Compute installability against both lists. + const recommendedNames = new Set( + (launchData.recommended || []).map(a => a.name), + ); + const installedNames = new Set( + (Array.isArray(installedApps) ? installedApps : []).map(a => a.name), + ); + const isUninstallable = name => + installedNames.has(name) + && ! recommendedNames.has(name) + && ! APP_NAMES_NO_UNINSTALL.has((name || '').toLowerCase()); + // Build seen set from launch apps const seen = new Set(); const merged = []; @@ -950,14 +966,14 @@ const TabApps = { for ( const app of launchApps ) { if ( seen.has(app.name) ) continue; seen.add(app.name); - merged.push(app); + merged.push({ ...app, uninstallable: isUninstallable(app.name) }); } // Append installed apps that aren't already in the list for ( const app of installedApps ) { if ( seen.has(app.name) ) continue; seen.add(app.name); - merged.push(app); + merged.push({ ...app, uninstallable: isUninstallable(app.name) }); } // Overlay the user's saved ordering (if any). New apps are appended