@@ -22,8 +22,13 @@ struct ConnectionFormView: View {
2222 @State private var database = " "
2323 @State private var sslEnabled = false
2424
25- // SQLite file picker
26- @State private var showFilePicker = false
25+ // File pickers
26+ enum ActiveFilePicker : Identifiable {
27+ case sqliteDatabase
28+ case sshKey
29+ var id : Int { hashValue }
30+ }
31+ @State private var activeFilePicker : ActiveFilePicker ?
2732 @State private var selectedFileURL : URL ?
2833 @State private var showNewDatabaseAlert = false
2934 @State private var newDatabaseName = " "
@@ -43,7 +48,12 @@ struct ConnectionFormView: View {
4348 @State private var sshKeyContent = " "
4449 @State private var sshKeyPassphrase = " "
4550 @State private var sshKeyInputMode = KeyInputMode . file
46- @State private var showSSHKeyPicker = false
51+ private var showFilePicker : Binding < Bool > {
52+ Binding (
53+ get: { activeFilePicker != nil } ,
54+ set: { if !$0 { activeFilePicker = nil } }
55+ )
56+ }
4757
4858 enum KeyInputMode : String , CaseIterable {
4959 case file = " Import File "
@@ -207,13 +217,11 @@ struct ConnectionFormView: View {
207217 if let stored = try ? appState. secureStore. retrieve ( forKey: connKey) , !stored. isEmpty {
208218 password = stored
209219 }
210- if sshEnabled {
211- if let sshPwd = try ? appState. secureStore. retrieve ( forKey: " com.TablePro.sshpassword. \( conn. id. uuidString) " ) , !sshPwd. isEmpty {
212- sshPassword = sshPwd
213- }
214- if let passphrase = try ? appState. secureStore. retrieve ( forKey: " com.TablePro.keypassphrase. \( conn. id. uuidString) " ) , !passphrase. isEmpty {
215- sshKeyPassphrase = passphrase
216- }
220+ if let sshPwd = try ? appState. secureStore. retrieve ( forKey: " com.TablePro.sshpassword. \( conn. id. uuidString) " ) , !sshPwd. isEmpty {
221+ sshPassword = sshPwd
222+ }
223+ if let passphrase = try ? appState. secureStore. retrieve ( forKey: " com.TablePro.keypassphrase. \( conn. id. uuidString) " ) , !passphrase. isEmpty {
224+ sshKeyPassphrase = passphrase
217225 }
218226 }
219227 }
@@ -229,26 +237,32 @@ struct ConnectionFormView: View {
229237 }
230238 }
231239 . fileImporter (
232- isPresented: $showSSHKeyPicker ,
233- allowedContentTypes: [ . data] ,
240+ isPresented: showFilePicker ,
241+ allowedContentTypes: activeFilePicker == . sqliteDatabase ? sqliteContentTypes : [ . data] ,
234242 allowsMultipleSelection: false
235243 ) { result in
236- if case . success( let urls) = result, let url = urls. first {
237- guard url. startAccessingSecurityScopedResource ( ) else { return }
238- defer { url. stopAccessingSecurityScopedResource ( ) }
239-
240- // Read key content directly — more reliable than copying file
241- if let content = try ? String ( contentsOf: url, encoding: . utf8) {
242- sshKeyContent = content
243- sshKeyInputMode = . paste
244- } else {
245- // Fallback: copy to app Documents
246- guard let docsDir = FileManager . default. urls ( for: . documentDirectory, in: . userDomainMask) . first else { return }
247- let dest = docsDir. appendingPathComponent ( " ssh_ " + url. lastPathComponent)
248- try ? FileManager . default. removeItem ( at: dest)
249- try ? FileManager . default. copyItem ( at: url, to: dest)
250- sshKeyPath = dest. path
244+ let picker = activeFilePicker
245+ activeFilePicker = nil
246+ switch picker {
247+ case . sqliteDatabase:
248+ handleFilePickerResult ( result)
249+ case . sshKey:
250+ if case . success( let urls) = result, let url = urls. first {
251+ guard url. startAccessingSecurityScopedResource ( ) else { return }
252+ defer { url. stopAccessingSecurityScopedResource ( ) }
253+ if let content = try ? String ( contentsOf: url, encoding: . utf8) {
254+ sshKeyContent = content
255+ sshKeyInputMode = . paste
256+ } else {
257+ guard let docsDir = FileManager . default. urls ( for: . documentDirectory, in: . userDomainMask) . first else { return }
258+ let dest = docsDir. appendingPathComponent ( " ssh_ " + url. lastPathComponent)
259+ try ? FileManager . default. removeItem ( at: dest)
260+ try ? FileManager . default. copyItem ( at: url, to: dest)
261+ sshKeyPath = dest. path
262+ }
251263 }
264+ case nil :
265+ break
252266 }
253267 }
254268 . alert ( " New Database " , isPresented: $showNewDatabaseAlert) {
@@ -293,7 +307,7 @@ struct ConnectionFormView: View {
293307 }
294308
295309 Button {
296- showFilePicker = true
310+ activeFilePicker = . sqliteDatabase
297311 } label: {
298312 Label ( " Open Database File " , systemImage: " folder " )
299313 }
@@ -304,13 +318,6 @@ struct ConnectionFormView: View {
304318 Label ( " Create New Database " , systemImage: " plus.circle " )
305319 }
306320 }
307- . fileImporter (
308- isPresented: $showFilePicker,
309- allowedContentTypes: sqliteContentTypes,
310- allowsMultipleSelection: false
311- ) { result in
312- handleFilePickerResult ( result)
313- }
314321 }
315322
316323 // MARK: - Server Section (MySQL, PostgreSQL, Redis)
@@ -377,7 +384,7 @@ struct ConnectionFormView: View {
377384
378385 if sshKeyInputMode == . file {
379386 Button {
380- showSSHKeyPicker = true
387+ activeFilePicker = . sshKey
381388 } label: {
382389 HStack {
383390 Text ( sshKeyPath. isEmpty
0 commit comments