Initial public release of Warp.
Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# APP-3919: Commit Dialog — Tech Spec
|
||||
|
||||
Product spec: `specs/APP-3919/PRODUCT.md`
|
||||
Branch: `edward/commit-dialog`
|
||||
|
||||
## Relevant Code
|
||||
|
||||
- `app/src/code_review/commit_dialog.rs` — new file, entire dialog view
|
||||
- `app/src/code_review/code_review_view.rs` — `open_commit_dialog`, dialog overlay rendering, action wiring
|
||||
- `app/src/util/git.rs` — `get_file_change_entries`, `FileChangeEntry`
|
||||
- `app/src/code_review/mod.rs` — module registration
|
||||
|
||||
## Changes
|
||||
|
||||
### 1. `CommitDialog` view (`commit_dialog.rs`)
|
||||
|
||||
New 718-line view implementing the dialog UI. Key types:
|
||||
|
||||
- `CommitIntent` enum — `CommitOnly` (future: `CommitAndPush`, `CommitAndCreatePr`)
|
||||
- `CommitDialogAction` — internal actions: `Cancel`, `Confirm`, `SetIntent`, `ToggleIncludeUnstaged`, `ToggleChangesExpanded`
|
||||
- `CommitDialogEvent` — events emitted to parent: `Confirmed { message, intent, include_unstaged }`, `Cancelled`
|
||||
|
||||
State:
|
||||
- `repo_path`, `branch_name` — set at construction
|
||||
- `intent: CommitIntent` — which action to take on confirm
|
||||
- `include_unstaged: bool` — toggle for staged-only vs all changes (default: true)
|
||||
- `file_changes: Vec<FileChangeEntry>` — loaded async on open and on toggle
|
||||
- `changes_expanded: bool` — collapsible file list
|
||||
- `message_editor: ViewHandle<EditorView>` — commit message input
|
||||
|
||||
The dialog uses the existing `Dialog` component with `dialog_styles`. The message editor uses `EditorView` with `soft_wrap`, `autogrow`, and `supports_vim_mode: false`.
|
||||
|
||||
File changes are loaded on construction and reloaded when `include_unstaged` is toggled. The confirm button is disabled when there are no files or no message.
|
||||
|
||||
### 2. `get_file_change_entries` (`git.rs`)
|
||||
|
||||
New async function that returns per-file change stats:
|
||||
|
||||
```rust
|
||||
pub async fn get_file_change_entries(
|
||||
repo_path: &Path,
|
||||
include_unstaged: bool,
|
||||
) -> Result<Vec<FileChangeEntry>>
|
||||
```
|
||||
|
||||
- When `include_unstaged` is true: runs `git diff --numstat HEAD` + `git ls-files --others --exclude-standard` for untracked files
|
||||
- When false: runs `git diff --cached --numstat` (staged only)
|
||||
- Returns `FileChangeEntry { path, additions, deletions }` for each file
|
||||
|
||||
### 3. Dialog lifecycle in `CodeReviewView`
|
||||
|
||||
New field: `commit_dialog: Option<ViewHandle<CommitDialog>>`
|
||||
|
||||
`open_commit_dialog` method:
|
||||
1. Guards against double-open
|
||||
2. Gets repo path and branch name from `DiffStateModel`
|
||||
3. Creates `CommitDialog` view
|
||||
4. Subscribes to `CommitDialogEvent`:
|
||||
- `Confirmed` → closes dialog, spawns async `run_commit`, shows success/error toast, reloads diffs + metadata + PR info
|
||||
- `Cancelled` → closes dialog
|
||||
5. Focuses the dialog
|
||||
|
||||
### 4. Overlay rendering
|
||||
|
||||
The dialog is rendered as a positioned overlay in `View::render`, using the same pattern as the discard confirmation dialog. Both dialogs are mutually exclusive — only one modal can be open at a time.
|
||||
|
||||
### 5. Action wiring
|
||||
|
||||
`CodeReviewAction::OpenCommitDialog` now calls `self.open_commit_dialog(ctx)` instead of being a TODO stub. `CommitAndPush` and `CommitAndCreatePr` remain stubs for child branches.
|
||||
|
||||
### 6. Post-commit refresh
|
||||
|
||||
After commit (success or failure):
|
||||
- `load_diffs_for_active_repo(false, ctx)` — reloads diffs
|
||||
- `refresh_diff_metadata_for_current_repo(PromptRefresh)` — updates stats
|
||||
- `refresh_pr_info(ctx)` — updates PR button state
|
||||
|
||||
## End-to-End Flow
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[User clicks Commit button] --> B[open_commit_dialog]
|
||||
B --> C[CommitDialog created + focused]
|
||||
C --> D{User action}
|
||||
D -->|Cancel/ESC| E[Dialog closes]
|
||||
D -->|Confirm| F[CommitDialogEvent::Confirmed emitted]
|
||||
F --> G[run_commit async]
|
||||
G -->|success| H[Toast: 'Changes successfully committed']
|
||||
G -->|failure| I[Toast: error message]
|
||||
H --> J[Reload diffs + metadata + PR info]
|
||||
I --> J
|
||||
```
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- Wire `CommitAndPush` intent (push-dialog branch)
|
||||
- Wire `CommitAndCreatePr` intent (pr-dialog branch)
|
||||
- Auto-generate commit message when left blank (AI integration)
|
||||
- Per-file staging/unstaging in the changes panel
|
||||
- Commit amend support
|
||||
Reference in New Issue
Block a user