@@ -11,21 +11,28 @@ import android.net.Uri
11
11
import android.os.Build
12
12
import android.os.Bundle
13
13
import android.util.Log
14
+ import android.webkit.CookieManager
14
15
import android.widget.TextView
15
16
import android.widget.Toast
16
17
import androidx.activity.enableEdgeToEdge
17
18
import androidx.activity.result.ActivityResultLauncher
18
19
import androidx.activity.result.contract.ActivityResultContracts
19
20
import androidx.activity.viewModels
20
21
import androidx.appcompat.app.AppCompatActivity
22
+ import androidx.core.content.edit
23
+ import androidx.core.net.toUri
21
24
import androidx.core.view.GravityCompat
22
25
import androidx.drawerlayout.widget.DrawerLayout
26
+ import androidx.lifecycle.lifecycleScope
23
27
import androidx.navigation.NavController
24
28
import androidx.navigation.NavOptions
25
29
import androidx.navigation.fragment.NavHostFragment
26
30
import androidx.navigation.ui.NavigationUI
27
31
import com.djangofiles.djangofiles.databinding.ActivityMainBinding
28
32
import com.djangofiles.djangofiles.ui.home.HomeViewModel
33
+ import kotlinx.coroutines.Dispatchers
34
+ import kotlinx.coroutines.launch
35
+ import kotlinx.coroutines.withContext
29
36
import java.net.URL
30
37
31
38
class MainActivity : AppCompatActivity () {
@@ -149,29 +156,35 @@ class MainActivity : AppCompatActivity() {
149
156
150
157
private fun handleIntent (intent : Intent , savedInstanceState : Bundle ? ) {
151
158
Log .d(" handleIntent" , " intent: $intent " )
152
- Log .d(" handleIntent" , " intent.data: ${intent.data} " )
153
- Log .d(" handleIntent" , " intent.type: ${intent.type} " )
154
- Log .d(" handleIntent" , " intent.action: ${intent.action} " )
159
+ val data = intent.data
160
+ val type = intent.type
161
+ val action = intent.action
162
+ Log .d(" handleIntent" , " data: $data " )
163
+ Log .d(" handleIntent" , " type: $type " )
164
+ Log .d(" handleIntent" , " action: $action " )
155
165
156
166
val extraText = intent.getStringExtra(Intent .EXTRA_TEXT )
157
167
Log .d(" handleIntent" , " extraText: $extraText " )
158
168
159
169
val sharedPreferences = getSharedPreferences(" AppPreferences" , MODE_PRIVATE )
160
170
val savedUrl = sharedPreferences.getString(" saved_url" , null )
161
171
Log .d(" handleIntent" , " savedUrl: $savedUrl " )
172
+ Log .d(" handleIntent" , " data?.host: ${data?.host} " )
162
173
// val authToken = sharedPreferences.getString("auth_token", null)
163
174
// Log.d("handleIntent", "authToken: $authToken")
164
175
165
- if (savedUrl.isNullOrEmpty()) {
166
- Log .i(" handleIntent" , " Missing Saved URL or Token..." )
176
+ Log .d(" handleIntent" , " data?.host: ${data?.host} " )
177
+ if (data?.host != " oauth" && savedUrl.isNullOrEmpty()) {
178
+ Log .i(" handleIntent" , " Missing Saved URL or Token! Showing Login..." )
167
179
180
+ setDrawerLockMode(false )
168
181
navController.navigate(
169
- R .id.nav_item_setup , null , NavOptions .Builder ()
182
+ R .id.nav_item_login , null , NavOptions .Builder ()
170
183
.setPopUpTo(R .id.nav_item_home, true )
171
184
.build()
172
185
)
173
186
174
- } else if (Intent .ACTION_MAIN == intent. action) {
187
+ } else if (Intent .ACTION_MAIN == action) {
175
188
Log .d(" handleIntent" , " ACTION_MAIN: ${savedInstanceState?.size()} " )
176
189
177
190
binding.drawerLayout.closeDrawers()
@@ -207,7 +220,7 @@ class MainActivity : AppCompatActivity() {
207
220
filePickerLauncher.launch(arrayOf(" */*" ))
208
221
}
209
222
210
- } else if (Intent .ACTION_SEND == intent. action) {
223
+ } else if (Intent .ACTION_SEND == action) {
211
224
Log .d(" handleIntent" , " ACTION_SEND" )
212
225
213
226
val fileUri = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .TIRAMISU ) {
@@ -243,10 +256,10 @@ class MainActivity : AppCompatActivity() {
243
256
Log .w(" handleIntent" , " NOT IMPLEMENTED" )
244
257
}
245
258
} else {
246
- showPreview(fileUri, intent. type)
259
+ showPreview(fileUri, type)
247
260
}
248
261
249
- } else if (Intent .ACTION_SEND_MULTIPLE == intent. action) {
262
+ } else if (Intent .ACTION_SEND_MULTIPLE == action) {
250
263
Log .d(" handleIntent" , " ACTION_SEND_MULTIPLE" )
251
264
252
265
val fileUris = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .TIRAMISU ) {
@@ -267,27 +280,35 @@ class MainActivity : AppCompatActivity() {
267
280
Toast .makeText(this , " Not Yet Implemented!" , Toast .LENGTH_LONG ).show()
268
281
Log .w(" handleIntent" , " NOT IMPLEMENTED" )
269
282
270
- } else if (Intent .ACTION_VIEW == intent. action) {
283
+ } else if (Intent .ACTION_VIEW == action) {
271
284
Log .d(" handleIntent" , " ACTION_VIEW" )
272
285
273
- if (" djangofiles" == intent.data?.scheme) {
274
- Log .d(" handleIntent" , " scheme: ${intent.data?.scheme} " )
275
- val host = intent.data?.host
276
- Log .d(" handleIntent" , " host: $host " )
277
- if (" serverlist" == host) {
286
+ if (data == null ) {
287
+ Toast .makeText(this , " That's a Bug!" , Toast .LENGTH_LONG ).show()
288
+ Log .e(" handleIntent" , " BUG: UNKNOWN action: $action " )
289
+ return
290
+ }
291
+ if (" djangofiles" == data.scheme) {
292
+ Log .d(" handleIntent" , " scheme: ${data.scheme} " )
293
+ Log .d(" handleIntent" , " host: ${data.host} " )
294
+ if (" serverlist" == data.host) {
278
295
Log .d(" handleIntent" , " djangofiles://serverlist" )
279
296
navController.navigate(R .id.nav_item_settings)
297
+ } else if (" logout" == data.host) {
298
+ processLogout()
299
+ } else if (" oauth" == data.host) {
300
+ processOauth(data)
280
301
} else {
281
302
Toast .makeText(this , " Unknown DeepLink!" , Toast .LENGTH_LONG ).show()
282
303
Log .w(" handleIntent" , " Unknown DeepLink!" )
283
304
}
284
305
} else {
285
- Log .d(" handleIntent" , " File URI: ${intent. data} " )
286
- showPreview(intent. data, intent. type)
306
+ Log .d(" handleIntent" , " File URI: $data " )
307
+ showPreview(data, type)
287
308
}
288
309
} else {
289
310
Toast .makeText(this , " That's a Bug!" , Toast .LENGTH_LONG ).show()
290
- Log .e(" handleIntent" , " BUG: UNKNOWN intent. action: ${intent. action} " )
311
+ Log .e(" handleIntent" , " BUG: UNKNOWN action: $action " )
291
312
}
292
313
}
293
314
@@ -315,6 +336,112 @@ class MainActivity : AppCompatActivity() {
315
336
// .build()
316
337
// navController.navigate(R.id.nav_item_preview, bundle, navOptions)
317
338
}
339
+
340
+ private fun processOauth (data : Uri ) {
341
+ // TODO: Can do this in a fragment to show loading screen/errors eventually...
342
+ Log .d(" handleIntent" , " processOauth: data: $data " )
343
+ val token = data.getQueryParameter(" token" )
344
+ val sessionKey = data.getQueryParameter(" session_key" )
345
+ val error = data.getQueryParameter(" error" )
346
+
347
+ // TODO: Handle null data and errors
348
+ Log .d(" handleIntent" , " token: $token " )
349
+ Log .d(" handleIntent" , " session_key: $sessionKey " )
350
+ Log .d(" handleIntent" , " error: $error " )
351
+
352
+ // TODO: Determine how to better get oauthUrl
353
+ val sharedPreferences = this .getSharedPreferences(" AppPreferences" , MODE_PRIVATE )
354
+ val oauthUrl = sharedPreferences.getString(" oauth_host" , null )
355
+ Log .d(" handleIntent" , " oauthUrl: $oauthUrl " )
356
+ if (oauthUrl == null ) {
357
+ // TODO: Handle this error...
358
+ Log .e(" handleIntent" , " oauthUrl is null" )
359
+ return
360
+ }
361
+
362
+ sharedPreferences.edit {
363
+ putString(" saved_url" , oauthUrl)
364
+ putString(" auth_token" , token)
365
+ }
366
+ lifecycleScope.launch {
367
+ val dao: ServerDao =
368
+ ServerDatabase .getInstance(this @MainActivity).serverDao()
369
+ withContext(Dispatchers .IO ) {
370
+ dao.add(Server (url = oauthUrl, token = token!! , active = true ))
371
+ }
372
+ }
373
+
374
+ val cookieManager = CookieManager .getInstance()
375
+ // cookieManager.setAcceptThirdPartyCookies(webView, true)
376
+ val cookie = " sessionid=$sessionKey ; Path=/; HttpOnly; Secure"
377
+ Log .d(" handleIntent" , " cookie: $cookie " )
378
+
379
+ val uri = oauthUrl.toUri()
380
+ val origin = " ${uri.scheme} ://${uri.authority} "
381
+ Log .d(" handleIntent" , " origin: $origin " )
382
+ cookieManager.setCookie(origin, cookie) { cookieManager.flush() }
383
+
384
+ Log .d(" handleIntent" , " navigate: nav_item_home - setPopUpTo: nav_item_login" )
385
+ setDrawerLockMode(true )
386
+ navController.navigate(
387
+ R .id.nav_item_home, null , NavOptions .Builder ()
388
+ .setPopUpTo(R .id.nav_item_login, true )
389
+ .build()
390
+ )
391
+ }
392
+
393
+ private fun processLogout () {
394
+ val sharedPreferences = this .getSharedPreferences(" AppPreferences" , MODE_PRIVATE )
395
+ val savedUrl = sharedPreferences.getString(" saved_url" , null )
396
+ Log .d(" processLogout" , " savedUrl: $savedUrl " )
397
+ sharedPreferences.edit {
398
+ remove(" saved_url" )
399
+ remove(" auth_token" )
400
+ }
401
+ val dao: ServerDao = ServerDatabase .getInstance(this ).serverDao()
402
+ lifecycleScope.launch {
403
+ if (savedUrl != null ) {
404
+ Log .d(" processLogout" , " dao.delete: $savedUrl " )
405
+ val server = Server (url = savedUrl)
406
+ Log .d(" processLogout" , " server: $server " )
407
+ withContext(Dispatchers .IO ) { dao.delete(server) }
408
+ }
409
+ val servers = withContext(Dispatchers .IO ) { dao.getAll() }
410
+ Log .d(" processLogout" , " servers: $servers " )
411
+ if (servers.isEmpty()) {
412
+ Log .d(" processLogout" , " NO MORE SERVERS - LOCK TO LOGIN" )
413
+ // (requireActivity() as MainActivity).setDrawerLockMode(false)
414
+ setDrawerLockMode(false )
415
+ // TODO: Confirm this removes history and locks user to login
416
+ navController.navigate(
417
+ R .id.nav_item_login, null , NavOptions .Builder ()
418
+ .setPopUpTo(R .id.nav_item_home, true )
419
+ .build()
420
+ )
421
+ } else {
422
+ Log .d(" processLogout" , " MORE SERVERS - ACTIVATE ONE" )
423
+ // servers.firstOrNull()?.let { dao.activate(it.url) }
424
+ val server = servers.first()
425
+ Log .d(" processLogout" , " server: $server " )
426
+ withContext(Dispatchers .IO ) { dao.activate(server.url) }
427
+
428
+ sharedPreferences.edit().apply {
429
+ putString(" saved_url" , server.url)
430
+ putString(" auth_token" , server.token)
431
+ apply ()
432
+ }
433
+
434
+ Log .d(" processLogout" , " navigate: nav_item_login" )
435
+ // TODO: Determine proper navigate call here...
436
+ navController.navigate(R .id.nav_item_settings)
437
+ // findNavController().navigate(
438
+ // R.id.nav_item_settings, null, NavOptions.Builder()
439
+ // .setPopUpTo(R.id.nav_item_home, true)
440
+ // .build()
441
+ // )
442
+ }
443
+ }
444
+ }
318
445
}
319
446
320
447
fun copyToClipboard (context : Context , url : String ) {
0 commit comments