Sebastian Herrlinger 1 месяц назад
Родитель
Сommit
372eba31e8
1 измененных файлов с 74 добавлено и 8 удалено
  1. 74 8
      .opencode/plugins/tui-smoke.tsx

+ 74 - 8
.opencode/plugins/tui-smoke.tsx

@@ -68,30 +68,53 @@ const tone = (api: TuiApi) => {
 }
 
 type Skin = ReturnType<typeof tone>
+type CubeOpts = ConstructorParameters<typeof ThreeRenderable>[1] & {
+  tint?: Color
+  spec?: Color
+  ambient?: Color
+  key_light?: Color
+  fill_light?: Color
+}
+
+const rgb = (value: unknown, fallback: string) => {
+  if (typeof value === "string") return new THREE.Color(value)
+  if (value && typeof value === "object") {
+    const item = value as { r?: unknown; g?: unknown; b?: unknown }
+    if (typeof item.r === "number" && typeof item.g === "number" && typeof item.b === "number") {
+      return new THREE.Color(item.r, item.g, item.b)
+    }
+  }
+  return new THREE.Color(fallback)
+}
 
 class Cube extends ThreeRenderable {
   private cube: THREE.Mesh
+  private mat: THREE.MeshPhongMaterial
+  private amb: THREE.AmbientLight
+  private key: THREE.DirectionalLight
+  private fill: THREE.DirectionalLight
 
-  constructor(ctx: RenderContext, opts: ConstructorParameters<typeof ThreeRenderable>[1]) {
+  constructor(ctx: RenderContext, opts: CubeOpts) {
     const scene = new THREE.Scene()
     const camera = new THREE.PerspectiveCamera(40, 1, 0.1, 100)
     camera.position.set(0, 0, 2.55)
 
-    scene.add(new THREE.AmbientLight(new THREE.Color(0.4, 0.4, 0.4), 1.0))
+    const amb = new THREE.AmbientLight(rgb(opts.ambient, "#666666"), 1.0)
+    scene.add(amb)
 
-    const key = new THREE.DirectionalLight(new THREE.Color(1.0, 0.95, 0.9), 1.2)
+    const key = new THREE.DirectionalLight(rgb(opts.key_light, "#fff2e6"), 1.2)
     key.position.set(2.5, 2.0, 3.0)
     scene.add(key)
 
-    const fill = new THREE.DirectionalLight(new THREE.Color(0.5, 0.7, 1.0), 0.6)
+    const fill = new THREE.DirectionalLight(rgb(opts.fill_light, "#80b3ff"), 0.6)
     fill.position.set(-2.0, -1.5, 2.5)
     scene.add(fill)
 
     const geo = new THREE.BoxGeometry(1.0, 1.0, 1.0)
     const mat = new THREE.MeshPhongMaterial({
-      color: new THREE.Color(0.25, 0.8, 1.0),
+      color: rgb(opts.tint, "#40ccff"),
       shininess: 80,
-      specular: new THREE.Color(0.9, 0.9, 1.0),
+      specular: rgb(opts.spec, "#e6e6ff"),
     })
     const cube = new THREE.Mesh(geo, mat)
     cube.scale.setScalar(1.12)
@@ -109,6 +132,30 @@ class Cube extends ThreeRenderable {
     })
 
     this.cube = cube
+    this.mat = mat
+    this.amb = amb
+    this.key = key
+    this.fill = fill
+  }
+
+  set tint(value: Color | undefined) {
+    this.mat.color.copy(rgb(value, "#40ccff"))
+  }
+
+  set spec(value: Color | undefined) {
+    this.mat.specular.copy(rgb(value, "#e6e6ff"))
+  }
+
+  set ambient(value: Color | undefined) {
+    this.amb.color.copy(rgb(value, "#666666"))
+  }
+
+  set key_light(value: Color | undefined) {
+    this.key.color.copy(rgb(value, "#fff2e6"))
+  }
+
+  set fill_light(value: Color | undefined) {
+    this.fill.color.copy(rgb(value, "#80b3ff"))
   }
 
   protected override renderSelf(buf: OptimizedBuffer, dt: number): void {
@@ -554,8 +601,27 @@ const slot = (input: ReturnType<typeof cfg>) => ({
         </box>
       )
     },
-    sidebar_top(_ctx, value) {
-      return <smoke_cube id={`smoke-cube-${value.session_id.slice(0, 8)}`} width="100%" height={16} />
+    sidebar_top(ctx, value) {
+      const map = ctx.theme.current as Record<string, unknown>
+      const get = (name: string, fallback: string) => {
+        const item = map[name]
+        if (typeof item === "string") return item
+        if (item && typeof item === "object") return item as RGBA
+        return fallback
+      }
+
+      return (
+        <smoke_cube
+          id={`smoke-cube-${value.session_id.slice(0, 8)}`}
+          width="100%"
+          height={16}
+          tint={get("primary", ui.accent)}
+          spec={get("text", ui.text)}
+          ambient={get("textMuted", ui.muted)}
+          key_light={get("success", ui.accent)}
+          fill_light={get("info", ui.accent)}
+        />
+      )
     },
   },
 })