diff --git a/image-recipe/build-auto-installer-iso.sh b/image-recipe/build-auto-installer-iso.sh index 7a1ed697..ad9c9f6a 100755 --- a/image-recipe/build-auto-installer-iso.sh +++ b/image-recipe/build-auto-installer-iso.sh @@ -1055,7 +1055,7 @@ IMAGES_CAPTURED_FROM_SERVER=0 if [ -n "$DEV_SERVER" ] && [ "$DEV_SERVER" != "localhost" ] && [ "$DEV_SERVER" != "127.0.0.1" ]; then echo " Capturing container images from live server ($DEV_SERVER)..." # Patterns match against `podman images` repository names (not container names) - CAPTURE_PATTERNS="bitcoin-ui bitcoinknots lnd lnd-ui electrs-ui filebrowser mempool backend frontend electrs tailscale homeassistant home-assistant btcpayserver nbxplorer postgres alpine-tor nostr-rs-relay strfry fedimintd gatewayd dwn-server grafana uptime-kuma jellyfin vaultwarden searxng mariadb valkey nginx-alpine portainer photoprism nextcloud nginx-proxy-manager onlyoffice adguard" + CAPTURE_PATTERNS="bitcoin-ui bitcoinknots lnd lnd-ui electrs-ui filebrowser mempool backend frontend electrs tailscale homeassistant home-assistant btcpayserver nbxplorer postgres alpine-tor nostr-rs-relay strfry fedimintd gatewayd dwn-server vaultwarden searxng mariadb valkey nginx-alpine portainer nginx-proxy-manager adguard" REMOTE_TMP="/tmp/archipelago-image-capture-$$" SAVED_LIST=$(ssh "$DEV_SERVER" "mkdir -p $REMOTE_TMP && for p in $CAPTURE_PATTERNS; do img=\$(podman images --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep -i \"\$p\" | head -1); [ -n \"\$img\" ] && podman save -o \"$REMOTE_TMP/\$p.tar\" \"\$img\" 2>/dev/null && echo \"\$p\"; done" 2>/dev/null) || true for p in $SAVED_LIST; do diff --git a/neode-ui/package.json b/neode-ui/package.json index 1a759ec1..c616c2a0 100644 --- a/neode-ui/package.json +++ b/neode-ui/package.json @@ -1,7 +1,7 @@ { "name": "neode-ui", "private": true, - "version": "1.2.0-alpha", + "version": "1.3.2", "type": "module", "scripts": { "start": "./start-dev.sh", diff --git a/neode-ui/src/composables/useOnboarding.ts b/neode-ui/src/composables/useOnboarding.ts index a2648452..b20e9156 100644 --- a/neode-ui/src/composables/useOnboarding.ts +++ b/neode-ui/src/composables/useOnboarding.ts @@ -29,4 +29,15 @@ export async function isOnboardingComplete(): Promise { export async function completeOnboarding(): Promise { await callWithRetry(() => rpcClient.completeOnboarding(), 3) localStorage.setItem('neode_onboarding_complete', '1') + localStorage.removeItem('neode_onboarding_step') +} + +/** Save current onboarding step so refresh resumes where user left off */ +export function saveOnboardingStep(step: string): void { + localStorage.setItem('neode_onboarding_step', step) +} + +/** Get the last saved onboarding step, or 'intro' if none */ +export function getSavedOnboardingStep(): string { + return localStorage.getItem('neode_onboarding_step') || 'intro' } diff --git a/neode-ui/src/main.ts b/neode-ui/src/main.ts index a1e949bf..d27e2f6e 100644 --- a/neode-ui/src/main.ts +++ b/neode-ui/src/main.ts @@ -4,6 +4,24 @@ import './style.css' import App from './App.vue' import router from './router' import i18n from './i18n' + +// Clipboard polyfill for HTTP (non-secure) contexts where navigator.clipboard is unavailable +if (!navigator.clipboard) { + Object.defineProperty(navigator, 'clipboard', { + value: { + async writeText(text: string) { + const ta = document.createElement('textarea') + ta.value = text + ta.style.cssText = 'position:fixed;opacity:0' + document.body.appendChild(ta) + ta.select() + document.execCommand('copy') + document.body.removeChild(ta) + }, + async readText() { return '' }, + }, + }) +} import { useToast } from '@/composables/useToast' const app = createApp(App) diff --git a/neode-ui/src/router/index.ts b/neode-ui/src/router/index.ts index 0f327189..4229c0ca 100644 --- a/neode-ui/src/router/index.ts +++ b/neode-ui/src/router/index.ts @@ -303,10 +303,11 @@ router.beforeEach(async (to, _from, next) => { } // Check if this is a fresh install that needs onboarding try { - const { isOnboardingComplete } = await import('@/composables/useOnboarding') + const { isOnboardingComplete, getSavedOnboardingStep } = await import('@/composables/useOnboarding') const setupDone = await isOnboardingComplete() if (!setupDone) { - next('/onboarding/intro') + const step = getSavedOnboardingStep() + next(`/onboarding/${step}`) return } } catch { @@ -328,6 +329,14 @@ router.beforeEach(async (to, _from, next) => { next() }) +// Persist onboarding step so page refresh resumes where user left off +router.afterEach((to) => { + const match = to.path.match(/^\/onboarding\/(.+)/) + if (match && match[1] !== 'intro') { + localStorage.setItem('neode_onboarding_step', match[1]!) + } +}) + // Stop all login/splash audio when entering the dashboard router.afterEach((to, from) => { if (to.path.startsWith('/dashboard') && !from.path.startsWith('/dashboard')) { diff --git a/neode-ui/src/views/OnboardingSeedRestore.vue b/neode-ui/src/views/OnboardingSeedRestore.vue index 8a768fdc..58487880 100644 --- a/neode-ui/src/views/OnboardingSeedRestore.vue +++ b/neode-ui/src/views/OnboardingSeedRestore.vue @@ -39,6 +39,15 @@ +
+
+

Your Nostr ID

+
+

{{ restoredNpub }}

+
+

For Nostr social apps and NIP-07 signing

+
+
@@ -120,6 +129,7 @@ const isRestoring = ref(false) const errorMessage = ref('') const serverStarting = ref(false) const restoredDid = ref('') +const restoredNpub = ref('') const allFilled = computed(() => seedWords.value.every(w => w.trim().length > 0)) @@ -167,6 +177,7 @@ async function restore() { if (res.restored) { restored.value = true restoredDid.value = res.did + restoredNpub.value = res.nostr_npub || '' if (res.did) localStorage.setItem('neode_did', res.did) if (res.nostr_npub) localStorage.setItem('neode_nostr_npub', res.nostr_npub) diff --git a/neode-ui/src/views/apps/AppCard.vue b/neode-ui/src/views/apps/AppCard.vue index 17edac15..8dbc237d 100644 --- a/neode-ui/src/views/apps/AppCard.vue +++ b/neode-ui/src/views/apps/AppCard.vue @@ -10,17 +10,17 @@ @click="$emit('goToApp', id)" @keydown.enter="handleEnter" > - +
-
- +
+ - Installing + {{ installProgress?.message || 'Installing...' }}
@@ -40,7 +40,7 @@