lint using oxlint (#106)

This commit is contained in:
Will Chen
2025-05-08 17:21:35 -07:00
committed by GitHub
parent 0e8cc26fb5
commit 2537fbb342
63 changed files with 251 additions and 292 deletions

View File

@@ -1,6 +1,6 @@
import { useEffect } from "react";
import { useNavigate, useRouterState } from "@tanstack/react-router";
import type { ChatSummary } from "@/lib/schemas";
import { formatDistanceToNow } from "date-fns";
import { PlusCircle, MoreVertical, Trash2 } from "lucide-react";
import { useAtom } from "jotai";
@@ -29,7 +29,7 @@ export function ChatList({ show }: { show?: boolean }) {
const navigate = useNavigate();
const [selectedChatId, setSelectedChatId] = useAtom(selectedChatIdAtom);
const [selectedAppId, setSelectedAppId] = useAtom(selectedAppIdAtom);
const [isDropdownOpen, setIsDropdownOpen] = useAtom(dropdownOpenAtom);
const [, setIsDropdownOpen] = useAtom(dropdownOpenAtom);
const { chats, loading, refreshChats } = useChats(selectedAppId);
const routerState = useRouterState();
const isChatRoute = routerState.location.pathname === "/chat";

View File

@@ -2,7 +2,7 @@ import { useState, useRef, useEffect, useCallback } from "react";
import { useAtom, useAtomValue } from "jotai";
import { chatMessagesAtom, chatStreamCountAtom } from "../atoms/chatAtoms";
import { IpcClient } from "@/ipc/ipc_client";
import { selectedAppIdAtom } from "@/atoms/appAtoms";
import { ChatHeader } from "./chat/ChatHeader";
import { MessagesList } from "./chat/MessagesList";
import { ChatInput } from "./chat/ChatInput";
@@ -20,14 +20,11 @@ export function ChatPanel({
isPreviewOpen,
onTogglePreview,
}: ChatPanelProps) {
const appId = useAtomValue(selectedAppIdAtom);
const [messages, setMessages] = useAtom(chatMessagesAtom);
const [appName, setAppName] = useState<string>("Chat");
const [isVersionPaneOpen, setIsVersionPaneOpen] = useState(false);
const [error, setError] = useState<string | null>(null);
const streamCount = useAtomValue(chatStreamCountAtom);
// Reference to store the processed prompt so we don't submit it twice
const processedPromptRef = useRef<string | null>(null);
const messagesEndRef = useRef<HTMLDivElement | null>(null);
const messagesContainerRef = useRef<HTMLDivElement | null>(null);
@@ -83,23 +80,6 @@ export function ChatPanel({
};
}, []);
useEffect(() => {
const fetchAppName = async () => {
if (!appId) return;
try {
const app = await IpcClient.getInstance().getApp(appId);
if (app?.name) {
setAppName(app.name);
}
} catch (error) {
console.error("Failed to fetch app name:", error);
}
};
fetchAppName();
}, [appId]);
const fetchChatMessages = useCallback(async () => {
if (!chatId) {
setMessages([]);

View File

@@ -1,10 +1,4 @@
import React, {
Component,
ErrorInfo,
ReactNode,
useState,
useEffect,
} from "react";
import React, { useState, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { LightbulbIcon } from "lucide-react";
import { ErrorComponentProps } from "@tanstack/react-router";

View File

@@ -292,7 +292,7 @@ Session ID: ${sessionId}
<div className="border rounded-md p-3">
<h3 className="font-medium mb-2">Chat Messages</h3>
<div className="text-sm bg-slate-50 dark:bg-slate-900 rounded p-2 max-h-40 overflow-y-auto">
{chatLogsData.chat.messages.map((msg, index) => (
{chatLogsData.chat.messages.map((msg) => (
<div key={msg.id} className="mb-2">
<span className="font-semibold">
{msg.role === "user" ? "You" : "Assistant"}:{" "}

View File

@@ -10,13 +10,8 @@ import { providerSettingsRoute } from "@/routes/settings/providers/$provider";
import type { ModelProvider } from "@/lib/schemas";
import { useSettings } from "@/hooks/useSettings";
import { GiftIcon } from "lucide-react";
interface ProviderSettingsProps {
configuredProviders?: ModelProvider[];
}
export function ProviderSettingsGrid({
configuredProviders = [],
}: ProviderSettingsProps) {
export function ProviderSettingsGrid() {
const navigate = useNavigate();
const handleProviderClick = (provider: ModelProvider) => {
@@ -33,10 +28,6 @@ export function ProviderSettingsGrid({
<h2 className="text-2xl font-bold mb-6">AI Providers</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{Object.entries(PROVIDERS).map(([key, provider]) => {
const isConfigured = configuredProviders.includes(
key as ModelProvider,
);
return (
<Card
key={key}

View File

@@ -1,8 +1,8 @@
import { useState, useEffect } from "react";
import { useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { SupabaseSchema } from "@/lib/schemas";
import { IpcClient } from "@/ipc/ipc_client";
import { toast } from "sonner";
import { useSettings } from "@/hooks/useSettings";
@@ -24,7 +24,7 @@ import {
import { Skeleton } from "@/components/ui/skeleton";
import { useLoadApp } from "@/hooks/useLoadApp";
import { useDeepLink } from "@/contexts/DeepLinkContext";
const OAUTH_CLIENT_ID = "bf747de7-60bb-48a2-9015-6494e0b04983";
// @ts-ignore
import supabaseLogoLight from "../../assets/supabase/supabase-logo-wordmark--light.svg";
// @ts-ignore
@@ -74,7 +74,7 @@ export function SupabaseConnector({ appId }: { appId: number }) {
toast.success("Project connected to app successfully");
await refreshApp();
} catch (error) {
toast.error("Failed to connect project to app");
toast.error("Failed to connect project to app: " + error);
}
};

View File

@@ -1,5 +1,5 @@
import { IpcClient } from "@/ipc/ipc_client";
import React, { useState } from "react";
import React from "react";
import { Button } from "./ui/button";
import { atom, useAtom } from "jotai";
import { useSettings } from "@/hooks/useSettings";

View File

@@ -1,7 +1,6 @@
import { useSettings } from "@/hooks/useSettings";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { showInfo } from "@/lib/toast";
export function TelemetrySwitch() {
const { settings, updateSettings } = useSettings();

View File

@@ -1,5 +1,4 @@
import { FileText, X } from "lucide-react";
import { useEffect } from "react";
interface AttachmentsListProps {
attachments: File[];

View File

@@ -3,11 +3,10 @@ import {
History,
PlusCircle,
GitBranch,
AlertCircle,
Info,
} from "lucide-react";
import { PanelRightClose } from "lucide-react";
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import { useAtom, useAtomValue } from "jotai";
import { selectedAppIdAtom } from "@/atoms/appAtoms";
import { useVersions } from "@/hooks/useVersions";
import { Button } from "../ui/button";

View File

@@ -58,17 +58,14 @@ import { useVersions } from "@/hooks/useVersions";
import { useAttachments } from "@/hooks/useAttachments";
import { AttachmentsList } from "./AttachmentsList";
import { DragDropOverlay } from "./DragDropOverlay";
import {
showError as showErrorToast,
showUncommittedFilesWarning,
} from "@/lib/toast";
import { showUncommittedFilesWarning } from "@/lib/toast";
const showTokenBarAtom = atom(false);
export function ChatInput({ chatId }: { chatId?: number }) {
const posthog = usePostHog();
const [inputValue, setInputValue] = useAtom(chatInputValueAtom);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const { settings, updateSettings, isAnyProviderSetup } = useSettings();
const { settings, updateSettings } = useSettings();
const appId = useAtomValue(selectedAppIdAtom);
const { refreshVersions } = useVersions(appId);
const { streamMessage, isStreaming, setIsStreaming, error, setError } =
@@ -76,7 +73,7 @@ export function ChatInput({ chatId }: { chatId?: number }) {
const [showError, setShowError] = useState(true);
const [isApproving, setIsApproving] = useState(false); // State for approving
const [isRejecting, setIsRejecting] = useState(false); // State for rejecting
const [messages, setMessages] = useAtom<Message[]>(chatMessagesAtom);
const [, setMessages] = useAtom<Message[]>(chatMessagesAtom);
const setIsPreviewOpen = useSetAtom(isPreviewOpenAtom);
const [showTokenBar, setShowTokenBar] = useAtom(showTokenBarAtom);
@@ -101,7 +98,7 @@ export function ChatInput({ chatId }: { chatId?: number }) {
error: proposalError,
refreshProposal,
} = useProposal(chatId);
const { proposal, chatId: proposalChatId, messageId } = proposalResult ?? {};
const { proposal, messageId } = proposalResult ?? {};
const adjustHeight = () => {
const textarea = textareaRef.current;
@@ -620,7 +617,6 @@ function ChatInputActions({
isApproving,
isRejecting,
}: ChatInputActionsProps) {
const [autoApprove, setAutoApprove] = useState(false);
const [isDetailsVisible, setIsDetailsVisible] = useState(false);
if (proposal.type === "tip-proposal") {

View File

@@ -1,4 +1,3 @@
import { memo } from "react";
import type { Message } from "@/ipc/ipc_types";
import {
DyadMarkdownParser,

View File

@@ -1,19 +1,10 @@
import type React from "react";
import type { ReactNode } from "react";
import { useState } from "react";
import { Button } from "../ui/button";
import { IpcClient } from "../../ipc/ipc_client";
import { useAtom, useAtomValue } from "jotai";
import { chatMessagesAtom, selectedChatIdAtom } from "../../atoms/chatAtoms";
import { useStreamChat } from "@/hooks/useStreamChat";
import {
Package,
ChevronsUpDown,
ChevronsDownUp,
Loader,
ExternalLink,
Download,
} from "lucide-react";
import { Package, ChevronsUpDown, ChevronsDownUp } from "lucide-react";
import { CodeHighlight } from "./CodeHighlight";
interface DyadAddDependencyProps {
@@ -28,15 +19,14 @@ export const DyadAddDependency: React.FC<DyadAddDependencyProps> = ({
}) => {
// Extract package attribute from the node if available
const packages = node?.properties?.packages?.split(" ") || "";
const [isInstalling, setIsInstalling] = useState(false);
const [isContentVisible, setIsContentVisible] = useState(false);
const hasChildren = !!children;
return (
<div
className={`bg-(--background-lightest) dark:bg-gray-900 hover:bg-(--background-lighter) rounded-lg px-4 py-3 border my-2 ${
className={`bg-(--background-lightest) dark:bg-gray-900 hover:bg-(--background-lighter) rounded-lg px-4 py-3 border my-2 border-border ${
hasChildren ? "cursor-pointer" : ""
} ${isInstalling ? "border-amber-500" : "border-border"}`}
}`}
onClick={
hasChildren ? () => setIsContentVisible(!isContentVisible) : undefined
}
@@ -66,12 +56,6 @@ export const DyadAddDependency: React.FC<DyadAddDependencyProps> = ({
</div>
</div>
)}
{isInstalling && (
<div className="flex items-center text-amber-600 text-xs ml-2">
<Loader size={14} className="mr-1 animate-spin" />
<span>Installing...</span>
</div>
)}
</div>
{hasChildren && (
<div className="flex items-center">

View File

@@ -30,7 +30,13 @@ type ContentPiece =
| { type: "markdown"; content: string }
| { type: "custom-tag"; tagInfo: CustomTagInfo };
const customLink = ({ node, ...props }: { node?: any; [key: string]: any }) => (
const customLink = ({
node: _node,
...props
}: {
node?: any;
[key: string]: any;
}) => (
<a
{...props}
onClick={(e) => {
@@ -358,11 +364,3 @@ function renderCustomTag(
return null;
}
}
/**
* Extract attribute values from className string
*/
function extractAttribute(className: string, attrName: string): string {
const match = new RegExp(`${attrName}="([^"]*)"`, "g").exec(className);
return match ? match[1] : "";
}

View File

@@ -6,8 +6,8 @@ import {
XCircle,
Sparkles,
} from "lucide-react";
import { useAtom, useSetAtom } from "jotai";
import { chatInputValueAtom, selectedChatIdAtom } from "@/atoms/chatAtoms";
import { useAtomValue } from "jotai";
import { selectedChatIdAtom } from "@/atoms/chatAtoms";
import { useStreamChat } from "@/hooks/useStreamChat";
interface DyadOutputProps {
type: "error" | "warning";
@@ -21,7 +21,7 @@ export const DyadOutput: React.FC<DyadOutputProps> = ({
children,
}) => {
const [isContentVisible, setIsContentVisible] = useState(false);
const [selectedChatId, setSelectedChatId] = useAtom(selectedChatIdAtom);
const selectedChatId = useAtomValue(selectedChatIdAtom);
const { streamMessage } = useStreamChat();
// If the type is not warning, it is an error (in case LLM gives a weird "type")

View File

@@ -1,6 +1,6 @@
import { SendIcon, StopCircleIcon, X, Paperclip, Loader2 } from "lucide-react";
import { SendIcon, StopCircleIcon, Paperclip } from "lucide-react";
import type React from "react";
import { useEffect, useRef, useState } from "react";
import { useEffect, useRef } from "react";
import { ModelPicker } from "@/components/ModelPicker";
import { useSettings } from "@/hooks/useSettings";
import { homeChatInputValueAtom } from "@/atoms/chatAtoms"; // Use a different atom for home input
@@ -21,7 +21,7 @@ export function HomeChatInput({
const [inputValue, setInputValue] = useAtom(homeChatInputValueAtom);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const { settings, updateSettings, isAnyProviderSetup } = useSettings();
const { streamMessage, isStreaming, setIsStreaming } = useStreamChat({
const { isStreaming } = useStreamChat({
hasChatId: false,
}); // eslint-disable-line @typescript-eslint/no-unused-vars

View File

@@ -6,12 +6,12 @@ import { SetupBanner } from "../SetupBanner";
import { useSettings } from "@/hooks/useSettings";
import { useStreamChat } from "@/hooks/useStreamChat";
import { selectedChatIdAtom } from "@/atoms/chatAtoms";
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import { useAtomValue, useSetAtom } from "jotai";
import { Loader2, RefreshCw, Undo } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useVersions } from "@/hooks/useVersions";
import { selectedAppIdAtom } from "@/atoms/appAtoms";
import { showError, showSuccess, showWarning } from "@/lib/toast";
import { showError, showWarning } from "@/lib/toast";
import { IpcClient } from "@/ipc/ipc_client";
import { chatMessagesAtom } from "@/atoms/chatAtoms";
@@ -24,13 +24,13 @@ export const MessagesList = forwardRef<HTMLDivElement, MessagesListProps>(
function MessagesList({ messages, messagesEndRef }, ref) {
const appId = useAtomValue(selectedAppIdAtom);
const { versions, revertVersion } = useVersions(appId);
const { streamMessage, isStreaming, error, setError } = useStreamChat();
const { streamMessage, isStreaming } = useStreamChat();
const { isAnyProviderSetup } = useSettings();
const setMessages = useSetAtom(chatMessagesAtom);
const [isUndoLoading, setIsUndoLoading] = useState(false);
const [isRetryLoading, setIsRetryLoading] = useState(false);
const [selectedChatId, setSelectedChatId] = useAtom(selectedChatIdAtom);
const selectedChatId = useAtomValue(selectedChatIdAtom);
return (
<div className="flex-1 overflow-y-auto p-4" ref={ref}>

View File

@@ -1,4 +1,3 @@
import { useState } from "react";
import { FileEditor } from "./FileEditor";
import { FileTree } from "./FileTree";
import { RefreshCw } from "lucide-react";

View File

@@ -90,7 +90,7 @@ export const FileEditor = ({ appId, filePath }: FileEditorProps) => {
const editorTheme = isDarkMode ? "dyad-dark" : "dyad-light";
// Handle editor mount
const handleEditorDidMount: OnMount = (editor, monaco) => {
const handleEditorDidMount: OnMount = (editor) => {
editorRef.current = editor;
// Listen for model content change events

View File

@@ -20,7 +20,7 @@ import {
} from "lucide-react";
import { selectedChatIdAtom } from "@/atoms/chatAtoms";
import { IpcClient } from "@/ipc/ipc_client";
import { useLoadApp } from "@/hooks/useLoadApp";
import { useLoadAppFile } from "@/hooks/useLoadAppFile";
import {
DropdownMenu,
@@ -28,8 +28,6 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useSettings } from "@/hooks/useSettings";
import { useRunApp } from "@/hooks/useRunApp";
import { useStreamChat } from "@/hooks/useStreamChat";
interface ErrorBannerProps {
@@ -113,7 +111,7 @@ export const PreviewIframe = ({ loading }: { loading: boolean }) => {
// State to trigger iframe reload
const [reloadKey, setReloadKey] = useState(0);
const [errorMessage, setErrorMessage] = useAtom(previewErrorMessageAtom);
const [selectedChatId, setSelectedChatId] = useAtom(selectedChatIdAtom);
const selectedChatId = useAtomValue(selectedChatIdAtom);
const { streamMessage } = useStreamChat();
const [availableRoutes, setAvailableRoutes] = useState<
Array<{ path: string; label: string }>
@@ -168,7 +166,6 @@ export const PreviewIframe = ({ loading }: { loading: boolean }) => {
const [navigationHistory, setNavigationHistory] = useState<string[]>([]);
const [currentHistoryPosition, setCurrentHistoryPosition] = useState(0);
const iframeRef = useRef<HTMLIFrameElement>(null);
const { settings } = useSettings();
// Add message listener for iframe errors and navigation events
useEffect(() => {

View File

@@ -5,7 +5,7 @@ import {
previewPanelKeyAtom,
selectedAppIdAtom,
} from "../../atoms/appAtoms";
import { useLoadApp } from "@/hooks/useLoadApp";
import { CodeView } from "./CodeView";
import { PreviewIframe } from "./PreviewIframe";
import {
@@ -14,11 +14,8 @@ import {
ChevronDown,
ChevronUp,
Logs,
RefreshCw,
MoreVertical,
Trash2,
Cog,
CirclePower,
Power,
} from "lucide-react";
import { motion } from "framer-motion";

View File

@@ -104,7 +104,7 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
providerSettings: {
...settings?.providerSettings,
[provider]: {
...(settings?.providerSettings?.[provider] || {}),
...settings?.providerSettings?.[provider],
apiKey: {
value: apiKeyInput,
},
@@ -134,7 +134,7 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
providerSettings: {
...settings?.providerSettings,
[provider]: {
...(settings?.providerSettings?.[provider] || {}),
...settings?.providerSettings?.[provider],
apiKey: undefined,
},
},

View File

@@ -1,7 +1,7 @@
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { type VariantProps, cva } from "class-variance-authority";
import { Menu, PanelLeftIcon } from "lucide-react";
import { Menu } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
@@ -224,7 +224,6 @@ function Sidebar({
}
function SidebarTrigger({
className,
onClick,
...props
}: React.ComponentProps<typeof Button>) {