clean up proposal logic
This commit is contained in:
@@ -274,10 +274,11 @@ function mapActionToButton(action: SuggestedAction) {
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="rounded-xl"
|
||||
key={action.id}
|
||||
onClick={restartApp}
|
||||
>
|
||||
Restart App
|
||||
Restart app
|
||||
</Button>
|
||||
);
|
||||
default:
|
||||
@@ -292,8 +293,21 @@ function mapActionToButton(action: SuggestedAction) {
|
||||
|
||||
function ActionProposalActions({ proposal }: { proposal: ActionProposal }) {
|
||||
return (
|
||||
<div className="p-2 pb-0">
|
||||
{proposal.actions.map((action) => mapActionToButton(action))}
|
||||
<div className="border-b border-border p-2 flex items-center justify-between">
|
||||
<div className="flex items-center space-x-2">
|
||||
{proposal.actions.map((action) => mapActionToButton(action))}
|
||||
</div>
|
||||
<AutoApproveSwitch />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AutoApproveSwitch() {
|
||||
// const [autoApprove, setAutoApprove] = useAtom(autoApproveAtom);
|
||||
return (
|
||||
<div className="flex items-center space-x-2">
|
||||
<Switch id="auto-approve" />
|
||||
<Label htmlFor="auto-approve">Auto-approve</Label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -376,17 +390,7 @@ function ChatInputActions({
|
||||
Reject
|
||||
</Button>
|
||||
<div className="flex items-center space-x-1 ml-auto">
|
||||
{/* Basic HTML checkbox styled to look like a toggle */}
|
||||
<input
|
||||
type="checkbox"
|
||||
id="auto-approve"
|
||||
checked={autoApprove}
|
||||
onChange={(e) => setAutoApprove(e.target.checked)}
|
||||
className="relative peer shrink-0 appearance-none w-8 h-4 border border-input rounded-full bg-input checked:bg-primary cursor-pointer after:absolute after:w-3 after:h-3 after:top-[1px] after:left-[2px] after:bg-background after:rounded-full after:transition-all checked:after:translate-x-4 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
|
||||
/>
|
||||
<label htmlFor="auto-approve" className="text-xs cursor-pointer">
|
||||
Auto-approve
|
||||
</label>
|
||||
<AutoApproveSwitch />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,9 @@ export function HomeChatInput({ onSubmit }: { onSubmit: () => void }) {
|
||||
const [inputValue, setInputValue] = useAtom(homeChatInputValueAtom);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const { settings, updateSettings, isAnyProviderSetup } = useSettings();
|
||||
const { streamMessage, isStreaming, setIsStreaming } = useStreamChat(); // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
const { streamMessage, isStreaming, setIsStreaming } = useStreamChat({
|
||||
hasChatId: false,
|
||||
}); // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
const adjustHeight = () => {
|
||||
const textarea = textareaRef.current;
|
||||
|
||||
@@ -8,35 +8,39 @@ export function useProposal(chatId?: number | undefined) {
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const fetchProposal = useCallback(async () => {
|
||||
if (chatId === undefined) {
|
||||
setProposalResult(null);
|
||||
setIsLoading(false);
|
||||
setError(null);
|
||||
return;
|
||||
}
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
setProposalResult(null); // Reset on new fetch
|
||||
try {
|
||||
// Type assertion might be needed depending on how IpcClient is typed
|
||||
const result = (await IpcClient.getInstance().getProposal(
|
||||
chatId
|
||||
)) as ProposalResult | null;
|
||||
|
||||
if (result) {
|
||||
setProposalResult(result);
|
||||
} else {
|
||||
setProposalResult(null); // Explicitly set to null if IPC returns null
|
||||
const fetchProposal = useCallback(
|
||||
async (overrideChatId?: number) => {
|
||||
chatId = overrideChatId ?? chatId;
|
||||
if (chatId === undefined) {
|
||||
setProposalResult(null);
|
||||
setIsLoading(false);
|
||||
setError(null);
|
||||
return;
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error("Error fetching proposal:", err);
|
||||
setError(err.message || "Failed to fetch proposal");
|
||||
setProposalResult(null); // Clear proposal data on error
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [chatId]); // Depend on chatId
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
setProposalResult(null); // Reset on new fetch
|
||||
try {
|
||||
// Type assertion might be needed depending on how IpcClient is typed
|
||||
const result = (await IpcClient.getInstance().getProposal(
|
||||
chatId
|
||||
)) as ProposalResult | null;
|
||||
|
||||
if (result) {
|
||||
setProposalResult(result);
|
||||
} else {
|
||||
setProposalResult(null); // Explicitly set to null if IPC returns null
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error("Error fetching proposal:", err);
|
||||
setError(err.message || "Failed to fetch proposal");
|
||||
setProposalResult(null); // Clear proposal data on error
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
},
|
||||
[chatId]
|
||||
); // Depend on chatId
|
||||
|
||||
useEffect(() => {
|
||||
fetchProposal();
|
||||
|
||||
@@ -22,7 +22,9 @@ export function getRandomString() {
|
||||
return Math.random().toString(36).substring(2, 15);
|
||||
}
|
||||
|
||||
export function useStreamChat() {
|
||||
export function useStreamChat({
|
||||
hasChatId = true,
|
||||
}: { hasChatId?: boolean } = {}) {
|
||||
const [messages, setMessages] = useAtom(chatMessagesAtom);
|
||||
const [isStreaming, setIsStreaming] = useAtom(isStreamingAtom);
|
||||
const [error, setError] = useAtom(chatErrorAtom);
|
||||
@@ -32,8 +34,14 @@ export function useStreamChat() {
|
||||
const { refreshApp } = useLoadApp(selectedAppId);
|
||||
const setStreamCount = useSetAtom(chatStreamCountAtom);
|
||||
const { refreshVersions } = useLoadVersions(selectedAppId);
|
||||
const { id: chatId } = useSearch({ from: "/chat" });
|
||||
const { refreshProposal } = useProposal(chatId);
|
||||
let chatId: number | undefined;
|
||||
|
||||
if (hasChatId) {
|
||||
const { id } = useSearch({ from: "/chat" });
|
||||
chatId = id;
|
||||
}
|
||||
let { refreshProposal } = hasChatId ? useProposal(chatId) : useProposal();
|
||||
|
||||
const streamMessage = useCallback(
|
||||
async ({
|
||||
prompt,
|
||||
@@ -93,7 +101,7 @@ export function useStreamChat() {
|
||||
if (response.updatedFiles) {
|
||||
setIsPreviewOpen(true);
|
||||
}
|
||||
refreshProposal();
|
||||
refreshProposal(chatId);
|
||||
|
||||
// Keep the same as below
|
||||
setIsStreaming(false);
|
||||
|
||||
@@ -51,18 +51,7 @@ const getProposalHandler = async (
|
||||
return null;
|
||||
}
|
||||
if (latestAssistantMessage?.approvalState === "approved") {
|
||||
return {
|
||||
proposal: {
|
||||
type: "action-proposal",
|
||||
actions: [
|
||||
{
|
||||
id: "restart-app",
|
||||
},
|
||||
],
|
||||
},
|
||||
chatId: chatId,
|
||||
messageId: latestAssistantMessage.id,
|
||||
};
|
||||
return null;
|
||||
}
|
||||
|
||||
if (latestAssistantMessage?.content && latestAssistantMessage.id) {
|
||||
|
||||
@@ -127,7 +127,13 @@ export interface ActionProposal {
|
||||
actions: SuggestedAction[];
|
||||
}
|
||||
|
||||
export type Proposal = CodeProposal | ActionProposal;
|
||||
export interface TipProposal {
|
||||
type: "tip-proposal";
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export type Proposal = CodeProposal | ActionProposal | TipProposal;
|
||||
|
||||
export interface ProposalResult {
|
||||
proposal: Proposal;
|
||||
|
||||
@@ -20,7 +20,7 @@ export default function HomePage() {
|
||||
const { settings, isAnyProviderSetup } = useSettings();
|
||||
const setIsPreviewOpen = useSetAtom(isPreviewOpenAtom);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { streamMessage } = useStreamChat();
|
||||
const { streamMessage } = useStreamChat({ hasChatId: false });
|
||||
|
||||
// Get the appId from search params
|
||||
const appId = search.appId ? Number(search.appId) : null;
|
||||
|
||||
Reference in New Issue
Block a user