mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-16 13:05:53 +00:00
Fix CLI installation animation issues in welcome dialog
- Added withAnimation wrapper to all state changes in CLIInstaller - Added small delay before checking installation status to allow view to settle - Updated permission text to say "AppleScript automation" - All state transitions now animate smoothly with 0.3s easeInOut - Fixed the "CLI tool is installed" text popping in without animation
This commit is contained in:
parent
042163d3ab
commit
90849a11e2
3 changed files with 41 additions and 14 deletions
Binary file not shown.
|
|
@ -229,7 +229,13 @@ private struct VTCommandPageView: View {
|
|||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.padding()
|
||||
.onAppear {
|
||||
cliInstaller.checkInstallationStatus()
|
||||
// Delay slightly to allow view to settle before animating
|
||||
Task {
|
||||
try? await Task.sleep(nanoseconds: 100_000_000) // 0.1 seconds
|
||||
await MainActor.run {
|
||||
cliInstaller.checkInstallationStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -255,7 +261,7 @@ private struct RequestPermissionsPageView: View {
|
|||
.fontWeight(.semibold)
|
||||
|
||||
Text(
|
||||
"VibeTunnel needs AppleScript to launch and manage terminal sessions\nand accessibility to send commands to certain terminals."
|
||||
"VibeTunnel needs AppleScript automation to launch and manage terminal sessions\nand accessibility to send commands to certain terminals."
|
||||
)
|
||||
.font(.body)
|
||||
.foregroundColor(.secondary)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import AppKit
|
||||
import Foundation
|
||||
import Observation
|
||||
import SwiftUI
|
||||
import os.log
|
||||
|
||||
/// Service responsible for creating symlinks to command line tools with sudo authentication.
|
||||
|
|
@ -36,7 +37,13 @@ final class CLIInstaller {
|
|||
/// Checks if the CLI tool is installed
|
||||
func checkInstallationStatus() {
|
||||
let targetPath = "/usr/local/bin/vt"
|
||||
isInstalled = FileManager.default.fileExists(atPath: targetPath)
|
||||
let installed = FileManager.default.fileExists(atPath: targetPath)
|
||||
|
||||
// Animate the state change for smooth UI transitions
|
||||
withAnimation(.easeInOut(duration: 0.3)) {
|
||||
isInstalled = installed
|
||||
}
|
||||
|
||||
logger.info("CLIInstaller: CLI tool installed: \(self.isInstalled)")
|
||||
}
|
||||
|
||||
|
|
@ -50,14 +57,18 @@ final class CLIInstaller {
|
|||
/// Installs the vt CLI tool to /usr/local/bin with proper symlink
|
||||
func installCLITool() {
|
||||
logger.info("CLIInstaller: Starting CLI tool installation...")
|
||||
isInstalling = true
|
||||
lastError = nil
|
||||
withAnimation(.easeInOut(duration: 0.3)) {
|
||||
isInstalling = true
|
||||
lastError = nil
|
||||
}
|
||||
|
||||
guard let resourcePath = Bundle.main.path(forResource: "vt", ofType: nil) else {
|
||||
logger.error("CLIInstaller: Could not find vt binary in app bundle")
|
||||
lastError = "The vt command line tool could not be found in the application bundle."
|
||||
showError("The vt command line tool could not be found in the application bundle.")
|
||||
isInstalling = false
|
||||
withAnimation(.easeInOut(duration: 0.3)) {
|
||||
isInstalling = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +90,9 @@ final class CLIInstaller {
|
|||
let response = alert.runModal()
|
||||
if response != .alertFirstButtonReturn {
|
||||
logger.info("CLIInstaller: User cancelled replacement")
|
||||
isInstalling = false
|
||||
withAnimation(.easeInOut(duration: 0.3)) {
|
||||
isInstalling = false
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -98,7 +111,9 @@ final class CLIInstaller {
|
|||
let response = confirmAlert.runModal()
|
||||
if response != .alertFirstButtonReturn {
|
||||
logger.info("CLIInstaller: User cancelled installation")
|
||||
isInstalling = false
|
||||
withAnimation(.easeInOut(duration: 0.3)) {
|
||||
isInstalling = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -174,21 +189,27 @@ final class CLIInstaller {
|
|||
|
||||
if task.terminationStatus == 0 {
|
||||
logger.info("CLIInstaller: Installation completed successfully")
|
||||
isInstalled = true
|
||||
isInstalling = false
|
||||
withAnimation(.easeInOut(duration: 0.3)) {
|
||||
isInstalled = true
|
||||
isInstalling = false
|
||||
}
|
||||
showSuccess()
|
||||
} else {
|
||||
let errorData = errorPipe.fileHandleForReading.readDataToEndOfFile()
|
||||
let errorString = String(data: errorData, encoding: .utf8) ?? "Unknown error"
|
||||
logger.error("CLIInstaller: Installation failed with status \(task.terminationStatus): \(errorString)")
|
||||
lastError = "Installation failed: \(errorString)"
|
||||
isInstalling = false
|
||||
withAnimation(.easeInOut(duration: 0.3)) {
|
||||
lastError = "Installation failed: \(errorString)"
|
||||
isInstalling = false
|
||||
}
|
||||
showError("Installation failed: \(errorString)")
|
||||
}
|
||||
} catch {
|
||||
logger.error("CLIInstaller: Installation failed with error: \(error)")
|
||||
lastError = "Installation failed: \(error.localizedDescription)"
|
||||
isInstalling = false
|
||||
withAnimation(.easeInOut(duration: 0.3)) {
|
||||
lastError = "Installation failed: \(error.localizedDescription)"
|
||||
isInstalling = false
|
||||
}
|
||||
showError("Installation failed: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue