Refactor app navigation and enhance background handling in various views

- Added error handling for router navigation to prevent unhandled promise rejections.
- Improved background image management in Dashboard.vue to dynamically set images based on route.
- Introduced timers for managing loading states and cleanup on component unmount in Apps.vue, Marketplace.vue, and other views.
- Updated app detail navigation to ensure smoother transitions and error handling.
- Enhanced clipboard copy functionality in Settings.vue with improved user feedback.
This commit is contained in:
Dorian
2026-03-01 18:07:35 +00:00
parent 7a05e11834
commit 94eb1e4283
7 changed files with 218 additions and 399 deletions
+15 -14
View File
@@ -326,7 +326,7 @@
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useAppStore } from '../stores/app'
import { rpcClient } from '../api/rpc-client'
@@ -392,48 +392,50 @@ const features = computed(() => {
]
})
let pendingRedirect: ReturnType<typeof setTimeout> | null = null
onMounted(() => {
console.log('[MarketplaceAppDetails] Loading app ID:', appId.value)
if (import.meta.env.DEV) console.log('[MarketplaceAppDetails] Loading app ID:', appId.value)
try {
// Get app data from composable
const loadedApp = getCurrentApp()
if (loadedApp && loadedApp.id === appId.value) {
app.value = loadedApp
console.log('[MarketplaceAppDetails] App loaded successfully:', app.value)
loading.value = false
} else {
console.warn('[MarketplaceAppDetails] App data not found in composable')
loading.value = false
// Navigate back to marketplace
setTimeout(() => {
router.push('/dashboard/marketplace')
pendingRedirect = setTimeout(() => {
router.push('/dashboard/marketplace').catch(() => {})
}, 500)
}
} catch (e) {
console.error('[MarketplaceAppDetails] Error loading app data:', e)
loading.value = false
setTimeout(() => {
router.push('/dashboard/marketplace')
pendingRedirect = setTimeout(() => {
router.push('/dashboard/marketplace').catch(() => {})
}, 500)
}
})
onBeforeUnmount(() => {
if (pendingRedirect) { clearTimeout(pendingRedirect); pendingRedirect = null }
})
function handleImageError(e: Event) {
const target = e.target as HTMLImageElement
target.src = '/assets/img/logo-archipelago.svg'
}
function goBack() {
router.push('/dashboard/marketplace')
router.push('/dashboard/marketplace').catch(() => {})
}
function goToInstalledApp() {
router.push({
path: `/dashboard/apps/${appId.value}`,
query: { from: 'marketplace' }
})
}).catch(() => {})
}
async function installApp() {
@@ -478,8 +480,7 @@ async function installApp() {
// Wait a moment for the package to be registered
await new Promise(resolve => setTimeout(resolve, 1000))
// Navigate to the installed app
router.push(`/dashboard/apps/${appId.value}`)
router.push(`/dashboard/apps/${appId.value}`).catch(() => {})
} catch (err: any) {
installError.value = err.message || 'Installation failed. Please try again.'
console.error('[MarketplaceAppDetails] Failed to install app:', err)