hot fixes to utc-6

This commit is contained in:
Dorian
2026-03-12 12:56:59 +00:00
parent 6fee6befed
commit f05198ea09
26 changed files with 1123 additions and 76 deletions
+33 -6
View File
@@ -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',
+1 -1
View File
@@ -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,
+8 -31
View File
@@ -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>