From 44f290da5413361825e2fb51b2b247832578ab3d Mon Sep 17 00:00:00 2001 From: Robin Kutesa Date: Sun, 17 May 2026 14:08:37 +0300 Subject: [PATCH] Show destination folder row always, activate after auth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove slide-in animation — destination row is always visible but dimmed (opacity 0.45, taps blocked) until credentials are verified. On successful auth it becomes fully active, green border appears once a valid path is chosen. Co-Authored-By: Kutesir Co-Authored-By: Sentry --- Features/Connect/ConnectView.swift | 74 ++++++++++++++++-------------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/Features/Connect/ConnectView.swift b/Features/Connect/ConnectView.swift index 75b6a3f..61f5f9b 100644 --- a/Features/Connect/ConnectView.swift +++ b/Features/Connect/ConnectView.swift @@ -175,43 +175,47 @@ struct ConnectView: View { .animation(.spring(response: 0.3, dampingFraction: 0.8), value: vm.isConnected) .animation(.spring(response: 0.3, dampingFraction: 0.8), value: vm.verifyError != nil) - // ── Step 2: Destination folder — slides in after auth ── - if vm.step != .credentials { - Button(action: { vm.showFolderBrowser = true }) { - HStack(spacing: 12) { - Image(systemName: vm.remotePath == "/" ? "folder" : "folder.fill") - .font(.system(size: 14, weight: .regular)) - .foregroundStyle(vm.remotePath == "/" ? AppTheme.inkSecondary : AppTheme.positive) - .frame(width: 20) - Text(vm.remotePath == "/" ? "Select destination folder" : vm.remotePath) - .font(AppTheme.body()) - .foregroundStyle(vm.remotePath == "/" ? AppTheme.inkTertiary : AppTheme.ink) - .lineLimit(2) - .multilineTextAlignment(.leading) - .frame(maxWidth: .infinity, alignment: .leading) - Image(systemName: "chevron.right") - .font(.system(size: 12, weight: .medium)) - .foregroundStyle(AppTheme.inkQuaternary) - } - .padding(.horizontal, 16) - .padding(.vertical, 14) - .background(AppTheme.surfaceRaised) - .clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous)) - .overlay( - RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous) - .stroke( - vm.step == .ready ? AppTheme.positive.opacity(0.45) : Color.clear, - lineWidth: 1 - ) - ) - .shadow(color: AppTheme.cardShadow, radius: 12, x: 0, y: 2) + // ── Destination folder — always visible, active only after auth ── + Button(action: { if vm.isConnected { vm.showFolderBrowser = true } }) { + HStack(spacing: 12) { + Image(systemName: vm.remotePath == "/" ? "folder" : "folder.fill") + .font(.system(size: 14, weight: .regular)) + .foregroundStyle( + !vm.isConnected ? AppTheme.inkQuaternary : + vm.remotePath == "/" ? AppTheme.inkSecondary : AppTheme.positive + ) + .frame(width: 20) + Text(vm.remotePath == "/" ? "Destination folder" : vm.remotePath) + .font(AppTheme.body()) + .foregroundStyle( + !vm.isConnected ? AppTheme.inkQuaternary : + vm.remotePath == "/" ? AppTheme.inkTertiary : AppTheme.ink + ) + .lineLimit(2) + .multilineTextAlignment(.leading) + .frame(maxWidth: .infinity, alignment: .leading) + Image(systemName: "folder.badge.plus") + .font(.system(size: 16)) + .foregroundStyle(vm.isConnected ? AppTheme.inkSecondary : AppTheme.inkQuaternary) } - .buttonStyle(ScaleButtonStyle()) - .padding(.horizontal, AppTheme.hPad) - .padding(.bottom, 12) - .transition(.opacity.combined(with: .move(edge: .top))) - .animation(.spring(response: 0.35, dampingFraction: 0.8), value: vm.step) + .padding(.horizontal, 16) + .padding(.vertical, 14) + .background(AppTheme.surfaceRaised) + .clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous)) + .overlay( + RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous) + .stroke( + vm.step == .ready ? AppTheme.positive.opacity(0.45) : Color.clear, + lineWidth: 1 + ) + ) + .shadow(color: AppTheme.cardShadow, radius: 12, x: 0, y: 2) + .opacity(vm.isConnected ? 1 : 0.45) + .animation(.spring(response: 0.3, dampingFraction: 0.8), value: vm.isConnected) } + .buttonStyle(ScaleButtonStyle()) + .padding(.horizontal, AppTheme.hPad) + .padding(.bottom, 12) // ── Status message ── HStack(spacing: 6) {