]> Repos - crimata-os/commitdiff
Wire UI dock to crimata-dock service
authorAndrew Gundersen <adgundersen@gmail.com>
Fri, 27 Feb 2026 16:13:37 +0000 (11:13 -0500)
committerAndrew Gundersen <adgundersen@gmail.com>
Fri, 27 Feb 2026 16:13:37 +0000 (11:13 -0500)
- Fetch installed apps from /dock/apps on init instead of hardcoded list
- Refresh running status every 10s
- Map dock response to app format (add url: /apps/{id})
- Show running indicator dot on active apps in dock

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ui/index.html
ui/js/os.js
ui/styles/dock.css

index 6f10d71f3a7b33d33d841220245874e48ea27aad..432482b925d1a537ee8108e7416bedadaa32ece3 100644 (file)
@@ -57,6 +57,7 @@
     <template x-for="app in installedApps" :key="app.id">
       <div class="dock-icon" @click="openApp(app)" :title="app.name">
         <span x-text="app.icon"></span>
+        <span class="dock-dot" x-show="app.running"></span>
       </div>
     </template>
   </div>
index d02dae41bfc7bd426e26d606ab8eec5153472bc7..04cc59f0e0105d2fae3d0d3441882ec8f2cf5f47 100644 (file)
@@ -122,15 +122,28 @@ document.addEventListener('alpine:init', () => {
     },
 
     // ── Installed apps ────────────────────────────────────────────────────
-    // Loaded from crimata.json manifests on the server
-    installedApps: [
-      { id: 'bio',      name: 'Bio',      icon: '🪪', url: '/apps/bio' },
-      { id: 'contacts', name: 'Contacts', icon: '👥', url: '/apps/contacts' },
-      { id: 'blog',     name: 'Blog',     icon: '📝', url: '/apps/blog' },
-    ],
+    installedApps: [],
+
+    async loadApps() {
+      try {
+        const res  = await fetch('/dock/apps')
+        const data = await res.json()
+        this.installedApps = data.map(app => ({
+          ...app,
+          url: `/apps/${app.id}`,
+        }))
+      } catch (e) {
+        console.error('dock unreachable:', e)
+      }
+    },
 
     // ── Init ──────────────────────────────────────────────────────────────
-    init() {
+    async init() {
+      await this.loadApps()
+
+      // Refresh running status every 10s
+      setInterval(() => this.loadApps(), 10_000)
+
       // Open bio full-screen on load
       const bio = this.installedApps.find(a => a.id === 'bio')
       if (bio) this.openApp(bio)
index bcb87c39f6f77cc824687917c978fefe751ae928..b9f088503c42da2087a8ee101042a9f9a3fb3922 100644 (file)
@@ -15,6 +15,7 @@
 }
 
 .dock-icon {
+  position: relative;
   width: 52px;
   height: 52px;
   border-radius: 12px;
   user-select: none;
 }
 
+.dock-dot {
+  position: absolute;
+  bottom: -6px;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 4px;
+  height: 4px;
+  border-radius: 50%;
+  background: rgba(255,255,255,0.9);
+}
+
 .dock-icon:hover {
   transform: translateY(-8px) scale(1.1);
   background: rgba(255,255,255,0.35);