Config screen
This commit is contained in:
parent
ac88e62abe
commit
4b3c512a9d
28 changed files with 2015 additions and 59 deletions
121
docs/plans/feature-5-restore.md
Normal file
121
docs/plans/feature-5-restore.md
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
# Feature 5: Restore
|
||||
|
||||
## Context
|
||||
Allows users to restore a previous backup, replacing their current WoW configuration. This is a destructive operation (overwrites current WTF/Interface folders), so it requires clear confirmation and progress feedback.
|
||||
|
||||
## Dependencies
|
||||
- **Depends on**: Feature 0 (config, platform), Feature 1 (screen routing), Feature 3 (BackupHistory, BackupEntry)
|
||||
- **Depended on by**: None (final feature)
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Step 1: Restore engine
|
||||
**Files to create:**
|
||||
- `composeApp/src/jvmMain/kotlin/com/rukira/wowbackup/backup/RestoreEngine.kt`
|
||||
|
||||
Responsibilities:
|
||||
- Given a `BackupEntry`, restore its contents to the WoW install directory
|
||||
- Handle both plain folder backups and ZIP backups
|
||||
- Process:
|
||||
1. Verify source backup exists
|
||||
2. Verify WoW install path exists
|
||||
3. Delete existing WTF/ and/or Interface/ in WoW install (only the ones present in the backup)
|
||||
4. Copy/extract backup contents to WoW install location
|
||||
- Report progress: total files, files restored, current file
|
||||
- Cancellable via coroutine cancellation
|
||||
- Return `RestoreResult` (success/failure)
|
||||
|
||||
```kotlin
|
||||
data class RestoreProgress(
|
||||
val totalFiles: Int,
|
||||
val completedFiles: Int,
|
||||
val currentFile: String,
|
||||
)
|
||||
|
||||
sealed class RestoreResult {
|
||||
data class Success(val restoredFiles: Int, val durationMs: Long) : RestoreResult()
|
||||
data class Failure(val reason: String, val exception: Throwable? = null) : RestoreResult()
|
||||
}
|
||||
```
|
||||
|
||||
### Step 2: RestoreViewModel
|
||||
**Files to create:**
|
||||
- `composeApp/src/jvmMain/kotlin/com/rukira/wowbackup/ui/restore/RestoreViewModel.kt`
|
||||
|
||||
State:
|
||||
```kotlin
|
||||
data class RestoreUiState(
|
||||
val backups: List<BackupEntry>, // available backups
|
||||
val selectedBackup: BackupEntry?, // user selection
|
||||
val showConfirmDialog: Boolean,
|
||||
val isRestoring: Boolean,
|
||||
val progress: RestoreProgress?,
|
||||
val result: RestoreResult?,
|
||||
)
|
||||
```
|
||||
|
||||
Actions:
|
||||
- `selectBackup(entry)` — select a backup from the list
|
||||
- `confirmRestore()` — show confirmation dialog
|
||||
- `startRestore()` — begin restore process
|
||||
- `cancelRestore()` — cancel in-progress restore
|
||||
- `dismiss()` — clear result and return to list
|
||||
|
||||
### Step 3: Build the RestoreScreen composable
|
||||
**Files to create:**
|
||||
- `composeApp/src/jvmMain/kotlin/com/rukira/wowbackup/ui/restore/RestoreScreen.kt`
|
||||
|
||||
Layout:
|
||||
|
||||
#### Header
|
||||
- "Restore Backup" title
|
||||
- "Open Backup Folder" button
|
||||
|
||||
#### Backup List
|
||||
- Scrollable list of all existing backups
|
||||
- Each row shows:
|
||||
- Date/time in human-readable format ("January 15, 2024 at 3:00 AM")
|
||||
- Size (e.g., "142 MB")
|
||||
- Type badge: "Compressed" or "Folder"
|
||||
- "Restore" button
|
||||
- Empty state: "No backups found. Run a backup first."
|
||||
|
||||
#### Confirmation Dialog (reuses ConfirmationDialog from Feature 2)
|
||||
- Title: "Restore Backup?"
|
||||
- Message: "This will replace your current WoW settings (WTF and Interface folders) with the backup from [date]. This action cannot be undone. Make sure WoW is not running."
|
||||
- Buttons: "Cancel" / "Restore" (destructive style)
|
||||
|
||||
#### Restore Progress (replaces list while restoring)
|
||||
- `LinearProgressIndicator` with percentage
|
||||
- File count: "142 / 350 files"
|
||||
- Current file name
|
||||
- Estimated time remaining (based on average file copy speed)
|
||||
- "Cancel" button
|
||||
|
||||
#### Result
|
||||
- Success: "Restore complete. X files restored."
|
||||
- Failure: "Restore failed: <reason>". Show "Try Again" button.
|
||||
|
||||
### Step 4: Wire into App.kt routing
|
||||
**Files to modify:**
|
||||
- `composeApp/src/jvmMain/kotlin/com/rukira/wowbackup/App.kt`
|
||||
|
||||
Replace restore placeholder with `RestoreScreen(viewModel, onNavigateToStatus)`.
|
||||
|
||||
## Edge Cases
|
||||
- WoW is running during restore → warn user but allow (they confirmed)
|
||||
- Backup file is corrupted/missing → show clear error
|
||||
- Insufficient disk space → detect before starting, show error
|
||||
- Restore cancelled mid-way → partial state warning: "Restore was cancelled. Your WoW configuration may be in an incomplete state."
|
||||
|
||||
## Verification
|
||||
1. Restore screen lists all existing backups with correct dates and sizes
|
||||
2. Empty state shows when no backups exist
|
||||
3. Selecting "Restore" shows confirmation dialog with correct date
|
||||
4. Cancelling dialog returns to list without action
|
||||
5. Confirming starts restore with live progress indicator
|
||||
6. Cancel button during restore stops the operation
|
||||
7. Successful restore copies all files to WoW install directory
|
||||
8. ZIP backups are extracted correctly
|
||||
9. Folder backups are copied correctly
|
||||
10. Error states display clearly (corrupted backup, missing paths)
|
||||
Loading…
Add table
Add a link
Reference in a new issue