Show destination folder row always, activate after auth

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 <kutesir@provoc.ug>
Co-Authored-By: Sentry <sentry@provoc.ug>
This commit is contained in:
Robin Kutesa
2026-05-17 14:08:37 +03:00
parent 00f68eebcd
commit 44f290da54

View File

@@ -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.isConnected)
.animation(.spring(response: 0.3, dampingFraction: 0.8), value: vm.verifyError != nil) .animation(.spring(response: 0.3, dampingFraction: 0.8), value: vm.verifyError != nil)
// Step 2: Destination folder slides in after auth // Destination folder always visible, active only after auth
if vm.step != .credentials { Button(action: { if vm.isConnected { vm.showFolderBrowser = true } }) {
Button(action: { vm.showFolderBrowser = true }) { HStack(spacing: 12) {
HStack(spacing: 12) { Image(systemName: vm.remotePath == "/" ? "folder" : "folder.fill")
Image(systemName: vm.remotePath == "/" ? "folder" : "folder.fill") .font(.system(size: 14, weight: .regular))
.font(.system(size: 14, weight: .regular)) .foregroundStyle(
.foregroundStyle(vm.remotePath == "/" ? AppTheme.inkSecondary : AppTheme.positive) !vm.isConnected ? AppTheme.inkQuaternary :
.frame(width: 20) vm.remotePath == "/" ? AppTheme.inkSecondary : AppTheme.positive
Text(vm.remotePath == "/" ? "Select destination folder" : vm.remotePath) )
.font(AppTheme.body()) .frame(width: 20)
.foregroundStyle(vm.remotePath == "/" ? AppTheme.inkTertiary : AppTheme.ink) Text(vm.remotePath == "/" ? "Destination folder" : vm.remotePath)
.lineLimit(2) .font(AppTheme.body())
.multilineTextAlignment(.leading) .foregroundStyle(
.frame(maxWidth: .infinity, alignment: .leading) !vm.isConnected ? AppTheme.inkQuaternary :
Image(systemName: "chevron.right") vm.remotePath == "/" ? AppTheme.inkTertiary : AppTheme.ink
.font(.system(size: 12, weight: .medium)) )
.foregroundStyle(AppTheme.inkQuaternary) .lineLimit(2)
} .multilineTextAlignment(.leading)
.padding(.horizontal, 16) .frame(maxWidth: .infinity, alignment: .leading)
.padding(.vertical, 14) Image(systemName: "folder.badge.plus")
.background(AppTheme.surfaceRaised) .font(.system(size: 16))
.clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous)) .foregroundStyle(vm.isConnected ? AppTheme.inkSecondary : AppTheme.inkQuaternary)
.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)
} }
.buttonStyle(ScaleButtonStyle()) .padding(.horizontal, 16)
.padding(.horizontal, AppTheme.hPad) .padding(.vertical, 14)
.padding(.bottom, 12) .background(AppTheme.surfaceRaised)
.transition(.opacity.combined(with: .move(edge: .top))) .clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous))
.animation(.spring(response: 0.35, dampingFraction: 0.8), value: vm.step) .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 // Status message
HStack(spacing: 6) { HStack(spacing: 6) {