Refactor Indeehub integration and enhance deployment documentation

- Updated Indeehub references throughout the codebase, changing the name from "IndeedHub" to "Indeehub" for consistency.
- Implemented a virtual app structure for Indeehub, allowing it to open an external URL without requiring a container.
- Enhanced deployment scripts and documentation to clarify SSH access and password management for Indeehub.
- Improved error handling and retry logic in various components to ensure better user experience during onboarding and app interactions.
- Updated CSS for visual enhancements and added new buttons for improved navigation in the AppLauncherOverlay.
This commit is contained in:
Dorian
2026-03-01 17:53:18 +00:00
parent 2c15311ab6
commit 7a05e11834
34 changed files with 877 additions and 163 deletions
+34 -12
View File
@@ -136,7 +136,7 @@ import AnimatedLogo from '@/components/AnimatedLogo.vue'
import { useAppStore } from '../stores/app'
import { useLoginTransitionStore } from '../stores/loginTransition'
import { rpcClient } from '../api/rpc-client'
import { startSynthwave, stopSynthwave, playLoginSuccessWhoosh, playPop } from '@/composables/useLoginSounds'
import { resumeAudioContext, startSynthwave, stopSynthwave, playLoginSuccessWhoosh, playPop } from '@/composables/useLoginSounds'
const router = useRouter()
const store = useAppStore()
@@ -155,17 +155,25 @@ const isSetupMode = computed(() => {
})
onMounted(async () => {
if (sessionStorage.getItem('archipelago_from_splash') !== '1') {
startSynthwave()
} else {
sessionStorage.removeItem('archipelago_from_splash')
const fromSplash = sessionStorage.getItem('archipelago_from_splash') === '1'
if (fromSplash) sessionStorage.removeItem('archipelago_from_splash')
const unlock = () => {
if (!fromSplash) {
resumeAudioContext()
startSynthwave()
}
document.removeEventListener('click', unlock)
document.removeEventListener('touchstart', unlock)
document.removeEventListener('keydown', unlock)
}
document.addEventListener('click', unlock, { once: true })
document.addEventListener('touchstart', unlock, { once: true })
document.addEventListener('keydown', unlock, { once: true })
if (isSetupMode.value) {
try {
const result = await rpcClient.call<boolean>({ method: 'auth.isSetup', params: {} })
const result = await rpcClient.call<boolean>({ method: 'auth.isSetup', params: {}, timeout: 8000 })
isSetup.value = Boolean(result)
} catch (err) {
console.error('Failed to check setup status:', err)
} catch {
isSetup.value = false
}
} else {
@@ -207,10 +215,17 @@ async function handleSetup() {
loginTransition.setJustLoggedIn(true)
await store.login(password.value)
await new Promise(r => setTimeout(r, 520))
router.replace({ name: 'home' })
await router.replace({ name: 'home' }).catch(() => {
window.location.href = '/dashboard'
})
} catch (err) {
whooshAway.value = false
error.value = err instanceof Error ? err.message : 'Setup failed. Please try again.'
const msg = err instanceof Error ? err.message : ''
if (/502|503|Bad Gateway|timeout|fetch|network/i.test(msg)) {
error.value = 'Server is starting up. Please try again in a moment.'
} else {
error.value = msg || 'Setup failed. Please try again.'
}
startSynthwave()
} finally {
loading.value = false
@@ -237,10 +252,17 @@ async function handleLogin() {
playLoginSuccessWhoosh()
loginTransition.setJustLoggedIn(true)
await new Promise(r => setTimeout(r, 520))
router.replace({ name: 'home' })
await router.replace({ name: 'home' }).catch(() => {
window.location.href = '/dashboard'
})
} catch (err) {
whooshAway.value = false
error.value = err instanceof Error ? err.message : 'Login failed. Please check your password.'
const msg = err instanceof Error ? err.message : ''
if (/502|503|Bad Gateway|timeout|fetch|network/i.test(msg)) {
error.value = 'Server is starting up. Please try again in a moment.'
} else {
error.value = msg || 'Login failed. Please check your password.'
}
startSynthwave()
} finally {
loading.value = false