| ... | ... | @@ -57,6 +57,8 @@ interface PendingDefaultBranchAction { |
| 57 | 57 | onConfirmed?: () => void; |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | type GitActionToastId = ReturnType<typeof toastManager.add>; |
| 61 | |
| 60 | 62 | function getMenuActionDisabledReason( |
| 61 | 63 | item: GitActionMenuItem, |
| 62 | 64 | gitStatus: GitStatusResult | null, |
| ... | ... | @@ -180,19 +182,10 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions |
| 180 | 182 | const current = branchList?.branches.find((branch) => branch.name === branchName); |
| 181 | 183 | return current?.isDefault ?? (branchName === "main" || branchName === "master"); |
| 182 | 184 | }, [branchList?.branches, gitStatusForActions?.branch]); |
| 183 | | const isDefaultBranchName = useCallback( |
| 184 | | (branchName: string | null | undefined) => { |
| 185 | | if (!branchName) return false; |
| 186 | | const defaultBranchName = branchList?.branches.find((branch) => branch.isDefault)?.name; |
| 187 | | if (defaultBranchName) return branchName === defaultBranchName; |
| 188 | | return branchName === "main" || branchName === "master"; |
| 189 | | }, |
| 190 | | [branchList?.branches], |
| 191 | | ); |
| 192 | 185 | |
| 193 | 186 | const gitActionMenuItems = useMemo( |
| 194 | | () => buildMenuItems(gitStatusForActions, isGitActionRunning, isDefaultBranch), |
| 195 | | [gitStatusForActions, isGitActionRunning, isDefaultBranch], |
| 187 | () => buildMenuItems(gitStatusForActions, isGitActionRunning), |
| 188 | [gitStatusForActions, isGitActionRunning], |
| 196 | 189 | ); |
| 197 | 190 | const quickAction = useMemo( |
| 198 | 191 | () => resolveQuickAction(gitStatusForActions, isGitActionRunning, isDefaultBranch), |
| ... | ... | @@ -245,26 +238,28 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions |
| 245 | 238 | forcePushOnlyProgress = false, |
| 246 | 239 | onConfirmed, |
| 247 | 240 | skipDefaultBranchPrompt = false, |
| 241 | statusOverride, |
| 248 | 242 | featureBranch = false, |
| 249 | 243 | isDefaultBranchOverride, |
| 244 | progressToastId, |
| 250 | 245 | }: { |
| 251 | 246 | action: GitStackedAction; |
| 252 | 247 | commitMessage?: string; |
| 253 | 248 | forcePushOnlyProgress?: boolean; |
| 254 | 249 | onConfirmed?: () => void; |
| 255 | 250 | skipDefaultBranchPrompt?: boolean; |
| 251 | statusOverride?: GitStatusResult | null; |
| 256 | 252 | featureBranch?: boolean; |
| 257 | 253 | isDefaultBranchOverride?: boolean; |
| 254 | progressToastId?: GitActionToastId; |
| 258 | 255 | }) => { |
| 259 | | const actionStatus = gitStatusForActions; |
| 256 | const actionStatus = statusOverride ?? gitStatusForActions; |
| 260 | 257 | const actionBranch = actionStatus?.branch ?? null; |
| 261 | | const actionIsDefaultBranch = |
| 262 | | isDefaultBranchOverride ?? (featureBranch ? false : isDefaultBranchName(actionBranch)); |
| 258 | const actionIsDefaultBranch = isDefaultBranchOverride ?? (featureBranch ? false : isDefaultBranch); |
| 263 | 259 | const includesCommit = |
| 264 | 260 | !forcePushOnlyProgress && (action === "commit" || !!actionStatus?.hasWorkingTreeChanges); |
| 265 | 261 | if ( |
| 266 | 262 | !skipDefaultBranchPrompt && |
| 267 | | !featureBranch && |
| 268 | 263 | requiresDefaultBranchConfirmation(action, actionIsDefaultBranch) && |
| 269 | 264 | actionBranch |
| 270 | 265 | ) { |
| ... | ... | @@ -292,17 +287,28 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions |
| 292 | 287 | featureBranch, |
| 293 | 288 | ...(pushTarget ? { pushTarget } : {}), |
| 294 | 289 | }); |
| 295 | | const progressToastId = toastManager.add({ |
| 296 | | type: "loading", |
| 297 | | title: progressStages[0] ?? "Running git action...", |
| 298 | | timeout: 0, |
| 299 | | data: threadToastData, |
| 300 | | }); |
| 290 | const resolvedProgressToastId = |
| 291 | progressToastId ?? |
| 292 | toastManager.add({ |
| 293 | type: "loading", |
| 294 | title: progressStages[0] ?? "Running git action...", |
| 295 | timeout: 0, |
| 296 | data: threadToastData, |
| 297 | }); |
| 298 | |
| 299 | if (progressToastId) { |
| 300 | toastManager.update(progressToastId, { |
| 301 | type: "loading", |
| 302 | title: progressStages[0] ?? "Running git action...", |
| 303 | timeout: 0, |
| 304 | data: threadToastData, |
| 305 | }); |
| 306 | } |
| 301 | 307 | |
| 302 | 308 | let stageIndex = 0; |
| 303 | 309 | const stageInterval = setInterval(() => { |
| 304 | 310 | stageIndex = Math.min(stageIndex + 1, progressStages.length - 1); |
| 305 | | toastManager.update(progressToastId, { |
| 311 | toastManager.update(resolvedProgressToastId, { |
| 306 | 312 | title: progressStages[stageIndex] ?? "Running git action...", |
| 307 | 313 | type: "loading", |
| 308 | 314 | timeout: 0, |
| ... | ... | @@ -338,10 +344,10 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions |
| 338 | 344 | result.push.status === "pushed" && |
| 339 | 345 | !actionIsDefaultBranch; |
| 340 | 346 | const closeResultToast = () => { |
| 341 | | toastManager.close(progressToastId); |
| 347 | toastManager.close(resolvedProgressToastId); |
| 342 | 348 | }; |
| 343 | 349 | |
| 344 | | toastManager.update(progressToastId, { |
| 350 | toastManager.update(resolvedProgressToastId, { |
| 345 | 351 | type: "success", |
| 346 | 352 | title: resultToast.title, |
| 347 | 353 | description: resultToast.description, |
| ... | ... | @@ -359,8 +365,8 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions |
| 359 | 365 | action: "commit_push", |
| 360 | 366 | forcePushOnlyProgress: true, |
| 361 | 367 | onConfirmed: closeResultToast, |
| 362 | | ...(featureBranch ? { skipDefaultBranchPrompt: true } : {}), |
| 363 | | ...(featureBranch ? { isDefaultBranchOverride: false } : {}), |
| 368 | statusOverride: actionStatus, |
| 369 | isDefaultBranchOverride: actionIsDefaultBranch, |
| 364 | 370 | }); |
| 365 | 371 | }, |
| 366 | 372 | }, |
| ... | ... | @@ -386,8 +392,8 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions |
| 386 | 392 | void runGitActionWithToast({ |
| 387 | 393 | action: "commit_push_pr", |
| 388 | 394 | forcePushOnlyProgress: true, |
| 389 | | ...(featureBranch ? { skipDefaultBranchPrompt: true } : {}), |
| 390 | | ...(featureBranch ? { isDefaultBranchOverride: false } : {}), |
| 395 | statusOverride: actionStatus, |
| 396 | isDefaultBranchOverride: actionIsDefaultBranch, |
| 391 | 397 | }); |
| 392 | 398 | }, |
| 393 | 399 | }, |
| ... | ... | @@ -396,7 +402,7 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions |
| 396 | 402 | }); |
| 397 | 403 | } catch (err) { |
| 398 | 404 | stopProgressUpdates(); |
| 399 | | toastManager.update(progressToastId, { |
| 405 | toastManager.update(resolvedProgressToastId, { |
| 400 | 406 | type: "error", |
| 401 | 407 | title: "Action failed", |
| 402 | 408 | description: err instanceof Error ? err.message : "An error occurred.", |
| ... | ... | @@ -406,7 +412,7 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions |
| 406 | 412 | }, |
| 407 | 413 | |
| 408 | 414 | [ |
| 409 | | isDefaultBranchName, |
| 415 | isDefaultBranch, |
| 410 | 416 | runImmediateGitActionMutation, |
| 411 | 417 | setPendingDefaultBranchAction, |
| 412 | 418 | threadToastData, |
| ... | ... | @@ -424,7 +430,6 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions |
| 424 | 430 | forcePushOnlyProgress, |
| 425 | 431 | ...(onConfirmed ? { onConfirmed } : {}), |
| 426 | 432 | skipDefaultBranchPrompt: true, |
| 427 | | isDefaultBranchOverride: true, |
| 428 | 433 | }); |
| 429 | 434 | }, [pendingDefaultBranchAction, runGitActionWithToast]); |
| 430 | 435 | |