chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { useState } from 'react';
import { Skeleton } from '#/components/atoms/skeleton.jsx';
import { RefSelect } from '#/components/molecules/ref-select.jsx';
import { RepoTree } from '#/components/molecules/repo-tree.jsx';
import { SearchField } from '#/components/molecules/search-field.jsx';
import { useFileList } from '#/lib/source.js';
/**
* The source view: one directory down the left, whatever the reader opened
* down the right. Opening a file keeps its neighbours in view, which is what
* makes reading a repository feel like reading a checkout.
*
* The rail opens on the ref picker and a filter over the tree, the way a
* forge's file rail does. The gauges are the home's, not the rail's. The tree is
* the whole repository, opened along the way to `dirPath`, with `selected`
* marked: the file in view, or the directory itself. The pane keeps its own
* scroll, so a long tree and a long file each move on their own.
* @param {{repo: string, record: Record<string, unknown>, refName: string, onSelectRef: (ref: string) => void, dirPath: string, selected?: string, space?: string, children: import('react').ReactNode}} props
*/
export function SourcePanes({
repo,
record,
refName,
onSelectRef,
dirPath,
selected = '',
space,
children,
}) {
const { data: files } = useFileList(repo, refName, space);
const [filter, setFilter] = useState('');
return (
// The panes fill what the window has left and each takes its own scroll,
// so a long listing and a long file move past each other.
<div className="flex min-h-0 flex-1 items-stretch">
<aside className="hidden w-72 shrink-0 flex-col border-border border-r md:flex">
<div className="flex shrink-0 flex-col gap-2 border-border border-b px-3 py-3">
<RefSelect
repo={record}
value={refName}
onSelect={onSelectRef}
className="w-full justify-start [&>span]:max-w-none"
/>
<SearchField
value={filter}
onChange={setFilter}
placeholder="Filter files"
/>
</div>
<div className="min-h-0 flex-1 overflow-y-auto">
{files ? (
<RepoTree
repo={repo}
refName={refName}
files={files}
path={dirPath}
selected={selected || dirPath}
filter={filter}
/>
) : (
<div className="flex flex-col gap-2 p-4">
<Skeleton className="h-4 w-32" />
<Skeleton className="h-4 w-24" />
<Skeleton className="h-4 w-36" />
</div>
)}
</div>
</aside>
<div className="min-w-0 flex-1 overflow-y-auto">{children}</div>
</div>
);
}