import { Component, For, createSignal, createEffect, Show, onMount, onCleanup, createMemo } from "solid-js" import { instances, getInstanceLogs, isInstanceLogStreaming, setInstanceLogStreaming } from "../stores/instances" import { ChevronDown } from "lucide-solid" import InstanceInfo from "./instance-info" interface InfoViewProps { instanceId: string } const logsScrollState = new Map() const InfoView: Component = (props) => { let scrollRef: HTMLDivElement | undefined const savedState = logsScrollState.get(props.instanceId) const [autoScroll, setAutoScroll] = createSignal(savedState?.autoScroll ?? false) const instance = () => instances().get(props.instanceId) const logs = createMemo(() => getInstanceLogs(props.instanceId)) const streamingEnabled = createMemo(() => isInstanceLogStreaming(props.instanceId)) const handleEnableLogs = () => setInstanceLogStreaming(props.instanceId, true) const handleDisableLogs = () => setInstanceLogStreaming(props.instanceId, false) onMount(() => { if (scrollRef && savedState) { scrollRef.scrollTop = savedState.scrollTop } }) onCleanup(() => { if (scrollRef) { logsScrollState.set(props.instanceId, { scrollTop: scrollRef.scrollTop, autoScroll: autoScroll(), }) } }) createEffect(() => { if (autoScroll() && scrollRef && logs().length > 0) { scrollRef.scrollTop = scrollRef.scrollHeight } }) const handleScroll = () => { if (!scrollRef) return const isAtBottom = scrollRef.scrollHeight - scrollRef.scrollTop <= scrollRef.clientHeight + 50 setAutoScroll(isAtBottom) } const scrollToBottom = () => { if (scrollRef) { scrollRef.scrollTop = scrollRef.scrollHeight setAutoScroll(true) } } const formatTime = (timestamp: number) => { const date = new Date(timestamp) return date.toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit", }) } const getLevelColor = (level: string) => { switch (level) { case "error": return "log-level-error" case "warn": return "log-level-warn" case "debug": return "log-level-debug" default: return "log-level-default" } } return (
{(inst) => }

Server Logs

Show server logs } >

Server logs are paused

Enable streaming to watch your OpenCode server activity.

} > 0} fallback={
Waiting for server output...
} > {(entry) => (
{formatTime(entry.timestamp)} {entry.message}
)}
) } export default InfoView