@@ -48,6 +48,9 @@ struct Django_FilesApp: App {
48
48
@State private var hasExistingSessions = false
49
49
@State private var isLoading = true
50
50
@State private var selectedTab : TabViewWindow . Tab = . files
51
+ @State private var showingServerConfirmation = false
52
+ @State private var pendingAuthURL : URL ? = nil
53
+ @State private var pendingAuthSignature : String ? = nil
51
54
52
55
init ( ) {
53
56
// print("📱 Setting up WebSocketToastObserver")
@@ -62,18 +65,40 @@ struct Django_FilesApp: App {
62
65
. onAppear {
63
66
checkForExistingSessions ( )
64
67
}
65
- } else if hasExistingSessions {
66
- TabViewWindow ( sessionManager: sessionManager, selectedTab: $selectedTab)
67
- } else {
68
+ } else if !hasExistingSessions {
68
69
SessionEditor ( onBoarding: true , session: nil , onSessionCreated: { newSession in
69
70
sessionManager. selectedSession = newSession
70
71
hasExistingSessions = true
71
72
} )
73
+ } else if sessionManager. selectedSession == nil {
74
+ NavigationStack {
75
+ ServerSelector ( selectedSession: $sessionManager. selectedSession)
76
+ . navigationTitle ( " Select Server " )
77
+ }
78
+ } else {
79
+ TabViewWindow ( sessionManager: sessionManager, selectedTab: $selectedTab)
72
80
}
73
81
}
74
82
. onOpenURL { url in
75
83
handleDeepLink ( url)
76
84
}
85
+ . sheet ( isPresented: $showingServerConfirmation) {
86
+ ServerConfirmationView (
87
+ serverURL: $pendingAuthURL,
88
+ signature: $pendingAuthSignature,
89
+ onConfirm: { setAsDefault in
90
+ Task {
91
+ await handleServerConfirmation ( confirmed: true , setAsDefault: setAsDefault)
92
+ }
93
+ } ,
94
+ onCancel: {
95
+ Task {
96
+ await handleServerConfirmation ( confirmed: false , setAsDefault: false )
97
+ }
98
+ } ,
99
+ context: sharedModelContainer. mainContext
100
+ )
101
+ }
77
102
}
78
103
. modelContainer ( sharedModelContainer)
79
104
#if os(macOS)
@@ -97,7 +122,7 @@ struct Django_FilesApp: App {
97
122
case " authorize " :
98
123
deepLinkAuth ( components)
99
124
case " serverlist " :
100
- selectedTab = . serverList
125
+ selectedTab = . settings
101
126
case " filelist " :
102
127
handleFileListDeepLink ( components)
103
128
default :
@@ -149,40 +174,111 @@ struct Django_FilesApp: App {
149
174
do {
150
175
let existingSessions = try context. fetch ( descriptor)
151
176
if let existingSession = existingSessions. first ( where: { $0. url == serverURL. absoluteString } ) {
152
- // If session exists, update it on the main thread
177
+ // If session exists, just select it and update UI
153
178
await MainActor . run {
154
179
sessionManager. selectedSession = existingSession
155
180
hasExistingSessions = true
181
+ ToastManager . shared. showToast ( message: " Connected to existing server \( existingSession. url) " )
156
182
}
157
183
return
158
184
}
159
185
160
- // If no existing session, create and authenticate a new one
161
- if let newSession = await sessionManager. createAndAuthenticateSession (
162
- url: serverURL,
163
- signature: signature,
164
- context: context
165
- ) {
166
- // Update the UI on the main thread
167
- await MainActor . run {
168
- sessionManager. selectedSession = newSession
169
- hasExistingSessions = true
170
- ToastManager . shared. showToast ( message: " Successfully logged into \( newSession. url) " )
171
- }
186
+ // No existing session, show confirmation dialog
187
+ await MainActor . run {
188
+ pendingAuthURL = serverURL
189
+ pendingAuthSignature = signature
190
+ showingServerConfirmation = true
172
191
}
173
192
} catch {
174
193
print ( " Error checking for existing sessions: \( error) " )
175
194
}
176
195
}
177
196
}
178
197
198
+ private func handleServerConfirmation( confirmed: Bool , setAsDefault: Bool ) async {
199
+ guard let serverURL = pendingAuthURL,
200
+ let signature = pendingAuthSignature else {
201
+ return
202
+ }
203
+
204
+ // If user cancelled, just clear the pending data and return
205
+ if !confirmed {
206
+ pendingAuthURL = nil
207
+ pendingAuthSignature = nil
208
+ return
209
+ }
210
+
211
+ // Create and authenticate the new session
212
+ let context = sharedModelContainer. mainContext
213
+ let descriptor = FetchDescriptor < DjangoFilesSession > ( )
214
+
215
+ do {
216
+ let existingSessions = try context. fetch ( descriptor)
217
+
218
+ // If no existing session, create and authenticate a new one
219
+ if let newSession = await sessionManager. createAndAuthenticateSession (
220
+ url: serverURL,
221
+ signature: signature,
222
+ context: context
223
+ ) {
224
+ // Update the UI on the main thread
225
+ await MainActor . run {
226
+ if setAsDefault {
227
+ // Reset all other sessions to not be default
228
+ for session in existingSessions {
229
+ session. defaultSession = false
230
+ }
231
+ newSession. defaultSession = true
232
+ }
233
+ sessionManager. selectedSession = newSession
234
+ hasExistingSessions = true
235
+ selectedTab = . files
236
+ ToastManager . shared. showToast ( message: " Successfully logged into \( newSession. url) " )
237
+ }
238
+ }
239
+ } catch {
240
+ ToastManager . shared. showToast ( message: " Problem signing into server \( error) " )
241
+ print ( " Error creating new session: \( error) " )
242
+ }
243
+
244
+ // Clear pending auth data
245
+ pendingAuthURL = nil
246
+ pendingAuthSignature = nil
247
+ }
248
+
249
+ private func checkDefaultServer( ) {
250
+ let context = sharedModelContainer. mainContext
251
+ let descriptor = FetchDescriptor < DjangoFilesSession > ( )
252
+
253
+ Task {
254
+ do {
255
+ let sessions = try context. fetch ( descriptor)
256
+ await MainActor . run {
257
+ if sessionManager. selectedSession == nil {
258
+ if let defaultSession = sessions. first ( where: { $0. defaultSession } ) {
259
+ sessionManager. selectedSession = defaultSession
260
+ selectedTab = . files
261
+ } else {
262
+ selectedTab = . settings
263
+ }
264
+ }
265
+ }
266
+ } catch {
267
+ print ( " Error checking for default server: \( error) " )
268
+ }
269
+ }
270
+ }
271
+
179
272
private func checkForExistingSessions( ) {
180
273
let context = sharedModelContainer. mainContext
181
274
let descriptor = FetchDescriptor < DjangoFilesSession > ( )
182
275
183
276
do {
184
277
let sessionsCount = try context. fetchCount ( descriptor)
185
278
hasExistingSessions = sessionsCount > 0
279
+ if hasExistingSessions {
280
+ checkDefaultServer ( )
281
+ }
186
282
isLoading = false // Set loading to false after check completes
187
283
} catch {
188
284
print ( " Error checking for existing sessions: \( error) " )
0 commit comments