Support dyad docker (#674)
TODOs: - [ ] clean-up docker images https://claude.ai/chat/13b2c5d3-0d46-49e3-a771-d10edf1e29f4
This commit is contained in:
74
src/components/RuntimeModeSelector.tsx
Normal file
74
src/components/RuntimeModeSelector.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { useSettings } from "@/hooks/useSettings";
|
||||
import { showError } from "@/lib/toast";
|
||||
import { IpcClient } from "@/ipc/ipc_client";
|
||||
|
||||
export function RuntimeModeSelector() {
|
||||
const { settings, updateSettings } = useSettings();
|
||||
|
||||
if (!settings) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isDockerMode = settings?.runtimeMode2 === "docker";
|
||||
|
||||
const handleRuntimeModeChange = async (value: "host" | "docker") => {
|
||||
try {
|
||||
await updateSettings({ runtimeMode2: value });
|
||||
} catch (error: any) {
|
||||
showError(`Failed to update runtime mode: ${error.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-1">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Label className="text-sm font-medium" htmlFor="runtime-mode">
|
||||
Runtime Mode
|
||||
</Label>
|
||||
<Select
|
||||
value={settings.runtimeMode2 ?? "host"}
|
||||
onValueChange={handleRuntimeModeChange}
|
||||
>
|
||||
<SelectTrigger className="w-48" id="runtime-mode">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="host">Local (default)</SelectItem>
|
||||
<SelectItem value="docker">Docker (experimental)</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="text-sm text-gray-500 dark:text-gray-400">
|
||||
Choose whether to run apps directly on the local machine or in Docker
|
||||
containers
|
||||
</div>
|
||||
</div>
|
||||
{isDockerMode && (
|
||||
<div className="text-sm text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20 p-2 rounded">
|
||||
⚠️ Docker mode is <b>experimental</b> and requires{" "}
|
||||
<button
|
||||
type="button"
|
||||
className="underline font-medium cursor-pointer"
|
||||
onClick={() =>
|
||||
IpcClient.getInstance().openExternalUrl(
|
||||
"https://www.docker.com/products/docker-desktop/",
|
||||
)
|
||||
}
|
||||
>
|
||||
Docker Desktop
|
||||
</button>{" "}
|
||||
to be installed and running
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -51,10 +51,11 @@ const ErrorBanner = ({ error, onDismiss, onAIFix }: ErrorBannerProps) => {
|
||||
const [isCollapsed, setIsCollapsed] = useState(true);
|
||||
const { isStreaming } = useStreamChat();
|
||||
if (!error) return null;
|
||||
const isDockerError = error.includes("Cannot connect to the Docker");
|
||||
|
||||
const getTruncatedError = () => {
|
||||
const firstLine = error.split("\n")[0];
|
||||
const snippetLength = 200;
|
||||
const snippetLength = 250;
|
||||
const snippet = error.substring(0, snippetLength);
|
||||
return firstLine.length < snippet.length
|
||||
? firstLine
|
||||
@@ -97,23 +98,27 @@ const ErrorBanner = ({ error, onDismiss, onAIFix }: ErrorBannerProps) => {
|
||||
<Lightbulb size={16} className=" text-red-800 dark:text-red-300" />
|
||||
</div>
|
||||
<span className="text-sm text-red-700 dark:text-red-200">
|
||||
<span className="font-medium">Tip: </span>Check if restarting the
|
||||
app fixes the error.
|
||||
<span className="font-medium">Tip: </span>
|
||||
{isDockerError
|
||||
? "Make sure Docker Desktop is running and try restarting the app."
|
||||
: "Check if restarting the app fixes the error."}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* AI Fix button at the bottom */}
|
||||
<div className="mt-2 flex justify-end">
|
||||
<button
|
||||
disabled={isStreaming}
|
||||
onClick={onAIFix}
|
||||
className="cursor-pointer flex items-center space-x-1 px-2 py-0.5 bg-red-500 dark:bg-red-600 text-white rounded text-sm hover:bg-red-600 dark:hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
<Sparkles size={14} />
|
||||
<span>Fix error with AI</span>
|
||||
</button>
|
||||
</div>
|
||||
{!isDockerError && (
|
||||
<div className="mt-2 flex justify-end">
|
||||
<button
|
||||
disabled={isStreaming}
|
||||
onClick={onAIFix}
|
||||
className="cursor-pointer flex items-center space-x-1 px-2 py-0.5 bg-red-500 dark:bg-red-600 text-white rounded text-sm hover:bg-red-600 dark:hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
<Sparkles size={14} />
|
||||
<span>Fix error with AI</span>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user