hot fixes to utc-6
This commit is contained in:
@@ -72,6 +72,7 @@
|
||||
</svg>
|
||||
{{ t('common.launch') }}
|
||||
</button>
|
||||
<template v-if="!isWebOnly">
|
||||
<button
|
||||
v-if="pkg.state === 'stopped'"
|
||||
@click="startApp"
|
||||
@@ -111,6 +112,7 @@
|
||||
</svg>
|
||||
{{ t('common.uninstall') }}
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -144,6 +146,7 @@
|
||||
|
||||
<!-- Uninstall Icon Button -->
|
||||
<button
|
||||
v-if="!isWebOnly"
|
||||
@click="uninstallApp"
|
||||
class="flex-shrink-0 w-10 h-10 rounded-lg bg-red-600/20 border border-red-600/40 text-red-300 hover:bg-red-600/30 transition-colors flex items-center justify-center"
|
||||
:title="t('common.uninstall')"
|
||||
@@ -159,6 +162,7 @@
|
||||
<button
|
||||
v-if="canLaunch"
|
||||
@click="launchApp"
|
||||
:class="isWebOnly ? 'col-span-2' : ''"
|
||||
class="glass-button glass-button-sm px-4 py-2.5 rounded-lg text-sm font-semibold flex items-center justify-center gap-2"
|
||||
>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
@@ -166,6 +170,7 @@
|
||||
</svg>
|
||||
{{ t('common.launch') }}
|
||||
</button>
|
||||
<template v-if="!isWebOnly">
|
||||
<button
|
||||
v-if="pkg.state === 'stopped'"
|
||||
@click="startApp"
|
||||
@@ -197,6 +202,7 @@
|
||||
</svg>
|
||||
{{ t('common.restart') }}
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -330,8 +336,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Requirements Card -->
|
||||
<div class="glass-card p-6">
|
||||
<!-- Requirements Card (hidden for web-only apps) -->
|
||||
<div v-if="!isWebOnly" class="glass-card p-6">
|
||||
<h3 class="text-lg font-bold text-white mb-4">{{ t('appDetails.requirements') }}</h3>
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-start gap-3">
|
||||
@@ -478,6 +484,20 @@ const { t } = useI18n()
|
||||
|
||||
const appId = computed(() => route.params.id as string)
|
||||
|
||||
// Web-only app detection (no container — external websites)
|
||||
const WEB_ONLY_APP_URLS: Record<string, string> = {
|
||||
'indeedhub': 'https://archipelago.indeehub.studio',
|
||||
'botfights': 'https://botfights.net',
|
||||
'nwnn': 'https://nwnn.l484.com',
|
||||
'484-kitchen': 'https://484.kitchen',
|
||||
'call-the-operator': 'https://cta.tx1138.com',
|
||||
'arch-presentation': 'https://present.l484.com',
|
||||
'syntropy-institute': 'https://syntropy.institute',
|
||||
't-zero': 'https://teeminuszero.net',
|
||||
}
|
||||
|
||||
const isWebOnly = computed(() => appId.value in WEB_ONLY_APP_URLS)
|
||||
|
||||
/** Map route/marketplace app IDs to backend package keys (container names). */
|
||||
const ROUTE_TO_PACKAGE_KEY: Record<string, string> = {
|
||||
mempool: 'mempool-web',
|
||||
@@ -625,7 +645,8 @@ const backButtonText = computed(() => {
|
||||
// Check if app has a UI interface and is running
|
||||
const canLaunch = computed(() => {
|
||||
if (!pkg.value) return false
|
||||
// For dummy apps, allow launch if running (they have interface addresses)
|
||||
// Web-only apps are always launchable
|
||||
if (isWebOnly.value) return true
|
||||
// For real apps, check for UI interface
|
||||
const hasUI = pkg.value.manifest.interfaces?.main?.ui || pkg.value.installed?.['interface-addresses']?.main
|
||||
const isRunning = pkg.value.state === 'running'
|
||||
@@ -693,12 +714,18 @@ function goBack() {
|
||||
|
||||
function launchApp() {
|
||||
if (!pkg.value) return
|
||||
|
||||
|
||||
const isDev = import.meta.env.DEV
|
||||
const id = appId.value
|
||||
|
||||
|
||||
// Web-only apps — use their external URL directly
|
||||
const webOnlyUrl = WEB_ONLY_APP_URLS[id]
|
||||
if (webOnlyUrl) {
|
||||
useAppLauncherStore().open({ url: webOnlyUrl, title: pkg.value.manifest.title })
|
||||
return
|
||||
}
|
||||
|
||||
// Special handling for apps with Docker containers
|
||||
// TODO: Replace dummy app URLs with real URLs when apps are packaged
|
||||
const appUrls: Record<string, { dev: string, prod: string }> = {
|
||||
'lorabell': {
|
||||
dev: 'http://192.168.1.166',
|
||||
|
||||
@@ -273,7 +273,7 @@ const WEB_ONLY_APPS: Record<string, PackageDataEntry> = {
|
||||
'indeedhub': {
|
||||
state: 'running' as PackageState,
|
||||
manifest: { id: 'indeedhub', title: 'Indeehub', version: '0.1.0', description: { short: 'Bitcoin documentary streaming platform', long: '' }, 'release-notes': '', license: '', 'wrapper-repo': '', 'upstream-repo': '', 'support-site': '', 'marketing-site': '', 'donation-url': null },
|
||||
'static-files': { license: '', instructions: '', icon: '/assets/img/app-icons/indeedhub.png' },
|
||||
'static-files': { license: '', instructions: '', icon: '/assets/img/app-icons/indeehub.ico' },
|
||||
},
|
||||
'botfights': {
|
||||
state: 'running' as PackageState,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="chat-fullscreen">
|
||||
<!-- Close button + connection indicator (desktop: top-right pill) -->
|
||||
<div class="chat-mode-pill hidden md:flex">
|
||||
<div class="chat-mode-pill flex">
|
||||
<button class="chat-close-btn" :aria-label="t('chat.closeAssistant')" @click="closeChat">
|
||||
<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
@@ -15,19 +15,12 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Mobile back button -->
|
||||
<button class="chat-mobile-back md:hidden" :aria-label="t('common.goBack')" @click="closeChat">
|
||||
<svg class="w-5 h-5" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- Loading indicator while checking availability or iframe loads -->
|
||||
<!-- Loading indicator while checking availability -->
|
||||
<Transition name="fade">
|
||||
<div v-if="aiuiAvailable === null || (aiuiUrl && !aiuiConnected)" class="chat-loading" role="status" aria-live="polite">
|
||||
<div v-if="aiuiAvailable === null" class="chat-loading" role="status" aria-live="polite">
|
||||
<div class="glass-card p-8 flex flex-col items-center gap-4">
|
||||
<div class="chat-loading-spinner" aria-hidden="true" />
|
||||
<p class="text-sm text-white/60">{{ aiuiAvailable === null ? t('chat.loadingAssistant') : t('chat.loadingAssistant') }}</p>
|
||||
<p class="text-sm text-white/60">{{ t('chat.loadingAssistant') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
@@ -39,13 +32,13 @@
|
||||
:src="aiuiUrl"
|
||||
:title="t('chat.aiAssistant')"
|
||||
class="chat-iframe chat-iframe-mobile"
|
||||
sandbox="allow-scripts allow-same-origin allow-forms"
|
||||
|
||||
allow="microphone"
|
||||
style="background: transparent"
|
||||
/>
|
||||
|
||||
<!-- Fallback when no AIUI URL configured -->
|
||||
<div v-else class="chat-placeholder">
|
||||
<!-- Fallback when AIUI is not deployed -->
|
||||
<div v-else-if="aiuiAvailable === false" class="chat-placeholder">
|
||||
<div class="chat-placeholder-inner">
|
||||
<div class="chat-placeholder-icon">
|
||||
<svg class="w-8 h-8 text-white/40" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
@@ -84,7 +77,7 @@ const aiuiUrl = computed(() => {
|
||||
const envUrl = import.meta.env.VITE_AIUI_URL
|
||||
if (envUrl) return `${envUrl}?embedded=true`
|
||||
// In production, only return the URL if we've confirmed AIUI files exist
|
||||
if (import.meta.env.PROD && aiuiAvailable.value === true) return '/aiui/?embedded=true'
|
||||
if (import.meta.env.PROD && aiuiAvailable.value === true) return `/aiui/?embedded=true&v=${Date.now()}`
|
||||
return ''
|
||||
})
|
||||
|
||||
@@ -177,20 +170,4 @@ onBeforeUnmount(() => {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.chat-mobile-back {
|
||||
position: absolute;
|
||||
top: 0.75rem;
|
||||
left: 0.75rem;
|
||||
z-index: 20;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
backdrop-filter: blur(8px);
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user