<script lang="ts">
import MonacoEditor from "../layout/MonacoEditor.svelte";
import { getCodeExternal } from "../../api/client.js";
import { explorer as explorerStore } from "../../stores/explorer.svelte.js";
import type { WorktreeId } from "../../api/scope.svelte.js";
import { scoped } from "../../stores/worktree-scope.svelte.js";
const explorer = scoped(explorerStore);
/**
* A file outside the worktree that omnicode named — a dependency's source, a standard
* library — shown read-only. The daemon serves only files a language server answered with.
*/
interface Props {
worktree: WorktreeId;
token: string;
name: string;
line?: number | null;
column?: number | null;
}
let { worktree, token, name, line = null, column = null }: Props = $props();
let loaded = $state<{ token: string; text: string } | { token: string; error: string } | null>(null);
$effect(() => {
const asked = token;
getCodeExternal(worktree, asked).then(
({ text }) => {
if (token === asked) loaded = { token: asked, text };
},
(e: unknown) => {
if (token === asked) loaded = { token: asked, error: e instanceof Error ? e.message : String(e) };
},
);
});
</script>
<div class="external-source">
<div class="external-toolbar" title={name}>
<span class="external-name">{name}</span>
<span class="external-badge">read only</span>
</div>
{#if loaded === null || loaded.token !== token}
<div class="external-state">Loading {name}…</div>
{:else if "error" in loaded}
<div class="external-state error">{loaded.error}</div>
{:else}
{#key token}
<MonacoEditor
value={loaded.text}
language={explorer.languageIdForPath(name)}
readOnly={true}
revealLine={line}
revealColumn={column}
height="100%"
onchange={() => {}}
/>
{/key}
{/if}
</div>
<style>
.external-source {
height: 100%;
display: flex;
flex-direction: column;
min-height: 0;
background: var(--vscode-tab-activeBackground);
}
.external-toolbar {
height: var(--wb-control-size-40);
display: flex;
align-items: center;
gap: var(--wb-spacing-12);
padding: 0 var(--wb-spacing-12);
border-bottom: 1px solid var(--vscode-panel-border);
flex-shrink: 0;
font-size: var(--wb-font-size-12);
}
.external-name {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--vscode-editor-foreground);
font-weight: 600;
}
.external-badge {
flex-shrink: 0;
color: var(--vscode-descriptionForeground);
}
.external-state {
padding: var(--wb-spacing-12);
color: var(--vscode-descriptionForeground);
}
.external-state.error {
color: var(--vscode-errorForeground);
}
</style>