import { useCallback, useRef, useState } from "react";
import type { Changes } from "@ace/channel/protocol";
import type { Listing } from "@ace/host/protocol";
import { SessionDetailsView, Sidebar, useLayoutRight } from "@ace/ui";
import { Conversation } from "./conversation";
import { host } from "./host";
import { CHAT, Layout } from "./layout/layout";
import { Diff } from "./panels/diff";
import { Terminal } from "./panels/terminal";
// Channels have one chat today; its tabs follow the chat the Chat tab shows.
const chat = 1;
export type ChannelDraft = { channel: string; text: string };
type Props = {
channel: Listing;
user: string;
remote: boolean;
draft?: ChannelDraft;
onDraftLoaded: () => void;
onSettings?: () => void;
};
export function ChannelDetails({ channel }: { channel: Listing }) {
const right = useLayoutRight();
return (
right.setOpen(false)} />
);
}
/** A channel's tabs: its chat, plus Diff and Terminal views of that chat's lane. */
export function Channel({ channel, user, remote, draft, onDraftLoaded, onSettings }: Props) {
const [changed, setChanged] = useState();
const check = useRef({ busy: false, again: false });
// One check at a time; work that lands during a check asks for one more after it.
const inspect = useCallback(() => {
const run = check.current;
if (run.busy) {
run.again = true;
return;
}
run.busy = true;
host.channel(channel.id, { op: "changes", chat }).then(
(value) => setChanged(value.files.length > 0),
() => {},
).finally(() => {
run.busy = false;
if (!run.again) return;
run.again = false;
inspect();
});
}, [channel.id]);
return (
{
if (uid === CHAT) {
return (
);
}
if (data.type === "diff") {
return ;
}
if (data.type !== "terminal") return null;
return (
update({ terminal })}
/>
);
}}
onTabClose={(_, data) => {
if (data.type !== "terminal" || !data.terminal) return;
host.request({ op: "terminal-close", terminal: data.terminal }).catch(() => {});
}}
/>
);
}