Spaces:
Running
Running
| <script lang="ts"> | |
| import { consoleStore } from '../../stores/console'; | |
| import ConsoleMessage from './ConsoleMessage.svelte'; | |
| import { afterUpdate } from 'svelte'; | |
| let consoleOutput: HTMLDivElement; | |
| let wasAtBottom = true; | |
| function clearConsole() { | |
| consoleStore.clear(); | |
| } | |
| function checkScrollPosition() { | |
| if (consoleOutput) { | |
| const threshold = 5; | |
| wasAtBottom = consoleOutput.scrollHeight - consoleOutput.scrollTop - consoleOutput.clientHeight < threshold; | |
| } | |
| } | |
| afterUpdate(() => { | |
| if (wasAtBottom && consoleOutput) { | |
| consoleOutput.scrollTop = consoleOutput.scrollHeight; | |
| } | |
| }); | |
| </script> | |
| <div class="console-section"> | |
| <div class="panel-header"> | |
| <h2>Console</h2> | |
| <button on:click={clearConsole} class="clear-button">Clear</button> | |
| </div> | |
| <div | |
| bind:this={consoleOutput} | |
| on:scroll={checkScrollPosition} | |
| class="console-output" | |
| > | |
| {#each $consoleStore.messages as message (message.id)} | |
| <ConsoleMessage {message} /> | |
| {/each} | |
| {#if $consoleStore.messages.length === 0} | |
| <div class="console-empty">Awaiting console output...</div> | |
| {/if} | |
| </div> | |
| </div> | |
| <style> | |
| .console-section { | |
| width: 100%; | |
| height: 100%; | |
| display: flex; | |
| flex-direction: column; | |
| background: rgba(8, 7, 6, 0.4); | |
| } | |
| .panel-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 10px 16px; | |
| background: rgba(15, 14, 12, 0.3); | |
| border-bottom: 1px solid rgba(139, 115, 85, 0.06); | |
| flex-shrink: 0; | |
| } | |
| .panel-header h2 { | |
| margin: 0; | |
| font-size: 11px; | |
| font-weight: 500; | |
| color: rgba(251, 248, 244, 0.5); | |
| text-transform: uppercase; | |
| letter-spacing: 0.5px; | |
| } | |
| .console-output { | |
| flex: 1; | |
| padding: 12px 16px; | |
| background: transparent; | |
| overflow-y: auto; | |
| font-family: "JetBrains Mono", "Monaco", "Menlo", monospace; | |
| font-size: 11px; | |
| line-height: 1.6; | |
| } | |
| .console-output::-webkit-scrollbar { | |
| width: 6px; | |
| } | |
| .console-output::-webkit-scrollbar-track { | |
| background: rgba(139, 115, 85, 0.02); | |
| } | |
| .console-output::-webkit-scrollbar-thumb { | |
| background: rgba(139, 115, 85, 0.1); | |
| border-radius: 3px; | |
| } | |
| .console-output::-webkit-scrollbar-thumb:hover { | |
| background: rgba(139, 115, 85, 0.15); | |
| } | |
| .console-empty { | |
| color: rgba(251, 248, 244, 0.3); | |
| font-style: italic; | |
| font-size: 11px; | |
| padding: 4px 6px; | |
| } | |
| .clear-button { | |
| padding: 4px 10px; | |
| background: rgba(139, 115, 85, 0.03); | |
| color: rgba(251, 248, 244, 0.4); | |
| border: 1px solid rgba(139, 115, 85, 0.08); | |
| border-radius: 4px; | |
| font-size: 10px; | |
| font-weight: 500; | |
| text-transform: uppercase; | |
| letter-spacing: 0.3px; | |
| cursor: pointer; | |
| transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); | |
| } | |
| .clear-button:hover { | |
| background: rgba(139, 115, 85, 0.06); | |
| color: rgba(251, 248, 244, 0.6); | |
| border-color: rgba(139, 115, 85, 0.12); | |
| } | |
| .clear-button:active { | |
| transform: scale(0.95); | |
| } | |
| </style> |