修复lint问题和错误
This commit is contained in:
@@ -645,40 +645,40 @@ function FolderLayoutInner({ children }: { children: React.ReactNode }) {
|
|||||||
<AlertProvider>
|
<AlertProvider>
|
||||||
<GitCredentialProvider>
|
<GitCredentialProvider>
|
||||||
<TaskProvider>
|
<TaskProvider>
|
||||||
<AcpConnectionsProvider>
|
<AcpConnectionsProvider>
|
||||||
<ConversationRuntimeProvider>
|
<ConversationRuntimeProvider>
|
||||||
<WorkspaceProvider key={`workspace-${normalizedFolderId}`}>
|
<WorkspaceProvider key={`workspace-${normalizedFolderId}`}>
|
||||||
<TabProvider>
|
<TabProvider>
|
||||||
<SessionStatsProvider>
|
<SessionStatsProvider>
|
||||||
<SidebarProvider
|
<SidebarProvider
|
||||||
key={`left-sidebar-${normalizedFolderId}`}
|
key={`left-sidebar-${normalizedFolderId}`}
|
||||||
folderId={normalizedFolderId}
|
|
||||||
>
|
|
||||||
<AuxPanelProvider
|
|
||||||
key={`right-sidebar-${normalizedFolderId}`}
|
|
||||||
folderId={normalizedFolderId}
|
folderId={normalizedFolderId}
|
||||||
>
|
>
|
||||||
<TerminalProvider>
|
<AuxPanelProvider
|
||||||
<div className="flex h-screen flex-col overflow-hidden">
|
key={`right-sidebar-${normalizedFolderId}`}
|
||||||
<FolderTitleBar />
|
folderId={normalizedFolderId}
|
||||||
<FolderWorkspaceShell>
|
>
|
||||||
{children}
|
<TerminalProvider>
|
||||||
</FolderWorkspaceShell>
|
<div className="flex h-screen flex-col overflow-hidden">
|
||||||
<StatusBar />
|
<FolderTitleBar />
|
||||||
<AppToaster
|
<FolderWorkspaceShell>
|
||||||
position="bottom-right"
|
{children}
|
||||||
duration={TOAST_DURATION_MS}
|
</FolderWorkspaceShell>
|
||||||
closeButton
|
<StatusBar />
|
||||||
/>
|
<AppToaster
|
||||||
</div>
|
position="bottom-right"
|
||||||
</TerminalProvider>
|
duration={TOAST_DURATION_MS}
|
||||||
</AuxPanelProvider>
|
closeButton
|
||||||
</SidebarProvider>
|
/>
|
||||||
</SessionStatsProvider>
|
</div>
|
||||||
</TabProvider>
|
</TerminalProvider>
|
||||||
</WorkspaceProvider>
|
</AuxPanelProvider>
|
||||||
</ConversationRuntimeProvider>
|
</SidebarProvider>
|
||||||
</AcpConnectionsProvider>
|
</SessionStatsProvider>
|
||||||
|
</TabProvider>
|
||||||
|
</WorkspaceProvider>
|
||||||
|
</ConversationRuntimeProvider>
|
||||||
|
</AcpConnectionsProvider>
|
||||||
</TaskProvider>
|
</TaskProvider>
|
||||||
</GitCredentialProvider>
|
</GitCredentialProvider>
|
||||||
</AlertProvider>
|
</AlertProvider>
|
||||||
|
|||||||
@@ -698,10 +698,9 @@ export function BranchDropdown({
|
|||||||
runGitTask(
|
runGitTask(
|
||||||
t("tasks.pullCode"),
|
t("tasks.pullCode"),
|
||||||
() =>
|
() =>
|
||||||
withCredentialRetry(
|
withCredentialRetry((creds) => gitPull(folderPath, creds), {
|
||||||
(creds) => gitPull(folderPath, creds),
|
folderPath,
|
||||||
{ folderPath }
|
}),
|
||||||
),
|
|
||||||
(result) => {
|
(result) => {
|
||||||
if (result.conflict?.has_conflicts) {
|
if (result.conflict?.has_conflicts) {
|
||||||
setConflictInfo(result.conflict)
|
setConflictInfo(result.conflict)
|
||||||
@@ -724,10 +723,9 @@ export function BranchDropdown({
|
|||||||
disabled={loading}
|
disabled={loading}
|
||||||
onSelect={() =>
|
onSelect={() =>
|
||||||
runGitTask(t("tasks.fetchInfo"), () =>
|
runGitTask(t("tasks.fetchInfo"), () =>
|
||||||
withCredentialRetry(
|
withCredentialRetry((creds) => gitFetch(folderPath, creds), {
|
||||||
(creds) => gitFetch(folderPath, creds),
|
folderPath,
|
||||||
{ folderPath }
|
})
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -83,7 +83,15 @@ export function AddGitAccountDialog({
|
|||||||
|
|
||||||
onAccountAdded(account)
|
onAccountAdded(account)
|
||||||
handleOpenChange(false)
|
handleOpenChange(false)
|
||||||
}, [serverUrl, username, password, isFirstAccount, onAccountAdded, handleOpenChange, t])
|
}, [
|
||||||
|
serverUrl,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
isFirstAccount,
|
||||||
|
onAccountAdded,
|
||||||
|
handleOpenChange,
|
||||||
|
t,
|
||||||
|
])
|
||||||
|
|
||||||
const canSubmit =
|
const canSubmit =
|
||||||
serverUrl.trim().length > 0 &&
|
serverUrl.trim().length > 0 &&
|
||||||
|
|||||||
@@ -186,10 +186,7 @@ export function AddGitHubAccountDialog({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button
|
<Button onClick={handleSubmit} disabled={validating || !token.trim()}>
|
||||||
onClick={handleSubmit}
|
|
||||||
disabled={validating || !token.trim()}
|
|
||||||
>
|
|
||||||
{validating ? (
|
{validating ? (
|
||||||
<>
|
<>
|
||||||
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
||||||
|
|||||||
@@ -205,7 +205,9 @@ export function VersionControlSettings() {
|
|||||||
if (trimmed) {
|
if (trimmed) {
|
||||||
const result = await testGitPath(trimmed)
|
const result = await testGitPath(trimmed)
|
||||||
if (!result.installed) {
|
if (!result.installed) {
|
||||||
toast.error(t("testFailed", { message: "not a valid git executable" }))
|
toast.error(
|
||||||
|
t("testFailed", { message: "not a valid git executable" })
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -415,11 +417,7 @@ export function VersionControlSettings() {
|
|||||||
>
|
>
|
||||||
{t("removeCancel")}
|
{t("removeCancel")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button size="sm" onClick={handleSaveGit} disabled={savingGit}>
|
||||||
size="sm"
|
|
||||||
onClick={handleSaveGit}
|
|
||||||
disabled={savingGit}
|
|
||||||
>
|
|
||||||
{savingGit ? (
|
{savingGit ? (
|
||||||
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -4,11 +4,19 @@ import {
|
|||||||
createContext,
|
createContext,
|
||||||
useCallback,
|
useCallback,
|
||||||
useContext,
|
useContext,
|
||||||
|
useEffect,
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
type ReactNode,
|
type ReactNode,
|
||||||
} from "react"
|
} from "react"
|
||||||
import { ExternalLink, Eye, EyeOff, Github, KeyRound, Loader2 } from "lucide-react"
|
import {
|
||||||
|
ExternalLink,
|
||||||
|
Eye,
|
||||||
|
EyeOff,
|
||||||
|
Github,
|
||||||
|
KeyRound,
|
||||||
|
Loader2,
|
||||||
|
} from "lucide-react"
|
||||||
import { openUrl } from "@tauri-apps/plugin-opener"
|
import { openUrl } from "@tauri-apps/plugin-opener"
|
||||||
import { useTranslations } from "next-intl"
|
import { useTranslations } from "next-intl"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
@@ -39,9 +47,7 @@ import {
|
|||||||
* - `folderPath`: detect remote from an existing repo's origin URL.
|
* - `folderPath`: detect remote from an existing repo's origin URL.
|
||||||
* - `remoteUrl`: use this URL directly (e.g. for clone operations).
|
* - `remoteUrl`: use this URL directly (e.g. for clone operations).
|
||||||
*/
|
*/
|
||||||
export type GitRemoteHint =
|
export type GitRemoteHint = { folderPath: string } | { remoteUrl: string }
|
||||||
| { folderPath: string }
|
|
||||||
| { remoteUrl: string }
|
|
||||||
|
|
||||||
interface GitCredentialContextValue {
|
interface GitCredentialContextValue {
|
||||||
/**
|
/**
|
||||||
@@ -57,8 +63,9 @@ interface GitCredentialContextValue {
|
|||||||
) => Promise<T>
|
) => Promise<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
const GitCredentialContext =
|
const GitCredentialContext = createContext<GitCredentialContextValue | null>(
|
||||||
createContext<GitCredentialContextValue | null>(null)
|
null
|
||||||
|
)
|
||||||
|
|
||||||
export function useGitCredential(): GitCredentialContextValue {
|
export function useGitCredential(): GitCredentialContextValue {
|
||||||
const ctx = useContext(GitCredentialContext)
|
const ctx = useContext(GitCredentialContext)
|
||||||
@@ -136,9 +143,7 @@ async function saveGenericAccount(
|
|||||||
try {
|
try {
|
||||||
const existing = await getGitHubAccounts()
|
const existing = await getGitHubAccounts()
|
||||||
const isDuplicate = existing.accounts.some(
|
const isDuplicate = existing.accounts.some(
|
||||||
(a) =>
|
(a) => a.username === creds.username && extractHost(a.server_url) === host
|
||||||
a.username === creds.username &&
|
|
||||||
extractHost(a.server_url) === host
|
|
||||||
)
|
)
|
||||||
if (!isDuplicate) {
|
if (!isDuplicate) {
|
||||||
await updateGitHubAccounts({
|
await updateGitHubAccounts({
|
||||||
@@ -162,11 +167,7 @@ async function saveGenericAccount(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function GitCredentialProvider({
|
export function GitCredentialProvider({ children }: { children: ReactNode }) {
|
||||||
children,
|
|
||||||
}: {
|
|
||||||
children: ReactNode
|
|
||||||
}) {
|
|
||||||
const t = useTranslations("GitCredentialDialog")
|
const t = useTranslations("GitCredentialDialog")
|
||||||
|
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
@@ -204,11 +205,18 @@ export function GitCredentialProvider({
|
|||||||
|
|
||||||
const pendingRef = useRef<PendingRequest | null>(null)
|
const pendingRef = useRef<PendingRequest | null>(null)
|
||||||
const saveCredentialsRef = useRef(saveCredentials)
|
const saveCredentialsRef = useRef(saveCredentials)
|
||||||
saveCredentialsRef.current = saveCredentials
|
|
||||||
const remoteHostRef = useRef(remoteHost)
|
const remoteHostRef = useRef(remoteHost)
|
||||||
remoteHostRef.current = remoteHost
|
|
||||||
const modeRef = useRef(mode)
|
const modeRef = useRef(mode)
|
||||||
modeRef.current = mode
|
|
||||||
|
useEffect(() => {
|
||||||
|
saveCredentialsRef.current = saveCredentials
|
||||||
|
}, [saveCredentials])
|
||||||
|
useEffect(() => {
|
||||||
|
remoteHostRef.current = remoteHost
|
||||||
|
}, [remoteHost])
|
||||||
|
useEffect(() => {
|
||||||
|
modeRef.current = mode
|
||||||
|
}, [mode])
|
||||||
|
|
||||||
const resetForm = useCallback(() => {
|
const resetForm = useCallback(() => {
|
||||||
setUsername("")
|
setUsername("")
|
||||||
@@ -222,7 +230,10 @@ export function GitCredentialProvider({
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const requestCredentials = useCallback(
|
const requestCredentials = useCallback(
|
||||||
(dialogMode: DialogMode, host: string | null): Promise<GitCredentials | null> => {
|
(
|
||||||
|
dialogMode: DialogMode,
|
||||||
|
host: string | null
|
||||||
|
): Promise<GitCredentials | null> => {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
pendingRef.current = { resolve }
|
pendingRef.current = { resolve }
|
||||||
resetForm()
|
resetForm()
|
||||||
@@ -333,9 +344,7 @@ export function GitCredentialProvider({
|
|||||||
|
|
||||||
// Detect remote host to decide dialog mode
|
// Detect remote host to decide dialog mode
|
||||||
const host = await resolveRemoteHost(hint)
|
const host = await resolveRemoteHost(hint)
|
||||||
const dialogMode: DialogMode = isGitHubHost(host)
|
const dialogMode: DialogMode = isGitHubHost(host) ? "github" : "generic"
|
||||||
? "github"
|
|
||||||
: "generic"
|
|
||||||
|
|
||||||
// Helper: save credentials after successful operation
|
// Helper: save credentials after successful operation
|
||||||
const maybeSave = async (c: GitCredentials) => {
|
const maybeSave = async (c: GitCredentials) => {
|
||||||
@@ -354,7 +363,7 @@ export function GitCredentialProvider({
|
|||||||
|
|
||||||
// Retry loop — keep trying until success or user cancels
|
// Retry loop — keep trying until success or user cancels
|
||||||
let lastError: unknown = firstError
|
let lastError: unknown = firstError
|
||||||
// eslint-disable-next-line no-constant-condition
|
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
const result = await operation(creds)
|
const result = await operation(creds)
|
||||||
@@ -389,7 +398,8 @@ export function GitCredentialProvider({
|
|||||||
)
|
)
|
||||||
|
|
||||||
const canSubmitGitHub = token.trim().length > 0
|
const canSubmitGitHub = token.trim().length > 0
|
||||||
const canSubmitGeneric = username.trim().length > 0 && password.trim().length > 0
|
const canSubmitGeneric =
|
||||||
|
username.trim().length > 0 && password.trim().length > 0
|
||||||
const canSubmit = mode === "github" ? canSubmitGitHub : canSubmitGeneric
|
const canSubmit = mode === "github" ? canSubmitGitHub : canSubmitGeneric
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -168,9 +168,7 @@ export function TabProvider({ children }: TabProviderProps) {
|
|||||||
}, [conversations])
|
}, [conversations])
|
||||||
|
|
||||||
// Callback set for preview tab replacement notifications
|
// Callback set for preview tab replacement notifications
|
||||||
const previewReplacedCallbacksRef = useRef(
|
const previewReplacedCallbacksRef = useRef(new Set<(tabId: string) => void>())
|
||||||
new Set<(tabId: string) => void>()
|
|
||||||
)
|
|
||||||
const onPreviewTabReplaced = useCallback(
|
const onPreviewTabReplaced = useCallback(
|
||||||
(callback: (tabId: string) => void) => {
|
(callback: (tabId: string) => void) => {
|
||||||
previewReplacedCallbacksRef.current.add(callback)
|
previewReplacedCallbacksRef.current.add(callback)
|
||||||
|
|||||||
Reference in New Issue
Block a user