feat: onboarding polish, splash screen, controller nav, dev script
Some checks failed
Build Archipelago ISO / build-iso (push) Has been cancelled
Build Archipelago ISO (dev) / build-iso (push) Failing after 45m15s

Onboarding flow:
- Intro: improved layout and transitions
- DID: better card styling and responsiveness
- Path: added visual enhancements
- Backup/Identity/Verify: streamlined markup
- SplashScreen component added

UI:
- Controller navigation improvements (useControllerNav)
- Style.css refinements

Backend:
- Runtime package fix

Dev:
- dev-start.sh improvements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-28 13:41:52 +00:00
parent 82eeb915a3
commit 7f03e39f58
12 changed files with 92 additions and 67 deletions

View File

@@ -74,13 +74,7 @@
</div>
<!-- Action Buttons -->
<div class="flex gap-3 sm:gap-4 max-w-[600px] mx-auto flex-shrink-0 px-3 sm:px-4 pb-4 sm:pb-6">
<button
@click="skipForNow"
class="path-action-button path-action-button--skip"
>
Skip
</button>
<div class="flex justify-center max-w-[600px] mx-auto flex-shrink-0 px-3 sm:px-4 pb-4 sm:pb-6">
<button
@click="proceed"
:disabled="!downloaded"
@@ -149,8 +143,5 @@ function proceed() {
router.push('/onboarding/verify').catch(() => {})
}
function skipForNow() {
router.push('/onboarding/verify').catch(() => {})
}
</script>

View File

@@ -98,15 +98,10 @@
</div>
<!-- Action Buttons -->
<div class="flex gap-4 max-w-[600px] mx-auto flex-shrink-0">
<button
@click="skipForNow"
class="path-action-button path-action-button--skip"
>
Skip
</button>
<div class="flex justify-center max-w-[600px] mx-auto flex-shrink-0">
<button
v-if="generatedDid"
ref="continueButton"
@click="proceed"
class="path-action-button path-action-button--continue"
>
@@ -118,11 +113,12 @@
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { rpcClient } from '@/api/rpc-client'
const router = useRouter()
const continueButton = ref<HTMLButtonElement | null>(null)
const generatedDid = ref<string>('')
const nostrNpub = ref<string>('')
const isGenerating = ref(false)
@@ -185,6 +181,16 @@ async function fetchDid() {
}
}
watch(generatedDid, (did) => {
if (did) {
nextTick(() => {
setTimeout(() => {
continueButton.value?.focus({ preventScroll: true })
}, 100)
})
}
})
onMounted(() => {
const cached = localStorage.getItem('neode_did')
const cachedNpub = localStorage.getItem('neode_nostr_npub')
@@ -205,11 +211,6 @@ function proceed() {
router.push('/onboarding/identity').catch(() => {})
}
function skipForNow() {
stopTimers()
router.push('/onboarding/identity').catch(() => {})
}
function copyDid() {
if (!generatedDid.value) return
navigator.clipboard.writeText(generatedDid.value).catch(() => {})

View File

@@ -60,13 +60,7 @@
<p v-else-if="errorMessage" class="text-red-400 text-sm text-center mb-4">{{ errorMessage }}</p>
<!-- Action Buttons -->
<div class="flex gap-3 sm:gap-4 max-w-[600px] mx-auto flex-shrink-0 px-3 sm:px-4 pb-4 sm:pb-6">
<button
@click="skip"
class="path-action-button path-action-button--skip"
>
Skip
</button>
<div class="flex justify-center max-w-[600px] mx-auto flex-shrink-0 px-3 sm:px-4 pb-4 sm:pb-6">
<button
@click="createIdentity"
:disabled="isCreating"
@@ -127,7 +121,4 @@ async function createIdentity() {
}
}
function skip() {
router.push('/onboarding/backup').catch(() => {})
}
</script>

View File

@@ -18,6 +18,7 @@
</p>
<button
ref="ctaButton"
@click="goToOptions"
class="glass-button px-6 py-3 sm:px-8 sm:py-4 rounded-lg text-base sm:text-lg font-medium transition-all hover:bg-black/70 hover:border-white/30 onb-cta"
>
@@ -65,12 +66,20 @@
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import AnimatedLogo from '@/components/AnimatedLogo.vue'
import { rpcClient } from '@/api/rpc-client'
const router = useRouter()
const ctaButton = ref<HTMLButtonElement | null>(null)
onMounted(() => {
// Auto-focus after entry animation completes (1.4s animation delay + 0.6s duration)
setTimeout(() => {
ctaButton.value?.focus({ preventScroll: true })
}, 2100)
})
function goToOptions() {
router.push('/onboarding/path').catch(() => {})

View File

@@ -82,6 +82,7 @@
<!-- Action Buttons -->
<div class="flex justify-center max-w-[600px] mx-auto flex-shrink-0 px-3 sm:px-4 pb-4 sm:pb-6">
<button
ref="continueButton"
@click="proceed"
class="path-action-button path-action-button--continue"
>
@@ -93,9 +94,17 @@
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const continueButton = ref<HTMLButtonElement | null>(null)
onMounted(() => {
setTimeout(() => {
continueButton.value?.focus({ preventScroll: true })
}, 400)
})
function proceed() {
router.push('/onboarding/did').catch(() => {})

View File

@@ -63,13 +63,7 @@
</div>
<!-- Action Buttons -->
<div class="flex gap-3 sm:gap-4 max-w-[600px] mx-auto flex-shrink-0 px-3 sm:px-4 pb-4 sm:pb-6">
<button
@click="skipForNow"
class="path-action-button path-action-button--skip"
>
Skip
</button>
<div class="flex justify-center max-w-[600px] mx-auto flex-shrink-0 px-3 sm:px-4 pb-4 sm:pb-6">
<button
v-if="verified"
@click="proceed"
@@ -152,13 +146,5 @@ async function proceed() {
router.push('/onboarding/done').catch(() => {})
}
async function skipForNow() {
try {
await completeOnboarding()
} catch {
/* localStorage fallback ensures we can proceed */
}
router.push('/onboarding/done').catch(() => {})
}
</script>