fix: container DNS, nginx chown, onboarding guard, seed UX, install flow

Backend:
- Add --add-host host.containers.internal:host-gateway to LND and Bitcoin
  Knots containers (fixes DNS resolution failure in rootless podman)
- Add --user 0:0 and DAC_OVERRIDE to nginx UI sidecar containers
  (fixes chown crash in rootless podman for bitcoin-ui, electrs-ui, lnd-ui)
- Add hostadd to Rust Podman API client for web UI container installs
- Add Chromium privacy flags to kiosk launcher (disable telemetry)

Frontend:
- Fix onboarding reset on raw IP visits (trust localStorage as first-class
  signal, skip boot screen when server is up but not onboarded)
- Fix seed regression: persist challenge indices in sessionStorage so going
  back from Verify doesn't change which words are asked
- Remove glass container from seed Generate/Verify/Restore screens
- Add Back button to Restore from Seed screen
- Replace Network card: Tor (purple), VPN status (orange), Bitcoin sync (orange)
- Add ElectrumX to curated app list with correct .webp icon
- Install flow: navigate to My Apps immediately with toast, hide
  installed/installing apps from marketplace and discover views

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-04-01 13:06:57 +01:00
co-authored by Claude Opus 4.6
parent 19587687b4
commit dad184cfc6
14 changed files with 3874 additions and 233 deletions
+7
View File
@@ -144,6 +144,7 @@ import { useServerStore } from '@/stores/server'
import { rpcClient } from '@/api/rpc-client'
import { useMarketplaceApp } from '@/composables/useMarketplaceApp'
import { useAppLauncherStore } from '@/stores/appLauncher'
import { useToast } from '@/composables/useToast'
import DiscoverHero from './discover/DiscoverHero.vue'
import FeaturedApps from './discover/FeaturedApps.vue'
import AppGrid from './discover/AppGrid.vue'
@@ -427,9 +428,13 @@ function startInstallPolling(appId: string, statusMessage: string) {
}, 1000)
}
const toast = useToast()
async function installApp(app: MarketplaceApp) {
if (installingApps.has(app.id) || isInstalled(app.id)) return
installingApps.set(app.id, { id: app.id, title: app.title ?? app.id, status: 'downloading', progress: 10, message: 'Preparing installation...', attempt: 0 })
toast.info(`Installing ${app.title ?? app.id} — check My Apps`)
router.push('/dashboard/apps').catch(() => {})
try {
const installUrl = app.url || app.manifestUrl || app.s9pkUrl
installingApps.set(app.id, { ...installingApps.get(app.id)!, status: 'downloading', progress: 30, message: 'Downloading package...' })
@@ -446,6 +451,8 @@ async function installApp(app: MarketplaceApp) {
async function installCommunityApp(app: MarketplaceApp) {
if (installingApps.has(app.id) || isInstalled(app.id) || !app.dockerImage) return
installingApps.set(app.id, { id: app.id, title: app.title ?? app.id, status: 'downloading', progress: 10, message: 'Pulling Docker image...', attempt: 0 })
toast.info(`Installing ${app.title ?? app.id} — check My Apps`)
router.push('/dashboard/apps').catch(() => {})
try {
installingApps.set(app.id, { ...installingApps.get(app.id)!, status: 'downloading', progress: 20, message: 'Downloading container image...' })
await rpcClient.call({ method: 'package.install', params: { id: app.id, dockerImage: app.dockerImage, version: app.version }, timeout: 180000 })