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:
+19
-14
@@ -171,7 +171,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, ref, onBeforeUnmount } from 'vue'
|
||||
import { useRouter, RouterLink } from 'vue-router'
|
||||
import { useAppStore } from '../stores/app'
|
||||
import { useAppLauncherStore } from '../stores/appLauncher'
|
||||
@@ -187,7 +187,7 @@ const loadingActions = ref<Record<string, boolean>>({})
|
||||
// Use real packages from store - no more dummy apps
|
||||
const packages = computed(() => {
|
||||
const realPackages = store.packages
|
||||
console.log('[Apps] Real packages from store:', Object.keys(realPackages || {}).length, 'apps')
|
||||
if (import.meta.env.DEV) console.log('[Apps] Real packages from store:', Object.keys(realPackages || {}).length, 'apps')
|
||||
return realPackages || {}
|
||||
})
|
||||
|
||||
@@ -276,7 +276,7 @@ function launchApp(id: string) {
|
||||
}
|
||||
|
||||
// For other apps, navigate to app details which has launch functionality
|
||||
router.push(`/dashboard/apps/${id}`)
|
||||
router.push(`/dashboard/apps/${id}`).catch(() => {})
|
||||
}
|
||||
|
||||
function getStatusClass(state: PackageState): string {
|
||||
@@ -297,19 +297,20 @@ function getStatusClass(state: PackageState): string {
|
||||
}
|
||||
|
||||
function goToApp(id: string) {
|
||||
router.push(`/dashboard/apps/${id}`)
|
||||
router.push(`/dashboard/apps/${id}`).catch(() => {})
|
||||
}
|
||||
|
||||
const actionTimers = new Map<string, ReturnType<typeof setTimeout>>()
|
||||
|
||||
async function startApp(id: string) {
|
||||
loadingActions.value[id] = true
|
||||
try {
|
||||
await store.startPackage(id)
|
||||
// Wait for state update from WebSocket
|
||||
// The loader will be cleared when we receive the updated state
|
||||
// For now, keep a max timeout as fallback
|
||||
setTimeout(() => {
|
||||
if (actionTimers.has(id)) clearTimeout(actionTimers.get(id)!)
|
||||
actionTimers.set(id, setTimeout(() => {
|
||||
loadingActions.value[id] = false
|
||||
}, 5000)
|
||||
actionTimers.delete(id)
|
||||
}, 5000))
|
||||
} catch (err) {
|
||||
console.error('Failed to start app:', err)
|
||||
loadingActions.value[id] = false
|
||||
@@ -320,18 +321,22 @@ async function stopApp(id: string) {
|
||||
loadingActions.value[id] = true
|
||||
try {
|
||||
await store.stopPackage(id)
|
||||
// Wait for state update from WebSocket
|
||||
// The loader will be cleared when we receive the updated state
|
||||
// For now, keep a max timeout as fallback
|
||||
setTimeout(() => {
|
||||
if (actionTimers.has(id)) clearTimeout(actionTimers.get(id)!)
|
||||
actionTimers.set(id, setTimeout(() => {
|
||||
loadingActions.value[id] = false
|
||||
}, 5000)
|
||||
actionTimers.delete(id)
|
||||
}, 5000))
|
||||
} catch (err) {
|
||||
console.error('Failed to stop app:', err)
|
||||
loadingActions.value[id] = false
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
for (const t of actionTimers.values()) clearTimeout(t)
|
||||
actionTimers.clear()
|
||||
})
|
||||
|
||||
// @ts-ignore - Function kept for future use
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
|
||||
Reference in New Issue
Block a user