fix: disable boot reconciler, fix onboarding loop, UI polish
Critical flow fixes: - Disable boot reconciliation that auto-created ALL containers on unbundled installs (only FileBrowser should exist on first boot) - Fix onboarding loop: RootRedirect no longer clears the neode_onboarding_complete flag on boot screen completion - Seed phrase persists when navigating back (no regeneration) UI fixes: - Boot screen: removed github and save icons from animation loop - Seed screens: viewport height scaling with 100dvh - Seed restore: removed outer card container from word input grid - Seed screens use distinct background (bg-intro-1.jpg) - Install progress simplified to "Installing" button style - Uninstall state moved to global store (persists across navigation) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
08f7f58a9d
commit
73fb961b9a
@@ -13,17 +13,14 @@
|
||||
<!-- Installing overlay -->
|
||||
<div
|
||||
v-if="isInstalling"
|
||||
class="absolute inset-0 z-20 flex flex-col items-center justify-center bg-black/70 backdrop-blur-sm rounded-xl gap-2"
|
||||
class="absolute inset-0 z-20 flex items-center justify-center bg-black/70 backdrop-blur-sm rounded-xl"
|
||||
>
|
||||
<div class="flex items-center gap-3 text-amber-400">
|
||||
<div class="flex items-center gap-3 text-white/90">
|
||||
<svg class="animate-spin h-5 w-5" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
<span class="text-sm font-medium">{{ installProgress?.message || t('common.installing') }}...</span>
|
||||
</div>
|
||||
<div v-if="installProgress" class="w-3/4 h-1 bg-white/10 rounded-full overflow-hidden">
|
||||
<div class="h-full bg-amber-500 rounded-full transition-all" :style="{ width: `${installProgress.progress}%` }"></div>
|
||||
<span class="text-sm font-medium">Installing</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,16 +2,19 @@
|
||||
|
||||
import { ref, onBeforeUnmount } from 'vue'
|
||||
import { useAppStore } from '@/stores/app'
|
||||
import { useServerStore } from '@/stores/server'
|
||||
|
||||
export function useAppsActions() {
|
||||
const store = useAppStore()
|
||||
const serverStore = useServerStore()
|
||||
const loadingActions = ref<Record<string, boolean>>({})
|
||||
const actionError = ref('')
|
||||
let errorTimer: ReturnType<typeof setTimeout> | undefined
|
||||
const actionTimers = new Map<string, ReturnType<typeof setTimeout>>()
|
||||
|
||||
const uninstalling = ref(false)
|
||||
const uninstallingApps = ref<Set<string>>(new Set())
|
||||
// Use global store so uninstall state persists across navigation
|
||||
const uninstallingApps = serverStore.uninstallingApps
|
||||
|
||||
function showActionError(msg: string) {
|
||||
actionError.value = msg
|
||||
@@ -70,14 +73,14 @@ export function useAppsActions() {
|
||||
async function confirmUninstall(appId: string) {
|
||||
uninstalling.value = true
|
||||
try {
|
||||
uninstallingApps.value.add(appId)
|
||||
uninstallingApps.add(appId)
|
||||
await store.uninstallPackage(appId)
|
||||
// State update comes via WebSocket — no manual deletion needed
|
||||
} catch (err) {
|
||||
if (import.meta.env.DEV) console.error('Failed to uninstall app:', err)
|
||||
showActionError(`Failed to uninstall: ${err instanceof Error ? err.message : 'Unknown error'}`)
|
||||
} finally {
|
||||
uninstallingApps.value.delete(appId)
|
||||
uninstallingApps.delete(appId)
|
||||
uninstalling.value = false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user